build 5.3.2
diff --git a/bin/build-as-modular-es5.sh b/bin/build-as-modular-es5.sh
deleted file mode 100755
index c29ca8b..0000000
--- a/bin/build-as-modular-es5.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# This script builds `src` to `lib` in a modular style that preserves the
-# original file structure. This is useful for things like 1) unit tests, which
-# need to "reach inside" the bundle, and 2) coverage reports, which need to be
-# able to run all tests against the codebase, including the unit tests.
-#
-
-npm run build
-
-# In this case, Babel is roughly equivalent to what Rollup would do.
-# "add-module-exports" gives us a backwards-compatible CJS module structure
-# that doesn't oblige use to do require('foo').default for every module.
-
-./node_modules/.bin/babel \
-  --plugins add-module-exports,transform-es2015-modules-commonjs \
-  --out-dir lib src
-
-# Add a version number to both files (equivalent to build.sh)
-
-VERSION=$(node -e "console.log(require('./package.json').version)")
-./node_modules/.bin/replace --silent __VERSION__ $VERSION lib/*
-
-# Make the extras point back to the modular code (instead of being bundles).
-
-echo "module.exports = require('../deps/promise');" \
-    > lib/extras/promise.js
-
-echo "module.exports = require('../replicate/checkpointer');" \
-    > lib/extras/checkpointer.js
-
-echo "module.exports = require('../deps/ajax/prequest');" \
-    > lib/extras/ajax.js
-
-echo "module.exports = require('../replicate/generateReplicationId');" \
-    > lib/extras/generateReplicationId.js
\ No newline at end of file
diff --git a/bin/build-node.sh b/bin/build-node.sh
deleted file mode 100755
index d819c6d..0000000
--- a/bin/build-node.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-
-# Don't rebuild in Travis; only during development. This screws with
-# our coverage/unit tests (https://github.com/pouchdb/pouchdb/issues/4767)
-if [[ -z $TRAVIS ]]; then
-  node ./bin/build.js node
-fi
\ No newline at end of file
diff --git a/bin/build-site.js b/bin/build-site.js
deleted file mode 100755
index 5ff6825..0000000
--- a/bin/build-site.js
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var http_server = require('http-server');
-var Promise = require('lie');
-var fs = require('fs');
-var watchGlob = require('watch-glob');
-var replace = require('replace');
-var exec = require('child-process-promise').exec;
-var mkdirp = require('mkdirp');
-
-var POUCHDB_CSS = __dirname + '/../docs/static/css/pouchdb.css';
-var POUCHDB_LESS = __dirname + '/../docs/static/less/pouchdb/pouchdb.less';
-
-process.chdir('docs');
-
-function checkJekyll() {
-  return exec('gem list jekyll -i').then(function (result) {
-    if (!/true/.test(result.stdout)) {
-      throw new Error('You need to do: gem install jekyll');
-    }
-  });
-}
-
-function buildCSS() {
-  mkdirp.sync(__dirname + '/../docs/static/css');
-  var cmd = __dirname + '/../node_modules/less/bin/lessc ' + POUCHDB_LESS;
-  return exec(cmd).then(function (child) {
-    fs.writeFileSync(POUCHDB_CSS, child.stdout);
-    console.log('Updated: ', POUCHDB_CSS);
-  });
-}
-
-function buildJekyll(path) {
-  // Dont rebuild on website artifacts being written
-  if (path && /^_site/.test(path.relative)) {
-    return;
-  }
-  return exec('jekyll build').then(function () {
-    console.log('=> Rebuilt jekyll');
-    return highlightEs6();
-  }).then(function () {
-    console.log('=> Highlighted ES6');
-  });
-}
-
-function highlightEs6() {
-  var path = require('path').resolve(__dirname, '../docs/_site');
-
-  // TODO: this is a fragile and hacky way to get
-  // 'async' and 'await' to highlight correctly
-  // in this blog post.
-  replace({
-    regex: '<span class="nx">(await|async|of)</span>',
-    replacement: '<span class="kd">$1</span>',
-    paths: [path],
-    recursive: true
-  });
-}
-
-function onError(err) {
-  console.error(err);
-  process.exit(1);
-}
-
-function buildEverything() {
-  return Promise.resolve()
-    .then(checkJekyll)
-    .then(buildCSS)
-    .then(buildJekyll)
-    .catch(onError);
-}
-
-if (!process.env.BUILD) {
-  watchGlob('**', buildJekyll);
-  watchGlob('docs/static/less/*/*.less', buildCSS);
-  http_server.createServer({root: '_site', cache: '-1'}).listen(4000);
-  console.log('Server address: http://0.0.0.0:4000');
-}
-
-buildEverything();
diff --git a/bin/build.js b/bin/build.js
deleted file mode 100644
index 6c5cb30..0000000
--- a/bin/build.js
+++ /dev/null
@@ -1,247 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var lie = require('lie');
-if (typeof Promise === 'undefined') {
-  global.Promise = lie; // required for denodeify in node 0.10
-}
-var denodeify = require('denodeify');
-var browserify = require('browserify');
-var collapse = require('bundle-collapser/plugin');
-var es3ify = require('es3ify');
-var rollup = require('rollup');
-var derequire = require('derequire');
-var fs = require('fs');
-var writeFileAsync = denodeify(fs.writeFile);
-var renameAsync = denodeify(fs.rename);
-var ncp = denodeify(require('ncp').ncp);
-var rimraf = denodeify(require('rimraf'));
-var mkdirp = denodeify(require('mkdirp'));
-var streamToPromise = require('stream-to-promise');
-var findit = require('findit');
-var spawn = require('child_process').spawn;
-
-var pkg = require('../package.json');
-var version = pkg.version;
-var external = Object.keys(pkg.dependencies).concat([
- 'fs', 'crypto', 'events', 'path', 'pouchdb'
-]);
-
-var plugins = ['fruitdown', 'localstorage', 'memory'];
-var extras = {
-  'src/deps/promise.js': 'promise.js',
-  'src/replicate/checkpointer.js': 'checkpointer.js',
-  'src/replicate/generateReplicationId.js': 'generateReplicationId.js',
-  'src/deps/ajax/prequest.js': 'ajax.js',
-  'src/plugins/websql/index.js': 'websql.js',
-  'src_browser/deps/ajax/prequest.js': 'ajax-browser.js',
-  'src_browser/replicate/checkpointer.js': 'checkpointer-browser.js',
-  'src_browser/replicate/generateReplicationId.js':
-    'generateReplicationId-browser.js'
-};
-
-var currentYear = new Date().getFullYear();
-
-var comments = {
-  'pouchdb': '// PouchDB ' + version +
-  '\n// ' +
-  '\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
-  '\n// PouchDB may be freely distributed under the Apache license, ' +
-  'version 2.0.' +
-  '\n// For all details and documentation:' +
-  '\n// http://pouchdb.com\n',
-
-  'memory': '// PouchDB in-memory plugin ' + version +
-  '\n// Based on MemDOWN: https://github.com/rvagg/memdown' +
-  '\n// ' +
-  '\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
-  '\n// PouchDB may be freely distributed under the Apache license, ' +
-  'version 2.0.' +
-  '\n// For all details and documentation:' +
-  '\n// http://pouchdb.com\n',
-
-  'localstorage': '// PouchDB localStorage plugin ' + version +
-  '\n// Based on localstorage-down: https://github.com/No9/localstorage-down' +
-  '\n// ' +
-  '\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
-  '\n// PouchDB may be freely distributed under the Apache license, ' +
-  'version 2.0.' +
-  '\n// For all details and documentation:' +
-  '\n// http://pouchdb.com\n',
-
-  'fruitdown': '// PouchDB fruitdown plugin ' + version +
-  '\n// Based on FruitDOWN: https://github.com/nolanlawson/fruitdown' +
-  '\n// ' +
-  '\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
-  '\n// PouchDB may be freely distributed under the Apache license, ' +
-  'version 2.0.' +
-  '\n// For all details and documentation:' +
-  '\n// http://pouchdb.com\n'
-};
-
-function writeFile(filename, contents) {
-  var tmp = filename + '.tmp';
-  return writeFileAsync(tmp, contents, 'utf-8').then(function () {
-    return renameAsync(tmp, filename);
-  }).then(function () {
-    console.log('Wrote ' + filename);
-  });
-}
-
-function addVersion(code) {
-  return code.replace('__VERSION__', version);
-}
-
-// do uglify in a separate process for better perf
-function doUglify(code, prepend, fileOut) {
-  var binPath = require.resolve('uglify-js/bin/uglifyjs');
-  var args = [binPath, '-c', '-m', 'warnings=false', '-'];
-
-  var child = spawn(process.execPath, args, {stdio: 'pipe'});
-  child.stdin.setEncoding('utf-8');
-  child.stdin.write(code);
-  child.stdin.end();
-  return streamToPromise(child.stdout).then(function (min) {
-    min = prepend + min;
-    return writeFile(fileOut, min);
-  });
-}
-
-function doBrowserify(path, opts, exclude) {
-  var b = browserify(path, opts);
-  b.transform(es3ify).plugin(collapse);
-
-  if (exclude) {
-    b.external(exclude);
-  }
-
-  return streamToPromise(b.bundle()).then(function (code) {
-    code = derequire(code);
-    return code;
-  });
-}
-
-function doRollup(entry, fileOut) {
-  return rollup.rollup({
-    entry: entry,
-    external: external
-  }).then(function (bundle) {
-    var code = bundle.generate({format: 'cjs'}).code;
-    return writeFile(fileOut, addVersion(code));
-  });
-}
-
-// build for Node (index.js)
-function buildForNode() {
-  return mkdirp('lib').then(function () {
-    return doRollup('src/index.js', 'lib/index.js');
-  });
-}
-
-// build for Browserify/Webpack (index-browser.js)
-function buildForBrowserify() {
-  return ncp('src', 'src_browser').then(function () {
-    return new Promise(function (resolve, reject) {
-      var files = [];
-      findit('src_browser').on('file', function (file) {
-        if (/-browser.js$/.test(file)) {
-          files.push(file);
-        }
-      }).on('end', function () {
-        resolve(files);
-      }).on('error', reject);
-    });
-  }).then(function (files) {
-    return Promise.all(files.map(function (file) {
-      return renameAsync(file, file.replace('-browser', ''));
-    }));
-  }).then(function () {
-    return doRollup('src_browser/index.js', 'lib/index-browser.js');
-  });
-}
-
-// build for the browser (dist)
-function buildForBrowser() {
-  return mkdirp('dist').then(function () {
-    return doBrowserify('.', {standalone: 'PouchDB'});
-  }).then(function (code) {
-    code = comments.pouchdb + code;
-    return Promise.all([
-      writeFile('dist/pouchdb.js', code),
-      doUglify(code, comments.pouchdb, 'dist/pouchdb.min.js')
-    ]);
-  });
-}
-
-function buildPerformanceBundle() {
-  return doBrowserify('tests/performance', {
-    debug: true,
-    fullPaths: true
-  }).then(function (code) {
-    return writeFile('tests/performance-bundle.js', code);
-  });
-}
-
-function cleanup() {
-  return rimraf('src_browser');
-}
-
-function buildPluginsForBrowserify() {
-  return mkdirp('lib/extras').then(function () {
-    return Promise.all(plugins.map(function (plugin) {
-      return doRollup('src_browser/plugins/' + plugin + '/index.js',
-                      'lib/extras/' + plugin + '.js');
-    }));
-  });
-}
-
-function buildExtras() {
-  return mkdirp('lib/extras').then(function () {
-    return Promise.all(Object.keys(extras).map(function (entry) {
-      var target = extras[entry];
-      return doRollup(entry, 'lib/extras/' + target);
-    }));
-  });
-}
-
-function buildPluginsForBrowser() {
-  return mkdirp('lib/extras').then(function () {
-    return Promise.all(plugins.map(function (plugin) {
-      var source = 'lib/extras/' + plugin + '.js';
-      return doBrowserify(source, {}, 'pouchdb').then(function (code) {
-        code = comments[plugin] + code;
-        return Promise.all([
-          writeFile('dist/pouchdb.' + plugin + '.js', code),
-          doUglify(code, comments[plugin], 'dist/pouchdb.' + plugin + '.min.js')
-        ]);
-      });
-    }));
-  });
-}
-
-if (process.argv[2] === 'node') {
-  rimraf('lib').then(buildForNode).then(function () {
-    process.exit(0);
-  }).catch(function (err) {
-    console.log(err.stack);
-    process.exit(1);
-  });
-} else {
-  Promise.resolve()
-    .then(function () { return rimraf('lib'); })
-    .then(function () { return rimraf('dist'); })
-    .then(buildForNode)
-    .then(buildForBrowserify)
-    .then(buildForBrowser)
-    .then(buildPluginsForBrowserify)
-    .then(buildPluginsForBrowser)
-    .then(buildExtras)
-    .then(buildPerformanceBundle)
-    .then(cleanup)
-    .catch(function (err) {
-      console.log(err.stack);
-      process.exit(1);
-    }
-  );
-}
diff --git a/bin/dev-server.js b/bin/dev-server.js
deleted file mode 100755
index f715c50..0000000
--- a/bin/dev-server.js
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var Promise = require('lie');
-var watch = require('node-watch');
-var http_server = require('http-server');
-var spawn = require('child_process').spawn;
-
-var queryParams = {};
-
-if (process.env.ADAPTERS) {
-  queryParams.adapters = process.env.ADAPTERS;
-}
-if (process.env.AUTO_COMPACTION) {
-  queryParams.autoCompaction = true;
-}
-if (process.env.POUCHDB_SRC) {
-  queryParams.src = process.env.POUCHDB_SRC;
-}
-if (process.env.COUCH_HOST) {
-  queryParams.couchHost = process.env.COUCH_HOST;
-}
-
-var rebuildPromise = Promise.resolve();
-
-function rebuild() {
-  // only run one build at a time
-  rebuildPromise = rebuildPromise.then(function () {
-    return new Promise(function (resolve) {
-      var child = spawn('npm', ['run', 'build']);
-      child.stdout.on('data', function (buf) {
-        console.log(String(buf).replace(/\s*$/, ''));
-      });
-      child.stderr.on('data', function (buf) {
-        console.log(String(buf).replace(/\s*$/, ''));
-      });
-      child.on('close', resolve);
-    });
-  });
-  return rebuildPromise;
-}
-
-watch('./src', rebuild);
-
-var filesWritten = false;
-
-Promise.resolve().then(function () {
-  if (require.main !== module) {
-    return; // don't bother rebuilding if we're in `npm run dev`
-  }
-  return rebuild();
-}).then(function () {
-  filesWritten = true;
-  checkReady();
-});
-
-var HTTP_PORT = 8000;
-
-// if SERVER=sync-gateway we also have 
-// tests/misc/sync-gateway-config-server.js 
-// listening on port 8001
-
-var serversStarted;
-var readyCallback;
-
-function startServers(callback) {
-  readyCallback = callback;
-  http_server.createServer().listen(HTTP_PORT, function () {
-    var testRoot = 'http://127.0.0.1:' + HTTP_PORT;
-    var query = '';
-    Object.keys(queryParams).forEach(function (key) {
-      query += (query ? '&' : '?');
-      query += key + '=' + encodeURIComponent(queryParams[key]);
-    });
-    console.log('Integration tests: ' + testRoot +
-                '/tests/integration/' + query);
-    console.log('Map/reduce  tests: ' + testRoot +
-                '/tests/mapreduce' + query);
-    console.log('Performance tests: ' + testRoot +
-                '/tests/performance/' + query);
-    serversStarted = true;
-    checkReady();
-  });
-}
-
-function checkReady() {
-  if (filesWritten && serversStarted && readyCallback) {
-    readyCallback();
-  }
-}
-
-if (require.main === module) {
-  startServers();
-} else {
-  module.exports.start = startServers;
-}
diff --git a/bin/es3ify.js b/bin/es3ify.js
deleted file mode 100755
index abcf64a..0000000
--- a/bin/es3ify.js
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env node
-'use strict';
-var es3ify = require('es3ify');
-process.stdin.pipe(es3ify()).pipe(process.stdout);
diff --git a/bin/publish-site.sh b/bin/publish-site.sh
deleted file mode 100755
index 12e84a0..0000000
--- a/bin/publish-site.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# Build the website
-BUILD=1 npm run build-site
-
-# Push the site live, requires credentials, open a bug
-# if you need to be able to push the site
-scp -r docs/_site/* pouchdb@pouchdb.com:/home/pouchdb/www/pouchdb.com/
diff --git a/bin/release.sh b/bin/release.sh
deleted file mode 100755
index 416dcdc..0000000
--- a/bin/release.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-#make sure deps are up to date
-rm -r node_modules
-npm install
-
-# get current version
-VERSION=$(node --eval "console.log(require('./package.json').version);")
-
-# Build
-git checkout -b build
-
-# Publish npm release with tests/scripts/goodies
-# `npm run build` is run as a prepublish step
-npm publish
-
-# Create git tag, which is also the Bower/Github release
-git add dist -f
-git add bower.json component.json package.json
-git rm -r bin docs scripts tests
-
-git commit -m "build $VERSION"
-
-# Tag and push
-git tag $VERSION
-git push --tags git@github.com:pouchdb/pouchdb.git $VERSION
-
-# Cleanup
-git checkout master
-git branch -D build
diff --git a/bin/run-cordova.sh b/bin/run-cordova.sh
deleted file mode 100755
index 5f9bced..0000000
--- a/bin/run-cordova.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-
-if [[ -z $CLIENT ]]; then
-  echo -e "\nUsing default client (android), you can specify with e.g."
-  echo -e '$CLIENT'"=android" or '$CLIENT'"=ios\n"
-  CLIENT=android
-fi;
-
-if [[ -z $DEVICE ]]; then
-  ACTION=emulate
-  echo -e "\nUsing default "'$DEVICE'"=false, you can also do:"
-  echo -e '$DEVICE'"=true to run on a real device\n"
-else
-  if [[ $DEVICE -ne 'true' ]]; then
-    ACTION=emulate
-  else
-    ACTION=run
-  fi;
-fi;
-
-TESTS_DIR=./tests/integration/cordova
-
-rm -fr $TESTS_DIR/www
-mkdir -p $TESTS_DIR/www
-
-mkdir -p $TESTS_DIR/www/node_modules
-cp -r node_modules/mocha node_modules/chai \
-    $TESTS_DIR/www/node_modules
-mkdir -p $TESTS_DIR/www/tests/integration
-cp -r tests/integration/*{js,html} tests/integration/deps $TESTS_DIR/www/tests/integration
-
-mkdir -p $TESTS_DIR/www/dist
-cp dist/pouchdb*js $TESTS_DIR/www/dist
-
-./node_modules/replace/bin/replace.js '<body>' \
-  '<body><script src="../../cordova.js"></script>' \
-  $TESTS_DIR/www/tests/integration/index.html
-
-if [[ ! -z $GREP ]]; then
-  ./node_modules/replace/bin/replace.js '<body>' \
-    "<body><script>window.GREP = ""'"$GREP"'"";</script>" \
-    $TESTS_DIR/www/tests/integration/index.html
-fi
-
-if [[ ! -z $COUCH_HOST ]]; then
-  ./node_modules/replace/bin/replace.js '<body>' \
-    "<body><script>window.COUCH_HOST = ""'"$COUCH_HOST"'"";</script>" \
-    $TESTS_DIR/www/tests/integration/index.html
-fi
-
-if [[ ! -z $ADAPTER ]]; then
-  ADAPTERS=$ADAPTER # I know I'm gonna mistype this
-fi
-
-if [[ ! -z $ADAPTERS ]]; then
- ./node_modules/replace/bin/replace.js '<body>' \
- "<body><script>window.ADAPTERS = ""'"$ADAPTERS"'"";</script>" \
- $TESTS_DIR/www/tests/integration/index.html
-fi
-
-if [[ ! -z $WEINRE_HOST ]]; then
-  ./node_modules/replace/bin/replace.js '<body>' \
-    "<body><script src=""'"$WEINRE_HOST"/target/target-script-min.js#anonymous""'""></script>" \
-    $TESTS_DIR/www/tests/integration/index.html
-
-fi
-
-cd $TESTS_DIR
-
-CORDOVA=../../../node_modules/cordova/bin/cordova
-
-$CORDOVA platform add $CLIENT
-if [[ $($CORDOVA plugin list | grep sqlite) ]]; then 
-  $CORDOVA plugin rm io.litehelpers.cordova.sqlite
-fi
-if [[ $SQLITE_PLUGIN == 'true' ]]; then 
-  $CORDOVA plugin add https://github.com/litehelpers/Cordova-sqlite-storage.git
-fi
-$CORDOVA $ACTION $CLIENT
diff --git a/bin/run-csg-on-travis.sh b/bin/run-csg-on-travis.sh
deleted file mode 100755
index 05ab0cd..0000000
--- a/bin/run-csg-on-travis.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-set -e
-set -x
-
-CWD=$(pwd)
-
-# Install CSG
-curl -o csg.deb http://packages.couchbase.com/releases/couchbase-sync-gateway/1.0.3/couchbase-sync-gateway-community_1.0.3_x86_64.deb
-
-dpkg --extract csg.deb csg
-cd csg/
-
-# Run CSG
-./opt/couchbase-sync-gateway/bin/sync_gateway ../tests/misc/sync-gateway-config.json >sg.log 2>&1 < /dev/null &
-
-# Lets get rid of this at some point :)
-sleep 2
-
-cd $CWD
diff --git a/bin/run-test.sh b/bin/run-test.sh
deleted file mode 100755
index f40ad14..0000000
--- a/bin/run-test.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/bash
-
-: ${CLIENT:="node"}
-: ${COUCH_HOST:="http://127.0.0.1:5984"}
-
-if [[ ! -z $SERVER ]]; then
-  if [ "$SERVER" == "pouchdb-server" ]; then
-    if [[ "$TRAVIS_REPO_SLUG" == "pouchdb/pouchdb" ]]; then
-      # for pouchdb-server to link to pouchdb, only in travis
-      rm -fr ./node_modules/pouchdb-server/node_modules/pouchdb
-      ln -s ../../.. ./node_modules/pouchdb-server/node_modules/pouchdb
-    fi
-    export COUCH_HOST='http://127.0.0.1:6984'
-    TESTDIR=./tests/pouchdb_server
-    rm -rf $TESTDIR && mkdir -p $TESTDIR
-    FLAGS="--dir $TESTDIR"
-    if [[ ! -z $SERVER_ADAPTER ]]; then
-      FLAGS="$FLAGS --level-backend $SERVER_ADAPTER"
-    fi
-    if [[ ! -z $SERVER_PREFIX ]]; then
-      FLAGS="$FLAGS --level-prefix $SERVER_PREFIX"
-    fi
-    echo -e "Starting up pouchdb-server with flags: $FLAGS \n"
-    ./node_modules/.bin/pouchdb-server -n -p 6984 $FLAGS &
-    export SERVER_PID=$!
-  elif [ "$SERVER" == "couchdb-master" ]; then
-    if [ -z $COUCH_HOST ]; then
-      export COUCH_HOST='http://127.0.0.1:15984'
-    fi
-  elif [ "$SERVER" == "pouchdb-express-router" ]; then
-    node ./tests/misc/pouchdb-express-router.js &
-    export SERVER_PID=$!
-    export COUCH_HOST='http://127.0.0.1:3000'
-  elif [ "$SERVER" == "express-pouchdb-minimum" ]; then
-    node ./tests/misc/express-pouchdb-minimum-for-pouchdb.js &
-    export SERVER_PID=$!
-    export COUCH_HOST='http://127.0.0.1:3000'
-  elif [ "$SERVER" == "sync-gateway" ]; then
-    if [[ -z $COUCH_HOST ]]; then
-      export COUCH_HOST='http://127.0.0.1:4985'
-    fi
-    if [[ "$TRAVIS_REPO_SLUG" == "pouchdb/pouchdb" ]]; then
-      ./bin/run-csg-on-travis.sh
-    fi
-    node ./tests/misc/sync-gateway-config-server.js &
-    # not the Sync Gateway pid, the config server pid
-    export SERVER_PID=$!
-  else
-    # I mistype pouchdb-server a lot
-    echo -e "Unknown SERVER $SERVER. Did you mean pouchdb-server?\n"
-    exit 1
-  fi
-fi
-
-if [ "$CLIENT" == "selenium:phantomjs" ]; then
-  npm install phantomjs@2.1.2 # do this on-demand to avoid slow installs
-fi
-
-printf 'Waiting for host to start .'
-WAITING=0
-until $(curl --output /dev/null --silent --head --fail --max-time 2 $COUCH_HOST); do
-    if [ $WAITING -eq 4 ]; then
-        printf '\nHost failed to start\n'
-        exit 1
-    fi
-    let WAITING=WAITING+1
-    printf '.'
-    sleep 5
-done
-printf '\nHost started :)'
-
-if [ "$CLIENT" == "unit" ]; then
-    npm run test-unit
-elif [ "$CLIENT" == "node" ]; then
-    npm run test-node
-elif [ "$CLIENT" == "dev" ]; then
-    npm run launch-dev-server
-else
-    npm run test-browser
-fi
-
-EXIT_STATUS=$?
-if [[ ! -z $SERVER_PID ]]; then
-  kill $SERVER_PID
-fi
-exit $EXIT_STATUS
diff --git a/bin/test-browser.js b/bin/test-browser.js
deleted file mode 100755
index 208a517..0000000
--- a/bin/test-browser.js
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env node
-'use strict';
-
-var wd = require('wd');
-wd.configureHttp({timeout: 180000}); // 3 minutes
-
-var sauceConnectLauncher = require('sauce-connect-launcher');
-var selenium = require('selenium-standalone');
-var querystring = require("querystring");
-var request = require('request').defaults({json: true});
-
-var devserver = require('./dev-server.js');
-
-var testTimeout = 30 * 60 * 1000;
-
-var username = process.env.SAUCE_USERNAME;
-var accessKey = process.env.SAUCE_ACCESS_KEY;
-
-var SELENIUM_VERSION = process.env.SELENIUM_VERSION || '2.45.0';
-
-// BAIL=0 to disable bailing
-var bail = process.env.BAIL !== '0';
-
-// process.env.CLIENT is a colon seperated list of
-// (saucelabs|selenium):browserName:browserVerion:platform
-var tmp = (process.env.CLIENT || 'selenium:firefox').split(':');
-var client = {
-  runner: tmp[0] || 'selenium',
-  browser: tmp[1] || 'firefox',
-  version: tmp[2] || null, // Latest
-  platform: tmp[3] || null
-};
-
-var testRoot = 'http://127.0.0.1:8000/tests/';
-var testUrl;
-if (process.env.PERF) {
-  testUrl = testRoot + 'performance/index.html';
-} else if (process.env.TYPE === 'fuzzy') {
-  testUrl = testRoot + 'fuzzy/index.html';
-} else if (process.env.TYPE === 'mapreduce') {
-  testUrl = testRoot + 'mapreduce/index.html';
-} else {
-  testUrl = testRoot + 'integration/index.html';
-}
-
-var qs = {};
-
-var sauceClient;
-var sauceConnectProcess;
-var tunnelId = process.env.TRAVIS_JOB_NUMBER || 'tunnel-' + Date.now();
-
-if (client.runner === 'saucelabs') {
-  qs.saucelabs = true;
-}
-if (process.env.INVERT) {
-  qs.invert = process.env.INVERT;
-}
-if (process.env.GREP) {
-  qs.grep = process.env.GREP;
-}
-if (process.env.ADAPTERS) {
-  qs.adapters = process.env.ADAPTERS;
-}
-if (process.env.AUTO_COMPACTION) {
-  qs.autoCompaction = true;
-}
-if (process.env.SERVER) {
-  qs.SERVER = process.env.SERVER;
-}
-if (process.env.SKIP_MIGRATION) {
-  qs.SKIP_MIGRATION = process.env.SKIP_MIGRATION;
-}
-if (process.env.POUCHDB_SRC) {
-  qs.src = process.env.POUCHDB_SRC;
-}
-if (process.env.COUCH_HOST) {
-  qs.couchHost = process.env.COUCH_HOST;
-}
-
-testUrl += '?';
-testUrl += querystring.stringify(qs);
-
-if (process.env.TRAVIS &&
-    client.runner === 'saucelabs' &&
-    process.env.TRAVIS_SECURE_ENV_VARS === 'false') {
-  console.error('Not running test, cannot connect to saucelabs');
-  process.exit(0);
-}
-
-function testError(e) {
-  console.error(e);
-  console.error('Doh, tests failed');
-  sauceClient.quit();
-  process.exit(3);
-}
-
-function postResult(result) {
-  if (process.env.PERF && process.env.DASHBOARD_HOST) {
-    result.branch = process.env.TRAVIS_BRANCH || process.env.BRANCH || false;
-    result.commit = process.env.TRAVIS_COMMIT || process.env.COMMIT || false;
-    result.pull_request = process.env.TRAVIS_PULL_REQUEST;
-    var commits = 'https://api.github.com/repos/pouchdb/pouchdb/git/commits/';
-    request({
-      method: 'GET',
-      uri: commits + result.commit,
-      headers: {'User-Agent': 'request'}
-    }, function (error, response, body) {
-      result._id = result.date = body.committer.date;
-      request({
-        method: 'POST',
-        uri: process.env.DASHBOARD_HOST + '/performance_results',
-        json: result
-      }, function (error) {
-        console.log(result);
-        process.exit(!!error);
-      });
-    });
-    return;
-  }
-  process.exit(!process.env.PERF && result.failed ? 1 : 0);
-}
-
-function testComplete(result) {
-  console.log(result);
-
-  sauceClient.quit().then(function () {
-    if (sauceConnectProcess) {
-      sauceConnectProcess.close(function () {
-        postResult(result);
-      });
-    } else {
-      postResult(result);
-    }
-  });
-}
-
-function startSelenium(callback) {
-  // Start selenium
-  var opts = {version: SELENIUM_VERSION};
-  selenium.install(opts, function (err) {
-    if (err) {
-      console.error('Failed to install selenium');
-      process.exit(1);
-    }
-    selenium.start(opts, function () {
-      sauceClient = wd.promiseChainRemote();
-      callback();
-    });
-  });
-}
-
-function startSauceConnect(callback) {
-
-  var options = {
-    username: username,
-    accessKey: accessKey,
-    tunnelIdentifier: tunnelId
-  };
-
-  sauceConnectLauncher(options, function (err, process) {
-    if (err) {
-      console.error('Failed to connect to saucelabs');
-      console.error(err);
-      return process.exit(1);
-    }
-    sauceConnectProcess = process;
-    sauceClient = wd.promiseChainRemote("localhost", 4445, username, accessKey);
-    callback();
-  });
-}
-
-function startTest() {
-
-  console.log('Starting', client);
-
-  var opts = {
-    browserName: client.browser,
-    version: client.version,
-    platform: client.platform,
-    tunnelTimeout: testTimeout,
-    name: client.browser + ' - ' + tunnelId,
-    'max-duration': 60 * 45,
-    'command-timeout': 599,
-    'idle-timeout': 599,
-    'tunnel-identifier': tunnelId
-  };
-
-  sauceClient.init(opts).get(testUrl, function () {
-
-    /* jshint evil: true */
-    var interval = setInterval(function () {
-      sauceClient.eval('window.results', function (err, results) {
-        if (err) {
-          clearInterval(interval);
-          testError(err);
-        } else if (results.completed || (results.failures.length && bail)) {
-          clearInterval(interval);
-          testComplete(results);
-        } else {
-          console.log('=> ', results);
-        }
-      });
-    }, 10 * 1000);
-  });
-}
-
-devserver.start(function () {
-  if (client.runner === 'saucelabs') {
-    startSauceConnect(startTest);
-  } else {
-    startSelenium(startTest);
-  }
-});
diff --git a/bin/test-node.sh b/bin/test-node.sh
deleted file mode 100755
index b077277..0000000
--- a/bin/test-node.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/bash
-
-: ${TIMEOUT:=50000}
-: ${REPORTER:="spec"}
-: ${BAIL:=1}
-: ${TYPE:="integration"}
-
-if [ $BAIL -eq 1 ]; then
-    BAIL_OPT="--bail"
-else
-    BAIL_OPT=""
-fi
-
-if [ $TYPE = "integration" ]; then
-    TESTS_PATH="tests/integration/test.*.js"
-fi
-if [ $TYPE = "fuzzy" ]; then
-    TESTS_PATH="tests/fuzzy/test.*.js"
-fi
-if [ $TYPE = "mapreduce" ]; then
-    TESTS_PATH="tests/mapreduce/test.*.js"
-fi
-if [ $COVERAGE ]; then
-    # run all tests when testing for coverage
-    TESTS_PATH="tests/{unit,integration,mapreduce,component}/test*.js"
-fi
-
-
-if [ $PERF ]; then
-    node tests/performance/index.js
-elif [ ! $COVERAGE ]; then
-    ./node_modules/.bin/mocha \
-        $BAIL_OPT \
-        --timeout $TIMEOUT \
-        --require=./tests/integration/node.setup.js \
-        --reporter=$REPORTER \
-        --grep=$GREP \
-        $TESTS_PATH
-else
-    ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- \
-        $BAIL_OPT \
-        --timeout $TIMEOUT \
-        --require=./tests/integration/node.setup.js \
-        --reporter=$REPORTER \
-        --grep=$GREP \
-        $TESTS_PATH
-fi
-
diff --git a/bin/test-webpack.sh b/bin/test-webpack.sh
deleted file mode 100644
index 5b44df3..0000000
--- a/bin/test-webpack.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# Build PouchDB with Webpack instead of Browserify, and test that.
-# We have this test because there are enough differences between
-# Webpack and Browserify to justify it.
-#
-
-npm run build
-./node_modules/.bin/webpack \
-  --output-library PouchDB --output-library-target umd \
-  . pouchdb-webpack.js
-POUCHDB_SRC='../../pouchdb-webpack.js' npm test
diff --git a/bin/verify-bundle-size.sh b/bin/verify-bundle-size.sh
deleted file mode 100755
index 43389b3..0000000
--- a/bin/verify-bundle-size.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-# Max size in bytes that we find acceptable.
-# We might have to change this later.
-MAX=50000
-
-npm run build
-SIZE=`gzip -c dist/pouchdb.min.js | wc -c`
-
-echo "Checking that pouchdb.min.js size $SIZE is less than $MAX"
-
-if [ "$SIZE" -lt "$MAX" ]; then
-  echo Success
-  exit 0
-else
-  echo Failure
-  exit 1
-fi
\ No newline at end of file
diff --git a/bower.json b/bower.json
index 2cfc481..699f813 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "pouchdb",
-  "version": "5.3.3-prerelease",
+  "version": "5.3.2",
   "description": "PouchDB is a pocket-sized database.",
   "repo": "daleharvey/pouchdb",
   "keywords": [
diff --git a/component.json b/component.json
index 5058dff..97b70d8 100644
--- a/component.json
+++ b/component.json
@@ -1,6 +1,6 @@
 {
   "name": "pouchdb",
-  "version": "5.3.3-prerelease",
+  "version": "5.3.2",
   "description": "PouchDB is a pocket-sized database.",
   "repo": "daleharvey/pouchdb",
   "keywords": [
diff --git a/dist/pouchdb.fruitdown.js b/dist/pouchdb.fruitdown.js
new file mode 100644
index 0000000..6c125fc
--- /dev/null
+++ b/dist/pouchdb.fruitdown.js
@@ -0,0 +1,17760 @@
+// PouchDB fruitdown plugin 5.3.2
+// Based on FruitDOWN: https://github.com/nolanlawson/fruitdown
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var levelup = _interopDefault(_dereq_(48));
+var sublevel = _interopDefault(_dereq_(72));
+var through2 = _dereq_(90);
+var events = _dereq_(23);
+var inherits = _interopDefault(_dereq_(31));
+var pouchdbCollections = _dereq_(53);
+var getArguments = _interopDefault(_dereq_(5));
+var vuvuzela = _interopDefault(_dereq_(95));
+var lie = _interopDefault(_dereq_(52));
+var Md5 = _interopDefault(_dereq_(57));
+var Deque = _interopDefault(_dereq_(19));
+var jsExtend = _dereq_(34);
+var downAdapter = _interopDefault(_dereq_(26));
+
+function isBinaryObject(object) {
+  return object instanceof ArrayBuffer ||
+    (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+  if (typeof buff.slice === 'function') {
+    return buff.slice(0);
+  }
+  // IE10-11 slice() polyfill
+  var target = new ArrayBuffer(buff.byteLength);
+  var targetArray = new Uint8Array(target);
+  var sourceArray = new Uint8Array(buff);
+  targetArray.set(sourceArray);
+  return target;
+}
+
+function cloneBinaryObject(object) {
+  if (object instanceof ArrayBuffer) {
+    return cloneArrayBuffer(object);
+  }
+  var size = object.size;
+  var type = object.type;
+  // Blob
+  if (typeof object.slice === 'function') {
+    return object.slice(0, size, type);
+  }
+  // PhantomJS slice() replacement
+  return object.webkitSlice(0, size, type);
+}
+
+function clone(object) {
+  var newObject;
+  var i;
+  var len;
+
+  if (!object || typeof object !== 'object') {
+    return object;
+  }
+
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone(object[i]);
+    }
+    return newObject;
+  }
+
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
+
+  if (isBinaryObject(object)) {
+    return cloneBinaryObject(object);
+  }
+
+  newObject = {};
+  for (i in object) {
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
+      }
+    }
+  }
+  return newObject;
+}
+
+function isChromeApp() {
+  return (typeof chrome !== "undefined" &&
+    typeof chrome.storage !== "undefined" &&
+    typeof chrome.storage.local !== "undefined");
+}
+
+var hasLocal;
+
+if (isChromeApp()) {
+  hasLocal = false;
+} else {
+  try {
+    localStorage.setItem('_pouch_check_localstorage', 1);
+    hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+  } catch (e) {
+    hasLocal = false;
+  }
+}
+
+function hasLocalStorage() {
+  return hasLocal;
+}
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
+
+inherits(Changes, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (isChromeApp()) {
+    chrome.storage.onChanged.addListener(function (e) {
+      // make sure it's event addressed to us
+      if (e.db_name != null) {
+        //object only has oldValue, newValue members
+        self.emit(e.dbName.newValue);
+      }
+    });
+  } else if (hasLocalStorage()) {
+    if (typeof addEventListener !== 'undefined') {
+      addEventListener("storage", function (e) {
+        self.emit(e.key);
+      });
+    } else { // old IE
+      window.attachEvent("storage", function (e) {
+        self.emit(e.key);
+      });
+    }
+  }
+}
+
+function Changes() {
+  events.EventEmitter.call(this);
+  this._listeners = {};
+
+  attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
+  }
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
+    }
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
+    }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary'
+    ]);
+
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
+    }
+
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        setTimeout(function (){
+          eventFunction();
+        },0);
+      }
+      inprogress = false;
+    }).on('error', onError);
+  }
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
+
+Changes.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
+    return;
+  }
+  events.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+};
+
+
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (isChromeApp()) {
+    chrome.storage.local.set({dbName: dbName});
+  } else if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
+
+Changes.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
+
+// BEGIN Math.uuid.js
+
+/*!
+Math.uuid.js (v1.4)
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+*/
+
+/*
+ * Generate a random uuid.
+ *
+ * USAGE: Math.uuid(length, radix)
+ *   length - the desired number of characters
+ *   radix  - the number of allowable values for each character.
+ *
+ * EXAMPLES:
+ *   // No arguments  - returns RFC4122, version 4 ID
+ *   >>> Math.uuid()
+ *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ *   // One argument - returns ID of the specified length
+ *   >>> Math.uuid(15)     // 15 character ID (default base=62)
+ *   "VcydxgltxrVZSTV"
+ *
+ *   // Two arguments - returns ID of the specified length, and radix. 
+ *   // (Radix must be <= 62)
+ *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
+ *   "01001010"
+ *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
+ *   "47473046"
+ *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
+ *   "098F4D35"
+ */
+var chars = (
+  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
+  'abcdefghijklmnopqrstuvwxyz'
+).split('');
+function getValue(radix) {
+  return 0 | Math.random() * radix;
+}
+function uuid(len, radix) {
+  radix = radix || chars.length;
+  var out = '';
+  var i = -1;
+
+  if (len) {
+    // Compact form
+    while (++i < len) {
+      out += chars[getValue(radix)];
+    }
+    return out;
+  }
+    // rfc4122, version 4 form
+    // Fill in random data.  At i==19 set the high bits of clock sequence as
+    // per rfc4122, sec. 4.1.5
+  while (++i < 36) {
+    switch (i) {
+      case 8:
+      case 13:
+      case 18:
+      case 23:
+        out += '-';
+        break;
+      case 19:
+        out += chars[(getValue(16) & 0x3) | 0x8];
+        break;
+      default:
+        out += chars[getValue(16)];
+    }
+  }
+
+  return out;
+}
+
+inherits(PouchError, Error);
+
+function PouchError(opts) {
+  Error.call(this, opts.reason);
+  this.status = opts.status;
+  this.name = opts.error;
+  this.message = opts.reason;
+  this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
+
+var UNAUTHORIZED = new PouchError({
+  status: 401,
+  error: 'unauthorized',
+  reason: "Name or password is incorrect."
+});
+
+var MISSING_BULK_DOCS = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: "Missing JSON list of 'docs'"
+});
+
+var MISSING_DOC = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'missing'
+});
+
+var REV_CONFLICT = new PouchError({
+  status: 409,
+  error: 'conflict',
+  reason: 'Document update conflict'
+});
+
+var INVALID_ID = new PouchError({
+  status: 400,
+  error: 'invalid_id',
+  reason: '_id field must contain a string'
+});
+
+var MISSING_ID = new PouchError({
+  status: 412,
+  error: 'missing_id',
+  reason: '_id is required for puts'
+});
+
+var RESERVED_ID = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Only reserved document ids may start with underscore.'
+});
+
+var NOT_OPEN = new PouchError({
+  status: 412,
+  error: 'precondition_failed',
+  reason: 'Database not open'
+});
+
+var UNKNOWN_ERROR = new PouchError({
+  status: 500,
+  error: 'unknown_error',
+  reason: 'Database encountered an unknown error'
+});
+
+var BAD_ARG = new PouchError({
+  status: 500,
+  error: 'badarg',
+  reason: 'Some query argument is invalid'
+});
+
+var INVALID_REQUEST = new PouchError({
+  status: 400,
+  error: 'invalid_request',
+  reason: 'Request was invalid'
+});
+
+var QUERY_PARSE_ERROR = new PouchError({
+  status: 400,
+  error: 'query_parse_error',
+  reason: 'Some query parameter is invalid'
+});
+
+var DOC_VALIDATION = new PouchError({
+  status: 500,
+  error: 'doc_validation',
+  reason: 'Bad special document member'
+});
+
+var BAD_REQUEST = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Something wrong with the request'
+});
+
+var NOT_AN_OBJECT = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Document must be a JSON object'
+});
+
+var DB_MISSING = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'Database not found'
+});
+
+var IDB_ERROR = new PouchError({
+  status: 500,
+  error: 'indexed_db_went_bad',
+  reason: 'unknown'
+});
+
+var WSQ_ERROR = new PouchError({
+  status: 500,
+  error: 'web_sql_went_bad',
+  reason: 'unknown'
+});
+
+var LDB_ERROR = new PouchError({
+  status: 500,
+  error: 'levelDB_went_went_bad',
+  reason: 'unknown'
+});
+
+var FORBIDDEN = new PouchError({
+  status: 403,
+  error: 'forbidden',
+  reason: 'Forbidden by design doc validate_doc_update function'
+});
+
+var INVALID_REV = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Invalid rev format'
+});
+
+var FILE_EXISTS = new PouchError({
+  status: 412,
+  error: 'file_exists',
+  reason: 'The database could not be created, the file already exists.'
+});
+
+var MISSING_STUB = new PouchError({
+  status: 412,
+  error: 'missing_stub'
+});
+
+var INVALID_URL = new PouchError({
+  status: 413,
+  error: 'invalid_url',
+  reason: 'Provided URL is invalid'
+});
+
+var allErrors = {
+  UNAUTHORIZED: UNAUTHORIZED,
+  MISSING_BULK_DOCS: MISSING_BULK_DOCS,
+  MISSING_DOC: MISSING_DOC,
+  REV_CONFLICT: REV_CONFLICT,
+  INVALID_ID: INVALID_ID,
+  MISSING_ID: MISSING_ID,
+  RESERVED_ID: RESERVED_ID,
+  NOT_OPEN: NOT_OPEN,
+  UNKNOWN_ERROR: UNKNOWN_ERROR,
+  BAD_ARG: BAD_ARG,
+  INVALID_REQUEST: INVALID_REQUEST,
+  QUERY_PARSE_ERROR: QUERY_PARSE_ERROR,
+  DOC_VALIDATION: DOC_VALIDATION,
+  BAD_REQUEST: BAD_REQUEST,
+  NOT_AN_OBJECT: NOT_AN_OBJECT,
+  DB_MISSING: DB_MISSING,
+  WSQ_ERROR: WSQ_ERROR,
+  LDB_ERROR: LDB_ERROR,
+  FORBIDDEN: FORBIDDEN,
+  INVALID_REV: INVALID_REV,
+  FILE_EXISTS: FILE_EXISTS,
+  MISSING_STUB: MISSING_STUB,
+  IDB_ERROR: IDB_ERROR,
+  INVALID_URL: INVALID_URL
+};
+
+function createError(error, reason, name) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
+    }
+    /* jshint ignore:end */
+    if (name !== undefined) {
+      this.name = name;
+    }
+    if (reason !== undefined) {
+      this.reason = reason;
+    }
+  }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
+
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return createError(BAD_REQUEST, msg);
+  }
+}
+
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
+
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
+    }
+
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
+
+    if (filterReturn) {
+      return false;
+    }
+
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
+  };
+}
+
+function slowJsonParse(str) {
+  try {
+    return JSON.parse(str);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.parse(str);
+  }
+}
+
+function safeJsonParse(str) {
+  // try/catch is deoptimized in V8, leading to slower
+  // times than we'd like to have. Most documents are _not_
+  // huge, and do not require a slower code path just to parse them.
+  // We can be pretty sure that a document under 50000 characters
+  // will not be so deeply nested as to throw a stack overflow error
+  // (depends on the engine and available memory, though, so this is
+  // just a hunch). 50000 was chosen based on the average length
+  // of this string in our test suite, to try to find a number that covers
+  // most of our test cases (26 over this size, 26378 under it).
+  if (str.length < 50000) {
+    return JSON.parse(str);
+  }
+  return slowJsonParse(str);
+}
+
+function safeJsonStringify(json) {
+  try {
+    return JSON.stringify(json);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.stringify(json);
+  }
+}
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+  var winningId;
+  var winningPos;
+  var winningDeleted;
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var tree = node.ids;
+    var branches = tree[2];
+    var pos = node.pos;
+    if (branches.length) { // non-leaf
+      for (var i = 0, len = branches.length; i < len; i++) {
+        toVisit.push({pos: pos + 1, ids: branches[i]});
+      }
+      continue;
+    }
+    var deleted = !!tree[1].deleted;
+    var id = tree[0];
+    // sort by deleted, then pos, then id
+    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+        winningPos !== pos ? winningPos < pos : winningId < id)) {
+      winningId = id;
+      winningPos = pos;
+      winningDeleted = deleted;
+    }
+  }
+
+  return winningPos + '-' + winningId;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+  var toVisit = revs.slice();
+
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var branches = tree[2];
+    var newCtx =
+      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+    }
+  }
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+  var revs = [];
+  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                               revHash, ctx, opts) {
+    if (opts.status === 'available' && !isLeaf) {
+      revs.push(pos + '-' + revHash);
+      opts.status = 'missing';
+    }
+  });
+  return revs;
+}
+
+function sortByPos(a, b) {
+  return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+  var leaves = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+    if (isLeaf) {
+      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+    }
+  });
+  leaves.sort(sortByPos).reverse();
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    delete leaves[i].pos;
+  }
+  return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+  var win = winningRev(metadata);
+  var leaves = collectLeaves(metadata.rev_tree);
+  var conflicts = [];
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    var leaf = leaves[i];
+    if (leaf.rev !== win && !leaf.opts.deleted) {
+      conflicts.push(leaf.rev);
+    }
+  }
+  return conflicts;
+}
+
+function getTrees(node) {
+  return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+//  - metadata: the metadata object from the doc store
+//  - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+  if (!rev) {
+    rev = winningRev(metadata);
+  }
+  var id = rev.substring(rev.indexOf('-') + 1);
+  var toVisit = metadata.rev_tree.map(getTrees);
+
+  var tree;
+  while ((tree = toVisit.pop())) {
+    if (tree[0] === id) {
+      return !!tree[1].deleted;
+    }
+    toVisit = toVisit.concat(tree[2]);
+  }
+}
+
+function isLocalId(id) {
+  return (/^_local/).test(id);
+}
+
+function toObject(array) {
+  return array.reduce(function (obj, item) {
+    obj[item] = true;
+    return obj;
+  }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+  '_id',
+  '_rev',
+  '_attachments',
+  '_deleted',
+  '_revisions',
+  '_revs_info',
+  '_conflicts',
+  '_deleted_conflicts',
+  '_local_seq',
+  '_rev_tree',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats',
+  // Specific to Couchbase Sync Gateway
+  '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+  '_attachments',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats'
+]);
+
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = createError(MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = createError(INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = createError(RESERVED_ID);
+  }
+  if (err) {
+    throw err;
+  }
+}
+
+function parseRevisionInfo(rev) {
+  if (!/^\d+\-./.test(rev)) {
+    return createError(INVALID_REV);
+  }
+  var idx = rev.indexOf('-');
+  var left = rev.substring(0, idx);
+  var right = rev.substring(idx + 1);
+  return {
+    prefix: parseInt(left, 10),
+    id: right
+  };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+  var pos = revisions.start - revisions.ids.length + 1;
+
+  var revisionIds = revisions.ids;
+  var ids = [revisionIds[0], opts, []];
+
+  for (var i = 1, len = revisionIds.length; i < len; i++) {
+    ids = [revisionIds[i], {status: 'missing'}, [ids]];
+  }
+
+  return [{
+    pos: pos,
+    ids: ids
+  }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits) {
+
+  var nRevNum;
+  var newRevId;
+  var revInfo;
+  var opts = {status: 'available'};
+  if (doc._deleted) {
+    opts.deleted = true;
+  }
+
+  if (newEdits) {
+    if (!doc._id) {
+      doc._id = uuid();
+    }
+    newRevId = uuid(32, 16).toLowerCase();
+    if (doc._rev) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      doc._rev_tree = [{
+        pos: revInfo.prefix,
+        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+      }];
+      nRevNum = revInfo.prefix + 1;
+    } else {
+      doc._rev_tree = [{
+        pos: 1,
+        ids : [newRevId, opts, []]
+      }];
+      nRevNum = 1;
+    }
+  } else {
+    if (doc._revisions) {
+      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+      nRevNum = doc._revisions.start;
+      newRevId = doc._revisions.ids[0];
+    }
+    if (!doc._rev_tree) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      nRevNum = revInfo.prefix;
+      newRevId = revInfo.id;
+      doc._rev_tree = [{
+        pos: nRevNum,
+        ids: [newRevId, opts, []]
+      }];
+    }
+  }
+
+  invalidIdError(doc._id);
+
+  doc._rev = nRevNum + '-' + newRevId;
+
+  var result = {metadata : {}, data : {}};
+  for (var key in doc) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(doc, key)) {
+      var specialKey = key[0] === '_';
+      if (specialKey && !reservedWords[key]) {
+        var error = createError(DOC_VALIDATION, key);
+        error.message = DOC_VALIDATION.message + ': ' + key;
+        throw error;
+      } else if (specialKey && !dataWords[key]) {
+        result.metadata[key.slice(1)] = doc[key];
+      } else {
+        result.data[key] = doc[key];
+      }
+    }
+  }
+  return result;
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+  var paths = [];
+  var toVisit = revs.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
+
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, opts: opts});
+    if (isLeaf) {
+      paths.push({pos: (pos + 1 - history.length), ids: history});
+    }
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+    }
+  }
+  return paths.reverse();
+}
+
+function sortByPos$1(a, b) {
+  return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (comparator(arr[mid], item) < 0) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+  var idx = binarySearch(arr, item, comparator);
+  arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+  var root;
+  var leaf;
+  for (var i = numStemmed, len = path.length; i < len; i++) {
+    var node = path[i];
+    var currentLeaf = [node.id, node.opts, []];
+    if (leaf) {
+      leaf[2].push(currentLeaf);
+      leaf = currentLeaf;
+    } else {
+      root = leaf = currentLeaf;
+    }
+  }
+  return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+  return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+  var queue = [{tree1: in_tree1, tree2: in_tree2}];
+  var conflicts = false;
+  while (queue.length > 0) {
+    var item = queue.pop();
+    var tree1 = item.tree1;
+    var tree2 = item.tree2;
+
+    if (tree1[1].status || tree2[1].status) {
+      tree1[1].status =
+        (tree1[1].status ===  'available' ||
+        tree2[1].status === 'available') ? 'available' : 'missing';
+    }
+
+    for (var i = 0; i < tree2[2].length; i++) {
+      if (!tree1[2][0]) {
+        conflicts = 'new_leaf';
+        tree1[2][0] = tree2[2][i];
+        continue;
+      }
+
+      var merged = false;
+      for (var j = 0; j < tree1[2].length; j++) {
+        if (tree1[2][j][0] === tree2[2][i][0]) {
+          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+          merged = true;
+        }
+      }
+      if (!merged) {
+        conflicts = 'new_branch';
+        insertSorted(tree1[2], tree2[2][i], compareTree);
+      }
+    }
+  }
+  return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+  var restree = [];
+  var conflicts = false;
+  var merged = false;
+  var res;
+
+  if (!tree.length) {
+    return {tree: [path], conflicts: 'new_leaf'};
+  }
+
+  for (var i = 0, len = tree.length; i < len; i++) {
+    var branch = tree[i];
+    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+      // Paths start at the same position and have the same root, so they need
+      // merged
+      res = mergeTree(branch.ids, path.ids);
+      restree.push({pos: branch.pos, ids: res.tree});
+      conflicts = conflicts || res.conflicts;
+      merged = true;
+    } else if (dontExpand !== true) {
+      // The paths start at a different position, take the earliest path and
+      // traverse up until it as at the same point from root as the path we
+      // want to merge.  If the keys match we return the longer path with the
+      // other merged After stemming we dont want to expand the trees
+
+      var t1 = branch.pos < path.pos ? branch : path;
+      var t2 = branch.pos < path.pos ? path : branch;
+      var diff = t2.pos - t1.pos;
+
+      var candidateParents = [];
+
+      var trees = [];
+      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+      while (trees.length > 0) {
+        var item = trees.pop();
+        if (item.diff === 0) {
+          if (item.ids[0] === t2.ids[0]) {
+            candidateParents.push(item);
+          }
+          continue;
+        }
+        var elements = item.ids[2];
+        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+          trees.push({
+            ids: elements[j],
+            diff: item.diff - 1,
+            parent: item.ids,
+            parentIdx: j
+          });
+        }
+      }
+
+      var el = candidateParents[0];
+
+      if (!el) {
+        restree.push(branch);
+      } else {
+        res = mergeTree(el.ids, t2.ids);
+        el.parent[2][el.parentIdx] = res.tree;
+        restree.push({pos: t1.pos, ids: t1.ids});
+        conflicts = conflicts || res.conflicts;
+        merged = true;
+      }
+    } else {
+      restree.push(branch);
+    }
+  }
+
+  // We didnt find
+  if (!merged) {
+    restree.push(path);
+  }
+
+  restree.sort(sortByPos$1);
+
+  return {
+    tree: restree,
+    conflicts: conflicts || 'internal_node'
+  };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+  // First we break out the tree into a complete list of root to leaf paths
+  var paths = rootToLeaf(tree);
+  var maybeStem = {};
+
+  var result;
+  for (var i = 0, len = paths.length; i < len; i++) {
+    // Then for each path, we cut off the start of the path based on the
+    // `depth` to stem to, and generate a new set of flat trees
+    var path = paths[i];
+    var stemmed = path.ids;
+    var numStemmed = Math.max(0, stemmed.length - depth);
+    var stemmedNode = {
+      pos: path.pos + numStemmed,
+      ids: pathToTree(stemmed, numStemmed)
+    };
+
+    for (var s = 0; s < numStemmed; s++) {
+      var rev = (path.pos + s) + '-' + stemmed[s].id;
+      maybeStem[rev] = true;
+    }
+
+    // Then we remerge all those flat trees together, ensuring that we dont
+    // connect trees that would go beyond the depth limit
+    if (result) {
+      result = doMerge(result, stemmedNode, true).tree;
+    } else {
+      result = [stemmedNode];
+    }
+  }
+
+  traverseRevTree(result, function (isLeaf, pos, revHash) {
+    // some revisions may have been removed in a branch but not in another
+    delete maybeStem[pos + '-' + revHash];
+  });
+
+  return {
+    tree: result,
+    revs: Object.keys(maybeStem)
+  };
+}
+
+function merge(tree, path, depth) {
+  var newTree = doMerge(tree, path);
+  var stemmed = stem(newTree.tree, depth);
+  return {
+    tree: stemmed.tree,
+    stemmedRevs: stemmed.revs,
+    conflicts: newTree.conflicts
+  };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+  var toVisit = revs.slice();
+  var splitRev = rev.split('-');
+  var targetPos = parseInt(splitRev[0], 10);
+  var targetId = splitRev[1];
+
+  var node;
+  while ((node = toVisit.pop())) {
+    if (node.pos === targetPos && node.ids[0] === targetId) {
+      return true;
+    }
+    var branches = node.ids[2];
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: node.pos + 1, ids: branches[i]});
+    }
+  }
+  return false;
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+                   i, cb, writeDoc, newEdits) {
+
+  if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
+    results[i] = docInfo;
+    return cb();
+  }
+
+  // sometimes this is pre-calculated. historically not always
+  var previousWinningRev = prev.winningRev || winningRev(prev);
+  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+    isDeleted(prev, previousWinningRev);
+  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+    isDeleted(docInfo.metadata);
+  var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+  if (previouslyDeleted && !deleted && newEdits && isRoot) {
+    var newDoc = docInfo.data;
+    newDoc._rev = previousWinningRev;
+    newDoc._id = docInfo.metadata.id;
+    docInfo = parseDoc(newDoc, newEdits);
+  }
+
+  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+  var inConflict = newEdits && (((previouslyDeleted && deleted) ||
+    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+  if (inConflict) {
+    var err = createError(REV_CONFLICT);
+    results[i] = err;
+    return cb();
+  }
+
+  var newRev = docInfo.metadata.rev;
+  docInfo.metadata.rev_tree = merged.tree;
+  docInfo.stemmedRevs = merged.stemmedRevs || [];
+  /* istanbul ignore else */
+  if (prev.rev_map) {
+    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+  }
+
+  // recalculate
+  var winningRev$$ = winningRev(docInfo.metadata);
+  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$);
+
+  // calculate the total number of documents that were added/removed,
+  // from the perspective of total_rows/doc_count
+  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+  var newRevIsDeleted;
+  if (newRev === winningRev$$) {
+    // if the new rev is the same as the winning rev, we can reuse that value
+    newRevIsDeleted = winningRevIsDeleted;
+  } else {
+    // if they're not the same, then we need to recalculate
+    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+  }
+
+  writeDoc(docInfo, winningRev$$, winningRevIsDeleted, newRevIsDeleted,
+    true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+                     writeDoc, opts, overallCallback) {
+
+  // Default to 1000 locally
+  revLimit = revLimit || 1000;
+
+  function insertDoc(docInfo, resultsIdx, callback) {
+    // Cant insert new deleted documents
+    var winningRev$$ = winningRev(docInfo.metadata);
+    var deleted = isDeleted(docInfo.metadata, winningRev$$);
+    if ('was_delete' in opts && deleted) {
+      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+      return callback();
+    }
+
+    // 4712 - detect whether a new document was inserted with a _rev
+    var inConflict = newEdits && rootIsMissing(docInfo);
+
+    if (inConflict) {
+      var err = createError(REV_CONFLICT);
+      results[resultsIdx] = err;
+      return callback();
+    }
+
+    var delta = deleted ? 0 : 1;
+
+    writeDoc(docInfo, winningRev$$, deleted, deleted, false,
+      delta, resultsIdx, callback);
+  }
+
+  var newEdits = opts.new_edits;
+  var idsToDocs = new pouchdbCollections.Map();
+
+  var docsDone = 0;
+  var docsToDo = docInfos.length;
+
+  function checkAllDocsDone() {
+    if (++docsDone === docsToDo && overallCallback) {
+      overallCallback();
+    }
+  }
+
+  docInfos.forEach(function (currentDoc, resultsIdx) {
+
+    if (currentDoc._id && isLocalId(currentDoc._id)) {
+      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+      api[fun](currentDoc, {ctx: tx}, function (err, res) {
+        results[resultsIdx] = err || res;
+        checkAllDocsDone();
+      });
+      return;
+    }
+
+    var id = currentDoc.metadata.id;
+    if (idsToDocs.has(id)) {
+      docsToDo--; // duplicate
+      idsToDocs.get(id).push([currentDoc, resultsIdx]);
+    } else {
+      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+    }
+  });
+
+  // in the case of new_edits, the user can provide multiple docs
+  // with the same id. these need to be processed sequentially
+  idsToDocs.forEach(function (docs, id) {
+    var numDone = 0;
+
+    function docWritten() {
+      if (++numDone < docs.length) {
+        nextDoc();
+      } else {
+        checkAllDocsDone();
+      }
+    }
+    function nextDoc() {
+      var value = docs[numDone];
+      var currentDoc = value[0];
+      var resultsIdx = value[1];
+
+      if (fetchedDocs.has(id)) {
+        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+          resultsIdx, docWritten, writeDoc, newEdits);
+      } else {
+        // Ensure stemming applies to new writes as well
+        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+        currentDoc.metadata.rev_tree = merged.tree;
+        currentDoc.stemmedRevs = merged.stemmedRevs || [];
+        insertDoc(currentDoc, resultsIdx, docWritten);
+      }
+    }
+    nextDoc();
+  });
+}
+
+/* istanbul ignore next */
+var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+
+function once(fun) {
+  var called = false;
+  return getArguments(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
+    }
+  });
+}
+
+function toPromise(func) {
+  //create the function we will be returning
+  return getArguments(function (args) {
+    // Clone arguments
+    args = clone(args);
+    var self = this;
+    var tempCB =
+      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    // if the last argument is a function, assume its a callback
+    var usedCB;
+    if (tempCB) {
+      // if it was a callback, create a new callback which calls it,
+      // but do so async so we don't trap any errors
+      usedCB = function (err, resp) {
+        process.nextTick(function () {
+          tempCB(err, resp);
+        });
+      };
+    }
+    var promise = new PouchPromise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
+      }
+    });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
+    }
+    return promise;
+  });
+}
+
+var thisAtob = function (str) {
+  return atob(str);
+};
+
+var thisBtoa = function (str) {
+  return btoa(str);
+};
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+  return thisBtoa(raw);
+}
+
+function appendBuffer(buffer, data, start, end) {
+  if (start > 0 || end < data.byteLength) {
+    // only create a subarray if we really need to
+    data = new Uint8Array(data, start,
+      Math.min(end, data.byteLength) - start);
+  }
+  buffer.append(data);
+}
+
+function appendString(buffer, data, start, end) {
+  if (start > 0 || end < data.length) {
+    // only create a substring if we really need to
+    data = data.substring(start, end);
+  }
+  buffer.appendBinary(data);
+}
+
+var md5 = toPromise(function (data, callback) {
+  var inputIsString = typeof data === 'string';
+  var len = inputIsString ? data.length : data.byteLength;
+  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+  var chunks = Math.ceil(len / chunkSize);
+  var currentChunk = 0;
+  var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+  var append = inputIsString ? appendString : appendBuffer;
+
+  function loadNextChunk() {
+    var start = currentChunk * chunkSize;
+    var end = start + chunkSize;
+    currentChunk++;
+    if (currentChunk < chunks) {
+      append(buffer, data, start, end);
+      setImmediateShim(loadNextChunk);
+    } else {
+      append(buffer, data, start, end);
+      var raw = buffer.end(true);
+      var base64 = rawToBase64(raw);
+      callback(null, base64);
+      buffer.destroy();
+    }
+  }
+  loadNextChunk();
+});
+
+// in the browser, LevelAlt doesn't need the
+// pre-2.2.0 LevelDB-specific migrations
+var toSublevel = function (name, db, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var localAndMetaStores = function (db, stores, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var migrate = {
+  toSublevel: toSublevel,
+  localAndMetaStores: localAndMetaStores
+};
+
+// shim for Function.prototype.name,
+// for browsers that don't support it like IE
+
+/* istanbul ignore next */
+function f() {}
+
+var hasName = f.name;
+var res;
+
+// We dont run coverage in IE
+/* istanbul ignore else */
+if (hasName) {
+  res = function (fun) {
+    return fun.name;
+  };
+} else {
+  res = function (fun) {
+    return fun.toString().match(/^\s*function\s*(\S*)\s*\(/)[1];
+  };
+}
+
+var functionName = res;
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+  parts = parts || [];
+  properties = properties || {};
+  try {
+    return new Blob(parts, properties);
+  } catch (e) {
+    if (e.name !== "TypeError") {
+      throw e;
+    }
+    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+                  WebKitBlobBuilder;
+    var builder = new Builder();
+    for (var i = 0; i < parts.length; i += 1) {
+      builder.append(parts[i]);
+    }
+    return builder.getBlob(properties.type);
+  }
+}
+
+function readAsBlobOrBuffer(storedObject, type) {
+  // In the browser, we've stored a binary string. This now comes back as a
+  // browserified Node-style Buffer, but we want a Blob instead.
+  return createBlob([storedObject.toArrayBuffer()], {type: type});
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
+  }
+  return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  if (typeof FileReader === 'undefined') {
+    // fix for Firefox in a web worker
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+    return callback(arrayBufferToBinaryString(
+      new FileReaderSync().readAsArrayBuffer(blob)));
+  }
+
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
+    }
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
+  }
+}
+
+// In the browser, we store a binary string
+function prepareAttachmentForStorage(attData, cb) {
+  readAsBinaryString(attData, cb);
+}
+
+function createEmptyBlobOrBuffer(type) {
+  return createBlob([''], {type: type});
+}
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
+  }
+  return buf;
+}
+
+function binStringToBluffer(binString, type) {
+  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+function getCacheFor(transaction, store) {
+  var prefix = store.prefix()[0];
+  var cache = transaction._cache;
+  var subCache = cache.get(prefix);
+  if (!subCache) {
+    subCache = new pouchdbCollections.Map();
+    cache.set(prefix, subCache);
+  }
+  return subCache;
+}
+
+function LevelTransaction() {
+  this._batch = [];
+  this._cache = new pouchdbCollections.Map();
+}
+
+LevelTransaction.prototype.get = function (store, key, callback) {
+  var cache = getCacheFor(this, store);
+  var exists = cache.get(key);
+  if (exists) {
+    return process.nextTick(function () {
+      callback(null, exists);
+    });
+  } else if (exists === null) { // deleted marker
+    /* istanbul ignore next */
+    return process.nextTick(function () {
+      callback({name: 'NotFoundError'});
+    });
+  }
+  store.get(key, function (err, res) {
+    if (err) {
+      /* istanbul ignore else */
+      if (err.name === 'NotFoundError') {
+        cache.set(key, null);
+      }
+      return callback(err);
+    }
+    cache.set(key, res);
+    callback(null, res);
+  });
+};
+
+LevelTransaction.prototype.batch = function (batch) {
+  for (var i = 0, len = batch.length; i < len; i++) {
+    var operation = batch[i];
+
+    var cache = getCacheFor(this, operation.prefix);
+
+    if (operation.type === 'put') {
+      cache.set(operation.key, operation.value);
+    } else {
+      cache.set(operation.key, null);
+    }
+  }
+  this._batch = this._batch.concat(batch);
+};
+
+LevelTransaction.prototype.execute = function (db, callback) {
+
+  var keys = new pouchdbCollections.Set();
+  var uniqBatches = [];
+
+  // remove duplicates; last one wins
+  for (var i = this._batch.length - 1; i >= 0; i--) {
+    var operation = this._batch[i];
+    var lookupKey = operation.prefix.prefix()[0] + '\xff' + operation.key;
+    if (keys.has(lookupKey)) {
+      continue;
+    }
+    keys.add(lookupKey);
+    uniqBatches.push(operation);
+  }
+
+  db.batch(uniqBatches, callback);
+};
+
+var DOC_STORE = 'document-store';
+var BY_SEQ_STORE = 'by-sequence';
+var ATTACHMENT_STORE = 'attach-store';
+var BINARY_STORE = 'attach-binary-store';
+var LOCAL_STORE = 'local-store';
+var META_STORE = 'meta-store';
+
+// leveldb barks if we try to open a db multiple times
+// so we cache opened connections here for initstore()
+var dbStores = new pouchdbCollections.Map();
+
+// store the value of update_seq in the by-sequence store the key name will
+// never conflict, since the keys in the by-sequence store are integers
+var UPDATE_SEQ_KEY = '_local_last_update_seq';
+var DOC_COUNT_KEY = '_local_doc_count';
+var UUID_KEY = '_local_uuid';
+
+var MD5_PREFIX = 'md5-';
+
+var safeJsonEncoding = {
+  encode: safeJsonStringify,
+  decode: safeJsonParse,
+  buffer: false,
+  type: 'cheap-json'
+};
+
+var levelChanges = new Changes();
+
+// require leveldown. provide verbose output on error as it is the default
+// nodejs adapter, which we do not provide for the user
+/* istanbul ignore next */
+var requireLeveldown = function () {
+  try {
+    return _dereq_(7);
+  } catch (err) {
+    /* eslint no-ex-assign: 0*/
+    err = err || 'leveldown import error';
+    if (err.code === 'MODULE_NOT_FOUND') {
+      // handle leveldown not installed case
+      return new Error([
+        'the \'leveldown\' package is not available. install it, or,',
+        'specify another storage backend using the \'db\' option'
+      ].join(' '));
+    } else if (err.message && err.message.match('Module version mismatch')) {
+      // handle common user enviornment error
+      return new Error([
+        err.message,
+        'This generally implies that leveldown was built with a different',
+        'version of node than that which is running now.  You may try',
+        'fully removing and reinstalling PouchDB or leveldown to resolve.'
+      ].join(' '));
+    }
+    // handle general internal nodejs require error
+    return new Error(err.toString() + ': unable to import leveldown');
+  }
+};
+
+// winningRev and deleted are performance-killers, but
+// in newer versions of PouchDB, they are cached on the metadata
+function getWinningRev(metadata) {
+  return 'winningRev' in metadata ?
+    metadata.winningRev : winningRev(metadata);
+}
+
+function getIsDeleted(metadata, winningRev) {
+  return 'deleted' in metadata ?
+    metadata.deleted : isDeleted(metadata, winningRev);
+}
+
+function fetchAttachment(att, stores, opts) {
+  var type = att.content_type;
+  return new PouchPromise(function (resolve, reject) {
+    stores.binaryStore.get(att.digest, function (err, buffer) {
+      var data;
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return reject(err);
+        } else {
+          // empty
+          if (!opts.binary) {
+            data = '';
+          } else {
+            data = binStringToBluffer('', type);
+          }
+        }
+      } else { // non-empty
+        if (opts.binary) {
+          data = readAsBlobOrBuffer(buffer, type);
+        } else {
+          data = buffer.toString('base64');
+        }
+      }
+      delete att.stub;
+      delete att.length;
+      att.data = data;
+      resolve();
+    });
+  });
+}
+
+function fetchAttachments(results, stores, opts) {
+  var atts = [];
+  results.forEach(function (row) {
+    if (!(row.doc && row.doc._attachments)) {
+      return;
+    }
+    var attNames = Object.keys(row.doc._attachments);
+    attNames.forEach(function (attName) {
+      var att = row.doc._attachments[attName];
+      if (!('data' in att)) {
+        atts.push(att);
+      }
+    });
+  });
+
+  return PouchPromise.all(atts.map(function (att) {
+    return fetchAttachment(att, stores, opts);
+  }));
+}
+
+function LevelPouch(opts, callback) {
+  opts = clone(opts);
+  var api = this;
+  var instanceId;
+  var stores = {};
+  var revLimit = opts.revs_limit;
+  var db;
+  var name = opts.name;
+  if (typeof opts.createIfMissing === 'undefined') {
+    opts.createIfMissing = true;
+  }
+
+  var leveldown = opts.db || requireLeveldown();
+  /* istanbul ignore if */
+  if (leveldown instanceof Error) {
+    return callback(leveldown);
+  }
+
+  if (typeof leveldown.destroy !== 'function') {
+    /* istanbul ignore next */
+    leveldown.destroy = function (name, cb) { cb(); };
+  }
+  var dbStore;
+  var leveldownName = functionName(leveldown);
+  if (dbStores.has(leveldownName)) {
+    dbStore = dbStores.get(leveldownName);
+  } else {
+    dbStore = new pouchdbCollections.Map();
+    dbStores.set(leveldownName, dbStore);
+  }
+  if (dbStore.has(name)) {
+    db = dbStore.get(name);
+    afterDBCreated();
+  } else {
+    dbStore.set(name, sublevel(levelup(name, opts, function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        dbStore["delete"](name);
+        return callback(err);
+      }
+      db = dbStore.get(name);
+      db._docCount  = -1;
+      db._queue = new Deque();
+      if (opts.db || opts.noMigrate) {
+        afterDBCreated();
+      } else {
+        migrate.toSublevel(name, db, afterDBCreated);
+      }
+    })));
+  }
+
+  function afterDBCreated() {
+    stores.docStore = db.sublevel(DOC_STORE, {valueEncoding: safeJsonEncoding});
+    stores.bySeqStore = db.sublevel(BY_SEQ_STORE, {valueEncoding: 'json'});
+    stores.attachmentStore =
+      db.sublevel(ATTACHMENT_STORE, {valueEncoding: 'json'});
+    stores.binaryStore = db.sublevel(BINARY_STORE, {valueEncoding: 'binary'});
+    stores.localStore = db.sublevel(LOCAL_STORE, {valueEncoding: 'json'});
+    stores.metaStore = db.sublevel(META_STORE, {valueEncoding: 'json'});
+    migrate.localAndMetaStores(db, stores, function () {
+      stores.metaStore.get(UPDATE_SEQ_KEY, function (err, value) {
+        if (typeof db._updateSeq === 'undefined') {
+          db._updateSeq = value || 0;
+        }
+        stores.metaStore.get(DOC_COUNT_KEY, function (err, value) {
+          db._docCount = !err ? value : 0;
+          stores.metaStore.get(UUID_KEY, function (err, value) {
+            instanceId = !err ? value : uuid();
+            stores.metaStore.put(UUID_KEY, instanceId, function () {
+              process.nextTick(function () {
+                callback(null, api);
+              });
+            });
+          });
+        });
+      });
+    });
+  }
+
+  function countDocs(callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(new Error('database is closed'));
+    }
+    return callback(null, db._docCount); // use cached value
+  }
+
+  api.type = function () {
+    return 'leveldb';
+  };
+
+  api._id = function (callback) {
+    callback(null, instanceId);
+  };
+
+  api._info = function (callback) {
+    var res = {
+      doc_count: db._docCount,
+      update_seq: db._updateSeq,
+      backend_adapter: functionName(leveldown)
+    };
+    return process.nextTick(function () {
+      callback(null, res);
+    });
+  };
+
+  function tryCode(fun, args) {
+    try {
+      fun.apply(null, args);
+    } catch (err) {
+      args[args.length - 1](err);
+    }
+  }
+
+  function executeNext() {
+    var firstTask = db._queue.peekFront();
+
+    if (firstTask.type === 'read') {
+      runReadOperation(firstTask);
+    } else { // write, only do one at a time
+      runWriteOperation(firstTask);
+    }
+  }
+
+  function runReadOperation(firstTask) {
+    // do multiple reads at once simultaneously, because it's safe
+
+    var readTasks = [firstTask];
+    var i = 1;
+    var nextTask = db._queue.get(i);
+    while (typeof nextTask !== 'undefined' && nextTask.type === 'read') {
+      readTasks.push(nextTask);
+      i++;
+      nextTask = db._queue.get(i);
+    }
+
+    var numDone = 0;
+
+    readTasks.forEach(function (readTask) {
+      var args = readTask.args;
+      var callback = args[args.length - 1];
+      args[args.length - 1] = getArguments(function (cbArgs) {
+        callback.apply(null, cbArgs);
+        if (++numDone === readTasks.length) {
+          process.nextTick(function () {
+            // all read tasks have finished
+            readTasks.forEach(function () {
+              db._queue.shift();
+            });
+            if (db._queue.length) {
+              executeNext();
+            }
+          });
+        }
+      });
+      tryCode(readTask.fun, args);
+    });
+  }
+
+  function runWriteOperation(firstTask) {
+    var args = firstTask.args;
+    var callback = args[args.length - 1];
+    args[args.length - 1] = getArguments(function (cbArgs) {
+      callback.apply(null, cbArgs);
+      process.nextTick(function () {
+        db._queue.shift();
+        if (db._queue.length) {
+          executeNext();
+        }
+      });
+    });
+    tryCode(firstTask.fun, args);
+  }
+
+  // all read/write operations to the database are done in a queue,
+  // similar to how websql/idb works. this avoids problems such
+  // as e.g. compaction needing to have a lock on the database while
+  // it updates stuff. in the future we can revisit this.
+  function writeLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'write'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  // same as the writelock, but multiple can run at once
+  function readLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'read'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  function formatSeq(n) {
+    return ('0000000000000000' + n).slice(-16);
+  }
+
+  function parseSeq(s) {
+    return parseInt(s, 10);
+  }
+
+  api._get = readLock(function (id, opts, callback) {
+    opts = clone(opts);
+
+    stores.docStore.get(id, function (err, metadata) {
+
+      if (err || !metadata) {
+        return callback(createError(MISSING_DOC, 'missing'));
+      }
+
+      var rev = getWinningRev(metadata);
+      var deleted = getIsDeleted(metadata, rev);
+      if (deleted && !opts.rev) {
+        return callback(createError(MISSING_DOC, "deleted"));
+      }
+
+      rev = opts.rev ? opts.rev : rev;
+
+      var seq = metadata.rev_map[rev];
+
+      stores.bySeqStore.get(formatSeq(seq), function (err, doc) {
+        if (!doc) {
+          return callback(createError(MISSING_DOC));
+        }
+        /* istanbul ignore if */
+        if ('_id' in doc && doc._id !== metadata.id) {
+          // this failing implies something very wrong
+          return callback(new Error('wrong doc returned'));
+        }
+        doc._id = metadata.id;
+        if ('_rev' in doc) {
+          /* istanbul ignore if */
+          if (doc._rev !== rev) {
+            // this failing implies something very wrong
+            return callback(new Error('wrong doc returned'));
+          }
+        } else {
+          // we didn't always store this
+          doc._rev = rev;
+        }
+        return callback(null, {doc: doc, metadata: metadata});
+      });
+    });
+  });
+
+  // not technically part of the spec, but if putAttachment has its own
+  // method...
+  api._getAttachment = function (attachment, opts, callback) {
+    var digest = attachment.digest;
+    var type = attachment.content_type;
+
+    stores.binaryStore.get(digest, function (err, attach) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        }
+        // Empty attachment
+        return callback(null, opts.binary ? createEmptyBlobOrBuffer(type) : '');
+      }
+
+      if (opts.binary) {
+        callback(null, readAsBlobOrBuffer(attach, type));
+      } else {
+        callback(null, attach.toString('base64'));
+      }
+    });
+  };
+
+  api._bulkDocs = writeLock(function (req, opts, callback) {
+    var newEdits = opts.new_edits;
+    var results = new Array(req.docs.length);
+    var fetchedDocs = new pouchdbCollections.Map();
+    var stemmedRevs = new pouchdbCollections.Map();
+
+    var txn = new LevelTransaction();
+    var docCountDelta = 0;
+    var newUpdateSeq = db._updateSeq;
+
+    // parse the docs and give each a sequence number
+    var userDocs = req.docs;
+    var docInfos = userDocs.map(function (doc) {
+      if (doc._id && isLocalId(doc._id)) {
+        return doc;
+      }
+      var newDoc = parseDoc(doc, newEdits);
+
+      if (newDoc.metadata && !newDoc.metadata.rev_map) {
+        newDoc.metadata.rev_map = {};
+      }
+
+      return newDoc;
+    });
+    var infoErrors = docInfos.filter(function (doc) {
+      return doc.error;
+    });
+
+    if (infoErrors.length) {
+      return callback(infoErrors[0]);
+    }
+
+    // verify any stub attachments as a precondition test
+
+    function verifyAttachment(digest, callback) {
+      txn.get(stores.attachmentStore, digest, function (levelErr) {
+        if (levelErr) {
+          var err = createError(MISSING_STUB,
+                                'unknown stub attachment with digest ' +
+                                digest);
+          callback(err);
+        } else {
+          callback();
+        }
+      });
+    }
+
+    function verifyAttachments(finish) {
+      var digests = [];
+      userDocs.forEach(function (doc) {
+        if (doc && doc._attachments) {
+          Object.keys(doc._attachments).forEach(function (filename) {
+            var att = doc._attachments[filename];
+            if (att.stub) {
+              digests.push(att.digest);
+            }
+          });
+        }
+      });
+      if (!digests.length) {
+        return finish();
+      }
+      var numDone = 0;
+      var err;
+
+      digests.forEach(function (digest) {
+        verifyAttachment(digest, function (attErr) {
+          if (attErr && !err) {
+            err = attErr;
+          }
+
+          if (++numDone === digests.length) {
+            finish(err);
+          }
+        });
+      });
+    }
+
+    function fetchExistingDocs(finish) {
+      var numDone = 0;
+      var overallErr;
+      function checkDone() {
+        if (++numDone === userDocs.length) {
+          return finish(overallErr);
+        }
+      }
+
+      userDocs.forEach(function (doc) {
+        if (doc._id && isLocalId(doc._id)) {
+          // skip local docs
+          return checkDone();
+        }
+        txn.get(stores.docStore, doc._id, function (err, info) {
+          if (err) {
+            /* istanbul ignore if */
+            if (err.name !== 'NotFoundError') {
+              overallErr = err;
+            }
+          } else {
+            fetchedDocs.set(doc._id, info);
+          }
+          checkDone();
+        });
+      });
+    }
+
+    function compact(revsMap, callback) {
+      var promise = PouchPromise.resolve();
+      revsMap.forEach(function (revs, docId) {
+        // TODO: parallelize, for now need to be sequential to
+        // pass orphaned attachment tests
+        promise = promise.then(function () {
+          return new PouchPromise(function (resolve, reject) {
+            api._doCompactionNoLock(docId, revs, {ctx: txn}, function (err) {
+              /* istanbul ignore if */
+              if (err) {
+                return reject(err);
+              }
+              resolve();
+            });
+          });
+        });
+      });
+
+      promise.then(function () {
+        callback();
+      }, callback);
+    }
+
+    function autoCompact(callback) {
+      var revsMap = new pouchdbCollections.Map();
+      fetchedDocs.forEach(function (metadata, docId) {
+        revsMap.set(docId, compactTree(metadata));
+      });
+      compact(revsMap, callback);
+    }
+
+    function finish() {
+      if (api.auto_compaction) {
+        return autoCompact(complete);
+      } else {
+        compact(stemmedRevs, complete);
+      }
+    }
+
+    function writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
+                      isUpdate, delta, resultsIdx, callback2) {
+      docCountDelta += delta;
+
+      var err = null;
+      var recv = 0;
+
+      docInfo.metadata.winningRev = winningRev;
+      docInfo.metadata.deleted = winningRevIsDeleted;
+
+      docInfo.data._id = docInfo.metadata.id;
+      docInfo.data._rev = docInfo.metadata.rev;
+
+      if (newRevIsDeleted) {
+        docInfo.data._deleted = true;
+      }
+
+      if (docInfo.stemmedRevs.length) {
+        stemmedRevs.set(docInfo.metadata.id, docInfo.stemmedRevs);
+      }
+
+      var attachments = docInfo.data._attachments ?
+        Object.keys(docInfo.data._attachments) :
+        [];
+
+      function attachmentSaved(attachmentErr) {
+        recv++;
+        if (!err) {
+          /* istanbul ignore if */
+          if (attachmentErr) {
+            err = attachmentErr;
+            callback2(err);
+          } else if (recv === attachments.length) {
+            finish();
+          }
+        }
+      }
+
+      function onMD5Load(doc, key, data, attachmentSaved) {
+        return function (result) {
+          saveAttachment(doc, MD5_PREFIX + result, key, data, attachmentSaved);
+        };
+      }
+
+      function doMD5(doc, key, attachmentSaved) {
+        return function (data) {
+          md5(data).then(
+            onMD5Load(doc, key, data, attachmentSaved)
+          );
+        };
+      }
+
+      for (var i = 0; i < attachments.length; i++) {
+        var key = attachments[i];
+        var att = docInfo.data._attachments[key];
+
+        if (att.stub) {
+          // still need to update the refs mapping
+          var id = docInfo.data._id;
+          var rev = docInfo.data._rev;
+          saveAttachmentRefs(id, rev, att.digest, attachmentSaved);
+          continue;
+        }
+        var data;
+        if (typeof att.data === 'string') {
+          // input is assumed to be a base64 string
+          try {
+            data = thisAtob(att.data);
+          } catch (e) {
+            callback(createError(BAD_ARG,
+                     'Attachment is not a valid base64 string'));
+            return;
+          }
+          doMD5(docInfo, key, attachmentSaved)(data);
+        } else {
+          prepareAttachmentForStorage(att.data,
+            doMD5(docInfo, key, attachmentSaved));
+        }
+      }
+
+      function finish() {
+        var seq = docInfo.metadata.rev_map[docInfo.metadata.rev];
+        /* istanbul ignore if */
+        if (seq) {
+          // check that there aren't any existing revisions with the same
+          // revision id, else we shouldn't do anything
+          return callback2(null, docInfo.revsStemmed);
+        }
+        seq = ++newUpdateSeq;
+        docInfo.metadata.rev_map[docInfo.metadata.rev] =
+          docInfo.metadata.seq = seq;
+        var seqKey = formatSeq(seq);
+        var batch = [{
+          key: seqKey,
+          value: docInfo.data,
+          prefix: stores.bySeqStore,
+          type: 'put'
+        }, {
+          key: docInfo.metadata.id,
+          value: docInfo.metadata,
+          prefix: stores.docStore,
+          type: 'put'
+        }];
+        txn.batch(batch);
+        results[resultsIdx] = {
+          ok: true,
+          id: docInfo.metadata.id,
+          rev: winningRev
+        };
+        fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+        callback2(null, docInfo.revsStemmed);
+      }
+
+      if (!attachments.length) {
+        finish();
+      }
+    }
+
+    // attachments are queued per-digest, otherwise the refs could be
+    // overwritten by concurrent writes in the same bulkDocs session
+    var attachmentQueues = {};
+
+    function saveAttachmentRefs(id, rev, digest, callback) {
+
+      function fetchAtt() {
+        return new PouchPromise(function (resolve, reject) {
+          txn.get(stores.attachmentStore, digest, function (err, oldAtt) {
+            /* istanbul ignore if */
+            if (err && err.name !== 'NotFoundError') {
+              return reject(err);
+            }
+            resolve(oldAtt);
+          });
+        });
+      }
+
+      function saveAtt(oldAtt) {
+        var ref = [id, rev].join('@');
+        var newAtt = {};
+
+        if (oldAtt) {
+          if (oldAtt.refs) {
+            // only update references if this attachment already has them
+            // since we cannot migrate old style attachments here without
+            // doing a full db scan for references
+            newAtt.refs = oldAtt.refs;
+            newAtt.refs[ref] = true;
+          }
+        } else {
+          newAtt.refs = {};
+          newAtt.refs[ref] = true;
+        }
+
+        return new PouchPromise(function (resolve) {
+          txn.batch([{
+            type: 'put',
+            prefix: stores.attachmentStore,
+            key: digest,
+            value: newAtt
+          }]);
+          resolve(!oldAtt);
+        });
+      }
+
+      // put attachments in a per-digest queue, to avoid two docs with the same
+      // attachment overwriting each other
+      var queue = attachmentQueues[digest] || PouchPromise.resolve();
+      attachmentQueues[digest] = queue.then(function () {
+        return fetchAtt().then(saveAtt).then(function (isNewAttachment) {
+          callback(null, isNewAttachment);
+        }, callback);
+      });
+    }
+
+    function saveAttachment(docInfo, digest, key, data, callback) {
+      var att = docInfo.data._attachments[key];
+      delete att.data;
+      att.digest = digest;
+      att.length = data.length;
+      var id = docInfo.metadata.id;
+      var rev = docInfo.metadata.rev;
+      att.revpos = parseInt(rev, 10);
+
+      saveAttachmentRefs(id, rev, digest, function (err, isNewAttachment) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        // do not try to store empty attachments
+        if (data.length === 0) {
+          return callback(err);
+        }
+        if (!isNewAttachment) {
+          // small optimization - don't bother writing it again
+          return callback(err);
+        }
+        txn.batch([{
+          type: 'put',
+          prefix: stores.binaryStore,
+          key: digest,
+          value: new Buffer(data, 'binary')
+        }]);
+        callback();
+      });
+    }
+
+    function complete(err) {
+      /* istanbul ignore if */
+      if (err) {
+        return process.nextTick(function () {
+          callback(err);
+        });
+      }
+      txn.batch([
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: UPDATE_SEQ_KEY,
+          value: newUpdateSeq
+        },
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: DOC_COUNT_KEY,
+          value: db._docCount + docCountDelta
+        }
+      ]);
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        db._docCount += docCountDelta;
+        db._updateSeq = newUpdateSeq;
+        levelChanges.notify(name);
+        process.nextTick(function () {
+          callback(null, results);
+        });
+      });
+    }
+
+    if (!docInfos.length) {
+      return callback(null, []);
+    }
+
+    verifyAttachments(function (err) {
+      if (err) {
+        return callback(err);
+      }
+      fetchExistingDocs(function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        processDocs(revLimit, docInfos, api, fetchedDocs, txn, results,
+                    writeDoc, opts, finish);
+      });
+    });
+  });
+  api._allDocs = readLock(function (opts, callback) {
+    opts = clone(opts);
+    countDocs(function (err, docCount) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var readstreamOpts = {};
+      var skip = opts.skip || 0;
+      if (opts.startkey) {
+        readstreamOpts.gte = opts.startkey;
+      }
+      if (opts.endkey) {
+        readstreamOpts.lte = opts.endkey;
+      }
+      if (opts.key) {
+        readstreamOpts.gte = readstreamOpts.lte = opts.key;
+      }
+      if (opts.descending) {
+        readstreamOpts.reverse = true;
+        // switch start and ends
+        var tmp = readstreamOpts.lte;
+        readstreamOpts.lte = readstreamOpts.gte;
+        readstreamOpts.gte = tmp;
+      }
+      var limit;
+      if (typeof opts.limit === 'number') {
+        limit = opts.limit;
+      }
+      if (limit === 0 ||
+          ('start' in readstreamOpts && 'end' in readstreamOpts &&
+          readstreamOpts.start > readstreamOpts.end)) {
+        // should return 0 results when start is greater than end.
+        // normally level would "fix" this for us by reversing the order,
+        // so short-circuit instead
+        return callback(null, {
+          total_rows: docCount,
+          offset: opts.skip,
+          rows: []
+        });
+      }
+      var results = [];
+      var docstream = stores.docStore.readStream(readstreamOpts);
+
+      var throughStream = through2.obj(function (entry, _, next) {
+        var metadata = entry.value;
+        // winningRev and deleted are performance-killers, but
+        // in newer versions of PouchDB, they are cached on the metadata
+        var winningRev = getWinningRev(metadata);
+        var deleted = getIsDeleted(metadata, winningRev);
+        if (!deleted) {
+          if (skip-- > 0) {
+            next();
+            return;
+          } else if (typeof limit === 'number' && limit-- <= 0) {
+            docstream.unpipe();
+            docstream.destroy();
+            next();
+            return;
+          }
+        } else if (opts.deleted !== 'ok') {
+          next();
+          return;
+        }
+        function allDocsInner(data) {
+          var doc = {
+            id: metadata.id,
+            key: metadata.id,
+            value: {
+              rev: winningRev
+            }
+          };
+          if (opts.include_docs) {
+            doc.doc = data;
+            doc.doc._rev = doc.value.rev;
+            if (opts.conflicts) {
+              doc.doc._conflicts = collectConflicts(metadata);
+            }
+            for (var att in doc.doc._attachments) {
+              if (doc.doc._attachments.hasOwnProperty(att)) {
+                doc.doc._attachments[att].stub = true;
+              }
+            }
+          }
+          if (opts.inclusive_end === false && metadata.id === opts.endkey) {
+            return next();
+          } else if (deleted) {
+            if (opts.deleted === 'ok') {
+              doc.value.deleted = true;
+              doc.doc = null;
+            } else {
+              /* istanbul ignore next */
+              return next();
+            }
+          }
+          results.push(doc);
+          next();
+        }
+        if (opts.include_docs) {
+          var seq = metadata.rev_map[winningRev];
+          stores.bySeqStore.get(formatSeq(seq), function (err, data) {
+            allDocsInner(data);
+          });
+        }
+        else {
+          allDocsInner();
+        }
+      }, function (next) {
+        PouchPromise.resolve().then(function () {
+          if (opts.include_docs && opts.attachments) {
+            return fetchAttachments(results, stores, opts);
+          }
+        }).then(function () {
+          callback(null, {
+            total_rows: docCount,
+            offset: opts.skip,
+            rows: results
+          });
+        }, callback);
+        next();
+      }).on('unpipe', function () {
+        throughStream.end();
+      });
+
+      docstream.on('error', callback);
+
+      docstream.pipe(throughStream);
+    });
+  });
+
+  api._changes = function (opts) {
+    opts = clone(opts);
+
+    if (opts.continuous) {
+      var id = name + ':' + uuid();
+      levelChanges.addListener(name, id, api, opts);
+      levelChanges.notify(name);
+      return {
+        cancel: function () {
+          levelChanges.removeListener(name, id);
+        }
+      };
+    }
+
+    var descending = opts.descending;
+    var results = [];
+    var lastSeq = opts.since || 0;
+    var called = 0;
+    var streamOpts = {
+      reverse: descending
+    };
+    var limit;
+    if ('limit' in opts && opts.limit > 0) {
+      limit = opts.limit;
+    }
+    if (!streamOpts.reverse) {
+      streamOpts.start = formatSeq(opts.since || 0);
+    }
+
+    var docIds = opts.doc_ids && new pouchdbCollections.Set(opts.doc_ids);
+    var filter = filterChange(opts);
+    var docIdsToMetadata = new pouchdbCollections.Map();
+
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+
+    function complete() {
+      opts.done = true;
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+      changeStream.unpipe(throughStream);
+      changeStream.destroy();
+      if (!opts.continuous && !opts.cancelled) {
+        if (opts.include_docs && opts.attachments) {
+          fetchAttachments(results, stores, opts).then(function () {
+            opts.complete(null, {results: results, last_seq: lastSeq});
+          });
+        } else {
+          opts.complete(null, {results: results, last_seq: lastSeq});
+        }
+      }
+    }
+    var changeStream = stores.bySeqStore.readStream(streamOpts);
+    var throughStream = through2.obj(function (data, _, next) {
+      if (limit && called >= limit) {
+        complete();
+        return next();
+      }
+      if (opts.cancelled || opts.done) {
+        return next();
+      }
+
+      var seq = parseSeq(data.key);
+      var doc = data.value;
+
+      if (seq === opts.since && !descending) {
+        // couchdb ignores `since` if descending=true
+        return next();
+      }
+
+      if (docIds && !docIds.has(doc._id)) {
+        return next();
+      }
+
+      var metadata;
+
+      function onGetMetadata(metadata) {
+        var winningRev = getWinningRev(metadata);
+
+        function onGetWinningDoc(winningDoc) {
+
+          var change = opts.processChange(winningDoc, metadata, opts);
+          change.seq = metadata.seq;
+
+          var filtered = filter(change);
+          if (typeof filtered === 'object') {
+            return opts.complete(filtered);
+          }
+
+          if (filtered) {
+            called++;
+
+            if (opts.attachments && opts.include_docs) {
+              // fetch attachment immediately for the benefit
+              // of live listeners
+              fetchAttachments([change], stores, opts).then(function () {
+                opts.onChange(change);
+              });
+            } else {
+              opts.onChange(change);
+            }
+
+            if (returnDocs) {
+              results.push(change);
+            }
+          }
+          next();
+        }
+
+        if (metadata.seq !== seq) {
+          // some other seq is later
+          return next();
+        }
+
+        lastSeq = seq;
+
+        if (winningRev === doc._rev) {
+          return onGetWinningDoc(doc);
+        }
+
+        // fetch the winner
+
+        var winningSeq = metadata.rev_map[winningRev];
+
+        stores.bySeqStore.get(formatSeq(winningSeq), function (err, doc) {
+          onGetWinningDoc(doc);
+        });
+      }
+
+      metadata = docIdsToMetadata.get(doc._id);
+      if (metadata) { // cached
+        return onGetMetadata(metadata);
+      }
+      // metadata not cached, have to go fetch it
+      stores.docStore.get(doc._id, function (err, metadata) {
+        /* istanbul ignore if */
+        if (opts.cancelled || opts.done || db.isClosed() ||
+          isLocalId(metadata.id)) {
+          return next();
+        }
+        docIdsToMetadata.set(doc._id, metadata);
+        onGetMetadata(metadata);
+      });
+    }, function (next) {
+      if (opts.cancelled) {
+        return next();
+      }
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+
+      next();
+    }).on('unpipe', function () {
+      throughStream.end();
+      complete();
+    });
+    changeStream.pipe(throughStream);
+    return {
+      cancel: function () {
+        opts.cancelled = true;
+        complete();
+      }
+    };
+  };
+
+  api._close = function (callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(createError(NOT_OPEN));
+    }
+    db.close(function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        callback(err);
+      } else {
+        dbStore["delete"](name);
+        callback();
+      }
+    });
+  };
+
+  api._getRevisionTree = function (docId, callback) {
+    stores.docStore.get(docId, function (err, metadata) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, metadata.rev_tree);
+      }
+    });
+  };
+
+  api._doCompaction = writeLock(function (docId, revs, opts, callback) {
+    api._doCompactionNoLock(docId, revs, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._doCompactionNoLock = function (docId, revs, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+
+    if (!revs.length) {
+      return callback();
+    }
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.docStore, docId, function (err, metadata) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var seqs = revs.map(function (rev) {
+        var seq = metadata.rev_map[rev];
+        delete metadata.rev_map[rev];
+        return seq;
+      });
+      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                         revHash, ctx, opts) {
+        var rev = pos + '-' + revHash;
+        if (revs.indexOf(rev) !== -1) {
+          opts.status = 'missing';
+        }
+      });
+
+      var batch = [];
+      batch.push({
+        key: metadata.id,
+        value: metadata,
+        type: 'put',
+        prefix: stores.docStore
+      });
+
+      var digestMap = {};
+      var numDone = 0;
+      var overallErr;
+      function checkDone(err) {
+        /* istanbul ignore if */
+        if (err) {
+          overallErr = err;
+        }
+        if (++numDone === revs.length) { // done
+          /* istanbul ignore if */
+          if (overallErr) {
+            return callback(overallErr);
+          }
+          deleteOrphanedAttachments();
+        }
+      }
+
+      function finish(err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        txn.batch(batch);
+        if (opts.ctx) {
+          // don't execute immediately
+          return callback();
+        }
+        txn.execute(db, callback);
+      }
+
+      function deleteOrphanedAttachments() {
+        var possiblyOrphanedAttachments = Object.keys(digestMap);
+        if (!possiblyOrphanedAttachments.length) {
+          return finish();
+        }
+        var numDone = 0;
+        var overallErr;
+        function checkDone(err) {
+          /* istanbul ignore if */
+          if (err) {
+            overallErr = err;
+          }
+          if (++numDone === possiblyOrphanedAttachments.length) {
+            finish(overallErr);
+          }
+        }
+        var refsToDelete = new pouchdbCollections.Map();
+        revs.forEach(function (rev) {
+          refsToDelete.set(docId + '@' + rev, true);
+        });
+        possiblyOrphanedAttachments.forEach(function (digest) {
+          txn.get(stores.attachmentStore, digest, function (err, attData) {
+            /* istanbul ignore if */
+            if (err) {
+              if (err.name === 'NotFoundError') {
+                return checkDone();
+              } else {
+                return checkDone(err);
+              }
+            }
+            var refs = Object.keys(attData.refs || {}).filter(function (ref) {
+              return !refsToDelete.has(ref);
+            });
+            var newRefs = {};
+            refs.forEach(function (ref) {
+              newRefs[ref] = true;
+            });
+            if (refs.length) { // not orphaned
+              batch.push({
+                key: digest,
+                type: 'put',
+                value: {refs: newRefs},
+                prefix: stores.attachmentStore
+              });
+            } else { // orphaned, can safely delete
+              batch = batch.concat([{
+                key: digest,
+                type: 'del',
+                prefix: stores.attachmentStore
+              }, {
+                key: digest,
+                type: 'del',
+                prefix: stores.binaryStore
+              }]);
+            }
+            checkDone();
+          });
+        });
+      }
+
+      seqs.forEach(function (seq) {
+        batch.push({
+          key: formatSeq(seq),
+          type: 'del',
+          prefix: stores.bySeqStore
+        });
+        txn.get(stores.bySeqStore, formatSeq(seq), function (err, doc) {
+          /* istanbul ignore if */
+          if (err) {
+            if (err.name === 'NotFoundError') {
+              return checkDone();
+            } else {
+              return checkDone(err);
+            }
+          }
+          var atts = Object.keys(doc._attachments || {});
+          atts.forEach(function (attName) {
+            var digest = doc._attachments[attName].digest;
+            digestMap[digest] = true;
+          });
+          checkDone();
+        });
+      });
+    });
+  };
+
+  api._getLocal = function (id, callback) {
+    stores.localStore.get(id, function (err, doc) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, doc);
+      }
+    });
+  };
+
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._putLocalNoLock(doc, opts, callback);
+    } else {
+      api._putLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._putLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._putLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._putLocalNoLock = function (doc, opts, callback) {
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.localStore, id, function (err, resp) {
+      if (err && oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      if (resp && resp._rev !== oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      doc._rev =
+          oldRev ? '0-' + (parseInt(oldRev.split('-')[1], 10) + 1) : '0-1';
+      var batch = [
+        {
+          type: 'put',
+          prefix: stores.localStore,
+          key: id,
+          value: doc
+        }
+      ];
+
+      txn.batch(batch);
+      var ret = {ok: true, id: doc._id, rev: doc._rev};
+
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._removeLocalNoLock(doc, opts, callback);
+    } else {
+      api._removeLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._removeLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._removeLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._removeLocalNoLock = function (doc, opts, callback) {
+    var txn = opts.ctx || new LevelTransaction();
+    txn.get(stores.localStore, doc._id, function (err, resp) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        } else {
+          return callback(createError(MISSING_DOC));
+        }
+      }
+      if (resp._rev !== doc._rev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      txn.batch([{
+        prefix: stores.localStore,
+        type: 'del',
+        key: doc._id
+      }]);
+      var ret = {ok: true, id: doc._id, rev: '0-0'};
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  // close and delete open leveldb stores
+  api._destroy = function (opts, callback) {
+    var dbStore;
+    var leveldownName = functionName(leveldown);
+    /* istanbul ignore else */
+    if (dbStores.has(leveldownName)) {
+      dbStore = dbStores.get(leveldownName);
+    } else {
+      return callDestroy(name, callback);
+    }
+
+    /* istanbul ignore else */
+    if (dbStore.has(name)) {
+      levelChanges.removeAllListeners(name);
+
+      dbStore.get(name).close(function () {
+        dbStore["delete"](name);
+        callDestroy(name, callback);
+      });
+    } else {
+      callDestroy(name, callback);
+    }
+  };
+  function callDestroy(name, cb) {
+    /* istanbul ignore else */
+    if (typeof leveldown.destroy === 'function') {
+      leveldown.destroy(name, cb);
+    } else {
+      process.nextTick(cb);
+    }
+  }
+}
+
+LevelPouch.valid = function () {
+  // this gets overriden by the *down-based browser adapters
+  return true;
+};
+
+LevelPouch.use_prefix = false;
+
+function altFactory(adapterConfig, downAdapter) {
+
+  function LevelPouchAlt(opts, callback) {
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    LevelPouch.call(this, _opts, callback);
+  }
+
+  // overrides for normal LevelDB behavior on Node
+  LevelPouchAlt.valid = function () {
+    return adapterConfig.valid();
+  };
+  LevelPouchAlt.use_prefix = adapterConfig.use_prefix;
+
+  LevelPouchAlt.destroy = toPromise(function (name, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    return LevelPouch.destroy(name, _opts, callback);
+  });
+  return LevelPouchAlt;
+}
+
+function pluginBase(adapterConfig, downAdapter) {
+  var adapterName = adapterConfig.name;
+  var adapter = altFactory(adapterConfig, downAdapter);
+  // use global PouchDB if it's there (e.g. window.PouchDB)
+  var PDB = (typeof PouchDB !== 'undefined') ? PouchDB : _dereq_("pouchdb");
+  if (!PDB) {
+    console.error(adapterConfig.name + ' adapter plugin error: ' +
+      'Cannot find global "PouchDB" object! ' +
+      'Did you remember to include pouchdb.js?');
+  } else {
+    PDB.adapter(adapterName, adapter, true);
+  }
+}
+
+var adapterConfig = {
+  name: 'fruitdown',
+  valid: function () {
+    return !!global.indexedDB;
+  },
+  use_prefix: true
+};
+
+pluginBase(adapterConfig, downAdapter);
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(8).Buffer)
+},{"19":19,"23":23,"26":26,"31":31,"34":34,"48":48,"5":5,"52":52,"53":53,"55":55,"57":57,"7":7,"72":72,"8":8,"90":90,"95":95,"pouchdb":"pouchdb"}],2:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKeyValue(key, 'key', this._db._isBuffer)
+  if (err) throw err
+  err = this._db._checkKeyValue(value, 'value', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+  if (!this._db._isBuffer(value)) value = String(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKeyValue(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+}).call(this,_dereq_(55))
+},{"55":55}],3:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractIterator (db) {
+  this.db = db
+  this._ended = false
+  this._nexting = false
+}
+
+AbstractIterator.prototype.next = function (callback) {
+  var self = this
+
+  if (typeof callback != 'function')
+    throw new Error('next() requires a callback argument')
+
+  if (self._ended)
+    return callback(new Error('cannot call next() after end()'))
+  if (self._nexting)
+    return callback(new Error('cannot call next() before previous next() has completed'))
+
+  self._nexting = true
+  if (typeof self._next == 'function') {
+    return self._next(function () {
+      self._nexting = false
+      callback.apply(null, arguments)
+    })
+  }
+
+  process.nextTick(function () {
+    self._nexting = false
+    callback()
+  })
+}
+
+AbstractIterator.prototype.end = function (callback) {
+  if (typeof callback != 'function')
+    throw new Error('end() requires a callback argument')
+
+  if (this._ended)
+    return callback(new Error('end() already called on iterator'))
+
+  this._ended = true
+
+  if (typeof this._end == 'function')
+    return this._end(callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractIterator
+
+}).call(this,_dereq_(55))
+},{"55":55}],4:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(96)
+  , AbstractIterator     = _dereq_(3)
+  , AbstractChainedBatch = _dereq_(2)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._open == 'function')
+    return this._open(options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function')
+    return this._close(callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (err = this._checkKeyValue(value, 'value', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  // coerce value to string in node, don't touch it in browser
+  // (indexeddb can store any JS type)
+  if (!this._isBuffer(value) && !process.browser)
+    value = String(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKeyValue(e.type, 'type', this._isBuffer))
+      return callback(err)
+
+    if (err = this._checkKeyValue(e.key, 'key', this._isBuffer))
+      return callback(err)
+
+    if (e.type == 'put') {
+      if (err = this._checkKeyValue(e.value, 'value', this._isBuffer))
+        return callback(err)
+    }
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  if (!this._isBuffer(start))
+    start = String(start)
+
+  if (!this._isBuffer(end))
+    end = String(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+
+  // fix `start` so it takes into account gt, gte, lt, lte as appropriate
+  if (options.reverse && options.lt)
+    options.start = options.lt
+  if (options.reverse && options.lte)
+    options.start = options.lte
+  if (!options.reverse && options.gt)
+    options.start = options.gt
+  if (!options.reverse && options.gte)
+    options.start = options.gte
+
+  if ((options.reverse && options.lt && !options.lte)
+    || (!options.reverse && options.gt && !options.gte))
+    options.exclusiveStart = true // start should *not* include matching key
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._checkKeyValue = function (obj, type) {
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj)) {
+    if (obj.length === 0)
+      return new Error(type + ' cannot be an empty Buffer')
+  } else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports.AbstractLevelDOWN    = AbstractLevelDOWN
+module.exports.AbstractIterator     = AbstractIterator
+module.exports.AbstractChainedBatch = AbstractChainedBatch
+
+}).call(this,{"isBuffer":_dereq_(32)},_dereq_(55))
+},{"2":2,"3":3,"32":32,"55":55,"96":96}],5:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+  return function () {
+    var len = arguments.length;
+    if (len) {
+      var args = [];
+      var i = -1;
+      while (++i < len) {
+        args[i] = arguments[i];
+      }
+      return fun.call(this, args);
+    } else {
+      return fun.call(this, []);
+    }
+  };
+}
+},{}],6:[function(_dereq_,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+	'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+	var PLUS   = '+'.charCodeAt(0)
+	var SLASH  = '/'.charCodeAt(0)
+	var NUMBER = '0'.charCodeAt(0)
+	var LOWER  = 'a'.charCodeAt(0)
+	var UPPER  = 'A'.charCodeAt(0)
+	var PLUS_URL_SAFE = '-'.charCodeAt(0)
+	var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+	function decode (elt) {
+		var code = elt.charCodeAt(0)
+		if (code === PLUS ||
+		    code === PLUS_URL_SAFE)
+			return 62 // '+'
+		if (code === SLASH ||
+		    code === SLASH_URL_SAFE)
+			return 63 // '/'
+		if (code < NUMBER)
+			return -1 //no match
+		if (code < NUMBER + 10)
+			return code - NUMBER + 26 + 26
+		if (code < UPPER + 26)
+			return code - UPPER
+		if (code < LOWER + 26)
+			return code - LOWER + 26
+	}
+
+	function b64ToByteArray (b64) {
+		var i, j, l, tmp, placeHolders, arr
+
+		if (b64.length % 4 > 0) {
+			throw new Error('Invalid string. Length must be a multiple of 4')
+		}
+
+		// the number of equal signs (place holders)
+		// if there are two placeholders, than the two characters before it
+		// represent one byte
+		// if there is only one, then the three characters before it represent 2 bytes
+		// this is just a cheap hack to not do indexOf twice
+		var len = b64.length
+		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+		// base64 is 4/3 + up to two characters of the original data
+		arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+		// if there are placeholders, only get up to the last complete 4 chars
+		l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+		var L = 0
+
+		function push (v) {
+			arr[L++] = v
+		}
+
+		for (i = 0, j = 0; i < l; i += 4, j += 3) {
+			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+			push((tmp & 0xFF0000) >> 16)
+			push((tmp & 0xFF00) >> 8)
+			push(tmp & 0xFF)
+		}
+
+		if (placeHolders === 2) {
+			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+			push(tmp & 0xFF)
+		} else if (placeHolders === 1) {
+			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+			push((tmp >> 8) & 0xFF)
+			push(tmp & 0xFF)
+		}
+
+		return arr
+	}
+
+	function uint8ToBase64 (uint8) {
+		var i,
+			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+			output = "",
+			temp, length
+
+		function encode (num) {
+			return lookup.charAt(num)
+		}
+
+		function tripletToBase64 (num) {
+			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+		}
+
+		// go through the array every three bytes, we'll deal with trailing stuff later
+		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+			output += tripletToBase64(temp)
+		}
+
+		// pad the end with zeros, but make sure to not forget the extra bytes
+		switch (extraBytes) {
+			case 1:
+				temp = uint8[uint8.length - 1]
+				output += encode(temp >> 2)
+				output += encode((temp << 4) & 0x3F)
+				output += '=='
+				break
+			case 2:
+				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+				output += encode(temp >> 10)
+				output += encode((temp >> 4) & 0x3F)
+				output += encode((temp << 2) & 0x3F)
+				output += '='
+				break
+		}
+
+		return output
+	}
+
+	exports.toByteArray = b64ToByteArray
+	exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],7:[function(_dereq_,module,exports){
+
+},{}],8:[function(_dereq_,module,exports){
+(function (global){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+/* eslint-disable no-proto */
+
+'use strict'
+
+var base64 = _dereq_(6)
+var ieee754 = _dereq_(29)
+var isArray = _dereq_(33)
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ *     on objects.
+ *
+ *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *     incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
+  ? global.TYPED_ARRAY_SUPPORT
+  : typedArraySupport()
+
+function typedArraySupport () {
+  function Bar () {}
+  try {
+    var arr = new Uint8Array(1)
+    arr.foo = function () { return 42 }
+    arr.constructor = Bar
+    return arr.foo() === 42 && // typed array instances can be augmented
+        arr.constructor === Bar && // constructor can be set
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+}
+
+function kMaxLength () {
+  return Buffer.TYPED_ARRAY_SUPPORT
+    ? 0x7fffffff
+    : 0x3fffffff
+}
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (arg) {
+  if (!(this instanceof Buffer)) {
+    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+    if (arguments.length > 1) return new Buffer(arg, arguments[1])
+    return new Buffer(arg)
+  }
+
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    this.length = 0
+    this.parent = undefined
+  }
+
+  // Common case.
+  if (typeof arg === 'number') {
+    return fromNumber(this, arg)
+  }
+
+  // Slightly less common case.
+  if (typeof arg === 'string') {
+    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+  }
+
+  // Unusual.
+  return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < length; i++) {
+      that[i] = 0
+    }
+  }
+  return that
+}
+
+function fromString (that, string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+  // Assumption: byteLength() return value is always < kMaxLength.
+  var length = byteLength(string, encoding) | 0
+  that = allocate(that, length)
+
+  that.write(string, encoding)
+  return that
+}
+
+function fromObject (that, object) {
+  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+  if (isArray(object)) return fromArray(that, object)
+
+  if (object == null) {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (typeof ArrayBuffer !== 'undefined') {
+    if (object.buffer instanceof ArrayBuffer) {
+      return fromTypedArray(that, object)
+    }
+    if (object instanceof ArrayBuffer) {
+      return fromArrayBuffer(that, object)
+    }
+  }
+
+  if (object.length) return fromArrayLike(that, object)
+
+  return fromJsonObject(that, object)
+}
+
+function fromBuffer (that, buffer) {
+  var length = checked(buffer.length) | 0
+  that = allocate(that, length)
+  buffer.copy(that, 0, 0, length)
+  return that
+}
+
+function fromArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  // Truncating the elements is probably not what people expect from typed
+  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+  // of the old Buffer constructor.
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function fromArrayBuffer (that, array) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    array.byteLength
+    that = Buffer._augment(new Uint8Array(array))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that = fromTypedArray(that, new Uint8Array(array))
+  }
+  return that
+}
+
+function fromArrayLike (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject (that, object) {
+  var array
+  var length = 0
+
+  if (object.type === 'Buffer' && isArray(object.data)) {
+    array = object.data
+    length = checked(array.length) | 0
+  }
+  that = allocate(that, length)
+
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+if (Buffer.TYPED_ARRAY_SUPPORT) {
+  Buffer.prototype.__proto__ = Uint8Array.prototype
+  Buffer.__proto__ = Uint8Array
+} else {
+  // pre-set for values that may exist in the future
+  Buffer.prototype.length = undefined
+  Buffer.prototype.parent = undefined
+}
+
+function allocate (that, length) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    that = Buffer._augment(new Uint8Array(length))
+    that.__proto__ = Buffer.prototype
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that.length = length
+    that._isBuffer = true
+  }
+
+  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+  if (fromPool) that.parent = rootParent
+
+  return that
+}
+
+function checked (length) {
+  // Note: cannot use `length < kMaxLength` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= kMaxLength()) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  var i = 0
+  var len = Math.min(x, y)
+  while (i < len) {
+    if (a[i] !== b[i]) break
+
+    ++i
+  }
+
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; i++) {
+      length += list[i].length
+    }
+  }
+
+  var buf = new Buffer(length)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+function byteLength (string, encoding) {
+  if (typeof string !== 'string') string = '' + string
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'binary':
+      // Deprecated
+      case 'raw':
+      case 'raws':
+        return len
+      case 'utf8':
+      case 'utf-8':
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start | 0
+  end = end === undefined || end === Infinity ? this.length : end | 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length | 0
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` is deprecated
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` is deprecated
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset | 0
+    if (isFinite(length)) {
+      length = length | 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  // legacy write(string, encoding, offset, length) - remove in v0.13
+  } else {
+    var swap = encoding
+    encoding = offset
+    offset = length | 0
+    length = swap
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'binary':
+        return binaryWrite(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; i--) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    // ascending copy from start
+    for (i = 0; i < len; i++) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), targetStart)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function fill (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function _augment (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array set method before overwriting
+  arr._set = arr.set
+
+  // deprecated
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.indexOf = BP.indexOf
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"29":29,"33":33,"6":6}],9:[function(_dereq_,module,exports){
+(function (Buffer){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+  if (Array.isArray) {
+    return Array.isArray(arg);
+  }
+  return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+}).call(this,{"isBuffer":_dereq_(32)})
+},{"32":32}],10:[function(_dereq_,module,exports){
+var Buffer = _dereq_(8).Buffer
+
+var CHARS = '.PYFGCRLAOEUIDHTNSQJKXBMWVZ_pyfgcrlaoeuidhtnsqjkxbmwvz1234567890'
+  .split('').sort().join('')
+
+module.exports = function (chars, exports) {
+  chars = chars || CHARS
+  exports = exports || {}
+  if(chars.length !== 64) throw new Error('a base 64 encoding requires 64 chars')
+
+  var codeToIndex = new Buffer(128)
+  codeToIndex.fill()
+
+  for(var i = 0; i < 64; i++) {
+    var code = chars.charCodeAt(i)
+    codeToIndex[code] = i
+  }
+
+  exports.encode = function (data) {
+      var s = '', l = data.length, hang = 0
+      for(var i = 0; i < l; i++) {
+        var v = data[i]
+
+        switch (i % 3) {
+          case 0:
+            s += chars[v >> 2]
+            hang = (v & 3) << 4
+          break;
+          case 1:
+            s += chars[hang | v >> 4]
+            hang = (v & 0xf) << 2
+          break;
+          case 2:
+            s += chars[hang | v >> 6]
+            s += chars[v & 0x3f]
+            hang = 0
+          break;
+        }
+
+      }
+      if(l%3) s += chars[hang]
+      return s
+    }
+  exports.decode = function (str) {
+      var l = str.length, j = 0
+      var b = new Buffer(~~((l/4)*3)), hang = 0
+
+      for(var i = 0; i < l; i++) {
+        var v = codeToIndex[str.charCodeAt(i)]
+
+        switch (i % 4) {
+          case 0:
+            hang = v << 2;
+          break;
+          case 1:
+            b[j++] = hang | v >> 4
+            hang = (v << 4) & 0xff
+          break;
+          case 2:
+            b[j++] = hang | v >> 2
+            hang = (v << 6) & 0xff
+          break;
+          case 3:
+            b[j++] = hang | v
+          break;
+        }
+
+      }
+      return b
+    }
+  return exports
+}
+
+module.exports(CHARS, module.exports)
+
+
+},{"8":8}],11:[function(_dereq_,module,exports){
+var util = _dereq_(94)
+  , AbstractIterator = _dereq_(16).AbstractIterator
+
+
+function DeferredIterator (options) {
+  AbstractIterator.call(this, options)
+
+  this._options = options
+  this._iterator = null
+  this._operations = []
+}
+
+util.inherits(DeferredIterator, AbstractIterator)
+
+DeferredIterator.prototype.setDb = function (db) {
+  var it = this._iterator = db.iterator(this._options)
+  this._operations.forEach(function (op) {
+    it[op.method].apply(it, op.args)
+  })
+}
+
+DeferredIterator.prototype._operation = function (method, args) {
+  if (this._iterator)
+    return this._iterator[method].apply(this._iterator, args)
+  this._operations.push({ method: method, args: args })
+}
+
+'next end'.split(' ').forEach(function (m) {
+  DeferredIterator.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+module.exports = DeferredIterator;
+
+},{"16":16,"94":94}],12:[function(_dereq_,module,exports){
+(function (Buffer,process){
+var util              = _dereq_(94)
+  , AbstractLevelDOWN = _dereq_(16).AbstractLevelDOWN
+  , DeferredIterator  = _dereq_(11)
+
+function DeferredLevelDOWN (location) {
+  AbstractLevelDOWN.call(this, typeof location == 'string' ? location : '') // optional location, who cares?
+  this._db         = undefined
+  this._operations = []
+  this._iterators  = []
+}
+
+util.inherits(DeferredLevelDOWN, AbstractLevelDOWN)
+
+// called by LevelUP when we have a real DB to take its place
+DeferredLevelDOWN.prototype.setDb = function (db) {
+  this._db = db
+  this._operations.forEach(function (op) {
+    db[op.method].apply(db, op.args)
+  })
+  this._iterators.forEach(function (it) {
+    it.setDb(db)
+  })
+}
+
+DeferredLevelDOWN.prototype._open = function (options, callback) {
+  return process.nextTick(callback)
+}
+
+// queue a new deferred operation
+DeferredLevelDOWN.prototype._operation = function (method, args) {
+  if (this._db)
+    return this._db[method].apply(this._db, args)
+  this._operations.push({ method: method, args: args })
+}
+
+// deferrables
+'put get del batch approximateSize'.split(' ').forEach(function (m) {
+  DeferredLevelDOWN.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+DeferredLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+DeferredLevelDOWN.prototype._iterator = function (options) {
+  if (this._db)
+    return this._db.iterator.apply(this._db, arguments)
+  var it = new DeferredIterator(options)
+  this._iterators.push(it)
+  return it
+}
+
+module.exports                  = DeferredLevelDOWN
+module.exports.DeferredIterator = DeferredIterator
+
+}).call(this,{"isBuffer":_dereq_(32)},_dereq_(55))
+},{"11":11,"16":16,"32":32,"55":55,"94":94}],13:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err)
+    throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+  if (!this._db._isBuffer(value)) value = String(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+}).call(this,_dereq_(55))
+},{"55":55}],14:[function(_dereq_,module,exports){
+arguments[4][3][0].apply(exports,arguments)
+},{"3":3,"55":55}],15:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(18)
+  , AbstractIterator     = _dereq_(14)
+  , AbstractChainedBatch = _dereq_(13)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+  this.status = 'new'
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.createIfMissing = options.createIfMissing != false
+  options.errorIfExists = !!options.errorIfExists
+
+  if (typeof this._open == 'function') {
+    this.status = 'opening'
+    this._open(options, function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'open'
+      callback()
+    })
+  } else {
+    this.status = 'open'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function') {
+    this.status = 'closing'
+    this._close(function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'closed'
+      callback()
+    })
+  } else {
+    this.status = 'closed'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.asBuffer = options.asBuffer != false
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  // coerce value to string in node, don't touch it in browser
+  // (indexeddb can store any JS type)
+  if (value != null && !this._isBuffer(value) && !process.browser)
+    value = String(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof array == 'function')
+    callback = array
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (!options || typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKey(e.type, 'type', this._isBuffer))
+      return callback(err)
+
+    if (err = this._checkKey(e.key, 'key', this._isBuffer))
+      return callback(err)
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  if (!this._isBuffer(start))
+    start = String(start)
+
+  if (!this._isBuffer(end))
+    end = String(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+  options.keys = options.keys != false
+  options.values = options.values != false
+  options.limit = 'limit' in options ? options.limit : -1
+  options.keyAsBuffer = options.keyAsBuffer != false
+  options.valueAsBuffer = options.valueAsBuffer != false
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._checkKey = function (obj, type) {
+
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj)) {
+    if (obj.length === 0)
+      return new Error(type + ' cannot be an empty Buffer')
+  } else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports = AbstractLevelDOWN
+
+}).call(this,{"isBuffer":_dereq_(32)},_dereq_(55))
+},{"13":13,"14":14,"18":18,"32":32,"55":55}],16:[function(_dereq_,module,exports){
+exports.AbstractLevelDOWN    = _dereq_(15)
+exports.AbstractIterator     = _dereq_(14)
+exports.AbstractChainedBatch = _dereq_(13)
+exports.isLevelDOWN          = _dereq_(17)
+
+},{"13":13,"14":14,"15":15,"17":17}],17:[function(_dereq_,module,exports){
+var AbstractLevelDOWN = _dereq_(15)
+
+function isLevelDOWN (db) {
+  if (!db || typeof db !== 'object')
+    return false
+  return Object.keys(AbstractLevelDOWN.prototype).filter(function (name) {
+    // TODO remove approximateSize check when method is gone
+    return name[0] != '_' && name != 'approximateSize'
+  }).every(function (name) {
+    return typeof db[name] == 'function'
+  })
+}
+
+module.exports = isLevelDOWN
+
+},{"15":15}],18:[function(_dereq_,module,exports){
+module.exports = extend
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function extend() {
+    var target = {}
+
+    for (var i = 0; i < arguments.length; i++) {
+        var source = arguments[i]
+
+        for (var key in source) {
+            if (hasOwnProperty.call(source, key)) {
+                target[key] = source[key]
+            }
+        }
+    }
+
+    return target
+}
+
+},{}],19:[function(_dereq_,module,exports){
+/**
+ * Copyright (c) 2013 Petka Antonov
+ * 
+ * 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:</p>
+ * 
+ * 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.
+ */
+"use strict";
+function Deque(capacity) {
+    this._capacity = getCapacity(capacity);
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+    if (isArray(capacity)) {
+        var len = capacity.length;
+        for (var i = 0; i < len; ++i) {
+            this[i] = capacity[i];
+        }
+        this._length = len;
+    }
+}
+
+Deque.prototype.toArray = function Deque$toArray() {
+    var len = this._length;
+    var ret = new Array(len);
+    var front = this._front;
+    var capacity = this._capacity;
+    for (var j = 0; j < len; ++j) {
+        ret[j] = this[(front + j) & (capacity - 1)];
+    }
+    return ret;
+};
+
+Deque.prototype.push = function Deque$push(item) {
+    var argsLength = arguments.length;
+    var length = this._length;
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = 0; i < argsLength; ++i) {
+                this._checkCapacity(length + 1);
+                var j = (this._front + length) & (this._capacity - 1);
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+            }
+            return length;
+        }
+        else {
+            var j = this._front;
+            for (var i = 0; i < argsLength; ++i) {
+                this[(j + length) & (capacity - 1)] = arguments[i];
+                j++;
+            }
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var i = (this._front + length) & (this._capacity - 1);
+    this[i] = item;
+    this._length = length + 1;
+    return length + 1;
+};
+
+Deque.prototype.pop = function Deque$pop() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var i = (this._front + length - 1) & (this._capacity - 1);
+    var ret = this[i];
+    this[i] = void 0;
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.shift = function Deque$shift() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var front = this._front;
+    var ret = this[front];
+    this[front] = void 0;
+    this._front = (front + 1) & (this._capacity - 1);
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.unshift = function Deque$unshift(item) {
+    var length = this._length;
+    var argsLength = arguments.length;
+
+
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = argsLength - 1; i >= 0; i--) {
+                this._checkCapacity(length + 1);
+                var capacity = this._capacity;
+                var j = (((( this._front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+                this._front = j;
+            }
+            return length;
+        }
+        else {
+            var front = this._front;
+            for (var i = argsLength - 1; i >= 0; i--) {
+                var j = (((( front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                front = j;
+            }
+            this._front = front;
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var capacity = this._capacity;
+    var i = (((( this._front - 1 ) &
+        ( capacity - 1) ) ^ capacity ) - capacity );
+    this[i] = item;
+    this._length = length + 1;
+    this._front = i;
+    return length + 1;
+};
+
+Deque.prototype.peekBack = function Deque$peekBack() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var index = (this._front + length - 1) & (this._capacity - 1);
+    return this[index];
+};
+
+Deque.prototype.peekFront = function Deque$peekFront() {
+    if (this._length === 0) {
+        return void 0;
+    }
+    return this[this._front];
+};
+
+Deque.prototype.get = function Deque$get(index) {
+    var i = index;
+    if ((i !== (i | 0))) {
+        return void 0;
+    }
+    var len = this._length;
+    if (i < 0) {
+        i = i + len;
+    }
+    if (i < 0 || i >= len) {
+        return void 0;
+    }
+    return this[(this._front + i) & (this._capacity - 1)];
+};
+
+Deque.prototype.isEmpty = function Deque$isEmpty() {
+    return this._length === 0;
+};
+
+Deque.prototype.clear = function Deque$clear() {
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+};
+
+Deque.prototype.toString = function Deque$toString() {
+    return this.toArray().toString();
+};
+
+Deque.prototype.valueOf = Deque.prototype.toString;
+Deque.prototype.removeFront = Deque.prototype.shift;
+Deque.prototype.removeBack = Deque.prototype.pop;
+Deque.prototype.insertFront = Deque.prototype.unshift;
+Deque.prototype.insertBack = Deque.prototype.push;
+Deque.prototype.enqueue = Deque.prototype.push;
+Deque.prototype.dequeue = Deque.prototype.shift;
+Deque.prototype.toJSON = Deque.prototype.toArray;
+
+Object.defineProperty(Deque.prototype, "length", {
+    get: function() {
+        return this._length;
+    },
+    set: function() {
+        throw new RangeError("");
+    }
+});
+
+Deque.prototype._makeCapacity = function Deque$_makeCapacity() {
+    var len = this._capacity;
+    for (var i = 0; i < len; ++i) {
+        this[i] = void 0;
+    }
+};
+
+Deque.prototype._checkCapacity = function Deque$_checkCapacity(size) {
+    if (this._capacity < size) {
+        this._resizeTo(getCapacity(this._capacity * 1.5 + 16));
+    }
+};
+
+Deque.prototype._resizeTo = function Deque$_resizeTo(capacity) {
+    var oldFront = this._front;
+    var oldCapacity = this._capacity;
+    var oldDeque = new Array(oldCapacity);
+    var length = this._length;
+
+    arrayCopy(this, 0, oldDeque, 0, oldCapacity);
+    this._capacity = capacity;
+    this._makeCapacity();
+    this._front = 0;
+    if (oldFront + length <= oldCapacity) {
+        arrayCopy(oldDeque, oldFront, this, 0, length);
+    } else {        var lengthBeforeWrapping =
+            length - ((oldFront + length) & (oldCapacity - 1));
+
+        arrayCopy(oldDeque, oldFront, this, 0, lengthBeforeWrapping);
+        arrayCopy(oldDeque, 0, this, lengthBeforeWrapping,
+            length - lengthBeforeWrapping);
+    }
+};
+
+
+var isArray = Array.isArray;
+
+function arrayCopy(src, srcIndex, dst, dstIndex, len) {
+    for (var j = 0; j < len; ++j) {
+        dst[j + dstIndex] = src[j + srcIndex];
+    }
+}
+
+function pow2AtLeast(n) {
+    n = n >>> 0;
+    n = n - 1;
+    n = n | (n >> 1);
+    n = n | (n >> 2);
+    n = n | (n >> 4);
+    n = n | (n >> 8);
+    n = n | (n >> 16);
+    return n + 1;
+}
+
+function getCapacity(capacity) {
+    if (typeof capacity !== "number") {
+        if (isArray(capacity)) {
+            capacity = capacity.length;
+        }
+        else {
+            return 16;
+        }
+    }
+    return pow2AtLeast(
+        Math.min(
+            Math.max(16, capacity), 1073741824)
+    );
+}
+
+module.exports = Deque;
+
+},{}],20:[function(_dereq_,module,exports){
+var prr = _dereq_(22)
+
+function init (type, message, cause) {
+  prr(this, {
+      type    : type
+    , name    : type
+      // can be passed just a 'cause'
+    , cause   : typeof message != 'string' ? message : cause
+    , message : !!message && typeof message != 'string' ? message.message : message
+
+  }, 'ewr')
+}
+
+// generic prototype, not intended to be actually used - helpful for `instanceof`
+function CustomError (message, cause) {
+  Error.call(this)
+  if (Error.captureStackTrace)
+    Error.captureStackTrace(this, arguments.callee)
+  init.call(this, 'CustomError', message, cause)
+}
+
+CustomError.prototype = new Error()
+
+function createError (errno, type, proto) {
+  var err = function (message, cause) {
+    init.call(this, type, message, cause)
+    //TODO: the specificity here is stupid, errno should be available everywhere
+    if (type == 'FilesystemError') {
+      this.code    = this.cause.code
+      this.path    = this.cause.path
+      this.errno   = this.cause.errno
+      this.message =
+        (errno.errno[this.cause.errno]
+          ? errno.errno[this.cause.errno].description
+          : this.cause.message)
+        + (this.cause.path ? ' [' + this.cause.path + ']' : '')
+    }
+    Error.call(this)
+    if (Error.captureStackTrace)
+      Error.captureStackTrace(this, arguments.callee)
+  }
+  err.prototype = !!proto ? new proto() : new CustomError()
+  return err
+}
+
+module.exports = function (errno) {
+  var ce = function (type, proto) {
+    return createError(errno, type, proto)
+  }
+  return {
+      CustomError     : CustomError
+    , FilesystemError : ce('FilesystemError')
+    , createError     : ce
+  }
+}
+
+},{"22":22}],21:[function(_dereq_,module,exports){
+var all = module.exports.all = [
+  {
+    errno: -2,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: -1,
+    code: 'UNKNOWN',
+    description: 'unknown error'
+  },
+  {
+    errno: 0,
+    code: 'OK',
+    description: 'success'
+  },
+  {
+    errno: 1,
+    code: 'EOF',
+    description: 'end of file'
+  },
+  {
+    errno: 2,
+    code: 'EADDRINFO',
+    description: 'getaddrinfo error'
+  },
+  {
+    errno: 3,
+    code: 'EACCES',
+    description: 'permission denied'
+  },
+  {
+    errno: 4,
+    code: 'EAGAIN',
+    description: 'resource temporarily unavailable'
+  },
+  {
+    errno: 5,
+    code: 'EADDRINUSE',
+    description: 'address already in use'
+  },
+  {
+    errno: 6,
+    code: 'EADDRNOTAVAIL',
+    description: 'address not available'
+  },
+  {
+    errno: 7,
+    code: 'EAFNOSUPPORT',
+    description: 'address family not supported'
+  },
+  {
+    errno: 8,
+    code: 'EALREADY',
+    description: 'connection already in progress'
+  },
+  {
+    errno: 9,
+    code: 'EBADF',
+    description: 'bad file descriptor'
+  },
+  {
+    errno: 10,
+    code: 'EBUSY',
+    description: 'resource busy or locked'
+  },
+  {
+    errno: 11,
+    code: 'ECONNABORTED',
+    description: 'software caused connection abort'
+  },
+  {
+    errno: 12,
+    code: 'ECONNREFUSED',
+    description: 'connection refused'
+  },
+  {
+    errno: 13,
+    code: 'ECONNRESET',
+    description: 'connection reset by peer'
+  },
+  {
+    errno: 14,
+    code: 'EDESTADDRREQ',
+    description: 'destination address required'
+  },
+  {
+    errno: 15,
+    code: 'EFAULT',
+    description: 'bad address in system call argument'
+  },
+  {
+    errno: 16,
+    code: 'EHOSTUNREACH',
+    description: 'host is unreachable'
+  },
+  {
+    errno: 17,
+    code: 'EINTR',
+    description: 'interrupted system call'
+  },
+  {
+    errno: 18,
+    code: 'EINVAL',
+    description: 'invalid argument'
+  },
+  {
+    errno: 19,
+    code: 'EISCONN',
+    description: 'socket is already connected'
+  },
+  {
+    errno: 20,
+    code: 'EMFILE',
+    description: 'too many open files'
+  },
+  {
+    errno: 21,
+    code: 'EMSGSIZE',
+    description: 'message too long'
+  },
+  {
+    errno: 22,
+    code: 'ENETDOWN',
+    description: 'network is down'
+  },
+  {
+    errno: 23,
+    code: 'ENETUNREACH',
+    description: 'network is unreachable'
+  },
+  {
+    errno: 24,
+    code: 'ENFILE',
+    description: 'file table overflow'
+  },
+  {
+    errno: 25,
+    code: 'ENOBUFS',
+    description: 'no buffer space available'
+  },
+  {
+    errno: 26,
+    code: 'ENOMEM',
+    description: 'not enough memory'
+  },
+  {
+    errno: 27,
+    code: 'ENOTDIR',
+    description: 'not a directory'
+  },
+  {
+    errno: 28,
+    code: 'EISDIR',
+    description: 'illegal operation on a directory'
+  },
+  {
+    errno: 29,
+    code: 'ENONET',
+    description: 'machine is not on the network'
+  },
+  {
+    errno: 31,
+    code: 'ENOTCONN',
+    description: 'socket is not connected'
+  },
+  {
+    errno: 32,
+    code: 'ENOTSOCK',
+    description: 'socket operation on non-socket'
+  },
+  {
+    errno: 33,
+    code: 'ENOTSUP',
+    description: 'operation not supported on socket'
+  },
+  {
+    errno: 34,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: 35,
+    code: 'ENOSYS',
+    description: 'function not implemented'
+  },
+  {
+    errno: 36,
+    code: 'EPIPE',
+    description: 'broken pipe'
+  },
+  {
+    errno: 37,
+    code: 'EPROTO',
+    description: 'protocol error'
+  },
+  {
+    errno: 38,
+    code: 'EPROTONOSUPPORT',
+    description: 'protocol not supported'
+  },
+  {
+    errno: 39,
+    code: 'EPROTOTYPE',
+    description: 'protocol wrong type for socket'
+  },
+  {
+    errno: 40,
+    code: 'ETIMEDOUT',
+    description: 'connection timed out'
+  },
+  {
+    errno: 41,
+    code: 'ECHARSET',
+    description: 'invalid Unicode character'
+  },
+  {
+    errno: 42,
+    code: 'EAIFAMNOSUPPORT',
+    description: 'address family for hostname not supported'
+  },
+  {
+    errno: 44,
+    code: 'EAISERVICE',
+    description: 'servname not supported for ai_socktype'
+  },
+  {
+    errno: 45,
+    code: 'EAISOCKTYPE',
+    description: 'ai_socktype not supported'
+  },
+  {
+    errno: 46,
+    code: 'ESHUTDOWN',
+    description: 'cannot send after transport endpoint shutdown'
+  },
+  {
+    errno: 47,
+    code: 'EEXIST',
+    description: 'file already exists'
+  },
+  {
+    errno: 48,
+    code: 'ESRCH',
+    description: 'no such process'
+  },
+  {
+    errno: 49,
+    code: 'ENAMETOOLONG',
+    description: 'name too long'
+  },
+  {
+    errno: 50,
+    code: 'EPERM',
+    description: 'operation not permitted'
+  },
+  {
+    errno: 51,
+    code: 'ELOOP',
+    description: 'too many symbolic links encountered'
+  },
+  {
+    errno: 52,
+    code: 'EXDEV',
+    description: 'cross-device link not permitted'
+  },
+  {
+    errno: 53,
+    code: 'ENOTEMPTY',
+    description: 'directory not empty'
+  },
+  {
+    errno: 54,
+    code: 'ENOSPC',
+    description: 'no space left on device'
+  },
+  {
+    errno: 55,
+    code: 'EIO',
+    description: 'i/o error'
+  },
+  {
+    errno: 56,
+    code: 'EROFS',
+    description: 'read-only file system'
+  },
+  {
+    errno: 57,
+    code: 'ENODEV',
+    description: 'no such device'
+  },
+  {
+    errno: 58,
+    code: 'ESPIPE',
+    description: 'invalid seek'
+  },
+  {
+    errno: 59,
+    code: 'ECANCELED',
+    description: 'operation canceled'
+  }
+]
+
+module.exports.errno = {}
+module.exports.code = {}
+
+all.forEach(function (error) {
+  module.exports.errno[error.errno] = error
+  module.exports.code[error.code] = error
+})
+
+module.exports.custom = _dereq_(20)(module.exports)
+module.exports.create = module.exports.custom.createError
+
+},{"20":20}],22:[function(_dereq_,module,exports){
+/*!
+  * prr
+  * (c) 2013 Rod Vagg <rod@vagg.org>
+  * https://github.com/rvagg/prr
+  * License: MIT
+  */
+
+(function (name, context, definition) {
+  if (typeof module != 'undefined' && module.exports)
+    module.exports = definition()
+  else
+    context[name] = definition()
+})('prr', this, function() {
+
+  var setProperty = typeof Object.defineProperty == 'function'
+      ? function (obj, key, options) {
+          Object.defineProperty(obj, key, options)
+          return obj
+        }
+      : function (obj, key, options) { // < es5
+          obj[key] = options.value
+          return obj
+        }
+
+    , makeOptions = function (value, options) {
+        var oo = typeof options == 'object'
+          , os = !oo && typeof options == 'string'
+          , op = function (p) {
+              return oo
+                ? !!options[p]
+                : os
+                  ? options.indexOf(p[0]) > -1
+                  : false
+            }
+
+        return {
+            enumerable   : op('enumerable')
+          , configurable : op('configurable')
+          , writable     : op('writable')
+          , value        : value
+        }
+      }
+
+    , prr = function (obj, key, value, options) {
+        var k
+
+        options = makeOptions(value, options)
+
+        if (typeof key == 'object') {
+          for (k in key) {
+            if (Object.hasOwnProperty.call(key, k)) {
+              options.value = key[k]
+              setProperty(obj, k, options)
+            }
+          }
+          return obj
+        }
+
+        return setProperty(obj, key, options)
+      }
+
+  return prr
+})
+},{}],23:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      }
+      throw TypeError('Uncaught, unspecified "error" event.');
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],24:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+//
+// Class that should contain everything necessary to interact
+// with IndexedDB as a generic key-value store (based on LocalStorage).
+//
+
+/* global indexedDB */
+
+var STORE = 'fruitdown';
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+// IE has race conditions, which is what these two caches work around
+// https://gist.github.com/nolanlawson/a841ee23436410f37168
+var cachedDBs = {};
+var openReqList = {};
+
+function StorageCore(dbName) {
+  this._dbName = dbName;
+}
+
+function getDatabase(dbName, callback) {
+  if (cachedDBs[dbName]) {
+    return nextTick(function () {
+      callback(null, cachedDBs[dbName]);
+    });
+  }
+
+  var req = indexedDB.open(dbName, 1);
+
+  openReqList[dbName] = req;
+
+  req.onupgradeneeded = function (e) {
+    var db = e.target.result;
+
+    // Apple migration bug (https://bugs.webkit.org/show_bug.cgi?id=136888)
+    // This will be null the first time rather than 0, so check for 1
+    if (e.oldVersion === 1) {
+      return;
+    }
+
+    // Create a superfluous secondary index purely so we can do
+    // openKeyCursor(). (Limitation of the IndexedDB API, fixed in v2.0.)
+    // We would also use this for detecting ConstraintErrors, but that
+    // doesn't work in Safari: https://bugs.webkit.org/show_bug.cgi?id=149107
+    db.createObjectStore(STORE).createIndex('fakeKey', 'fakeKey');
+
+  };
+
+  req.onsuccess = function (e) {
+    var db = cachedDBs[dbName] = e.target.result;
+    callback(null, db);
+  };
+
+  req.onerror = function(e) {
+    var msg = 'Failed to open indexedDB, are you in private browsing mode?';
+    console.error(msg);
+    callback(e);
+  };
+}
+
+function openTransactionSafely(db, mode) {
+  try {
+    return {
+      txn: db.transaction(STORE, mode)
+    };
+  } catch (err) {
+    return {
+      error: err
+    };
+  }
+}
+
+StorageCore.prototype.getKeys = function (callback) {
+  getDatabase(this._dbName, function (err, db) {
+    if (err) {
+      return callback(err);
+    }
+    var txnRes = openTransactionSafely(db, 'readonly');
+    if (txnRes.error) {
+      return callback(txnRes.error);
+    }
+    var txn = txnRes.txn;
+    var store = txn.objectStore(STORE);
+
+    txn.onerror = callback;
+
+    var keys = [];
+    txn.oncomplete = function () {
+      // Safari has a bug where these keys aren't returned in sorted
+      // order, so we have to sort them explicitly
+      // https://bugs.webkit.org/show_bug.cgi?id=149205
+      callback(null, keys.sort());
+    };
+
+    // using openKeyCursor avoids reading in the whole value,
+    // which may be large
+    var req = store.index('fakeKey').openKeyCursor();
+
+    req.onsuccess = function (e) {
+      var cursor = e.target.result;
+      if (!cursor) {
+        return;
+      }
+      keys.push(cursor.primaryKey);
+      cursor.continue();
+    };
+  });
+};
+
+StorageCore.prototype.put = function (key, value, callback) {
+  getDatabase(this._dbName, function (err, db) {
+    if (err) {
+      return callback(err);
+    }
+    var txnRes = openTransactionSafely(db, 'readwrite');
+    if (txnRes.error) {
+      return callback(txnRes.error);
+    }
+    var txn = txnRes.txn;
+    var store = txn.objectStore(STORE);
+
+    var valueToStore = typeof value === 'string' ? value : value.toString();
+
+    txn.onerror = callback;
+    txn.oncomplete = function () {
+      callback();
+    };
+
+    store.put({value: valueToStore, fakeKey: 0}, key);
+  });
+};
+
+StorageCore.prototype.get = function (key, callback) {
+  getDatabase(this._dbName, function (err, db) {
+    if (err) {
+      return callback(err);
+    }
+    var txnRes = openTransactionSafely(db, 'readonly');
+    if (txnRes.error) {
+      return callback(txnRes.error);
+    }
+    var txn = txnRes.txn;
+    var store = txn.objectStore(STORE);
+
+    var gotten;
+    var req = store.get(key);
+    req.onsuccess = function (e) {
+      if (e.target.result) {
+        gotten = e.target.result.value;
+      }
+    };
+
+    txn.onerror = callback;
+    txn.oncomplete = function () {
+      callback(null, gotten);
+    };
+  });
+};
+
+StorageCore.prototype.remove = function (key, callback) {
+  getDatabase(this._dbName, function (err, db) {
+    if (err) {
+      return callback(err);
+    }
+    var txnRes = openTransactionSafely(db, 'readwrite');
+    if (txnRes.error) {
+      return callback(txnRes.error);
+    }
+    var txn = txnRes.txn;
+    var store = txn.objectStore(STORE);
+
+    store.delete(key);
+
+    txn.onerror = callback;
+    txn.oncomplete = function () {
+      callback();
+    };
+  });
+};
+
+StorageCore.destroy = function (dbName, callback) {
+  nextTick(function () {
+    //Close open request for "dbName" database to fix ie delay.
+    if (openReqList[dbName] && openReqList[dbName].result) {
+      openReqList[dbName].result.close();
+      delete cachedDBs[dbName];
+    }
+    var req = indexedDB.deleteDatabase(dbName);
+
+    req.onsuccess = function () {
+      //Remove open request from the list.
+      if (openReqList[dbName]) {
+        openReqList[dbName] = null;
+      }
+      callback(null);
+    };
+
+    req.onerror = callback;
+  });
+};
+
+module.exports = StorageCore;
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"55":55}],25:[function(_dereq_,module,exports){
+(function (Buffer){
+'use strict';
+
+// ArrayBuffer/Uint8Array are old formats that date back to before we
+// had a proper browserified buffer type. they may be removed later
+var arrayBuffPrefix = 'ArrayBuffer:';
+var arrayBuffRegex = new RegExp('^' + arrayBuffPrefix);
+var uintPrefix = 'Uint8Array:';
+var uintRegex = new RegExp('^' + uintPrefix);
+
+// this is the new encoding format used going forward
+var bufferPrefix = 'Buff:';
+var bufferRegex = new RegExp('^' + bufferPrefix);
+
+var utils = _dereq_(28);
+var DatabaseCore = _dereq_(24);
+var TaskQueue = _dereq_(27);
+var d64 = _dereq_(10);
+
+function Database(dbname) {
+  this._store = new DatabaseCore(dbname);
+  this._queue = new TaskQueue();
+}
+
+Database.prototype.sequentialize = function (callback, fun) {
+  this._queue.add(fun, callback);
+};
+
+Database.prototype.init = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    self._store.getKeys(function (err, keys) {
+      if (err) {
+        return callback(err);
+      }
+      self._keys = keys;
+      return callback();
+    });
+  });
+};
+
+Database.prototype.keys = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    callback(null, self._keys.slice());
+  });
+};
+
+//setItem: Saves and item at the key provided.
+Database.prototype.setItem = function (key, value, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    if (Buffer.isBuffer(value)) {
+      value = bufferPrefix + d64.encode(value);
+    }
+
+    var idx = utils.sortedIndexOf(self._keys, key);
+    if (self._keys[idx] !== key) {
+      self._keys.splice(idx, 0, key);
+    }
+    self._store.put(key, value, callback);
+  });
+};
+
+//getItem: Returns the item identified by it's key.
+Database.prototype.getItem = function (key, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    self._store.get(key, function (err, retval) {
+      if (err) {
+        return callback(err);
+      }
+      if (typeof retval === 'undefined' || retval === null) {
+        // 'NotFound' error, consistent with LevelDOWN API
+        return callback(new Error('NotFound'));
+      }
+      if (typeof retval !== 'undefined') {
+        if (bufferRegex.test(retval)) {
+          retval = d64.decode(retval.substring(bufferPrefix.length));
+        } else if (arrayBuffRegex.test(retval)) {
+          // this type is kept for backwards
+          // compatibility with older databases, but may be removed
+          // after a major version bump
+          retval = retval.substring(arrayBuffPrefix.length);
+          retval = new ArrayBuffer(atob(retval).split('').map(function (c) {
+            return c.charCodeAt(0);
+          }));
+        } else if (uintRegex.test(retval)) {
+          // ditto
+          retval = retval.substring(uintPrefix.length);
+          retval = new Uint8Array(atob(retval).split('').map(function (c) {
+            return c.charCodeAt(0);
+          }));
+        }
+      }
+      callback(null, retval);
+    });
+  });
+};
+
+//removeItem: Removes the item identified by it's key.
+Database.prototype.removeItem = function (key, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    var idx = utils.sortedIndexOf(self._keys, key);
+    if (self._keys[idx] === key) {
+      self._keys.splice(idx, 1);
+      self._store.remove(key, function (err) {
+        if (err) {
+          return callback(err);
+        }
+        callback();
+      });
+    } else {
+      callback();
+    }
+  });
+};
+
+Database.prototype.length = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    callback(null, self._keys.length);
+  });
+};
+
+module.exports = Database;
+
+}).call(this,{"isBuffer":_dereq_(32)})
+},{"10":10,"24":24,"27":27,"28":28,"32":32}],26:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+'use strict';
+
+var inherits = _dereq_(31);
+var AbstractLevelDOWN = _dereq_(4).AbstractLevelDOWN;
+var AbstractIterator = _dereq_(4).AbstractIterator;
+
+var Database = _dereq_(25);
+var DatabaseCore = _dereq_(24);
+var utils = _dereq_(28);
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+function DatabaseIterator(db, options) {
+
+  AbstractIterator.call(this, db);
+
+  this._reverse = !!options.reverse;
+  this._endkey     = options.end;
+  this._startkey   = options.start;
+  this._gt      = options.gt;
+  this._gte     = options.gte;
+  this._lt      = options.lt;
+  this._lte     = options.lte;
+  this._exclusiveStart = options.exclusiveStart;
+  this._limit = options.limit;
+  this._count = 0;
+
+  this.onInitCompleteListeners = [];
+}
+
+inherits(DatabaseIterator, AbstractIterator);
+
+DatabaseIterator.prototype._init = function (callback) {
+  nextTick(function () {
+    callback();
+  });
+};
+
+DatabaseIterator.prototype._next = function (callback) {
+  var self = this;
+
+  function onInitComplete() {
+    if (self._pos === self._keys.length || self._pos < 0) { // done reading
+      return callback();
+    }
+
+    var key = self._keys[self._pos];
+
+    if (!!self._endkey && (self._reverse ? key < self._endkey : key > self._endkey)) {
+      return callback();
+    }
+
+    if (!!self._limit && self._limit > 0 && self._count++ >= self._limit) {
+      return callback();
+    }
+
+    if ((self._lt  && key >= self._lt) ||
+      (self._lte && key > self._lte) ||
+      (self._gt  && key <= self._gt) ||
+      (self._gte && key < self._gte)) {
+      return callback();
+    }
+
+    self._pos += self._reverse ? -1 : 1;
+    self.db.container.getItem(key, function (err, value) {
+      if (err) {
+        if (err.message === 'NotFound') {
+          return nextTick(function () {
+            self._next(callback);
+          });
+        }
+        return callback(err);
+      }
+      callback(null, key, value);
+    });
+  }
+  if (!self.initStarted) {
+    self.initStarted = true;
+    self._init(function (err) {
+      if (err) {
+        return callback(err);
+      }
+      self.db.container.keys(function (err, keys) {
+        if (err) {
+          return callback(err);
+        }
+        self._keys = keys;
+        if (self._startkey) {
+          var index = utils.sortedIndexOf(self._keys, self._startkey);
+          var startkey = (index >= self._keys.length || index < 0) ?
+            undefined : self._keys[index];
+          self._pos = index;
+          if (self._reverse) {
+            if (self._exclusiveStart || startkey !== self._startkey) {
+              self._pos--;
+            }
+          } else if (self._exclusiveStart && startkey === self._startkey) {
+            self._pos++;
+          }
+        } else {
+          self._pos = self._reverse ? self._keys.length - 1 : 0;
+        }
+        onInitComplete();
+
+        self.initCompleted = true;
+        var i = -1;
+        while (++i < self.onInitCompleteListeners) {
+          nextTick(self.onInitCompleteListeners[i]);
+        }
+      });
+    });
+  } else if (!self.initCompleted) {
+    self.onInitCompleteListeners.push(onInitComplete);
+  } else {
+    onInitComplete();
+  }
+};
+
+function FruitDown(location) {
+  if (!(this instanceof FruitDown)) {
+    return new FruitDown(location);
+  }
+  AbstractLevelDOWN.call(this, location);
+  this.container = new Database(location);
+}
+
+inherits(FruitDown, AbstractLevelDOWN);
+
+FruitDown.prototype._open = function (options, callback) {
+  this.container.init(callback);
+};
+
+FruitDown.prototype._put = function (key, value, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  err = checkKeyValue(value, 'value');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  if (typeof value === 'object' && !Buffer.isBuffer(value) && value.buffer === undefined) {
+    var obj = {};
+    obj.storetype = "json";
+    obj.data = value;
+    value = JSON.stringify(obj);
+  }
+
+  this.container.setItem(key, value, callback);
+};
+
+FruitDown.prototype._get = function (key, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  if (!Buffer.isBuffer(key)) {
+    key = String(key);
+  }
+  this.container.getItem(key, function (err, value) {
+
+    if (err) {
+      return callback(err);
+    }
+
+    if (options.asBuffer !== false && !Buffer.isBuffer(value)) {
+      value = new Buffer(value);
+    }
+
+
+    if (options.asBuffer === false) {
+      if (value.indexOf("{\"storetype\":\"json\",\"data\"") > -1) {
+        var res = JSON.parse(value);
+        value = res.data;
+      }
+    }
+    callback(null, value);
+  });
+};
+
+FruitDown.prototype._del = function (key, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+  if (!Buffer.isBuffer(key)) {
+    key = String(key);
+  }
+
+  this.container.removeItem(key, callback);
+};
+
+FruitDown.prototype._batch = function (array, options, callback) {
+  var self = this;
+  nextTick(function () {
+    var err;
+    var key;
+    var value;
+
+    var numDone = 0;
+    var overallErr;
+    function checkDone() {
+      if (++numDone === array.length) {
+        callback(overallErr);
+      }
+    }
+
+    if (Array.isArray(array) && array.length) {
+      for (var i = 0; i < array.length; i++) {
+        var task = array[i];
+        if (task) {
+          key = Buffer.isBuffer(task.key) ? task.key : String(task.key);
+          err = checkKeyValue(key, 'key');
+          if (err) {
+            overallErr = err;
+            checkDone();
+          } else if (task.type === 'del') {
+            self._del(task.key, options, checkDone);
+          } else if (task.type === 'put') {
+            value = Buffer.isBuffer(task.value) ? task.value : String(task.value);
+            err = checkKeyValue(value, 'value');
+            if (err) {
+              overallErr = err;
+              checkDone();
+            } else {
+              self._put(key, value, options, checkDone);
+            }
+          }
+        } else {
+          checkDone();
+        }
+      }
+    } else {
+      callback();
+    }
+  });
+};
+
+FruitDown.prototype._iterator = function (options) {
+  return new DatabaseIterator(this, options);
+};
+
+FruitDown.destroy = function (name, callback) {
+  DatabaseCore.destroy(name, callback);
+};
+
+function checkKeyValue(obj, type) {
+  if (obj === null || obj === undefined) {
+    return new Error(type + ' cannot be `null` or `undefined`');
+  }
+  if (obj === null || obj === undefined) {
+    return new Error(type + ' cannot be `null` or `undefined`');
+  }
+
+  if (type === 'key') {
+
+    if (obj instanceof Boolean) {
+      return new Error(type + ' cannot be `null` or `undefined`');
+    }
+    if (obj === '') {
+      return new Error(type + ' cannot be empty');
+    }
+  }
+  if (obj.toString().indexOf("[object ArrayBuffer]") === 0) {
+    if (obj.byteLength === 0 || obj.byteLength === undefined) {
+      return new Error(type + ' cannot be an empty Buffer');
+    }
+  }
+
+  if (Buffer.isBuffer(obj)) {
+    if (obj.length === 0) {
+      return new Error(type + ' cannot be an empty Buffer');
+    }
+  } else if (String(obj) === '') {
+    return new Error(type + ' cannot be an empty String');
+  }
+}
+
+module.exports = FruitDown;
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(8).Buffer)
+},{"24":24,"25":25,"28":28,"31":31,"4":4,"55":55,"8":8}],27:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+var argsarray = _dereq_(5);
+var Queue = _dereq_(91);
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+function TaskQueue() {
+  this.queue = new Queue();
+  this.running = false;
+}
+
+TaskQueue.prototype.add = function (fun, callback) {
+  this.queue.push({fun: fun, callback: callback});
+  this.processNext();
+};
+
+TaskQueue.prototype.processNext = function () {
+  var self = this;
+  if (self.running || !self.queue.length) {
+    return;
+  }
+  self.running = true;
+
+  var task = self.queue.shift();
+  nextTick(function () {
+    task.fun(argsarray(function (args) {
+      task.callback.apply(null, args);
+      self.running = false;
+      self.processNext();
+    }));
+  });
+};
+
+module.exports = TaskQueue;
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"5":5,"55":55,"91":91}],28:[function(_dereq_,module,exports){
+'use strict';
+// taken from rvagg/memdown commit 2078b40
+exports.sortedIndexOf = function(arr, item) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (arr[mid] < item) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+};
+
+},{}],29:[function(_dereq_,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],30:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
+
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
+
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
+  }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],31:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
+
+},{}],32:[function(_dereq_,module,exports){
+/**
+ * Determine if an object is Buffer
+ *
+ * Author:   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * License:  MIT
+ *
+ * `npm install is-buffer`
+ */
+
+module.exports = function (obj) {
+  return !!(obj != null &&
+    (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
+      (obj.constructor &&
+      typeof obj.constructor.isBuffer === 'function' &&
+      obj.constructor.isBuffer(obj))
+    ))
+}
+
+},{}],33:[function(_dereq_,module,exports){
+var toString = {}.toString;
+
+module.exports = Array.isArray || function (arr) {
+  return toString.call(arr) == '[object Array]';
+};
+
+},{}],34:[function(_dereq_,module,exports){
+(function(factory) {
+  if(typeof exports === 'object') {
+    factory(exports);
+  } else {
+    factory(this);
+  }
+}).call(this, function(root) { 
+
+  var slice   = Array.prototype.slice,
+      each    = Array.prototype.forEach;
+
+  var extend = function(obj) {
+    if(typeof obj !== 'object') throw obj + ' is not an object' ;
+
+    var sources = slice.call(arguments, 1); 
+
+    each.call(sources, function(source) {
+      if(source) {
+        for(var prop in source) {
+          if(typeof source[prop] === 'object' && obj[prop]) {
+            extend.call(obj, obj[prop], source[prop]);
+          } else {
+            obj[prop] = source[prop];
+          }
+        } 
+      }
+    });
+
+    return obj;
+  }
+
+  root.extend = extend;
+});
+
+},{}],35:[function(_dereq_,module,exports){
+var encodings = _dereq_(36);
+
+module.exports = Codec;
+
+function Codec(opts){
+  this.opts = opts || {};
+  this.encodings = encodings;
+}
+
+Codec.prototype._encoding = function(encoding){
+  if (typeof encoding == 'string') encoding = encodings[encoding];
+  if (!encoding) encoding = encodings.id;
+  return encoding;
+};
+
+Codec.prototype._keyEncoding = function(opts, batchOpts){
+  return this._encoding(batchOpts && batchOpts.keyEncoding
+    || opts && opts.keyEncoding
+    || this.opts.keyEncoding);
+};
+
+Codec.prototype._valueEncoding = function(opts, batchOpts){
+  return this._encoding(
+    batchOpts && (batchOpts.valueEncoding || batchOpts.encoding)
+    || opts && (opts.valueEncoding || opts.encoding)
+    || (this.opts.valueEncoding || this.opts.encoding));
+};
+
+Codec.prototype.encodeKey = function(key, opts, batchOpts){
+  return this._keyEncoding(opts, batchOpts).encode(key);
+};
+
+Codec.prototype.encodeValue = function(value, opts, batchOpts){
+  return this._valueEncoding(opts, batchOpts).encode(value);
+};
+
+Codec.prototype.decodeKey = function(key, opts){
+  return this._keyEncoding(opts).decode(key);
+};
+
+Codec.prototype.decodeValue = function(value, opts){
+  return this._valueEncoding(opts).decode(value);
+};
+
+Codec.prototype.encodeBatch = function(ops, opts){
+  var self = this;
+
+  return ops.map(function(_op){
+    var op = {
+      type: _op.type,
+      key: self.encodeKey(_op.key, opts, _op)
+    };
+    if (self.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary';
+    if (_op.prefix) op.prefix = _op.prefix;
+    if ('value' in _op) {
+      op.value = self.encodeValue(_op.value, opts, _op);
+      if (self.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary';
+    }
+    return op;
+  });
+};
+
+var ltgtKeys = ['lt', 'gt', 'lte', 'gte', 'start', 'end'];
+
+Codec.prototype.encodeLtgt = function(ltgt){
+  var self = this;
+  var ret = {};
+  Object.keys(ltgt).forEach(function(key){
+    ret[key] = ltgtKeys.indexOf(key) > -1
+      ? self.encodeKey(ltgt[key], ltgt)
+      : ltgt[key]
+  });
+  return ret;
+};
+
+Codec.prototype.createStreamDecoder = function(opts){
+  var self = this;
+
+  if (opts.keys && opts.values) {
+    return function(key, value){
+      return {
+        key: self.decodeKey(key, opts),
+        value: self.decodeValue(value, opts)
+      };
+    };
+  } else if (opts.keys) {
+    return function(key) {
+      return self.decodeKey(key, opts);
+    }; 
+  } else if (opts.values) {
+    return function(_, value){
+      return self.decodeValue(value, opts);
+    }
+  } else {
+    return function(){};
+  }
+};
+
+Codec.prototype.keyAsBuffer = function(opts){
+  return this._keyEncoding(opts).buffer;
+};
+
+Codec.prototype.valueAsBuffer = function(opts){
+  return this._valueEncoding(opts).buffer;
+};
+
+
+},{"36":36}],36:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.utf8 = exports['utf-8'] = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : String(data);
+  },
+  decode: identity,
+  buffer: false,
+  type: 'utf8'
+};
+
+exports.json = {
+  encode: JSON.stringify,
+  decode: JSON.parse,
+  buffer: false,
+  type: 'json'
+};
+
+exports.binary = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : new Buffer(data);      
+  },
+  decode: identity,
+  buffer: true,
+  type: 'binary'
+};
+
+exports.id = {
+  encode: function(data){
+    return data;
+  },
+  decode: function(data){
+    return data;
+  },
+  buffer: false,
+  type: 'id'
+};
+
+var bufferEncodings = [
+  'hex',
+  'ascii',
+  'base64',
+  'ucs2',
+  'ucs-2',
+  'utf16le',
+  'utf-16le'
+];
+
+bufferEncodings.forEach(function(type){
+  exports[type] = {
+    encode: function(data){
+      return isBinary(data)
+        ? data
+        : new Buffer(data, type);
+    },
+    decode: function(buffer){
+      return buffer.toString(type);
+    },
+    buffer: true,
+    type: type
+  };
+});
+
+function identity(value){
+  return value;
+}
+
+function isBinary(data){
+  return data === undefined
+    || data === null
+    || Buffer.isBuffer(data);
+}
+
+
+}).call(this,_dereq_(8).Buffer)
+},{"8":8}],37:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(21).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+    LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"21":21}],38:[function(_dereq_,module,exports){
+var inherits = _dereq_(31);
+var Readable = _dereq_(45).Readable;
+var extend = _dereq_(46);
+var EncodingError = _dereq_(37).EncodingError;
+
+module.exports = ReadStream;
+inherits(ReadStream, Readable);
+
+function ReadStream(iterator, options){
+  if (!(this instanceof ReadStream)) return new ReadStream(iterator, options);
+  Readable.call(this, extend(options, {
+    objectMode: true
+  }));
+  this._iterator = iterator;
+  this._destroyed = false;
+  this._decoder = null;
+  if (options && options.decoder) this._decoder = options.decoder;
+  this.on('end', this._cleanup.bind(this));
+}
+
+ReadStream.prototype._read = function(){
+  var self = this;
+  if (this._destroyed) return;
+
+  this._iterator.next(function(err, key, value){
+    if (self._destroyed) return;
+    if (err) return self.emit('error', err);
+    if (key === undefined && value === undefined) {
+      self.push(null);
+    } else {
+      if (!self._decoder) return self.push({ key: key, value: value });
+
+      try {
+        var value = self._decoder(key, value);
+      } catch (err) {
+        self.emit('error', new EncodingError(err));
+        self.push(null);
+        return;
+      }
+      self.push(value);
+    }
+  });
+};
+
+ReadStream.prototype.destroy =
+ReadStream.prototype._cleanup = function(){
+  var self = this;
+  if (this._destroyed) return;
+  this._destroyed = true;
+
+  this._iterator.end(function(err){
+    if (err) return self.emit('error', err);
+    self.emit('close');
+  });
+};
+
+
+},{"31":31,"37":37,"45":45,"46":46}],39:[function(_dereq_,module,exports){
+module.exports = Array.isArray || function (arr) {
+  return Object.prototype.toString.call(arr) == '[object Array]';
+};
+
+},{}],40:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) keys.push(key);
+  return keys;
+}
+/*</replacement>*/
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var Readable = _dereq_(42);
+var Writable = _dereq_(44);
+
+util.inherits(Duplex, Readable);
+
+forEach(objectKeys(Writable.prototype), function(method) {
+  if (!Duplex.prototype[method])
+    Duplex.prototype[method] = Writable.prototype[method];
+});
+
+function Duplex(options) {
+  if (!(this instanceof Duplex))
+    return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false)
+    this.readable = false;
+
+  if (options && options.writable === false)
+    this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false)
+    this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended)
+    return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  process.nextTick(this.end.bind(this));
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+}).call(this,_dereq_(55))
+},{"31":31,"42":42,"44":44,"55":55,"9":9}],41:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(43);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough))
+    return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function(chunk, encoding, cb) {
+  cb(null, chunk);
+};
+
+},{"31":31,"43":43,"9":9}],42:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(39);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var StringDecoder;
+
+
+/*<replacement>*/
+var debug = _dereq_(7);
+if (debug && debug.debuglog) {
+  debug = debug.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  var Duplex = _dereq_(40);
+
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  var Duplex = _dereq_(40);
+
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (util.isString(chunk) && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (util.isNullOrUndefined(chunk)) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      if (!addToFront)
+        state.reading = false;
+
+      // if we want the data now, just emit it.
+      if (state.flowing && state.length === 0 && !state.sync) {
+        stream.emit('data', chunk);
+        stream.read(0);
+      } else {
+        // update the buffer info.
+        state.length += state.objectMode ? 1 : chunk.length;
+        if (addToFront)
+          state.buffer.unshift(chunk);
+        else
+          state.buffer.push(chunk);
+
+        if (state.needReadable)
+          emitReadable(stream);
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (isNaN(n) || util.isNull(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (!util.isNumber(n) || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended)
+      endReadable(this);
+    else
+      emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0)
+      endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (util.isNull(ret)) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0)
+    endReadable(this);
+
+  if (!util.isNull(ret))
+    this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync)
+      process.nextTick(function() {
+        emitReadable_(stream);
+      });
+    else
+      emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain &&
+        (!dest._writableState || dest._writableState.needDrain))
+      ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      debug('false write response, pause',
+            src._readableState.awaitDrain);
+      src._readableState.awaitDrain++;
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain)
+      state.awaitDrain--;
+    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        var self = this;
+        process.nextTick(function() {
+          debug('readable nexttick read 0');
+          self.read(0);
+        });
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    if (!state.reading) {
+      debug('resume read 0');
+      this.read(0);
+    }
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    process.nextTick(function() {
+      resume_(stream, state);
+    });
+  }
+}
+
+function resume_(stream, state) {
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading)
+    stream.read(0);
+}
+
+Readable.prototype.pause = function() {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    debug('wrapped data');
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+    if (!chunk || !state.objectMode && !chunk.length)
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"31":31,"39":39,"40":40,"55":55,"58":58,"69":69,"7":7,"8":8,"9":9}],43:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(40);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (!util.isNullOrUndefined(data))
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('prefinish', function() {
+    if (util.isFunction(this._flush))
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"31":31,"40":40,"9":9}],44:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  var Duplex = _dereq_(40);
+
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(40);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (!util.isFunction(cb))
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function() {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function() {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing &&
+        !state.corked &&
+        !state.finished &&
+        !state.bufferProcessing &&
+        state.buffer.length)
+      clearBuffer(this, state);
+  }
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      util.isString(chunk)) {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing || state.corked)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev)
+    stream._writev(chunk, state.onwrite);
+  else
+    stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      state.pendingcb--;
+      cb(er);
+    });
+  else {
+    state.pendingcb--;
+    cb(er);
+  }
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished &&
+        !state.corked &&
+        !state.bufferProcessing &&
+        state.buffer.length) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  if (stream._writev && state.buffer.length > 1) {
+    // Fast case, write everything using _writev()
+    var cbs = [];
+    for (var c = 0; c < state.buffer.length; c++)
+      cbs.push(state.buffer[c].callback);
+
+    // count the one we are adding, as well.
+    // TODO(isaacs) clean this up
+    state.pendingcb++;
+    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
+      for (var i = 0; i < cbs.length; i++) {
+        state.pendingcb--;
+        cbs[i](err);
+      }
+    });
+
+    // Clear buffer
+    state.buffer = [];
+  } else {
+    // Slow case, write chunks one-by-one
+    for (var c = 0; c < state.buffer.length; c++) {
+      var entry = state.buffer[c];
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        c++;
+        break;
+      }
+    }
+
+    if (c < state.buffer.length)
+      state.buffer = state.buffer.slice(c);
+    else
+      state.buffer.length = 0;
+  }
+
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (util.isFunction(chunk)) {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (!util.isNullOrUndefined(chunk))
+    this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else
+      prefinish(stream, state);
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(55))
+},{"31":31,"40":40,"55":55,"58":58,"8":8,"9":9}],45:[function(_dereq_,module,exports){
+(function (process){
+exports = module.exports = _dereq_(42);
+exports.Stream = _dereq_(58);
+exports.Readable = exports;
+exports.Writable = _dereq_(44);
+exports.Duplex = _dereq_(40);
+exports.Transform = _dereq_(43);
+exports.PassThrough = _dereq_(41);
+if (!process.browser && process.env.READABLE_STREAM === 'disable') {
+  module.exports = _dereq_(58);
+}
+
+}).call(this,_dereq_(55))
+},{"40":40,"41":41,"42":42,"43":43,"44":44,"55":55,"58":58}],46:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],47:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var util          = _dereq_(49)
+  , WriteError    = _dereq_(37).WriteError
+
+  , getOptions    = util.getOptions
+  , dispatchError = util.dispatchError
+
+function Batch (levelup, codec) {
+  this._levelup = levelup
+  this._codec = codec
+  this.batch = levelup.db.batch()
+  this.ops = []
+  this.length = 0
+}
+
+Batch.prototype.put = function (key_, value_, options) {
+  options = getOptions(options)
+
+  var key   = this._codec.encodeKey(key_, options)
+    , value = this._codec.encodeValue(value_, options)
+
+  try {
+    this.batch.put(key, value)
+  } catch (e) {
+    throw new WriteError(e)
+  }
+  this.ops.push({ type : 'put', key : key, value : value })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.del = function (key_, options) {
+  options = getOptions(options)
+
+  var key = this._codec.encodeKey(key_, options)
+
+  try {
+    this.batch.del(key)
+  } catch (err) {
+    throw new WriteError(err)
+  }
+  this.ops.push({ type : 'del', key : key })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.clear = function () {
+  try {
+    this.batch.clear()
+  } catch (err) {
+    throw new WriteError(err)
+  }
+
+  this.ops = []
+  this.length = 0
+  return this
+}
+
+Batch.prototype.write = function (callback) {
+  var levelup = this._levelup
+    , ops     = this.ops
+
+  try {
+    this.batch.write(function (err) {
+      if (err)
+        return dispatchError(levelup, new WriteError(err), callback)
+      levelup.emit('batch', ops)
+      if (callback)
+        callback()
+    })
+  } catch (err) {
+    throw new WriteError(err)
+  }
+}
+
+module.exports = Batch
+
+},{"37":37,"49":49}],48:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var EventEmitter        = _dereq_(23).EventEmitter
+  , inherits            = _dereq_(94).inherits
+  , deprecate           = _dereq_(94).deprecate
+  , extend              = _dereq_(50)
+  , prr                 = _dereq_(56)
+  , DeferredLevelDOWN   = _dereq_(12)
+  , IteratorStream      = _dereq_(38)
+
+  , errors              = _dereq_(37)
+  , WriteError          = errors.WriteError
+  , ReadError           = errors.ReadError
+  , NotFoundError       = errors.NotFoundError
+  , OpenError           = errors.OpenError
+  , EncodingError       = errors.EncodingError
+  , InitializationError = errors.InitializationError
+
+  , util                = _dereq_(49)
+  , Batch               = _dereq_(47)
+  , Codec               = _dereq_(35)
+
+  , getOptions          = util.getOptions
+  , defaultOptions      = util.defaultOptions
+  , getLevelDOWN        = util.getLevelDOWN
+  , dispatchError       = util.dispatchError
+  , isDefined           = util.isDefined
+
+function getCallback (options, callback) {
+  return typeof options == 'function' ? options : callback
+}
+
+// Possible LevelUP#_status values:
+//  - 'new'     - newly created, not opened or closed
+//  - 'opening' - waiting for the database to be opened, post open()
+//  - 'open'    - successfully opened the database, available for use
+//  - 'closing' - waiting for the database to be closed, post close()
+//  - 'closed'  - database has been successfully closed, should not be
+//                 used except for another open() operation
+
+function LevelUP (location, options, callback) {
+  if (!(this instanceof LevelUP))
+    return new LevelUP(location, options, callback)
+
+  var error
+
+  EventEmitter.call(this)
+  this.setMaxListeners(Infinity)
+
+  if (typeof location == 'function') {
+    options = typeof options == 'object' ? options : {}
+    options.db = location
+    location = null
+  } else if (typeof location == 'object' && typeof location.db == 'function') {
+    options = location
+    location = null
+  }
+
+
+  if (typeof options == 'function') {
+    callback = options
+    options  = {}
+  }
+
+  if ((!options || typeof options.db != 'function') && typeof location != 'string') {
+    error = new InitializationError(
+        'Must provide a location for the database')
+    if (callback) {
+      return process.nextTick(function () {
+        callback(error)
+      })
+    }
+    throw error
+  }
+
+  options      = getOptions(options)
+  this.options = extend(defaultOptions, options)
+  this._codec = new Codec(this.options)
+  this._status = 'new'
+  // set this.location as enumerable but not configurable or writable
+  prr(this, 'location', location, 'e')
+
+  this.open(callback)
+}
+
+inherits(LevelUP, EventEmitter)
+
+LevelUP.prototype.open = function (callback) {
+  var self = this
+    , dbFactory
+    , db
+
+  if (this.isOpen()) {
+    if (callback)
+      process.nextTick(function () { callback(null, self) })
+    return this
+  }
+
+  if (this._isOpening()) {
+    return callback && this.once(
+        'open'
+      , function () { callback(null, self) }
+    )
+  }
+
+  this.emit('opening')
+
+  this._status = 'opening'
+  this.db      = new DeferredLevelDOWN(this.location)
+  dbFactory    = this.options.db || getLevelDOWN()
+  db           = dbFactory(this.location)
+
+  db.open(this.options, function (err) {
+    if (err) {
+      return dispatchError(self, new OpenError(err), callback)
+    } else {
+      self.db.setDb(db)
+      self.db = db
+      self._status = 'open'
+      if (callback)
+        callback(null, self)
+      self.emit('open')
+      self.emit('ready')
+    }
+  })
+}
+
+LevelUP.prototype.close = function (callback) {
+  var self = this
+
+  if (this.isOpen()) {
+    this._status = 'closing'
+    this.db.close(function () {
+      self._status = 'closed'
+      self.emit('closed')
+      if (callback)
+        callback.apply(null, arguments)
+    })
+    this.emit('closing')
+    this.db = new DeferredLevelDOWN(this.location)
+  } else if (this._status == 'closed' && callback) {
+    return process.nextTick(callback)
+  } else if (this._status == 'closing' && callback) {
+    this.once('closed', callback)
+  } else if (this._isOpening()) {
+    this.once('open', function () {
+      self.close(callback)
+    })
+  }
+}
+
+LevelUP.prototype.isOpen = function () {
+  return this._status == 'open'
+}
+
+LevelUP.prototype._isOpening = function () {
+  return this._status == 'opening'
+}
+
+LevelUP.prototype.isClosed = function () {
+  return (/^clos/).test(this._status)
+}
+
+function maybeError(db, options, callback) {
+  if (!db._isOpening() && !db.isOpen()) {
+    dispatchError(
+        db
+      , new ReadError('Database is not open')
+      , callback
+    )
+    return true
+  }
+}
+
+function writeError (db, message, callback) {
+  dispatchError(
+      db
+     , new WriteError(message)
+     , callback
+  )
+}
+
+function readError (db, message, callback) {
+  dispatchError(
+      db
+     , new ReadError(message)
+     , callback
+  )
+}
+
+
+LevelUP.prototype.get = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  if (key_ === null || key_ === undefined || 'function' !== typeof callback)
+    return readError(this
+      , 'get() requires key and callback arguments', callback)
+
+  options = util.getOptions(options)
+  key = this._codec.encodeKey(key_, options)
+
+  options.asBuffer = this._codec.valueAsBuffer(options)
+
+  this.db.get(key, options, function (err, value) {
+    if (err) {
+      if ((/notfound/i).test(err) || err.notFound) {
+        err = new NotFoundError(
+            'Key not found in database [' + key_ + ']', err)
+      } else {
+        err = new ReadError(err)
+      }
+      return dispatchError(self, err, callback)
+    }
+    if (callback) {
+      try {
+        value = self._codec.decodeValue(value, options)
+      } catch (e) {
+        return callback(new EncodingError(e))
+      }
+      callback(null, value)
+    }
+  })
+}
+
+LevelUP.prototype.put = function (key_, value_, options, callback) {
+  var self = this
+    , key
+    , value
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'put() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+  value   = this._codec.encodeValue(value_, options)
+
+  this.db.put(key, value, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('put', key_, value_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.del = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'del() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+
+  this.db.del(key, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('del', key_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.batch = function (arr_, options, callback) {
+  var self = this
+    , keyEnc
+    , valueEnc
+    , arr
+
+  if (!arguments.length)
+    return new Batch(this, this._codec)
+
+  callback = getCallback(options, callback)
+
+  if (!Array.isArray(arr_))
+    return writeError(this, 'batch() requires an array argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options  = getOptions(options)
+  arr      = self._codec.encodeBatch(arr_, options)
+  arr      = arr.map(function (op) {
+    if (!op.type && op.key !== undefined && op.value !== undefined)
+      op.type = 'put'
+    return op
+  })
+
+  this.db.batch(arr, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('batch', arr_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.approximateSize = deprecate(function (start_, end_, options, callback) {   
+  var self = this    
+    , start    
+    , end    
+   
+  callback = getCallback(options, callback)    
+   
+  options = getOptions(options)    
+   
+  if (start_ === null || start_ === undefined    
+        || end_ === null || end_ === undefined || 'function' !== typeof callback)    
+    return readError(this, 'approximateSize() requires start, end and callback arguments', callback)   
+   
+  start = this._codec.encodeKey(start_, options)   
+  end   = this._codec.encodeKey(end_, options)   
+   
+  this.db.approximateSize(start, end, function (err, size) {   
+    if (err) {   
+      return dispatchError(self, new OpenError(err), callback)   
+    } else if (callback) {   
+      callback(null, size)   
+    }    
+  })   
+}, 'db.approximateSize() is deprecated. Use db.db.approximateSize() instead')
+
+LevelUP.prototype.readStream =
+LevelUP.prototype.createReadStream = function (options) {
+  options = extend( {keys: true, values: true}, this.options, options)
+
+  options.keyEncoding   = options.keyEncoding
+  options.valueEncoding = options.valueEncoding
+
+  options = this._codec.encodeLtgt(options);
+  options.keyAsBuffer   = this._codec.keyAsBuffer(options)
+  options.valueAsBuffer = this._codec.valueAsBuffer(options)
+
+  if ('number' !== typeof options.limit)
+    options.limit = -1
+
+  return new IteratorStream(this.db.iterator(options), extend(options, {
+    decoder: this._codec.createStreamDecoder(options)
+  }))
+}
+
+LevelUP.prototype.keyStream =
+LevelUP.prototype.createKeyStream = function (options) {
+  return this.createReadStream(extend(options, { keys: true, values: false }))
+}
+
+LevelUP.prototype.valueStream =
+LevelUP.prototype.createValueStream = function (options) {
+  return this.createReadStream(extend(options, { keys: false, values: true }))
+}
+
+LevelUP.prototype.toString = function () {
+  return 'LevelUP'
+}
+
+function utilStatic (name) {
+  return function (location, callback) {
+    getLevelDOWN()[name](location, callback || function () {})
+  }
+}
+
+module.exports         = LevelUP
+module.exports.errors  = _dereq_(37)
+module.exports.destroy = deprecate(
+    utilStatic('destroy')
+  , 'levelup.destroy() is deprecated. Use leveldown.destroy() instead'
+)
+module.exports.repair  = deprecate(
+    utilStatic('repair')
+  , 'levelup.repair() is deprecated. Use leveldown.repair() instead'
+)
+
+
+}).call(this,_dereq_(55))
+},{"12":12,"23":23,"35":35,"37":37,"38":38,"47":47,"49":49,"50":50,"55":55,"56":56,"94":94}],49:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var extend         = _dereq_(50)
+  , LevelUPError   = _dereq_(37).LevelUPError
+  , format         = _dereq_(94).format
+  , defaultOptions = {
+        createIfMissing : true
+      , errorIfExists   : false
+      , keyEncoding     : 'utf8'
+      , valueEncoding   : 'utf8'
+      , compression     : true
+    }
+
+  , leveldown
+
+function getOptions (options) {
+  if (typeof options == 'string')
+    options = { valueEncoding: options }
+  if (typeof options != 'object')
+    options = {}
+  return options
+}
+
+function getLevelDOWN () {
+  if (leveldown)
+    return leveldown
+
+  var requiredVersion  = _dereq_(51).devDependencies.leveldown
+    , leveldownVersion
+
+  try {
+    leveldownVersion = _dereq_(7).version
+  } catch (e) {
+    throw requireError(e)
+  }
+
+  if (!_dereq_(7).satisfies(leveldownVersion, requiredVersion)) {
+    throw new LevelUPError(
+        'Installed version of LevelDOWN ('
+      + leveldownVersion
+      + ') does not match required version ('
+      + requiredVersion
+      + ')'
+    )
+  }
+
+  try {
+    return leveldown = _dereq_(7)
+  } catch (e) {
+    throw requireError(e)
+  }
+}
+
+function requireError (e) {
+  var template = 'Failed to require LevelDOWN (%s). Try `npm install leveldown` if it\'s missing'
+  return new LevelUPError(format(template, e.message))
+}
+
+function dispatchError (db, error, callback) {
+  typeof callback == 'function' ? callback(error) : db.emit('error', error)
+}
+
+function isDefined (v) {
+  return typeof v !== 'undefined'
+}
+
+module.exports = {
+    defaultOptions  : defaultOptions
+  , getOptions      : getOptions
+  , getLevelDOWN    : getLevelDOWN
+  , dispatchError   : dispatchError
+  , isDefined       : isDefined
+}
+
+},{"37":37,"50":50,"51":51,"7":7,"94":94}],50:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],51:[function(_dereq_,module,exports){
+module.exports={
+  "_args": [
+    [
+      "levelup@1.3.1",
+      "/Users/nolan/workspace/pouchdb"
+    ]
+  ],
+  "_from": "levelup@1.3.1",
+  "_id": "levelup@1.3.1",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/levelup",
+  "_nodeVersion": "4.2.2",
+  "_npmUser": {
+    "email": "ralphtheninja@riseup.net",
+    "name": "ralphtheninja"
+  },
+  "_npmVersion": "3.5.0",
+  "_phantomChildren": {},
+  "_requested": {
+    "name": "levelup",
+    "raw": "levelup@1.3.1",
+    "rawSpec": "1.3.1",
+    "scope": null,
+    "spec": "1.3.1",
+    "type": "version"
+  },
+  "_requiredBy": [
+    "/",
+    "/pouchdb"
+  ],
+  "_resolved": "http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",
+  "_shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+  "_shrinkwrap": null,
+  "_spec": "levelup@1.3.1",
+  "_where": "/Users/nolan/workspace/pouchdb",
+  "browser": {
+    "leveldown": false,
+    "leveldown/package": false,
+    "semver": false
+  },
+  "bugs": {
+    "url": "https://github.com/level/levelup/issues"
+  },
+  "contributors": [
+    {
+      "email": "r@va.gg",
+      "name": "Rod Vagg",
+      "url": "https://github.com/rvagg"
+    },
+    {
+      "email": "john@chesl.es",
+      "name": "John Chesley",
+      "url": "https://github.com/chesles/"
+    },
+    {
+      "email": "raynos2@gmail.com",
+      "name": "Jake Verbaten",
+      "url": "https://github.com/raynos"
+    },
+    {
+      "email": "dominic.tarr@gmail.com",
+      "name": "Dominic Tarr",
+      "url": "https://github.com/dominictarr"
+    },
+    {
+      "email": "max@maxogden.com",
+      "name": "Max Ogden",
+      "url": "https://github.com/maxogden"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "Lars-Magnus Skog",
+      "url": "https://github.com/ralphtheninja"
+    },
+    {
+      "email": "david.bjorklund@gmail.com",
+      "name": "David Björklund",
+      "url": "https://github.com/kesla"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "Julian Gruber",
+      "url": "https://github.com/juliangruber"
+    },
+    {
+      "email": "paolo@async.ly",
+      "name": "Paolo Fragomeni",
+      "url": "https://github.com/hij1nx"
+    },
+    {
+      "email": "anton.whalley@nearform.com",
+      "name": "Anton Whalley",
+      "url": "https://github.com/No9"
+    },
+    {
+      "email": "matteo.collina@gmail.com",
+      "name": "Matteo Collina",
+      "url": "https://github.com/mcollina"
+    },
+    {
+      "email": "pedro.teixeira@gmail.com",
+      "name": "Pedro Teixeira",
+      "url": "https://github.com/pgte"
+    },
+    {
+      "email": "mail@substack.net",
+      "name": "James Halliday",
+      "url": "https://github.com/substack"
+    },
+    {
+      "email": "jcrugzz@gmail.com",
+      "name": "Jarrett Cruger",
+      "url": "https://github.com/jcrugzz"
+    }
+  ],
+  "dependencies": {
+    "deferred-leveldown": "~1.2.1",
+    "level-codec": "~6.1.0",
+    "level-errors": "~1.0.3",
+    "level-iterator-stream": "~1.3.0",
+    "prr": "~1.0.1",
+    "semver": "~5.1.0",
+    "xtend": "~4.0.0"
+  },
+  "description": "Fast & simple storage - a Node.js-style LevelDB wrapper",
+  "devDependencies": {
+    "async": "~1.5.0",
+    "bustermove": "~1.0.0",
+    "delayed": "~1.0.1",
+    "faucet": "~0.0.1",
+    "leveldown": "^1.1.0",
+    "memdown": "~1.1.0",
+    "msgpack-js": "~0.3.0",
+    "referee": "~1.2.0",
+    "rimraf": "~2.4.3",
+    "slow-stream": "0.0.4",
+    "tap": "~2.3.1",
+    "tape": "~4.2.1"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+    "tarball": "https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"
+  },
+  "gitHead": "40bd66872974140c79a74d9411b992ddffa926a4",
+  "homepage": "https://github.com/level/levelup",
+  "keywords": [
+    "leveldb",
+    "stream",
+    "database",
+    "db",
+    "store",
+    "storage",
+    "json"
+  ],
+  "license": "MIT",
+  "main": "lib/levelup.js",
+  "maintainers": [
+    {
+      "email": "rod@vagg.org",
+      "name": "rvagg"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "ralphtheninja"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "juliangruber"
+    }
+  ],
+  "name": "levelup",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/level/levelup.git"
+  },
+  "scripts": {
+    "test": "tape test/*-test.js | faucet"
+  },
+  "version": "1.3.1"
+}
+
+},{}],52:[function(_dereq_,module,exports){
+'use strict';
+var immediate = _dereq_(30);
+
+/* istanbul ignore next */
+function INTERNAL() {}
+
+var handlers = {};
+
+var REJECTED = ['REJECTED'];
+var FULFILLED = ['FULFILLED'];
+var PENDING = ['PENDING'];
+
+module.exports = exports = Promise;
+
+function Promise(resolver) {
+  if (typeof resolver !== 'function') {
+    throw new TypeError('resolver must be a function');
+  }
+  this.state = PENDING;
+  this.queue = [];
+  this.outcome = void 0;
+  if (resolver !== INTERNAL) {
+    safelyResolveThenable(this, resolver);
+  }
+}
+
+Promise.prototype["catch"] = function (onRejected) {
+  return this.then(null, onRejected);
+};
+Promise.prototype.then = function (onFulfilled, onRejected) {
+  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
+    typeof onRejected !== 'function' && this.state === REJECTED) {
+    return this;
+  }
+  var promise = new this.constructor(INTERNAL);
+  if (this.state !== PENDING) {
+    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
+    unwrap(promise, resolver, this.outcome);
+  } else {
+    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
+  }
+
+  return promise;
+};
+function QueueItem(promise, onFulfilled, onRejected) {
+  this.promise = promise;
+  if (typeof onFulfilled === 'function') {
+    this.onFulfilled = onFulfilled;
+    this.callFulfilled = this.otherCallFulfilled;
+  }
+  if (typeof onRejected === 'function') {
+    this.onRejected = onRejected;
+    this.callRejected = this.otherCallRejected;
+  }
+}
+QueueItem.prototype.callFulfilled = function (value) {
+  handlers.resolve(this.promise, value);
+};
+QueueItem.prototype.otherCallFulfilled = function (value) {
+  unwrap(this.promise, this.onFulfilled, value);
+};
+QueueItem.prototype.callRejected = function (value) {
+  handlers.reject(this.promise, value);
+};
+QueueItem.prototype.otherCallRejected = function (value) {
+  unwrap(this.promise, this.onRejected, value);
+};
+
+function unwrap(promise, func, value) {
+  immediate(function () {
+    var returnValue;
+    try {
+      returnValue = func(value);
+    } catch (e) {
+      return handlers.reject(promise, e);
+    }
+    if (returnValue === promise) {
+      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
+    } else {
+      handlers.resolve(promise, returnValue);
+    }
+  });
+}
+
+handlers.resolve = function (self, value) {
+  var result = tryCatch(getThen, value);
+  if (result.status === 'error') {
+    return handlers.reject(self, result.value);
+  }
+  var thenable = result.value;
+
+  if (thenable) {
+    safelyResolveThenable(self, thenable);
+  } else {
+    self.state = FULFILLED;
+    self.outcome = value;
+    var i = -1;
+    var len = self.queue.length;
+    while (++i < len) {
+      self.queue[i].callFulfilled(value);
+    }
+  }
+  return self;
+};
+handlers.reject = function (self, error) {
+  self.state = REJECTED;
+  self.outcome = error;
+  var i = -1;
+  var len = self.queue.length;
+  while (++i < len) {
+    self.queue[i].callRejected(error);
+  }
+  return self;
+};
+
+function getThen(obj) {
+  // Make sure we only access the accessor once as required by the spec
+  var then = obj && obj.then;
+  if (obj && typeof obj === 'object' && typeof then === 'function') {
+    return function appyThen() {
+      then.apply(obj, arguments);
+    };
+  }
+}
+
+function safelyResolveThenable(self, thenable) {
+  // Either fulfill, reject or reject with error
+  var called = false;
+  function onError(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.reject(self, value);
+  }
+
+  function onSuccess(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.resolve(self, value);
+  }
+
+  function tryToUnwrap() {
+    thenable(onSuccess, onError);
+  }
+
+  var result = tryCatch(tryToUnwrap);
+  if (result.status === 'error') {
+    onError(result.value);
+  }
+}
+
+function tryCatch(func, value) {
+  var out = {};
+  try {
+    out.value = func(value);
+    out.status = 'success';
+  } catch (e) {
+    out.status = 'error';
+    out.value = e;
+  }
+  return out;
+}
+
+exports.resolve = resolve;
+function resolve(value) {
+  if (value instanceof this) {
+    return value;
+  }
+  return handlers.resolve(new this(INTERNAL), value);
+}
+
+exports.reject = reject;
+function reject(reason) {
+  var promise = new this(INTERNAL);
+  return handlers.reject(promise, reason);
+}
+
+exports.all = all;
+function all(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var values = new Array(len);
+  var resolved = 0;
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    allResolver(iterable[i], i);
+  }
+  return promise;
+  function allResolver(value, i) {
+    self.resolve(value).then(resolveFromAll, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+    function resolveFromAll(outValue) {
+      values[i] = outValue;
+      if (++resolved === len && !called) {
+        called = true;
+        handlers.resolve(promise, values);
+      }
+    }
+  }
+}
+
+exports.race = race;
+function race(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    resolver(iterable[i]);
+  }
+  return promise;
+  function resolver(value) {
+    self.resolve(value).then(function (response) {
+      if (!called) {
+        called = true;
+        handlers.resolve(promise, response);
+      }
+    }, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+  }
+}
+
+},{"30":30}],53:[function(_dereq_,module,exports){
+'use strict';
+exports.Map = LazyMap; // TODO: use ES6 map
+exports.Set = LazySet; // TODO: use ES6 set
+// based on https://github.com/montagejs/collections
+function LazyMap() {
+  this.store = {};
+}
+LazyMap.prototype.mangle = function (key) {
+  if (typeof key !== "string") {
+    throw new TypeError("key must be a string but Got " + key);
+  }
+  return '$' + key;
+};
+LazyMap.prototype.unmangle = function (key) {
+  return key.substring(1);
+};
+LazyMap.prototype.get = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    return this.store[mangled];
+  }
+  return void 0;
+};
+LazyMap.prototype.set = function (key, value) {
+  var mangled = this.mangle(key);
+  this.store[mangled] = value;
+  return true;
+};
+LazyMap.prototype.has = function (key) {
+  var mangled = this.mangle(key);
+  return mangled in this.store;
+};
+LazyMap.prototype.delete = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    delete this.store[mangled];
+    return true;
+  }
+  return false;
+};
+LazyMap.prototype.forEach = function (cb) {
+  var keys = Object.keys(this.store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this.store[key];
+    key = this.unmangle(key);
+    cb(value, key);
+  }
+};
+
+function LazySet(array) {
+  this.store = new LazyMap();
+
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
+    }
+  }
+}
+LazySet.prototype.add = function (key) {
+  return this.store.set(key, true);
+};
+LazySet.prototype.has = function (key) {
+  return this.store.has(key);
+};
+LazySet.prototype.delete = function (key) {
+  return this.store.delete(key);
+};
+
+},{}],54:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+if (!process.version ||
+    process.version.indexOf('v0.') === 0 ||
+    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+  module.exports = nextTick;
+} else {
+  module.exports = process.nextTick;
+}
+
+function nextTick(fn) {
+  var args = new Array(arguments.length - 1);
+  var i = 0;
+  while (i < args.length) {
+    args[i++] = arguments[i];
+  }
+  process.nextTick(function afterTick() {
+    fn.apply(null, args);
+  });
+}
+
+}).call(this,_dereq_(55))
+},{"55":55}],55:[function(_dereq_,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = setTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    clearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],56:[function(_dereq_,module,exports){
+arguments[4][22][0].apply(exports,arguments)
+},{"22":22}],57:[function(_dereq_,module,exports){
+(function (factory) {
+    if (typeof exports === 'object') {
+        // Node/CommonJS
+        module.exports = factory();
+    } else if (typeof define === 'function' && define.amd) {
+        // AMD
+        define(factory);
+    } else {
+        // Browser globals (with support for web workers)
+        var glob;
+
+        try {
+            glob = window;
+        } catch (e) {
+            glob = self;
+        }
+
+        glob.SparkMD5 = factory();
+    }
+}(function (undefined) {
+
+    'use strict';
+
+    /*
+     * Fastest md5 implementation around (JKM md5).
+     * Credits: Joseph Myers
+     *
+     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+     * @see http://jsperf.com/md5-shootout/7
+     */
+
+    /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+    var add32 = function (a, b) {
+        return (a + b) & 0xFFFFFFFF;
+    },
+        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+    function cmn(q, a, b, x, s, t) {
+        a = add32(add32(a, q), add32(x, t));
+        return add32((a << s) | (a >>> (32 - s)), b);
+    }
+
+    function ff(a, b, c, d, x, s, t) {
+        return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+    }
+
+    function gg(a, b, c, d, x, s, t) {
+        return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+    }
+
+    function hh(a, b, c, d, x, s, t) {
+        return cmn(b ^ c ^ d, a, b, x, s, t);
+    }
+
+    function ii(a, b, c, d, x, s, t) {
+        return cmn(c ^ (b | (~d)), a, b, x, s, t);
+    }
+
+    function md5cycle(x, k) {
+        var a = x[0],
+            b = x[1],
+            c = x[2],
+            d = x[3];
+
+        a = ff(a, b, c, d, k[0], 7, -680876936);
+        d = ff(d, a, b, c, k[1], 12, -389564586);
+        c = ff(c, d, a, b, k[2], 17, 606105819);
+        b = ff(b, c, d, a, k[3], 22, -1044525330);
+        a = ff(a, b, c, d, k[4], 7, -176418897);
+        d = ff(d, a, b, c, k[5], 12, 1200080426);
+        c = ff(c, d, a, b, k[6], 17, -1473231341);
+        b = ff(b, c, d, a, k[7], 22, -45705983);
+        a = ff(a, b, c, d, k[8], 7, 1770035416);
+        d = ff(d, a, b, c, k[9], 12, -1958414417);
+        c = ff(c, d, a, b, k[10], 17, -42063);
+        b = ff(b, c, d, a, k[11], 22, -1990404162);
+        a = ff(a, b, c, d, k[12], 7, 1804603682);
+        d = ff(d, a, b, c, k[13], 12, -40341101);
+        c = ff(c, d, a, b, k[14], 17, -1502002290);
+        b = ff(b, c, d, a, k[15], 22, 1236535329);
+
+        a = gg(a, b, c, d, k[1], 5, -165796510);
+        d = gg(d, a, b, c, k[6], 9, -1069501632);
+        c = gg(c, d, a, b, k[11], 14, 643717713);
+        b = gg(b, c, d, a, k[0], 20, -373897302);
+        a = gg(a, b, c, d, k[5], 5, -701558691);
+        d = gg(d, a, b, c, k[10], 9, 38016083);
+        c = gg(c, d, a, b, k[15], 14, -660478335);
+        b = gg(b, c, d, a, k[4], 20, -405537848);
+        a = gg(a, b, c, d, k[9], 5, 568446438);
+        d = gg(d, a, b, c, k[14], 9, -1019803690);
+        c = gg(c, d, a, b, k[3], 14, -187363961);
+        b = gg(b, c, d, a, k[8], 20, 1163531501);
+        a = gg(a, b, c, d, k[13], 5, -1444681467);
+        d = gg(d, a, b, c, k[2], 9, -51403784);
+        c = gg(c, d, a, b, k[7], 14, 1735328473);
+        b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+        a = hh(a, b, c, d, k[5], 4, -378558);
+        d = hh(d, a, b, c, k[8], 11, -2022574463);
+        c = hh(c, d, a, b, k[11], 16, 1839030562);
+        b = hh(b, c, d, a, k[14], 23, -35309556);
+        a = hh(a, b, c, d, k[1], 4, -1530992060);
+        d = hh(d, a, b, c, k[4], 11, 1272893353);
+        c = hh(c, d, a, b, k[7], 16, -155497632);
+        b = hh(b, c, d, a, k[10], 23, -1094730640);
+        a = hh(a, b, c, d, k[13], 4, 681279174);
+        d = hh(d, a, b, c, k[0], 11, -358537222);
+        c = hh(c, d, a, b, k[3], 16, -722521979);
+        b = hh(b, c, d, a, k[6], 23, 76029189);
+        a = hh(a, b, c, d, k[9], 4, -640364487);
+        d = hh(d, a, b, c, k[12], 11, -421815835);
+        c = hh(c, d, a, b, k[15], 16, 530742520);
+        b = hh(b, c, d, a, k[2], 23, -995338651);
+
+        a = ii(a, b, c, d, k[0], 6, -198630844);
+        d = ii(d, a, b, c, k[7], 10, 1126891415);
+        c = ii(c, d, a, b, k[14], 15, -1416354905);
+        b = ii(b, c, d, a, k[5], 21, -57434055);
+        a = ii(a, b, c, d, k[12], 6, 1700485571);
+        d = ii(d, a, b, c, k[3], 10, -1894986606);
+        c = ii(c, d, a, b, k[10], 15, -1051523);
+        b = ii(b, c, d, a, k[1], 21, -2054922799);
+        a = ii(a, b, c, d, k[8], 6, 1873313359);
+        d = ii(d, a, b, c, k[15], 10, -30611744);
+        c = ii(c, d, a, b, k[6], 15, -1560198380);
+        b = ii(b, c, d, a, k[13], 21, 1309151649);
+        a = ii(a, b, c, d, k[4], 6, -145523070);
+        d = ii(d, a, b, c, k[11], 10, -1120210379);
+        c = ii(c, d, a, b, k[2], 15, 718787259);
+        b = ii(b, c, d, a, k[9], 21, -343485551);
+
+        x[0] = add32(a, x[0]);
+        x[1] = add32(b, x[1]);
+        x[2] = add32(c, x[2]);
+        x[3] = add32(d, x[3]);
+    }
+
+    function md5blk(s) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+        }
+        return md5blks;
+    }
+
+    function md5blk_array(a) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+        }
+        return md5blks;
+    }
+
+    function md51(s) {
+        var n = s.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk(s.substring(i - 64, i)));
+        }
+        s = s.substring(i - 64);
+        length = s.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+        }
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+        return state;
+    }
+
+    function md51_array(a) {
+        var n = a.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+        }
+
+        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+        // containing the last element of the parent array if the sub array specified starts
+        // beyond the length of the parent array - weird.
+        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+        length = a.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= a[i] << ((i % 4) << 3);
+        }
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+
+        return state;
+    }
+
+    function rhex(n) {
+        var s = '',
+            j;
+        for (j = 0; j < 4; j += 1) {
+            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+        }
+        return s;
+    }
+
+    function hex(x) {
+        var i;
+        for (i = 0; i < x.length; i += 1) {
+            x[i] = rhex(x[i]);
+        }
+        return x.join('');
+    }
+
+    // In some cases the fast add32 function cannot be used..
+    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+        add32 = function (x, y) {
+            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+            return (msw << 16) | (lsw & 0xFFFF);
+        };
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * ArrayBuffer slice polyfill.
+     *
+     * @see https://github.com/ttaubert/node-arraybuffer-slice
+     */
+
+    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+        (function () {
+            function clamp(val, length) {
+                val = (val | 0) || 0;
+
+                if (val < 0) {
+                    return Math.max(val + length, 0);
+                }
+
+                return Math.min(val, length);
+            }
+
+            ArrayBuffer.prototype.slice = function (from, to) {
+                var length = this.byteLength,
+                    begin = clamp(from, length),
+                    end = length,
+                    num,
+                    target,
+                    targetArray,
+                    sourceArray;
+
+                if (to !== undefined) {
+                    end = clamp(to, length);
+                }
+
+                if (begin > end) {
+                    return new ArrayBuffer(0);
+                }
+
+                num = end - begin;
+                target = new ArrayBuffer(num);
+                targetArray = new Uint8Array(target);
+
+                sourceArray = new Uint8Array(this, begin, num);
+                targetArray.set(sourceArray);
+
+                return target;
+            };
+        })();
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * Helpers.
+     */
+
+    function toUtf8(str) {
+        if (/[\u0080-\uFFFF]/.test(str)) {
+            str = unescape(encodeURIComponent(str));
+        }
+
+        return str;
+    }
+
+    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+        var length = str.length,
+           buff = new ArrayBuffer(length),
+           arr = new Uint8Array(buff),
+           i;
+
+        for (i = 0; i < length; i += 1) {
+            arr[i] = str.charCodeAt(i);
+        }
+
+        return returnUInt8Array ? arr : buff;
+    }
+
+    function arrayBuffer2Utf8Str(buff) {
+        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    }
+
+    function concatenateArrayBuffers(first, second, returnUInt8Array) {
+        var result = new Uint8Array(first.byteLength + second.byteLength);
+
+        result.set(new Uint8Array(first));
+        result.set(new Uint8Array(second), first.byteLength);
+
+        return returnUInt8Array ? result : result.buffer;
+    }
+
+    function hexToBinaryString(hex) {
+        var bytes = [],
+            length = hex.length,
+            x;
+
+        for (x = 0; x < length - 1; x += 2) {
+            bytes.push(parseInt(hex.substr(x, 2), 16));
+        }
+
+        return String.fromCharCode.apply(String, bytes);
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation.
+     *
+     * Use this class to perform an incremental md5, otherwise use the
+     * static methods instead.
+     */
+
+    function SparkMD5() {
+        // call reset to init the instance
+        this.reset();
+    }
+
+    /**
+     * Appends a string.
+     * A conversion will be applied if an utf8 string is detected.
+     *
+     * @param {String} str The string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.append = function (str) {
+        // Converts the string to utf8 bytes if necessary
+        // Then append as binary
+        this.appendBinary(toUtf8(str));
+
+        return this;
+    };
+
+    /**
+     * Appends a binary string.
+     *
+     * @param {String} contents The binary string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.appendBinary = function (contents) {
+        this._buff += contents;
+        this._length += contents.length;
+
+        var length = this._buff.length,
+            i;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+        }
+
+        this._buff = this._buff.substring(i - 64);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            i,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.reset = function () {
+        this._buff = '';
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.prototype.getState = function () {
+        return {
+            buff: this._buff,
+            length: this._length,
+            hash: this._hash
+        };
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.setState = function (state) {
+        this._buff = state.buff;
+        this._length = state.length;
+        this._hash = state.hash;
+
+        return this;
+    };
+
+    /**
+     * Releases memory used by the incremental buffer and other additional
+     * resources. If you plan to use the instance again, use reset instead.
+     */
+    SparkMD5.prototype.destroy = function () {
+        delete this._hash;
+        delete this._buff;
+        delete this._length;
+    };
+
+    /**
+     * Finish the final calculation based on the tail.
+     *
+     * @param {Array}  tail   The tail (will be modified)
+     * @param {Number} length The length of the remaining buffer
+     */
+    SparkMD5.prototype._finish = function (tail, length) {
+        var i = length,
+            tmp,
+            lo,
+            hi;
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(this._hash, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Do the final computation based on the tail and length
+        // Beware that the final length may not fit in 32 bits so we take care of that
+        tmp = this._length * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+        md5cycle(this._hash, tail);
+    };
+
+    /**
+     * Performs the md5 hash on a string.
+     * A conversion will be applied if utf8 string is detected.
+     *
+     * @param {String}  str The string
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hash = function (str, raw) {
+        // Converts the string to utf8 bytes if necessary
+        // Then compute it using the binary function
+        return SparkMD5.hashBinary(toUtf8(str), raw);
+    };
+
+    /**
+     * Performs the md5 hash on a binary string.
+     *
+     * @param {String}  content The binary string
+     * @param {Boolean} raw     True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hashBinary = function (content, raw) {
+        var hash = md51(content),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation for array buffers.
+     *
+     * Use this class to perform an incremental md5 ONLY for array buffers.
+     */
+    SparkMD5.ArrayBuffer = function () {
+        // call reset to init the instance
+        this.reset();
+    };
+
+    /**
+     * Appends an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array to be appended
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+            length = buff.length,
+            i;
+
+        this._length += arr.byteLength;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+        }
+
+        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            i,
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.reset = function () {
+        this._buff = new Uint8Array(0);
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.ArrayBuffer.prototype.getState = function () {
+        var state = SparkMD5.prototype.getState.call(this);
+
+        // Convert buffer to a string
+        state.buff = arrayBuffer2Utf8Str(state.buff);
+
+        return state;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+        // Convert string to buffer
+        state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+        return SparkMD5.prototype.setState.call(this, state);
+    };
+
+    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+    /**
+     * Performs the md5 hash on an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array buffer
+     * @param {Boolean}     raw True to get the raw string, false to get the hex one
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+        var hash = md51_array(new Uint8Array(arr)),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    return SparkMD5;
+}));
+
+},{}],58:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Stream;
+
+var EE = _dereq_(23).EventEmitter;
+var inherits = _dereq_(31);
+
+inherits(Stream, EE);
+Stream.Readable = _dereq_(66);
+Stream.Writable = _dereq_(68);
+Stream.Duplex = _dereq_(59);
+Stream.Transform = _dereq_(67);
+Stream.PassThrough = _dereq_(65);
+
+// Backwards-compat with node 0.4.x
+Stream.Stream = Stream;
+
+
+
+// old-style streams.  Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+  EE.call(this);
+}
+
+Stream.prototype.pipe = function(dest, options) {
+  var source = this;
+
+  function ondata(chunk) {
+    if (dest.writable) {
+      if (false === dest.write(chunk) && source.pause) {
+        source.pause();
+      }
+    }
+  }
+
+  source.on('data', ondata);
+
+  function ondrain() {
+    if (source.readable && source.resume) {
+      source.resume();
+    }
+  }
+
+  dest.on('drain', ondrain);
+
+  // If the 'end' option is not supplied, dest.end() will be called when
+  // source gets the 'end' or 'close' events.  Only dest.end() once.
+  if (!dest._isStdio && (!options || options.end !== false)) {
+    source.on('end', onend);
+    source.on('close', onclose);
+  }
+
+  var didOnEnd = false;
+  function onend() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    dest.end();
+  }
+
+
+  function onclose() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    if (typeof dest.destroy === 'function') dest.destroy();
+  }
+
+  // don't leave dangling pipes when there are errors.
+  function onerror(er) {
+    cleanup();
+    if (EE.listenerCount(this, 'error') === 0) {
+      throw er; // Unhandled stream error in pipe.
+    }
+  }
+
+  source.on('error', onerror);
+  dest.on('error', onerror);
+
+  // remove all the event listeners that were added.
+  function cleanup() {
+    source.removeListener('data', ondata);
+    dest.removeListener('drain', ondrain);
+
+    source.removeListener('end', onend);
+    source.removeListener('close', onclose);
+
+    source.removeListener('error', onerror);
+    dest.removeListener('error', onerror);
+
+    source.removeListener('end', cleanup);
+    source.removeListener('close', cleanup);
+
+    dest.removeListener('close', cleanup);
+  }
+
+  source.on('end', cleanup);
+  source.on('close', cleanup);
+
+  dest.on('close', cleanup);
+
+  dest.emit('pipe', source);
+
+  // Allow for unix-like usage: A.pipe(B).pipe(C)
+  return dest;
+};
+
+},{"23":23,"31":31,"59":59,"65":65,"66":66,"67":67,"68":68}],59:[function(_dereq_,module,exports){
+module.exports = _dereq_(60)
+
+},{"60":60}],60:[function(_dereq_,module,exports){
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+'use strict';
+
+/*<replacement>*/
+
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) {
+    keys.push(key);
+  }return keys;
+};
+/*</replacement>*/
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var Readable = _dereq_(62);
+var Writable = _dereq_(64);
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+  var method = keys[v];
+  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+  if (!(this instanceof Duplex)) return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false) this.readable = false;
+
+  if (options && options.writable === false) this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended) return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+  self.end();
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+},{"31":31,"54":54,"62":62,"64":64,"9":9}],61:[function(_dereq_,module,exports){
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+'use strict';
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(63);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+  cb(null, chunk);
+};
+},{"31":31,"63":63,"9":9}],62:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+module.exports = Readable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var isArray = _dereq_(33);
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23);
+
+/*<replacement>*/
+var EElistenerCount = function (emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+/*<replacement>*/
+var debugUtil = _dereq_(7);
+var debug = undefined;
+if (debugUtil && debugUtil.debuglog) {
+  debug = debugUtil.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+var Duplex;
+function ReadableState(options, stream) {
+  Duplex = Duplex || _dereq_(60);
+
+  options = options || {};
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+  this.resumeScheduled = false;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder) StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+var Duplex;
+function Readable(options) {
+  Duplex = Duplex || _dereq_(60);
+
+  if (!(this instanceof Readable)) return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  if (options && typeof options.read === 'function') this._read = options.read;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function (chunk, encoding) {
+  var state = this._readableState;
+
+  if (!state.objectMode && typeof chunk === 'string') {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function (chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+Readable.prototype.isPaused = function () {
+  return this._readableState.flowing === false;
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null) {
+    state.reading = false;
+    onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      var skipAdd;
+      if (state.decoder && !addToFront && !encoding) {
+        chunk = state.decoder.write(chunk);
+        skipAdd = !state.objectMode && chunk.length === 0;
+      }
+
+      if (!addToFront) state.reading = false;
+
+      // Don't add to the buffer if we've decoded to an empty string chunk and
+      // we're not in object mode
+      if (!skipAdd) {
+        // if we want the data now, just emit it.
+        if (state.flowing && state.length === 0 && !state.sync) {
+          stream.emit('data', chunk);
+          stream.read(0);
+        } else {
+          // update the buffer info.
+          state.length += state.objectMode ? 1 : chunk.length;
+          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
+
+          if (state.needReadable) emitReadable(stream);
+        }
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function (enc) {
+  if (!StringDecoder) StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 8MB
+var MAX_HWM = 0x800000;
+function computeNewHighWaterMark(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    n |= n >>> 1;
+    n |= n >>> 2;
+    n |= n >>> 4;
+    n |= n >>> 8;
+    n |= n >>> 16;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended) return 0;
+
+  if (state.objectMode) return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
+  }
+
+  if (n <= 0) return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else {
+      return state.length;
+    }
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function (n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0) endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0) state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0) ret = fromList(n, state);else ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended) state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
+
+  if (ret !== null) this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+function onEofChunk(stream, state) {
+  if (state.ended) return;
+  if (state.decoder) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    processNextTick(maybeReadMore_, stream, state);
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;else len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function (n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function (dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  var cleanedUp = false;
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    cleanedUp = true;
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      // If the user unpiped during `dest.write()`, it is possible
+      // to get stuck in a permanently paused state if that write
+      // also returned false.
+      if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
+        debug('false write response, pause', src._readableState.awaitDrain);
+        src._readableState.awaitDrain++;
+      }
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function () {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain) state.awaitDrain--;
+    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+Readable.prototype.unpipe = function (dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0) return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes) return this;
+
+    if (!dest) dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest) dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var _i = 0; _i < len; _i++) {
+      dests[_i].emit('unpipe', this);
+    }return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1) return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1) state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function (ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && !this._readableState.endEmitted) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        processNextTick(nReadingNextTick, this);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+function nReadingNextTick(self) {
+  debug('readable nexttick read 0');
+  self.read(0);
+}
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function () {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    processNextTick(resume_, stream, state);
+  }
+}
+
+function resume_(stream, state) {
+  if (!state.reading) {
+    debug('resume read 0');
+    stream.read(0);
+  }
+
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading) stream.read(0);
+}
+
+Readable.prototype.pause = function () {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function (stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function () {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length) self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function (chunk) {
+    debug('wrapped data');
+    if (state.decoder) chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (this[i] === undefined && typeof stream[i] === 'function') {
+      this[i] = function (method) {
+        return function () {
+          return stream[method].apply(stream, arguments);
+        };
+      }(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function (ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function (n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0) return null;
+
+  if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode) ret = '';else ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0) throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    processNextTick(endReadableNT, state, stream);
+  }
+}
+
+function endReadableNT(state, stream) {
+  // Check that we didn't get one last unshift.
+  if (!state.endEmitted && state.length === 0) {
+    state.endEmitted = true;
+    stream.readable = false;
+    stream.emit('end');
+  }
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf(xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+}).call(this,_dereq_(55))
+},{"23":23,"31":31,"33":33,"54":54,"55":55,"60":60,"69":69,"7":7,"8":8,"9":9}],63:[function(_dereq_,module,exports){
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+'use strict';
+
+module.exports = Transform;
+
+var Duplex = _dereq_(60);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+function TransformState(stream) {
+  this.afterTransform = function (er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+  this.writeencoding = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined) stream.push(data);
+
+  cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+function Transform(options) {
+  if (!(this instanceof Transform)) return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  if (options) {
+    if (typeof options.transform === 'function') this._transform = options.transform;
+
+    if (typeof options.flush === 'function') this._flush = options.flush;
+  }
+
+  this.once('prefinish', function () {
+    if (typeof this._flush === 'function') this._flush(function (er) {
+      done(stream, er);
+    });else done(stream);
+  });
+}
+
+Transform.prototype.push = function (chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function (chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function (chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function (n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+function done(stream, er) {
+  if (er) return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length) throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming) throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+},{"31":31,"60":60,"9":9}],64:[function(_dereq_,module,exports){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !true ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(92)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(60);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(60);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+},{"23":23,"31":31,"54":54,"60":60,"8":8,"9":9,"92":92}],65:[function(_dereq_,module,exports){
+module.exports = _dereq_(61)
+
+},{"61":61}],66:[function(_dereq_,module,exports){
+var Stream = (function (){
+  try {
+    return _dereq_('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
+  } catch(_){}
+}());
+exports = module.exports = _dereq_(62);
+exports.Stream = Stream || exports;
+exports.Readable = exports;
+exports.Writable = _dereq_(64);
+exports.Duplex = _dereq_(60);
+exports.Transform = _dereq_(63);
+exports.PassThrough = _dereq_(61);
+
+// inline-process-browser and unreachable-branch-transform make sure this is
+// removed in browserify builds
+if (!true) {
+  module.exports = _dereq_(58);
+}
+
+},{"58":58,"60":60,"61":61,"62":62,"63":63,"64":64}],67:[function(_dereq_,module,exports){
+module.exports = _dereq_(63)
+
+},{"63":63}],68:[function(_dereq_,module,exports){
+module.exports = _dereq_(64)
+
+},{"64":64}],69:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Buffer = _dereq_(8).Buffer;
+
+var isBufferEncoding = Buffer.isEncoding
+  || function(encoding) {
+       switch (encoding && encoding.toLowerCase()) {
+         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
+         default: return false;
+       }
+     }
+
+
+function assertEncoding(encoding) {
+  if (encoding && !isBufferEncoding(encoding)) {
+    throw new Error('Unknown encoding: ' + encoding);
+  }
+}
+
+// StringDecoder provides an interface for efficiently splitting a series of
+// buffers into a series of JS strings without breaking apart multi-byte
+// characters. CESU-8 is handled as part of the UTF-8 encoding.
+//
+// @TODO Handling all encodings inside a single object makes it very difficult
+// to reason about this code, so it should be split up in the future.
+// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
+// points as used by CESU-8.
+var StringDecoder = exports.StringDecoder = function(encoding) {
+  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+  assertEncoding(encoding);
+  switch (this.encoding) {
+    case 'utf8':
+      // CESU-8 represents each of Surrogate Pair by 3-bytes
+      this.surrogateSize = 3;
+      break;
+    case 'ucs2':
+    case 'utf16le':
+      // UTF-16 represents each of Surrogate Pair by 2-bytes
+      this.surrogateSize = 2;
+      this.detectIncompleteChar = utf16DetectIncompleteChar;
+      break;
+    case 'base64':
+      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+      this.surrogateSize = 3;
+      this.detectIncompleteChar = base64DetectIncompleteChar;
+      break;
+    default:
+      this.write = passThroughWrite;
+      return;
+  }
+
+  // Enough space to store all bytes of a single character. UTF-8 needs 4
+  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
+  this.charBuffer = new Buffer(6);
+  // Number of bytes received for the current incomplete multi-byte character.
+  this.charReceived = 0;
+  // Number of bytes expected for the current incomplete multi-byte character.
+  this.charLength = 0;
+};
+
+
+// write decodes the given buffer and returns it as JS string that is
+// guaranteed to not contain any partial multi-byte characters. Any partial
+// character found at the end of the buffer is buffered up, and will be
+// returned when calling write again with the remaining bytes.
+//
+// Note: Converting a Buffer containing an orphan surrogate to a String
+// currently works, but converting a String to a Buffer (via `new Buffer`, or
+// Buffer#write) will replace incomplete surrogates with the unicode
+// replacement character. See https://codereview.chromium.org/121173009/ .
+StringDecoder.prototype.write = function(buffer) {
+  var charStr = '';
+  // if our last write ended with an incomplete multibyte character
+  while (this.charLength) {
+    // determine how many remaining bytes this buffer has to offer for this char
+    var available = (buffer.length >= this.charLength - this.charReceived) ?
+        this.charLength - this.charReceived :
+        buffer.length;
+
+    // add the new bytes to the char buffer
+    buffer.copy(this.charBuffer, this.charReceived, 0, available);
+    this.charReceived += available;
+
+    if (this.charReceived < this.charLength) {
+      // still not enough chars in this buffer? wait for more ...
+      return '';
+    }
+
+    // remove bytes belonging to the current character from the buffer
+    buffer = buffer.slice(available, buffer.length);
+
+    // get the character that was split
+    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
+
+    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+    var charCode = charStr.charCodeAt(charStr.length - 1);
+    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      this.charLength += this.surrogateSize;
+      charStr = '';
+      continue;
+    }
+    this.charReceived = this.charLength = 0;
+
+    // if there are no more bytes in this buffer, just emit our char
+    if (buffer.length === 0) {
+      return charStr;
+    }
+    break;
+  }
+
+  // determine and set charLength / charReceived
+  this.detectIncompleteChar(buffer);
+
+  var end = buffer.length;
+  if (this.charLength) {
+    // buffer the incomplete character bytes we got
+    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
+    end -= this.charReceived;
+  }
+
+  charStr += buffer.toString(this.encoding, 0, end);
+
+  var end = charStr.length - 1;
+  var charCode = charStr.charCodeAt(end);
+  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+  if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+    var size = this.surrogateSize;
+    this.charLength += size;
+    this.charReceived += size;
+    this.charBuffer.copy(this.charBuffer, size, 0, size);
+    buffer.copy(this.charBuffer, 0, 0, size);
+    return charStr.substring(0, end);
+  }
+
+  // or just emit the charStr
+  return charStr;
+};
+
+// detectIncompleteChar determines if there is an incomplete UTF-8 character at
+// the end of the given buffer. If so, it sets this.charLength to the byte
+// length that character, and sets this.charReceived to the number of bytes
+// that are available for this character.
+StringDecoder.prototype.detectIncompleteChar = function(buffer) {
+  // determine how many bytes we have to check at the end of this buffer
+  var i = (buffer.length >= 3) ? 3 : buffer.length;
+
+  // Figure out if one of the last i bytes of our buffer announces an
+  // incomplete char.
+  for (; i > 0; i--) {
+    var c = buffer[buffer.length - i];
+
+    // See http://en.wikipedia.org/wiki/UTF-8#Description
+
+    // 110XXXXX
+    if (i == 1 && c >> 5 == 0x06) {
+      this.charLength = 2;
+      break;
+    }
+
+    // 1110XXXX
+    if (i <= 2 && c >> 4 == 0x0E) {
+      this.charLength = 3;
+      break;
+    }
+
+    // 11110XXX
+    if (i <= 3 && c >> 3 == 0x1E) {
+      this.charLength = 4;
+      break;
+    }
+  }
+  this.charReceived = i;
+};
+
+StringDecoder.prototype.end = function(buffer) {
+  var res = '';
+  if (buffer && buffer.length)
+    res = this.write(buffer);
+
+  if (this.charReceived) {
+    var cr = this.charReceived;
+    var buf = this.charBuffer;
+    var enc = this.encoding;
+    res += buf.slice(0, cr).toString(enc);
+  }
+
+  return res;
+};
+
+function passThroughWrite(buffer) {
+  return buffer.toString(this.encoding);
+}
+
+function utf16DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 2;
+  this.charLength = this.charReceived ? 2 : 0;
+}
+
+function base64DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 3;
+  this.charLength = this.charReceived ? 3 : 0;
+}
+
+},{"8":8}],70:[function(_dereq_,module,exports){
+module.exports = {
+  encode: function (decodedKey) {
+    return '\xff' + decodedKey[0] + '\xff' + decodedKey[1]
+  },
+  decode: function (encodedKeyAsBuffer) {
+    var str = encodedKeyAsBuffer.toString()
+    var idx = str.indexOf('\xff', 1)
+    return [str.substring(1, idx), str.substring(idx + 1)]
+  },
+  lowerBound: '\x00',
+  upperBound: '\xff'
+}
+
+
+},{}],71:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(21).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+  LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"21":21}],72:[function(_dereq_,module,exports){
+var nut   = _dereq_(73)
+var shell = _dereq_(75) //the shell surrounds the nut
+var Codec = _dereq_(35)
+var codec = new Codec();
+
+var ReadStream = _dereq_(74)
+
+var precodec = _dereq_(70)
+
+module.exports = function (db) {
+  return shell ( nut ( db, precodec, codec ), [], ReadStream, db.options)
+}
+
+
+},{"35":35,"70":70,"73":73,"74":74,"75":75}],73:[function(_dereq_,module,exports){
+var ltgt = _dereq_(77)
+
+function isFunction (f) {
+  return 'function' === typeof f
+}
+
+function getPrefix (db) {
+  if(db == null) return db
+  if(isFunction(db.prefix)) return db.prefix()
+  return db
+}
+
+function clone (_obj) {
+  var obj = {}
+  for(var k in _obj)
+    obj[k] = _obj[k]
+  return obj
+}
+
+module.exports = function (db, precodec, codec, compare) {
+  var waiting = [], ready = false
+
+  function encodePrefix(prefix, key, opts1, opts2) {
+    return precodec.encode([ prefix, codec.encodeKey(key, opts1, opts2 ) ])
+  }
+
+  function decodePrefix(data) {
+    return precodec.decode(data)
+  }
+
+  function addEncodings(op, prefix) {
+    if(prefix && prefix.options) {
+      op.keyEncoding =
+        op.keyEncoding || prefix.options.keyEncoding
+      op.valueEncoding =
+        op.valueEncoding || prefix.options.valueEncoding
+    }
+    return op
+  }
+
+  function start () {
+    ready = true
+    while(waiting.length)
+      waiting.shift()()
+  }
+
+  if(isFunction(db.isOpen)) {
+    if(db.isOpen())
+      ready = true
+    else
+      db.open(start)
+  } else {
+    db.open(start)
+  }
+
+  return {
+    apply: function (ops, opts, cb) {
+      for(var i = 0; i < ops.length; i++) {
+        var op = ops[i]
+        addEncodings(op, op.prefix)
+        op.prefix = getPrefix(op.prefix)
+      }
+
+      opts = opts || {}
+
+      if('object' !== typeof opts) throw new Error('opts must be object, was:'+ opts) 
+
+      if('function' === typeof opts) cb = opts, opts = {}
+
+      if(ops.length)
+        (db.db || db).batch(
+          ops.map(function (op) {
+            return {
+              key: encodePrefix(op.prefix, op.key, opts, op),
+              value:
+                  op.type !== 'del'
+                ? codec.encodeValue(
+                    op.value,
+                    opts,
+                    op
+                  )
+                : undefined,
+              type:
+                op.type || (op.value === undefined ? 'del' : 'put')
+            }
+          }),
+          opts,
+          function (err) {
+              if(err) return cb(err)
+            cb()
+          }
+        )
+      else
+        cb()
+    },
+    get: function (key, prefix, opts, cb) {
+      opts.asBuffer = codec.valueAsBuffer(opts)
+      return (db.db || db).get(
+        encodePrefix(prefix, key, opts),
+        opts,
+        function (err, value) {
+          if(err) cb(err)
+          else    cb(null, codec.decodeValue(value, opts))
+        }
+      )
+    },
+    createDecoder: function (opts) {
+      return function (key, value) {
+        return {
+          key: codec.decodeKey(precodec.decode(key)[1], opts),
+          value: codec.decodeValue(value, opts)
+        }
+      }
+    },
+    isOpen: function isOpen() {
+      if (db.db && isFunction(db.db.isOpen))
+        return db.db.isOpen()
+
+      return db.isOpen()
+    },
+    isClosed: function isClosed() {
+      if (db.db && isFunction(db.db.isClosed))
+        return db.db.isClosed()
+
+      return db.isClosed()
+    },
+    close: function close (cb) {
+      return db.close(cb)
+    },
+    iterator: function (_opts, cb) {
+      var opts = clone(_opts || {})
+      var prefix = _opts.prefix || []
+
+      function encodeKey(key) {
+        return encodePrefix(prefix, key, opts, {})
+      }
+
+      ltgt.toLtgt(_opts, opts, encodeKey, precodec.lowerBound, precodec.upperBound)
+
+      // if these legacy values are in the options, remove them
+
+      opts.prefix = null
+
+      //************************************************
+      //hard coded defaults, for now...
+      //TODO: pull defaults and encoding out of levelup.
+      opts.keyAsBuffer = opts.valueAsBuffer = false
+      //************************************************
+
+
+      //this is vital, otherwise limit: undefined will
+      //create an empty stream.
+      if ('number' !== typeof opts.limit)
+        opts.limit = -1
+
+      opts.keyAsBuffer = precodec.buffer
+      opts.valueAsBuffer = codec.valueAsBuffer(opts)
+
+      function wrapIterator (iterator) {
+        return {
+          next: function (cb) {
+            return iterator.next(cb)
+          },
+          end: function (cb) {
+            iterator.end(cb)
+          }
+        }
+      }
+
+      if(ready)
+        return wrapIterator((db.db || db).iterator(opts))
+      else
+        waiting.push(function () {
+          cb(null, wrapIterator((db.db || db).iterator(opts)))
+        })
+
+    }
+  }
+
+}
+
+},{"77":77}],74:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+// NOTE: we are fixed to readable-stream@1.0.x for now
+// for pure Streams2 across Node versions
+var Readable      = _dereq_(83).Readable
+  , inherits      = _dereq_(31)
+  , EncodingError = _dereq_(71).EncodingError;
+
+function ReadStream (options, makeData) {
+  if (!(this instanceof ReadStream))
+    return new ReadStream(options, makeData)
+
+  Readable.call(this, { objectMode: true, highWaterMark: options.highWaterMark })
+
+  // purely to keep `db` around until we're done so it's not GCed if the user doesn't keep a ref
+
+  this._waiting = false
+  this._options = options
+  this._makeData = makeData
+}
+
+inherits(ReadStream, Readable)
+
+ReadStream.prototype.setIterator = function (it) {
+  var self = this
+  this._iterator = it
+  if(this._destroyed) return it.end(function () {})
+  if(this._waiting) {
+    this._waiting = false
+    return this._read()
+  }
+  return this
+}
+
+ReadStream.prototype._read = function read () {
+  var self = this
+  if (self._destroyed)
+    return
+  if(!self._iterator)
+    return this._waiting = true
+
+  self._iterator.next(function(err, key, value) {
+    if (err || (key === undefined && value === undefined)) {
+      if (!err && !self._destroyed)
+        self.push(null)
+      return self._cleanup(err)
+    }
+
+
+    try {
+      value = self._makeData(key, value)
+    } catch (e) {
+      return self._cleanup(new EncodingError(e))
+    }
+    if (!self._destroyed)
+      self.push(value)
+  })
+}
+
+ReadStream.prototype._cleanup = function (err) {
+  if (this._destroyed)
+    return
+
+  this._destroyed = true
+
+  var self = this
+  if (err)
+    self.emit('error', err)
+
+  if (self._iterator) {
+    self._iterator.end(function () {
+      self._iterator = null
+      self.emit('close')
+    })
+  } else {
+    self.emit('close')
+  }
+}
+
+ReadStream.prototype.destroy = function () {
+  this._cleanup()
+}
+
+ReadStream.prototype.toString = function () {
+  return 'LevelUP.ReadStream'
+}
+
+
+module.exports = ReadStream
+
+
+},{"31":31,"71":71,"83":83}],75:[function(_dereq_,module,exports){
+(function (process){
+var EventEmitter = _dereq_(23).EventEmitter
+
+var errors = _dereq_(71)
+
+var version = "6.5.4"
+
+var sublevel = module.exports = function (nut, prefix, createStream, options) {
+  var emitter = new EventEmitter()
+  emitter.sublevels = {}
+  emitter.options = options
+
+  emitter.version = version
+
+  emitter.methods = {}
+  prefix = prefix || []
+
+  function errback (err) { if (err) emitter.emit('error', err) }
+
+  function mergeOpts(opts) {
+    var o = {}
+    if(options)
+      for(var k in options)
+        if(options[k] != undefined)o[k] = options[k]
+    if(opts)
+      for(var k in opts)
+        if(opts[k] != undefined) o[k] = opts[k]
+    return o
+  }
+
+  emitter.put = function (key, value, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key, value: value,
+      prefix: prefix.slice(), type: 'put'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('put', key, value); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.prefix = function () {
+    return prefix.slice()
+  }
+
+  emitter.del = function (key, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key,
+      prefix: prefix.slice(), type: 'del'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('del', key); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.batch = function (ops, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    ops = ops.map(function (op) {
+      return {
+        key:           op.key,
+        value:         op.value,
+        prefix:        op.prefix || prefix,
+        keyEncoding:   op.keyEncoding,    // *
+        valueEncoding: op.valueEncoding,  // * (TODO: encodings on sublevel)
+        type:          op.type
+      }
+    })
+
+    nut.apply(ops, mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('batch', ops); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.get = function (key, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    nut.get(key, prefix, mergeOpts(opts), function (err, value) {
+      if(err) cb(new errors.NotFoundError('Key not found in database', err))
+      else cb(null, value)
+    })
+  }
+
+  emitter.clone = function(opts) {
+    return sublevel(nut, prefix, createStream, mergeOpts(opts))
+  }
+
+  emitter.sublevel = function (name, opts) {
+    return emitter.sublevels[name] =
+      emitter.sublevels[name] || sublevel(nut, prefix.concat(name), createStream, mergeOpts(opts))
+  }
+
+  emitter.readStream = emitter.createReadStream = function (opts) {
+    opts = mergeOpts(opts)
+    opts.prefix = prefix
+    var stream
+    var it = nut.iterator(opts, function (err, it) {
+      stream.setIterator(it)
+    })
+
+    stream = createStream(opts, nut.createDecoder(opts))
+    if(it) stream.setIterator(it)
+
+    return stream
+  }
+
+  emitter.valueStream =
+  emitter.createValueStream = function (opts) {
+    opts = opts || {}
+    opts.values = true
+    opts.keys = false
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.keyStream =
+  emitter.createKeyStream = function (opts) {
+    opts = opts || {}
+    opts.values = false
+    opts.keys = true
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.close = function (cb) {
+    //TODO: deregister all hooks
+    cb = cb || function () {}
+    if (!prefix.length) nut.close(cb)
+    else process.nextTick(cb)
+  }
+
+  emitter.isOpen = nut.isOpen
+  emitter.isClosed = nut.isClosed
+
+  return emitter
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"55":55,"71":71}],76:[function(_dereq_,module,exports){
+arguments[4][39][0].apply(exports,arguments)
+},{"39":39}],77:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.compare = function (a, b) {
+
+  if(Buffer.isBuffer(a)) {
+    var l = Math.min(a.length, b.length)
+    for(var i = 0; i < l; i++) {
+      var cmp = a[i] - b[i]
+      if(cmp) return cmp
+    }
+    return a.length - b.length
+  }
+
+  return a < b ? -1 : a > b ? 1 : 0
+}
+
+function has(obj, key) {
+  return Object.hasOwnProperty.call(obj, key)
+}
+
+// to be compatible with the current abstract-leveldown tests
+// nullish or empty strings.
+// I could use !!val but I want to permit numbers and booleans,
+// if possible.
+
+function isDef (val) {
+  return val !== undefined && val !== ''
+}
+
+function has (range, name) {
+  return Object.hasOwnProperty.call(range, name)
+}
+
+function hasKey(range, name) {
+  return Object.hasOwnProperty.call(range, name) && name
+}
+
+var lowerBoundKey = exports.lowerBoundKey = function (range) {
+    return (
+       hasKey(range, 'gt')
+    || hasKey(range, 'gte')
+    || hasKey(range, 'min')
+    || (range.reverse ? hasKey(range, 'end') : hasKey(range, 'start'))
+    || undefined
+    )
+}
+
+var lowerBound = exports.lowerBound = function (range) {
+  var k = lowerBoundKey(range)
+  return k && range[k]
+}
+
+exports.lowerBoundInclusive = function (range) {
+  return has(range, 'gt') ? false : true
+}
+
+exports.upperBoundInclusive =
+  function (range) {
+    return has(range, 'lt') || !range.minEx ? false : true
+  }
+
+var lowerBoundExclusive = exports.lowerBoundExclusive =
+  function (range) {
+    return has(range, 'gt') || range.minEx ? true : false
+  }
+
+var upperBoundExclusive = exports.upperBoundExclusive =
+  function (range) {
+    return has(range, 'lt') ? true : false
+  }
+
+var upperBoundKey = exports.upperBoundKey = function (range) {
+    return (
+       hasKey(range, 'lt')
+    || hasKey(range, 'lte')
+    || hasKey(range, 'max')
+    || (range.reverse ? hasKey(range, 'start') : hasKey(range, 'end'))
+    || undefined
+    )
+}
+
+var upperBound = exports.upperBound = function (range) {
+  var k = upperBoundKey(range)
+  return k && range[k]
+}
+
+function id (e) { return e }
+
+exports.toLtgt = function (range, _range, map, lower, upper) {
+  _range = _range || {}
+  map = map || id
+  var defaults = arguments.length > 3
+  var lb = exports.lowerBoundKey(range)
+  var ub = exports.upperBoundKey(range)
+  if(lb) {
+    if(lb === 'gt') _range.gt = map(range.gt, false)
+    else            _range.gte = map(range[lb], false)
+  }
+  else if(defaults)
+    _range.gte = map(lower, false)
+
+  if(ub) {
+    if(ub === 'lt') _range.lt = map(range.lt, true)
+    else            _range.lte = map(range[ub], true)
+  }
+  else if(defaults)
+    _range.lte = map(upper, true)
+
+  if(range.reverse != null)
+    _range.reverse = !!range.reverse
+
+  //if range was used mutably
+  //(in level-sublevel it's part of an options object
+  //that has more properties on it.)
+  if(has(_range, 'max'))   delete _range.max
+  if(has(_range, 'min'))   delete _range.min
+  if(has(_range, 'start')) delete _range.start
+  if(has(_range, 'end'))   delete _range.end
+
+  return _range
+}
+
+exports.contains = function (range, key, compare) {
+  compare = compare || exports.compare
+
+  var lb = lowerBound(range)
+  if(isDef(lb)) {
+    var cmp = compare(key, lb)
+    if(cmp < 0 || (cmp === 0 && lowerBoundExclusive(range)))
+      return false
+  }
+
+  var ub = upperBound(range)
+  if(isDef(ub)) {
+    var cmp = compare(key, ub)
+    if(cmp > 0 || (cmp === 0) && upperBoundExclusive(range))
+      return false
+  }
+
+  return true
+}
+
+exports.filter = function (range, compare) {
+  return function (key) {
+    return exports.contains(range, key, compare)
+  }
+}
+
+}).call(this,{"isBuffer":_dereq_(32)})
+},{"32":32}],78:[function(_dereq_,module,exports){
+arguments[4][40][0].apply(exports,arguments)
+},{"31":31,"40":40,"55":55,"80":80,"82":82,"9":9}],79:[function(_dereq_,module,exports){
+arguments[4][41][0].apply(exports,arguments)
+},{"31":31,"41":41,"81":81,"9":9}],80:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(76);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = false;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // In streams that never have any data, and do push(null) right away,
+  // the consumer can miss the 'end' event if they do some I/O before
+  // consuming the stream.  So, we don't emit('end') until some reading
+  // happens.
+  this.calledRead = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (typeof chunk === 'string' && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null || chunk === undefined) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      // update the buffer info.
+      state.length += state.objectMode ? 1 : chunk.length;
+      if (addToFront) {
+        state.buffer.unshift(chunk);
+      } else {
+        state.reading = false;
+        state.buffer.push(chunk);
+      }
+
+      if (state.needReadable)
+        emitReadable(stream);
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  var state = this._readableState;
+  state.calledRead = true;
+  var nOrig = n;
+  var ret;
+
+  if (typeof n !== 'number' || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    ret = null;
+
+    // In cases where the decoder did not receive enough data
+    // to produce a full chunk, then immediately received an
+    // EOF, state.buffer will contain [<Buffer >, <Buffer 00 ...>].
+    // howMuchToRead will see this and coerce the amount to
+    // read to zero (because it's looking at the length of the
+    // first <Buffer > in state.buffer), and we'll end up here.
+    //
+    // This can only happen via state.decoder -- no other venue
+    // exists for pushing a zero-length chunk into state.buffer
+    // and triggering this behavior. In this case, we return our
+    // remaining data and end the stream, if appropriate.
+    if (state.length > 0 && state.decoder) {
+      ret = fromList(n, state);
+      state.length -= ret.length;
+    }
+
+    if (state.length === 0)
+      endReadable(this);
+
+    return ret;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length - n <= state.highWaterMark)
+    doRead = true;
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading)
+    doRead = false;
+
+  if (doRead) {
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read called its callback synchronously, then `reading`
+  // will be false, and we need to re-evaluate how much data we
+  // can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we happened to read() exactly the remaining amount in the
+  // buffer, and the EOF has been seen at this point, then make sure
+  // that we emit 'end' on the very next tick.
+  if (state.ended && !state.endEmitted && state.length === 0)
+    endReadable(this);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // if we've ended and we have some data left, then emit
+  // 'readable' now to make sure it gets picked up.
+  if (state.length > 0)
+    emitReadable(stream);
+  else
+    endReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (state.emittedReadable)
+    return;
+
+  state.emittedReadable = true;
+  if (state.sync)
+    process.nextTick(function() {
+      emitReadable_(stream);
+    });
+  else
+    emitReadable_(stream);
+}
+
+function emitReadable_(stream) {
+  stream.emit('readable');
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    if (readable !== src) return;
+    cleanup();
+  }
+
+  function onend() {
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (!dest._writableState || dest._writableState.needDrain)
+      ondrain();
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    // the handler that waits for readable events after all
+    // the data gets sucked out in flow.
+    // This would be easier to follow with a .once() handler
+    // in flow(), but that is too slow.
+    this.on('readable', pipeOnReadable);
+
+    state.flowing = true;
+    process.nextTick(function() {
+      flow(src);
+    });
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var dest = this;
+    var state = src._readableState;
+    state.awaitDrain--;
+    if (state.awaitDrain === 0)
+      flow(src);
+  };
+}
+
+function flow(src) {
+  var state = src._readableState;
+  var chunk;
+  state.awaitDrain = 0;
+
+  function write(dest, i, list) {
+    var written = dest.write(chunk);
+    if (false === written) {
+      state.awaitDrain++;
+    }
+  }
+
+  while (state.pipesCount && null !== (chunk = src.read())) {
+
+    if (state.pipesCount === 1)
+      write(state.pipes, 0, null);
+    else
+      forEach(state.pipes, write);
+
+    src.emit('data', chunk);
+
+    // if anyone needs a drain, then we have to wait for that.
+    if (state.awaitDrain > 0)
+      return;
+  }
+
+  // if every destination was unpiped, either before entering this
+  // function, or in the while loop, then stop flowing.
+  //
+  // NB: This is a pretty rare edge case.
+  if (state.pipesCount === 0) {
+    state.flowing = false;
+
+    // if there were data event listeners added, then switch to old mode.
+    if (EE.listenerCount(src, 'data') > 0)
+      emitDataEvents(src);
+    return;
+  }
+
+  // at this point, no one needed a drain, so we just ran out of data
+  // on the next readable event, start it over again.
+  state.ranOut = true;
+}
+
+function pipeOnReadable() {
+  if (this._readableState.ranOut) {
+    this._readableState.ranOut = false;
+    flow(this);
+  }
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  if (ev === 'data' && !this._readableState.flowing)
+    emitDataEvents(this);
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        this.read(0);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  emitDataEvents(this);
+  this.read(0);
+  this.emit('resume');
+};
+
+Readable.prototype.pause = function() {
+  emitDataEvents(this, true);
+  this.emit('pause');
+};
+
+function emitDataEvents(stream, startPaused) {
+  var state = stream._readableState;
+
+  if (state.flowing) {
+    // https://github.com/isaacs/readable-stream/issues/16
+    throw new Error('Cannot switch to old mode now.');
+  }
+
+  var paused = startPaused || false;
+  var readable = false;
+
+  // convert to an old-style stream.
+  stream.readable = true;
+  stream.pipe = Stream.prototype.pipe;
+  stream.on = stream.addListener = Stream.prototype.on;
+
+  stream.on('readable', function() {
+    readable = true;
+
+    var c;
+    while (!paused && (null !== (c = stream.read())))
+      stream.emit('data', c);
+
+    if (c === null) {
+      readable = false;
+      stream._readableState.needReadable = true;
+    }
+  });
+
+  stream.pause = function() {
+    paused = true;
+    this.emit('pause');
+  };
+
+  stream.resume = function() {
+    paused = false;
+    if (readable)
+      process.nextTick(function() {
+        stream.emit('readable');
+      });
+    else
+      this.read(0);
+    this.emit('resume');
+  };
+
+  // now make it start, just in case it hadn't already.
+  stream.emit('readable');
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    //if (state.objectMode && util.isNullOrUndefined(chunk))
+    if (state.objectMode && (chunk === null || chunk === undefined))
+      return;
+    else if (!state.objectMode && (!chunk || !chunk.length))
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (typeof stream[i] === 'function' &&
+        typeof this[i] === 'undefined') {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted && state.calledRead) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"31":31,"55":55,"58":58,"69":69,"76":76,"8":8,"9":9}],81:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(78);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined)
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  var ts = this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('finish', function() {
+    if ('function' === typeof this._flush)
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var rs = stream._readableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"31":31,"78":78,"9":9}],82:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(78);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function')
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb))
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+
+  return ret;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      cb(er);
+    });
+  else
+    cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished && !state.bufferProcessing && state.buffer.length)
+      clearBuffer(stream, state);
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  cb();
+  if (finished)
+    finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  for (var c = 0; c < state.buffer.length; c++) {
+    var entry = state.buffer[c];
+    var chunk = entry.chunk;
+    var encoding = entry.encoding;
+    var cb = entry.callback;
+    var len = state.objectMode ? 1 : chunk.length;
+
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+    // if we didn't call the onwrite immediately, then
+    // it means that we need to wait until it does.
+    // also, that means that the chunk and cb are currently
+    // being processed, so move the buffer counter past them.
+    if (state.writing) {
+      c++;
+      break;
+    }
+  }
+
+  state.bufferProcessing = false;
+  if (c < state.buffer.length)
+    state.buffer = state.buffer.slice(c);
+  else
+    state.buffer.length = 0;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (typeof chunk !== 'undefined' && chunk !== null)
+    this.write(chunk, encoding);
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    state.finished = true;
+    stream.emit('finish');
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(55))
+},{"31":31,"55":55,"58":58,"78":78,"8":8,"9":9}],83:[function(_dereq_,module,exports){
+var Stream = _dereq_(58); // hack to fix a circular dependency issue when used with browserify
+exports = module.exports = _dereq_(80);
+exports.Stream = Stream;
+exports.Readable = exports;
+exports.Writable = _dereq_(82);
+exports.Duplex = _dereq_(78);
+exports.Transform = _dereq_(81);
+exports.PassThrough = _dereq_(79);
+
+},{"58":58,"78":78,"79":79,"80":80,"81":81,"82":82}],84:[function(_dereq_,module,exports){
+arguments[4][60][0].apply(exports,arguments)
+},{"31":31,"54":54,"60":60,"85":85,"87":87,"9":9}],85:[function(_dereq_,module,exports){
+arguments[4][62][0].apply(exports,arguments)
+},{"23":23,"31":31,"33":33,"54":54,"55":55,"62":62,"69":69,"7":7,"8":8,"84":84,"9":9}],86:[function(_dereq_,module,exports){
+arguments[4][63][0].apply(exports,arguments)
+},{"31":31,"63":63,"84":84,"9":9}],87:[function(_dereq_,module,exports){
+(function (process){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(31);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(92)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(84);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(84);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+}).call(this,_dereq_(55))
+},{"23":23,"31":31,"54":54,"55":55,"8":8,"84":84,"9":9,"92":92}],88:[function(_dereq_,module,exports){
+arguments[4][67][0].apply(exports,arguments)
+},{"67":67,"86":86}],89:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],90:[function(_dereq_,module,exports){
+(function (process){
+var Transform = _dereq_(88)
+  , inherits  = _dereq_(94).inherits
+  , xtend     = _dereq_(89)
+
+function DestroyableTransform(opts) {
+  Transform.call(this, opts)
+  this._destroyed = false
+}
+
+inherits(DestroyableTransform, Transform)
+
+DestroyableTransform.prototype.destroy = function(err) {
+  if (this._destroyed) return
+  this._destroyed = true
+  
+  var self = this
+  process.nextTick(function() {
+    if (err)
+      self.emit('error', err)
+    self.emit('close')
+  })
+}
+
+// a noop _transform function
+function noop (chunk, enc, callback) {
+  callback(null, chunk)
+}
+
+
+// create a new export function, used by both the main export and
+// the .ctor export, contains common logic for dealing with arguments
+function through2 (construct) {
+  return function (options, transform, flush) {
+    if (typeof options == 'function') {
+      flush     = transform
+      transform = options
+      options   = {}
+    }
+
+    if (typeof transform != 'function')
+      transform = noop
+
+    if (typeof flush != 'function')
+      flush = null
+
+    return construct(options, transform, flush)
+  }
+}
+
+
+// main export, just make me a transform stream!
+module.exports = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(options)
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+
+// make me a reusable prototype that I can `new`, or implicitly `new`
+// with a constructor call
+module.exports.ctor = through2(function (options, transform, flush) {
+  function Through2 (override) {
+    if (!(this instanceof Through2))
+      return new Through2(override)
+
+    this.options = xtend(options, override)
+
+    DestroyableTransform.call(this, this.options)
+  }
+
+  inherits(Through2, DestroyableTransform)
+
+  Through2.prototype._transform = transform
+
+  if (flush)
+    Through2.prototype._flush = flush
+
+  return Through2
+})
+
+
+module.exports.obj = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options))
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+}).call(this,_dereq_(55))
+},{"55":55,"88":88,"89":89,"94":94}],91:[function(_dereq_,module,exports){
+'use strict';
+
+// Simple FIFO queue implementation to avoid having to do shift()
+// on an array, which is slow.
+
+function Queue() {
+  this.length = 0;
+}
+
+Queue.prototype.push = function (item) {
+  var node = {item: item};
+  if (this.last) {
+    this.last = this.last.next = node;
+  } else {
+    this.last = this.first = node;
+  }
+  this.length++;
+};
+
+Queue.prototype.shift = function () {
+  var node = this.first;
+  if (node) {
+    this.first = node.next;
+    if (!(--this.length)) {
+      this.last = undefined;
+    }
+    return node.item;
+  }
+};
+
+Queue.prototype.slice = function (start, end) {
+  start = typeof start === 'undefined' ? 0 : start;
+  end = typeof end === 'undefined' ? Infinity : end;
+
+  var output = [];
+
+  var i = 0;
+  for (var node = this.first; node; node = node.next) {
+    if (--end < 0) {
+      break;
+    } else if (++i > start) {
+      output.push(node.item);
+    }
+  }
+  return output;
+}
+
+module.exports = Queue;
+
+},{}],92:[function(_dereq_,module,exports){
+(function (global){
+
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used.
+ * Returns a modified function which warns once by default.
+ *
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ *
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ *
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ *
+ * @param {Function} fn - the function to deprecate
+ * @param {String} msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+  if (config('noDeprecation')) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (config('throwDeprecation')) {
+        throw new Error(msg);
+      } else if (config('traceDeprecation')) {
+        console.trace(msg);
+      } else {
+        console.warn(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ *
+ * @param {String} name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
+  try {
+    if (!global.localStorage) return false;
+  } catch (_) {
+    return false;
+  }
+  var val = global.localStorage[name];
+  if (null == val) return false;
+  return String(val).toLowerCase() === 'true';
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],93:[function(_dereq_,module,exports){
+module.exports = function isBuffer(arg) {
+  return arg && typeof arg === 'object'
+    && typeof arg.copy === 'function'
+    && typeof arg.fill === 'function'
+    && typeof arg.readUInt8 === 'function';
+}
+},{}],94:[function(_dereq_,module,exports){
+(function (process,global){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+  if (!isString(f)) {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j':
+        try {
+          return JSON.stringify(args[i++]);
+        } catch (_) {
+          return '[Circular]';
+        }
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (isNull(x) || !isObject(x)) {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+  // Allow for deprecating things in the process of starting up.
+  if (isUndefined(global.process)) {
+    return function() {
+      return exports.deprecate(fn, msg).apply(this, arguments);
+    };
+  }
+
+  if (process.noDeprecation === true) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (process.throwDeprecation) {
+        throw new Error(msg);
+      } else if (process.traceDeprecation) {
+        console.trace(msg);
+      } else {
+        console.error(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+  if (isUndefined(debugEnviron))
+    debugEnviron = process.env.NODE_DEBUG || '';
+  set = set.toUpperCase();
+  if (!debugs[set]) {
+    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+      var pid = process.pid;
+      debugs[set] = function() {
+        var msg = exports.format.apply(exports, arguments);
+        console.error('%s %d: %s', set, pid, msg);
+      };
+    } else {
+      debugs[set] = function() {};
+    }
+  }
+  return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+  // default options
+  var ctx = {
+    seen: [],
+    stylize: stylizeNoColor
+  };
+  // legacy...
+  if (arguments.length >= 3) ctx.depth = arguments[2];
+  if (arguments.length >= 4) ctx.colors = arguments[3];
+  if (isBoolean(opts)) {
+    // legacy...
+    ctx.showHidden = opts;
+  } else if (opts) {
+    // got an "options" object
+    exports._extend(ctx, opts);
+  }
+  // set default options
+  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+  if (isUndefined(ctx.depth)) ctx.depth = 2;
+  if (isUndefined(ctx.colors)) ctx.colors = false;
+  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+  if (ctx.colors) ctx.stylize = stylizeWithColor;
+  return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+  'bold' : [1, 22],
+  'italic' : [3, 23],
+  'underline' : [4, 24],
+  'inverse' : [7, 27],
+  'white' : [37, 39],
+  'grey' : [90, 39],
+  'black' : [30, 39],
+  'blue' : [34, 39],
+  'cyan' : [36, 39],
+  'green' : [32, 39],
+  'magenta' : [35, 39],
+  'red' : [31, 39],
+  'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+  'special': 'cyan',
+  'number': 'yellow',
+  'boolean': 'yellow',
+  'undefined': 'grey',
+  'null': 'bold',
+  'string': 'green',
+  'date': 'magenta',
+  // "name": intentionally not styling
+  'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+  var style = inspect.styles[styleType];
+
+  if (style) {
+    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+           '\u001b[' + inspect.colors[style][1] + 'm';
+  } else {
+    return str;
+  }
+}
+
+
+function stylizeNoColor(str, styleType) {
+  return str;
+}
+
+
+function arrayToHash(array) {
+  var hash = {};
+
+  array.forEach(function(val, idx) {
+    hash[val] = true;
+  });
+
+  return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+  // Provide a hook for user-specified inspect functions.
+  // Check that value is an object with an inspect function on it
+  if (ctx.customInspect &&
+      value &&
+      isFunction(value.inspect) &&
+      // Filter out the util module, it's inspect function is special
+      value.inspect !== exports.inspect &&
+      // Also filter out any prototype objects using the circular check.
+      !(value.constructor && value.constructor.prototype === value)) {
+    var ret = value.inspect(recurseTimes, ctx);
+    if (!isString(ret)) {
+      ret = formatValue(ctx, ret, recurseTimes);
+    }
+    return ret;
+  }
+
+  // Primitive types cannot have properties
+  var primitive = formatPrimitive(ctx, value);
+  if (primitive) {
+    return primitive;
+  }
+
+  // Look up the keys of the object.
+  var keys = Object.keys(value);
+  var visibleKeys = arrayToHash(keys);
+
+  if (ctx.showHidden) {
+    keys = Object.getOwnPropertyNames(value);
+  }
+
+  // IE doesn't make error fields non-enumerable
+  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+  if (isError(value)
+      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+    return formatError(value);
+  }
+
+  // Some type of object without properties can be shortcutted.
+  if (keys.length === 0) {
+    if (isFunction(value)) {
+      var name = value.name ? ': ' + value.name : '';
+      return ctx.stylize('[Function' + name + ']', 'special');
+    }
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    }
+    if (isDate(value)) {
+      return ctx.stylize(Date.prototype.toString.call(value), 'date');
+    }
+    if (isError(value)) {
+      return formatError(value);
+    }
+  }
+
+  var base = '', array = false, braces = ['{', '}'];
+
+  // Make Array say that they are Array
+  if (isArray(value)) {
+    array = true;
+    braces = ['[', ']'];
+  }
+
+  // Make functions say that they are functions
+  if (isFunction(value)) {
+    var n = value.name ? ': ' + value.name : '';
+    base = ' [Function' + n + ']';
+  }
+
+  // Make RegExps say that they are RegExps
+  if (isRegExp(value)) {
+    base = ' ' + RegExp.prototype.toString.call(value);
+  }
+
+  // Make dates with properties first say the date
+  if (isDate(value)) {
+    base = ' ' + Date.prototype.toUTCString.call(value);
+  }
+
+  // Make error with message first say the error
+  if (isError(value)) {
+    base = ' ' + formatError(value);
+  }
+
+  if (keys.length === 0 && (!array || value.length == 0)) {
+    return braces[0] + base + braces[1];
+  }
+
+  if (recurseTimes < 0) {
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    } else {
+      return ctx.stylize('[Object]', 'special');
+    }
+  }
+
+  ctx.seen.push(value);
+
+  var output;
+  if (array) {
+    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+  } else {
+    output = keys.map(function(key) {
+      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+    });
+  }
+
+  ctx.seen.pop();
+
+  return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+  if (isUndefined(value))
+    return ctx.stylize('undefined', 'undefined');
+  if (isString(value)) {
+    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+                                             .replace(/'/g, "\\'")
+                                             .replace(/\\"/g, '"') + '\'';
+    return ctx.stylize(simple, 'string');
+  }
+  if (isNumber(value))
+    return ctx.stylize('' + value, 'number');
+  if (isBoolean(value))
+    return ctx.stylize('' + value, 'boolean');
+  // For some reason typeof null is "object", so special case here.
+  if (isNull(value))
+    return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+  return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+  var output = [];
+  for (var i = 0, l = value.length; i < l; ++i) {
+    if (hasOwnProperty(value, String(i))) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          String(i), true));
+    } else {
+      output.push('');
+    }
+  }
+  keys.forEach(function(key) {
+    if (!key.match(/^\d+$/)) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          key, true));
+    }
+  });
+  return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+  var name, str, desc;
+  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+  if (desc.get) {
+    if (desc.set) {
+      str = ctx.stylize('[Getter/Setter]', 'special');
+    } else {
+      str = ctx.stylize('[Getter]', 'special');
+    }
+  } else {
+    if (desc.set) {
+      str = ctx.stylize('[Setter]', 'special');
+    }
+  }
+  if (!hasOwnProperty(visibleKeys, key)) {
+    name = '[' + key + ']';
+  }
+  if (!str) {
+    if (ctx.seen.indexOf(desc.value) < 0) {
+      if (isNull(recurseTimes)) {
+        str = formatValue(ctx, desc.value, null);
+      } else {
+        str = formatValue(ctx, desc.value, recurseTimes - 1);
+      }
+      if (str.indexOf('\n') > -1) {
+        if (array) {
+          str = str.split('\n').map(function(line) {
+            return '  ' + line;
+          }).join('\n').substr(2);
+        } else {
+          str = '\n' + str.split('\n').map(function(line) {
+            return '   ' + line;
+          }).join('\n');
+        }
+      }
+    } else {
+      str = ctx.stylize('[Circular]', 'special');
+    }
+  }
+  if (isUndefined(name)) {
+    if (array && key.match(/^\d+$/)) {
+      return str;
+    }
+    name = JSON.stringify('' + key);
+    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+      name = name.substr(1, name.length - 2);
+      name = ctx.stylize(name, 'name');
+    } else {
+      name = name.replace(/'/g, "\\'")
+                 .replace(/\\"/g, '"')
+                 .replace(/(^"|"$)/g, "'");
+      name = ctx.stylize(name, 'string');
+    }
+  }
+
+  return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+  var numLinesEst = 0;
+  var length = output.reduce(function(prev, cur) {
+    numLinesEst++;
+    if (cur.indexOf('\n') >= 0) numLinesEst++;
+    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+  }, 0);
+
+  if (length > 60) {
+    return braces[0] +
+           (base === '' ? '' : base + '\n ') +
+           ' ' +
+           output.join(',\n  ') +
+           ' ' +
+           braces[1];
+  }
+
+  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+  return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return isObject(e) &&
+      (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = _dereq_(93);
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+  return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+              'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+  var d = new Date();
+  var time = [pad(d.getHours()),
+              pad(d.getMinutes()),
+              pad(d.getSeconds())].join(':');
+  return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ *     prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = _dereq_(31);
+
+exports._extend = function(origin, add) {
+  // Don't do anything if add isn't an object
+  if (!add || !isObject(add)) return origin;
+
+  var keys = Object.keys(add);
+  var i = keys.length;
+  while (i--) {
+    origin[keys[i]] = add[keys[i]];
+  }
+  return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"31":31,"55":55,"93":93}],95:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+  var queue = [];
+  queue.push({obj: input});
+
+  var res = '';
+  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+  while ((next = queue.pop())) {
+    obj = next.obj;
+    prefix = next.prefix || '';
+    val = next.val || '';
+    res += prefix;
+    if (val) {
+      res += val;
+    } else if (typeof obj !== 'object') {
+      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+    } else if (obj === null) {
+      res += 'null';
+    } else if (Array.isArray(obj)) {
+      queue.push({val: ']'});
+      for (i = obj.length - 1; i >= 0; i--) {
+        arrayPrefix = i === 0 ? '' : ',';
+        queue.push({obj: obj[i], prefix: arrayPrefix});
+      }
+      queue.push({val: '['});
+    } else { // object
+      keys = [];
+      for (k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          keys.push(k);
+        }
+      }
+      queue.push({val: '}'});
+      for (i = keys.length - 1; i >= 0; i--) {
+        key = keys[i];
+        value = obj[key];
+        objPrefix = (i > 0 ? ',' : '');
+        objPrefix += JSON.stringify(key) + ':';
+        queue.push({obj: value, prefix: objPrefix});
+      }
+      queue.push({val: '{'});
+    }
+  }
+  return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+  var lastMetaElement = metaStack[metaStack.length - 1];
+  if (obj === lastMetaElement.element) {
+    // popping a meta-element, e.g. an object whose value is another object
+    metaStack.pop();
+    lastMetaElement = metaStack[metaStack.length - 1];
+  }
+  var element = lastMetaElement.element;
+  var lastElementIndex = lastMetaElement.index;
+  if (Array.isArray(element)) {
+    element.push(obj);
+  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+    var key = stack.pop();
+    element[key] = obj;
+  } else {
+    stack.push(obj); // obj with key only
+  }
+}
+
+exports.parse = function (str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
+  var collationIndex,parsedNum,numChar;
+  var parsedString,lastCh,numConsecutiveSlashes,ch;
+  var arrayElement, objElement;
+  while (true) {
+    collationIndex = str[i++];
+    if (collationIndex === '}' ||
+        collationIndex === ']' ||
+        typeof collationIndex === 'undefined') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack.pop(), stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case ' ':
+      case '\t':
+      case '\n':
+      case ':':
+      case ',':
+        break;
+      case 'n':
+        i += 3; // 'ull'
+        pop(null, stack, metaStack);
+        break;
+      case 't':
+        i += 3; // 'rue'
+        pop(true, stack, metaStack);
+        break;
+      case 'f':
+        i += 4; // 'alse'
+        pop(false, stack, metaStack);
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '-':
+        parsedNum = '';
+        i--;
+        while (true) {
+          numChar = str[i++];
+          if (/[\d\.\-e\+]/.test(numChar)) {
+            parsedNum += numChar;
+          } else {
+            i--;
+            break;
+          }
+        }
+        pop(parseFloat(parsedNum), stack, metaStack);
+        break;
+      case '"':
+        parsedString = '';
+        lastCh = void 0;
+        numConsecutiveSlashes = 0;
+        while (true) {
+          ch = str[i++];
+          if (ch !== '"' || (lastCh === '\\' &&
+              numConsecutiveSlashes % 2 === 1)) {
+            parsedString += ch;
+            lastCh = ch;
+            if (lastCh === '\\') {
+              numConsecutiveSlashes++;
+            } else {
+              numConsecutiveSlashes = 0;
+            }
+          } else {
+            break;
+          }
+        }
+        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+        break;
+      case '[':
+        arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '{':
+        objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      default:
+        throw new Error(
+          'unexpectedly reached end of input: ' + collationIndex);
+    }
+  }
+};
+
+},{}],96:[function(_dereq_,module,exports){
+module.exports = extend
+
+function extend() {
+    var target = {}
+
+    for (var i = 0; i < arguments.length; i++) {
+        var source = arguments[i]
+
+        for (var key in source) {
+            if (source.hasOwnProperty(key)) {
+                target[key] = source[key]
+            }
+        }
+    }
+
+    return target
+}
+
+},{}]},{},[1]);
diff --git a/dist/pouchdb.fruitdown.min.js b/dist/pouchdb.fruitdown.min.js
new file mode 100644
index 0000000..73e29bd
--- /dev/null
+++ b/dist/pouchdb.fruitdown.min.js
@@ -0,0 +1,14 @@
+// PouchDB fruitdown plugin 5.3.2
+// Based on FruitDOWN: https://github.com/nolanlawson/fruitdown
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+!function e(t,n,r){function i(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return i(n?n:e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<r.length;a++)i(r[a]);return i}({1:[function(e,t,n){(function(t,n,r){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e["default"]:e}function o(e){return e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}function a(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}function s(e){if(e instanceof ArrayBuffer)return a(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}function u(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;r>n;n++)t[n]=u(e[n]);return t}if(e instanceof Date)return e.toISOString();if(o(e))return s(e);t={};for(n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var i=u(e[n]);"undefined"!=typeof i&&(t[n]=i)}return t}function c(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function f(){return me}function l(e,t){for(var n={},r=0,i=t.length;i>r;r++){var o=t[r];o in e&&(n[o]=e[o])}return n}function h(e){c()?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):f()&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}function d(){Se.EventEmitter.call(this),this._listeners={},h(this)}function p(e){return 0|Math.random()*e}function g(e,t){t=t||Ie.length;var n="",r=-1;if(e){for(;++r<e;)n+=Ie[p(t)];return n}for(;++r<36;)switch(r){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=Ie[3&p(16)|8];break;default:n+=Ie[p(16)]}return n}function v(e){Error.call(this,e.reason),this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}function y(e,t,n){function r(t){for(var r in e)"function"!=typeof e[r]&&(this[r]=e[r]);void 0!==n&&(this.name=n),void 0!==t&&(this.reason=t)}return r.prototype=v.prototype,new r(t)}function b(e,t,n){try{return!e(t,n)}catch(r){var i="Filter function threw: "+r.toString();return y(Ye,i)}}function _(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){r.doc||(r.doc={});var i=n&&b(e.filter,r.doc,t);if("object"==typeof i)return i;if(i)return!1;if(e.include_docs){if(!e.attachments)for(var o in r.doc._attachments)r.doc._attachments.hasOwnProperty(o)&&(r.doc._attachments[o].stub=!0)}else delete r.doc;return!0}}function m(e){try{return JSON.parse(e)}catch(t){return Ae.parse(e)}}function w(e){return e.length<5e4?JSON.parse(e):m(e)}function E(e){try{return JSON.stringify(e)}catch(t){return Ae.stringify(e)}}function k(e){for(var t,n,r,i,o=e.rev_tree.slice();i=o.pop();){var a=i.ids,s=a[2],u=i.pos;if(s.length)for(var c=0,f=s.length;f>c;c++)o.push({pos:u+1,ids:s[c]});else{var l=!!a[1].deleted,h=a[0];t&&!(r!==l?r:n!==u?u>n:h>t)||(t=h,n=u,r=l)}}return n+"-"+t}function S(e,t){for(var n,r=e.slice();n=r.pop();)for(var i=n.pos,o=n.ids,a=o[2],s=t(0===a.length,i,o[0],n.ctx,o[1]),u=0,c=a.length;c>u;u++)r.push({pos:i+1,ids:a[u],ctx:s})}function x(e){var t=[];return S(e.rev_tree,function(e,n,r,i,o){"available"!==o.status||e||(t.push(n+"-"+r),o.status="missing")}),t}function B(e,t){return e.pos-t.pos}function R(e){var t=[];S(e,function(e,n,r,i,o){e&&t.push({rev:n+"-"+r,pos:n,opts:o})}),t.sort(B).reverse();for(var n=0,r=t.length;r>n;n++)delete t[n].pos;return t}function A(e){for(var t=k(e),n=R(e.rev_tree),r=[],i=0,o=n.length;o>i;i++){var a=n[i];a.rev===t||a.opts.deleted||r.push(a.rev)}return r}function L(e){return e.ids}function M(e,t){t||(t=k(e));for(var n,r=t.substring(t.indexOf("-")+1),i=e.rev_tree.map(L);n=i.pop();){if(n[0]===r)return!!n[1].deleted;i=i.concat(n[2])}}function j(e){return/^_local/.test(e)}function O(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function T(e){var t;if(e?"string"!=typeof e?t=y(Ue):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=y(We)):t=y(Pe),t)throw t}function C(e){if(!/^\d+\-./.test(e))return y(Ve);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function I(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,i=[r[0],t,[]],o=1,a=r.length;a>o;o++)i=[r[o],{status:"missing"},[i]];return[{pos:n,ids:i}]}function D(e,t){var n,r,i,o={status:"available"};if(e._deleted&&(o.deleted=!0),t)if(e._id||(e._id=g()),r=g(32,16).toLowerCase(),e._rev){if(i=C(e._rev),i.error)return i;e._rev_tree=[{pos:i.prefix,ids:[i.id,{status:"missing"},[[r,o,[]]]]}],n=i.prefix+1}else e._rev_tree=[{pos:1,ids:[r,o,[]]}],n=1;else if(e._revisions&&(e._rev_tree=I(e._revisions,o),n=e._revisions.start,r=e._revisions.ids[0]),!e._rev_tree){if(i=C(e._rev),i.error)return i;n=i.prefix,r=i.id,e._rev_tree=[{pos:n,ids:[r,o,[]]}]}T(e._id),e._rev=n+"-"+r;var a={metadata:{},data:{}};for(var s in e)if(Object.prototype.hasOwnProperty.call(e,s)){var u="_"===s[0];if(u&&!He[s]){var c=y(Ke,s);throw c.message=Ke.message+": "+s,c}u&&!Ge[s]?a.metadata[s.slice(1)]=e[s]:a.data[s]=e[s]}return a}function N(e){for(var t,n=[],r=e.slice();t=r.pop();){var i=t.pos,o=t.ids,a=o[0],s=o[1],u=o[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:a,opts:s}),c&&n.push({pos:i+1-f.length,ids:f});for(var l=0,h=u.length;h>l;l++)r.push({pos:i+1,ids:u[l],history:f})}return n.reverse()}function q(e,t){return e.pos-t.pos}function U(e,t,n){for(var r,i=0,o=e.length;o>i;)r=i+o>>>1,n(e[r],t)<0?i=r+1:o=r;return i}function P(e,t,n){var r=U(e,t,n);e.splice(r,0,t)}function W(e,t){for(var n,r,i=t,o=e.length;o>i;i++){var a=e[i],s=[a.id,a.opts,[]];r?(r[2].push(s),r=s):n=r=s}return n}function F(e,t){return e[0]<t[0]?-1:1}function z(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var i=n.pop(),o=i.tree1,a=i.tree2;(o[1].status||a[1].status)&&(o[1].status="available"===o[1].status||"available"===a[1].status?"available":"missing");for(var s=0;s<a[2].length;s++)if(o[2][0]){for(var u=!1,c=0;c<o[2].length;c++)o[2][c][0]===a[2][s][0]&&(n.push({tree1:o[2][c],tree2:a[2][s]}),u=!0);u||(r="new_branch",P(o[2],a[2][s],F))}else r="new_leaf",o[2][0]=a[2][s]}return{conflicts:r,tree:e}}function K(e,t,n){var r,i=[],o=!1,a=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var s=0,u=e.length;u>s;s++){var c=e[s];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=z(c.ids,t.ids),i.push({pos:c.pos,ids:r.tree}),o=o||r.conflicts,a=!0;else if(n!==!0){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,h=l.pos-f.pos,d=[],p=[];for(p.push({ids:f.ids,diff:h,parent:null,parentIdx:null});p.length>0;){var g=p.pop();if(0!==g.diff)for(var v=g.ids[2],y=0,b=v.length;b>y;y++)p.push({ids:v[y],diff:g.diff-1,parent:g.ids,parentIdx:y});else g.ids[0]===l.ids[0]&&d.push(g)}var _=d[0];_?(r=z(_.ids,l.ids),_.parent[2][_.parentIdx]=r.tree,i.push({pos:f.pos,ids:f.ids}),o=o||r.conflicts,a=!0):i.push(c)}else i.push(c)}return a||i.push(t),i.sort(q),{tree:i,conflicts:o||"internal_node"}}function Y(e,t){for(var n,r=N(e),i={},o=0,a=r.length;a>o;o++){for(var s=r[o],u=s.ids,c=Math.max(0,u.length-t),f={pos:s.pos+c,ids:W(u,c)},l=0;c>l;l++){var h=s.pos+l+"-"+u[l].id;i[h]=!0}n=n?K(n,f,!0).tree:[f]}return S(n,function(e,t,n){delete i[t+"-"+n]}),{tree:n,revs:Object.keys(i)}}function V(e,t,n){var r=K(e,t),i=Y(r.tree,n);return{tree:i.tree,stemmedRevs:i.revs,conflicts:r.conflicts}}function J(e,t){for(var n,r=e.slice(),i=t.split("-"),o=parseInt(i[0],10),a=i[1];n=r.pop();){if(n.pos===o&&n.ids[0]===a)return!0;for(var s=n.ids[2],u=0,c=s.length;c>u;u++)r.push({pos:n.pos+1,ids:s[u]})}return!1}function H(e,t,n,r,i,o,a,s){if(J(t.rev_tree,n.metadata.rev))return r[i]=n,o();var u=t.winningRev||k(t),c="deleted"in t?t.deleted:M(t,u),f="deleted"in n.metadata?n.metadata.deleted:M(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&s&&l){var h=n.data;h._rev=u,h._id=n.metadata.id,n=D(h,s)}var d=V(t.rev_tree,n.metadata.rev_tree[0],e),p=s&&(c&&f||!c&&"new_leaf"!==d.conflicts||c&&!f&&"new_branch"===d.conflicts);if(p){var g=y(qe);return r[i]=g,o()}var v=n.metadata.rev;n.metadata.rev_tree=d.tree,n.stemmedRevs=d.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var b,_=k(n.metadata),m=M(n.metadata,_),w=c===m?0:m>c?-1:1;b=v===_?m:M(n.metadata,v),a(n,_,m,b,!0,w,i,o)}function G(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}function $(e,t,n,r,i,o,a,s,u){function c(e,t,n){var r=k(e.metadata),i=M(e.metadata,r);if("was_delete"in s&&i)return o[t]=y(Ne,"deleted"),n();var u=l&&G(e);if(u){var c=y(qe);return o[t]=c,n()}var f=i?0:1;a(e,r,i,i,!1,f,t,n)}function f(){++d===p&&u&&u()}e=e||1e3;var l=s.new_edits,h=new Be.Map,d=0,p=t.length;t.forEach(function(e,t){if(e._id&&j(e._id)){var r=e._deleted?"_removeLocal":"_putLocal";return void n[r](e,{ctx:i},function(e,n){o[t]=e||n,f()})}var a=e.metadata.id;h.has(a)?(p--,h.get(a).push([e,t])):h.set(a,[[e,t]])}),h.forEach(function(t,n){function i(){++u<t.length?s():f()}function s(){var s=t[u],f=s[0],h=s[1];if(r.has(n))H(e,r.get(n),f,o,h,i,a,l);else{var d=V([],f.metadata.rev_tree[0],e);f.metadata.rev_tree=d.tree,f.stemmedRevs=d.stemmedRevs||[],c(f,h,i)}}var u=0;s()})}function X(e){var t=!1;return Re(function(n){if(t)throw new Error("once called more than once");t=!0,e.apply(this,n)})}function Z(e){return Re(function(n){n=u(n);var r,i=this,o="function"==typeof n[n.length-1]?n.pop():!1;o&&(r=function(e,n){t.nextTick(function(){o(e,n)})});var a=new $e(function(t,r){var o;try{var a=X(function(e,n){e?r(e):t(n)});n.push(a),o=e.apply(i,n),o&&"function"==typeof o.then&&t(o)}catch(s){r(s)}});return r&&a.then(function(e){r(null,e)},r),a})}function Q(e){return Ze(e)}function ee(e,t,n,r){(n>0||r<t.byteLength)&&(t=new Uint8Array(t,n,Math.min(r,t.byteLength)-n)),e.append(t)}function te(e,t,n,r){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t)}function ne(){}function re(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(n){if("TypeError"!==n.name)throw n;for(var r="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,i=new r,o=0;o<e.length;o+=1)i.append(e[o]);return i.getBlob(t.type)}}function ie(e,t){return re([e.toArrayBuffer()],{type:t})}function oe(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,i=0;r>i;i++)t+=String.fromCharCode(n[i]);return t}function ae(e,t){if("undefined"==typeof FileReader)return t(oe((new FileReaderSync).readAsArrayBuffer(e)));var n=new FileReader,r="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";return r?t(n):void t(oe(n))},r?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}function se(e,t){ae(e,t)}function ue(e){return re([""],{type:e})}function ce(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),i=0;t>i;i++)r[i]=e.charCodeAt(i);return n}function fe(e,t){return re([ce(e)],{type:t})}function le(e,t){var n=t.prefix()[0],r=e._cache,i=r.get(n);return i||(i=new Be.Map,r.set(n,i)),i}function he(){this._batch=[],this._cache=new Be.Map}function de(e){return"winningRev"in e?e.winningRev:k(e)}function pe(e,t){return"deleted"in e?e.deleted:M(e,t)}function ge(e,t,n){var r=e.content_type;return new $e(function(i,o){t.binaryStore.get(e.digest,function(t,a){var s;if(t){if("NotFoundError"!==t.name)return o(t);s=n.binary?fe("",r):""}else s=n.binary?ie(a,r):a.toString("base64");delete e.stub,delete e.length,e.data=s,i()})})}function ve(e,t,n){var r=[];return e.forEach(function(e){if(e.doc&&e.doc._attachments){var t=Object.keys(e.doc._attachments);t.forEach(function(t){var n=e.doc._attachments[t];"data"in n||r.push(n)})}}),$e.all(r.map(function(e){return ge(e,t,n)}))}function ye(e,n){function i(){E.docStore=m.sublevel(st,{valueEncoding:bt}),E.bySeqStore=m.sublevel(ut,{valueEncoding:"json"}),E.attachmentStore=m.sublevel(ct,{valueEncoding:"json"}),E.binaryStore=m.sublevel(ft,{valueEncoding:"binary"}),E.localStore=m.sublevel(lt,{valueEncoding:"json"}),E.metaStore=m.sublevel(ht,{valueEncoding:"json"}),it.localAndMetaStores(m,E,function(){E.metaStore.get(pt,function(e,r){"undefined"==typeof m._updateSeq&&(m._updateSeq=r||0),E.metaStore.get(gt,function(e,r){m._docCount=e?0:r,E.metaStore.get(vt,function(e,r){b=e?g():r,E.metaStore.put(vt,b,function(){t.nextTick(function(){n(null,w)})})})})})})}function o(e){return m.isClosed()?e(new Error("database is closed")):e(null,m._docCount)}function a(e,t){try{e.apply(null,t)}catch(n){t[t.length-1](n)}}function s(){var e=m._queue.peekFront();"read"===e.type?c(e):f(e)}function c(e){for(var n=[e],r=1,i=m._queue.get(r);"undefined"!=typeof i&&"read"===i.type;)n.push(i),r++,i=m._queue.get(r);var o=0;n.forEach(function(e){var r=e.args,i=r[r.length-1];r[r.length-1]=Re(function(e){i.apply(null,e),++o===n.length&&t.nextTick(function(){n.forEach(function(){m._queue.shift()}),m._queue.length&&s()})}),a(e.fun,r)})}function f(e){var n=e.args,r=n[n.length-1];n[n.length-1]=Re(function(e){r.apply(null,e),t.nextTick(function(){m._queue.shift(),m._queue.length&&s()})}),a(e.fun,n)}function l(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"write"}),1===m._queue.length&&t.nextTick(s)})}function h(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"read"}),1===m._queue.length&&t.nextTick(s)})}function d(e){return("0000000000000000"+e).slice(-16)}function p(e){return parseInt(e,10)}function v(e,n){"function"==typeof R.destroy?R.destroy(e,n):t.nextTick(n)}e=u(e);var b,m,w=this,E={},k=e.revs_limit,B=e.name;"undefined"==typeof e.createIfMissing&&(e.createIfMissing=!0);var R=e.db||mt();if(R instanceof Error)return n(R);"function"!=typeof R.destroy&&(R.destroy=function(e,t){t()});var L,M=at(R);dt.has(M)?L=dt.get(M):(L=new Be.Map,dt.set(M,L)),L.has(B)?(m=L.get(B),i()):L.set(B,Ee(we(B,e,function(t){return t?(L["delete"](B),n(t)):(m=L.get(B),m._docCount=-1,m._queue=new je,void(e.db||e.noMigrate?i():it.toSublevel(B,m,i)))}))),w.type=function(){return"leveldb"},w._id=function(e){e(null,b)},w._info=function(e){var n={doc_count:m._docCount,update_seq:m._updateSeq,backend_adapter:at(R)};return t.nextTick(function(){e(null,n)})},w._get=h(function(e,t,n){t=u(t),E.docStore.get(e,function(e,r){if(e||!r)return n(y(Ne,"missing"));var i=de(r),o=pe(r,i);if(o&&!t.rev)return n(y(Ne,"deleted"));i=t.rev?t.rev:i;var a=r.rev_map[i];E.bySeqStore.get(d(a),function(e,t){if(!t)return n(y(Ne));if("_id"in t&&t._id!==r.id)return n(new Error("wrong doc returned"));if(t._id=r.id,"_rev"in t){if(t._rev!==i)return n(new Error("wrong doc returned"))}else t._rev=i;return n(null,{doc:t,metadata:r})})})}),w._getAttachment=function(e,t,n){var r=e.digest,i=e.content_type;E.binaryStore.get(r,function(e,r){return e?"NotFoundError"!==e.name?n(e):n(null,t.binary?ue(i):""):void(t.binary?n(null,ie(r,i)):n(null,r.toString("base64")))})},w._bulkDocs=l(function(e,n,i){function o(e,t){R.get(E.attachmentStore,e,function(n){if(n){var r=y(Je,"unknown stub attachment with digest "+e);t(r)}else t()})}function a(e){var t=[];if(M.forEach(function(e){e&&e._attachments&&Object.keys(e._attachments).forEach(function(n){var r=e._attachments[n];r.stub&&t.push(r.digest)})}),!t.length)return e();var n,r=0;t.forEach(function(i){o(i,function(i){i&&!n&&(n=i),++r===t.length&&e(n)})})}function s(e){function t(){return++r===M.length?e(n):void 0}var n,r=0;M.forEach(function(e){return e._id&&j(e._id)?t():void R.get(E.docStore,e._id,function(r,i){r?"NotFoundError"!==r.name&&(n=r):_.set(e._id,i),t()})})}function u(e,t){var n=$e.resolve();e.forEach(function(e,t){n=n.then(function(){return new $e(function(n,r){w._doCompactionNoLock(t,e,{ctx:R},function(e){return e?r(e):void n()})})})}),n.then(function(){t()},t)}function c(e){var t=new Be.Map;_.forEach(function(e,n){t.set(n,x(e))}),u(t,e)}function f(){return w.auto_compaction?c(g):void u(S,g)}function l(e,t,n,r,o,a,s,u){function c(e){m++,v||(e?(v=e,u(v)):m===w.length&&g())}function f(e,t,n,r){return function(i){p(e,yt+i,t,n,r)}}function l(e,t,n){return function(r){tt(r).then(f(e,t,r,n))}}function g(){var n=e.metadata.rev_map[e.metadata.rev];if(n)return u(null,e.revsStemmed);n=++L,e.metadata.rev_map[e.metadata.rev]=e.metadata.seq=n;var r=d(n),i=[{key:r,value:e.data,prefix:E.bySeqStore,type:"put"},{key:e.metadata.id,value:e.metadata,prefix:E.docStore,type:"put"}];R.batch(i),b[s]={ok:!0,id:e.metadata.id,rev:t},_.set(e.metadata.id,e.metadata),u(null,e.revsStemmed)}A+=a;var v=null,m=0;e.metadata.winningRev=t,e.metadata.deleted=n,e.data._id=e.metadata.id,e.data._rev=e.metadata.rev,r&&(e.data._deleted=!0),e.stemmedRevs.length&&S.set(e.metadata.id,e.stemmedRevs);for(var w=e.data._attachments?Object.keys(e.data._attachments):[],k=0;k<w.length;k++){var x=w[k],B=e.data._attachments[x];if(B.stub){var M=e.data._id,j=e.data._rev;h(M,j,B.digest,c)}else{var O;if("string"==typeof B.data){try{O=Xe(B.data)}catch(T){return void i(y(ze,"Attachment is not a valid base64 string"))}l(e,x,c)(O)}else se(B.data,l(e,x,c))}}w.length||g()}function h(e,t,n,r){function i(){return new $e(function(e,t){R.get(E.attachmentStore,n,function(n,r){return n&&"NotFoundError"!==n.name?t(n):void e(r)})})}function o(r){var i=[e,t].join("@"),o={};return r?r.refs&&(o.refs=r.refs,o.refs[i]=!0):(o.refs={},o.refs[i]=!0),new $e(function(e){R.batch([{type:"put",prefix:E.attachmentStore,key:n,value:o}]),e(!r)})}var a=C[n]||$e.resolve();C[n]=a.then(function(){return i().then(o).then(function(e){r(null,e)},r)})}function p(e,t,n,i,o){var a=e.data._attachments[n];delete a.data,a.digest=t,a.length=i.length;var s=e.metadata.id,u=e.metadata.rev;a.revpos=parseInt(u,10),h(s,u,t,function(e,n){return e?o(e):0===i.length?o(e):n?(R.batch([{type:"put",prefix:E.binaryStore,key:t,value:new r(i,"binary")}]),void o()):o(e)})}function g(e){return e?t.nextTick(function(){i(e)}):(R.batch([{prefix:E.metaStore,type:"put",key:pt,value:L},{prefix:E.metaStore,type:"put",key:gt,value:m._docCount+A}]),void R.execute(m,function(e){return e?i(e):(m._docCount+=A,m._updateSeq=L,_t.notify(B),void t.nextTick(function(){i(null,b)}))}))}var v=n.new_edits,b=new Array(e.docs.length),_=new Be.Map,S=new Be.Map,R=new he,A=0,L=m._updateSeq,M=e.docs,O=M.map(function(e){if(e._id&&j(e._id))return e;var t=D(e,v);return t.metadata&&!t.metadata.rev_map&&(t.metadata.rev_map={}),t}),T=O.filter(function(e){return e.error});if(T.length)return i(T[0]);var C={};return O.length?void a(function(e){return e?i(e):void s(function(e){return e?i(e):void $(k,O,w,_,R,b,l,n,f)})}):i(null,[])}),w._allDocs=h(function(e,t){e=u(e),o(function(n,r){if(n)return t(n);var i={},o=e.skip||0;if(e.startkey&&(i.gte=e.startkey),e.endkey&&(i.lte=e.endkey),e.key&&(i.gte=i.lte=e.key),e.descending){i.reverse=!0;var a=i.lte;i.lte=i.gte,i.gte=a}var s;if("number"==typeof e.limit&&(s=e.limit),0===s||"start"in i&&"end"in i&&i.start>i.end)return t(null,{total_rows:r,offset:e.skip,rows:[]});var u=[],c=E.docStore.readStream(i),f=ke.obj(function(t,n,r){function i(t){var n={id:a.id,key:a.id,value:{rev:f}};if(e.include_docs){n.doc=t,n.doc._rev=n.value.rev,e.conflicts&&(n.doc._conflicts=A(a));for(var i in n.doc._attachments)n.doc._attachments.hasOwnProperty(i)&&(n.doc._attachments[i].stub=!0)}if(e.inclusive_end===!1&&a.id===e.endkey)return r();if(l){if("ok"!==e.deleted)return r();n.value.deleted=!0,n.doc=null}u.push(n),r()}var a=t.value,f=de(a),l=pe(a,f);if(l){if("ok"!==e.deleted)return void r()}else{if(o-- >0)return void r();if("number"==typeof s&&s--<=0)return c.unpipe(),c.destroy(),void r()}if(e.include_docs){var h=a.rev_map[f];E.bySeqStore.get(d(h),function(e,t){i(t)})}else i()},function(n){$e.resolve().then(function(){return e.include_docs&&e.attachments?ve(u,E,e):void 0}).then(function(){t(null,{total_rows:r,offset:e.skip,rows:u})},t),n()}).on("unpipe",function(){f.end()});c.on("error",t),c.pipe(f)})}),w._changes=function(e){function t(){e.done=!0,f&&e.limit&&e.limit<o.length&&(o.length=e.limit),y.unpipe(b),y.destroy(),e.continuous||e.cancelled||(e.include_docs&&e.attachments?ve(o,E,e).then(function(){e.complete(null,{results:o,last_seq:a})}):e.complete(null,{results:o,last_seq:a}))}if(e=u(e),e.continuous){var n=B+":"+g();return _t.addListener(B,n,w,e),_t.notify(B),{cancel:function(){_t.removeListener(B,n)}}}var r,i=e.descending,o=[],a=e.since||0,s=0,c={reverse:i};"limit"in e&&e.limit>0&&(r=e.limit),c.reverse||(c.start=d(e.since||0));var f,l=e.doc_ids&&new Be.Set(e.doc_ids),h=_(e),v=new Be.Map;f="return_docs"in e?e.return_docs:"returnDocs"in e?e.returnDocs:!0;var y=E.bySeqStore.readStream(c),b=ke.obj(function(n,u,c){function g(t){function n(n){var r=e.processChange(n,t,e);r.seq=t.seq;var i=h(r);return"object"==typeof i?e.complete(i):(i&&(s++,e.attachments&&e.include_docs?ve([r],E,e).then(function(){e.onChange(r)}):e.onChange(r),f&&o.push(r)),void c())}var r=de(t);if(t.seq!==y)return c();if(a=y,r===b._rev)return n(b);var i=t.rev_map[r];E.bySeqStore.get(d(i),function(e,t){n(t)})}if(r&&s>=r)return t(),c();if(e.cancelled||e.done)return c();var y=p(n.key),b=n.value;if(y===e.since&&!i)return c();if(l&&!l.has(b._id))return c();var _;return(_=v.get(b._id))?g(_):void E.docStore.get(b._id,function(t,n){return e.cancelled||e.done||m.isClosed()||j(n.id)?c():(v.set(b._id,n),void g(n))})},function(t){return e.cancelled?t():(f&&e.limit&&e.limit<o.length&&(o.length=e.limit),void t())}).on("unpipe",function(){b.end(),t()});return y.pipe(b),{cancel:function(){e.cancelled=!0,t()}}},w._close=function(e){return m.isClosed()?e(y(Fe)):void m.close(function(t){t?e(t):(L["delete"](B),e())})},w._getRevisionTree=function(e,t){E.docStore.get(e,function(e,n){e?t(y(Ne)):t(null,n.rev_tree)})},w._doCompaction=l(function(e,t,n,r){w._doCompactionNoLock(e,t,n,r)}),w._doCompactionNoLock=function(e,t,n,r){if("function"==typeof n&&(r=n,n={}),!t.length)return r();var i=n.ctx||new he;i.get(E.docStore,e,function(o,a){function s(e){if(e&&(h=e),++g===t.length){if(h)return r(h);c()}}function u(e){return e?r(e):(i.batch(l),n.ctx?r():void i.execute(m,r))}function c(){function n(e){e&&(o=e),++a===r.length&&u(o)}var r=Object.keys(p);if(!r.length)return u();var o,a=0,s=new Be.Map;t.forEach(function(t){s.set(e+"@"+t,!0)}),r.forEach(function(e){i.get(E.attachmentStore,e,function(t,r){if(t)return"NotFoundError"===t.name?n():n(t);var i=Object.keys(r.refs||{}).filter(function(e){return!s.has(e)}),o={};i.forEach(function(e){o[e]=!0}),i.length?l.push({key:e,type:"put",value:{refs:o},prefix:E.attachmentStore}):l=l.concat([{key:e,type:"del",prefix:E.attachmentStore},{key:e,type:"del",prefix:E.binaryStore}]),n()})})}if(o)return r(o);var f=t.map(function(e){var t=a.rev_map[e];return delete a.rev_map[e],t});S(a.rev_tree,function(e,n,r,i,o){var a=n+"-"+r;-1!==t.indexOf(a)&&(o.status="missing")});var l=[];l.push({key:a.id,value:a,type:"put",prefix:E.docStore});var h,p={},g=0;f.forEach(function(e){l.push({key:d(e),type:"del",prefix:E.bySeqStore}),i.get(E.bySeqStore,d(e),function(e,t){if(e)return"NotFoundError"===e.name?s():s(e);var n=Object.keys(t._attachments||{});n.forEach(function(e){var n=t._attachments[e].digest;p[n]=!0}),s()})})})},w._getLocal=function(e,t){E.localStore.get(e,function(e,n){e?t(y(Ne)):t(null,n)})},w._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._putLocalNoLock(e,t,n):w._putLocalWithLock(e,t,n)},w._putLocalWithLock=l(function(e,t,n){w._putLocalNoLock(e,t,n)}),w._putLocalNoLock=function(e,t,n){delete e._revisions;var r=e._rev,i=e._id,o=t.ctx||new he;o.get(E.localStore,i,function(a,s){if(a&&r)return n(y(qe));if(s&&s._rev!==r)return n(y(qe));e._rev=r?"0-"+(parseInt(r.split("-")[1],10)+1):"0-1";var u=[{type:"put",prefix:E.localStore,key:i,value:e}];o.batch(u);var c={ok:!0,id:e._id,rev:e._rev};return t.ctx?n(null,c):void o.execute(m,function(e){return e?n(e):void n(null,c)})})},w._removeLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._removeLocalNoLock(e,t,n):w._removeLocalWithLock(e,t,n)},w._removeLocalWithLock=l(function(e,t,n){w._removeLocalNoLock(e,t,n)}),w._removeLocalNoLock=function(e,t,n){var r=t.ctx||new he;r.get(E.localStore,e._id,function(i,o){if(i)return n("NotFoundError"!==i.name?i:y(Ne));if(o._rev!==e._rev)return n(y(qe));r.batch([{prefix:E.localStore,type:"del",key:e._id}]);var a={ok:!0,id:e._id,rev:"0-0"};return t.ctx?n(null,a):void r.execute(m,function(e){return e?n(e):void n(null,a)})})},w._destroy=function(e,t){var n,r=at(R);return dt.has(r)?(n=dt.get(r),void(n.has(B)?(_t.removeAllListeners(B),n.get(B).close(function(){n["delete"](B),v(B,t)})):v(B,t))):v(B,t)}}function be(e,t){function n(e,n){var r=Oe.extend({db:t},e);ye.call(this,r,n)}return n.valid=function(){return e.valid()},n.use_prefix=e.use_prefix,n.destroy=Z(function(e,n,r){"function"==typeof n&&(r=n,n={});var i=Oe.extend({db:t},n);return ye.destroy(e,i,r)}),n}function _e(t,n){var r=t.name,i=be(t,n),o="undefined"!=typeof PouchDB?PouchDB:e("pouchdb");o?o.adapter(r,i,!0):console.error(t.name+' adapter plugin error: Cannot find global "PouchDB" object! Did you remember to include pouchdb.js?')}var me,we=i(e(48)),Ee=i(e(72)),ke=e(90),Se=e(23),xe=i(e(31)),Be=e(53),Re=i(e(5)),Ae=i(e(95)),Le=i(e(52)),Me=i(e(57)),je=i(e(19)),Oe=e(34),Te=i(e(26));if(c())me=!1;else try{localStorage.setItem("_pouch_check_localstorage",1),me=!!localStorage.getItem("_pouch_check_localstorage")}catch(Ce){me=!1}xe(d,Se.EventEmitter),d.prototype.addListener=function(e,t,n,r){function i(){function e(){a=!1}if(o._listeners[t]){if(a)return void(a="waiting");a=!0;var s=l(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary"]);n.changes(s).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===a&&setTimeout(function(){i()},0),a=!1}).on("error",e)}}if(!this._listeners[t]){var o=this,a=!1;this._listeners[t]=i,this.on(e,i)}},d.prototype.removeListener=function(e,t){t in this._listeners&&Se.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t])},d.prototype.notifyLocalWindows=function(e){c()?chrome.storage.local.set({dbName:e}):f()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},d.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var Ie="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");xe(v,Error),v.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};var De,Ne=(new v({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),new v({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),new v({status:404,error:"not_found",reason:"missing"})),qe=new v({status:409,error:"conflict",reason:"Document update conflict"}),Ue=new v({status:400,error:"invalid_id",reason:"_id field must contain a string"}),Pe=new v({status:412,error:"missing_id",reason:"_id is required for puts"}),We=new v({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),Fe=new v({status:412,error:"precondition_failed",reason:"Database not open"}),ze=(new v({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),new v({status:500,error:"badarg",reason:"Some query argument is invalid"})),Ke=(new v({status:400,error:"invalid_request",reason:"Request was invalid"}),new v({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),new v({status:500,error:"doc_validation",reason:"Bad special document member"})),Ye=new v({status:400,error:"bad_request",reason:"Something wrong with the request"}),Ve=(new v({status:400,error:"bad_request",reason:"Document must be a JSON object"}),new v({status:404,error:"not_found",reason:"Database not found"}),new v({status:500,error:"indexed_db_went_bad",reason:"unknown"}),new v({status:500,error:"web_sql_went_bad",reason:"unknown"}),new v({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),new v({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),new v({status:400,error:"bad_request",reason:"Invalid rev format"})),Je=(new v({status:412,error:"file_exists",reason:"The database could not be created, the file already exists."}),new v({status:412,error:"missing_stub"})),He=(new v({status:413,error:"invalid_url",reason:"Provided URL is invalid"}),O(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"])),Ge=O(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]),$e="function"==typeof Promise?Promise:Le,Xe=function(e){return atob(e)},Ze=function(e){return btoa(e)},Qe=n.setImmediate||n.setTimeout,et=32768,tt=Z(function(e,t){function n(){var r=s*o,i=r+o;if(s++,a>s)c(u,e,r,i),Qe(n);else{c(u,e,r,i);var f=u.end(!0),l=Q(f);t(null,l),u.destroy()}}var r="string"==typeof e,i=r?e.length:e.byteLength,o=Math.min(et,i),a=Math.ceil(i/o),s=0,u=r?new Me:new Me.ArrayBuffer,c=r?te:ee;n()}),nt=function(e,n,r){t.nextTick(function(){r()})},rt=function(e,n,r){t.nextTick(function(){r()})},it={toSublevel:nt,localAndMetaStores:rt},ot=ne.name;De=ot?function(e){return e.name}:function(e){return e.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]};var at=De;he.prototype.get=function(e,n,r){var i=le(this,e),o=i.get(n);return o?t.nextTick(function(){r(null,o)}):null===o?t.nextTick(function(){r({name:"NotFoundError"})}):void e.get(n,function(e,t){return e?("NotFoundError"===e.name&&i.set(n,null),r(e)):(i.set(n,t),void r(null,t))})},he.prototype.batch=function(e){for(var t=0,n=e.length;n>t;t++){var r=e[t],i=le(this,r.prefix);"put"===r.type?i.set(r.key,r.value):i.set(r.key,null)}this._batch=this._batch.concat(e)},he.prototype.execute=function(e,t){for(var n=new Be.Set,r=[],i=this._batch.length-1;i>=0;i--){var o=this._batch[i],a=o.prefix.prefix()[0]+"ÿ"+o.key;n.has(a)||(n.add(a),r.push(o))}e.batch(r,t)};var st="document-store",ut="by-sequence",ct="attach-store",ft="attach-binary-store",lt="local-store",ht="meta-store",dt=new Be.Map,pt="_local_last_update_seq",gt="_local_doc_count",vt="_local_uuid",yt="md5-",bt={encode:E,decode:w,buffer:!1,type:"cheap-json"},_t=new d,mt=function(){try{return e(7)}catch(t){return t=t||"leveldown import error","MODULE_NOT_FOUND"===t.code?new Error(["the 'leveldown' package is not available. install it, or,","specify another storage backend using the 'db' option"].join(" ")):t.message&&t.message.match("Module version mismatch")?new Error([t.message,"This generally implies that leveldown was built with a different","version of node than that which is running now.  You may try","fully removing and reinstalling PouchDB or leveldown to resolve."].join(" ")):new Error(t.toString()+": unable to import leveldown")}};ye.valid=function(){return!0},ye.use_prefix=!1;var wt={name:"fruitdown",valid:function(){return!!n.indexedDB},use_prefix:!0};_e(wt,Te)}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(8).Buffer)},{19:19,23:23,26:26,31:31,34:34,48:48,5:5,52:52,53:53,55:55,57:57,7:7,72:72,8:8,90:90,95:95,pouchdb:"pouchdb"}],2:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(n)throw n;if(n=this._db._checkKeyValue(t,"value",this._db._isBuffer))throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKeyValue(e,"key",this._db._isBuffer);
+if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(55))},{55:55}],3:[function(e,t,n){(function(e){function n(e){this.db=e,this._ended=!1,this._nexting=!1}n.prototype.next=function(t){var n=this;if("function"!=typeof t)throw new Error("next() requires a callback argument");return n._ended?t(new Error("cannot call next() after end()")):n._nexting?t(new Error("cannot call next() before previous next() has completed")):(n._nexting=!0,"function"==typeof n._next?n._next(function(){n._nexting=!1,t.apply(null,arguments)}):void e.nextTick(function(){n._nexting=!1,t()}))},n.prototype.end=function(t){if("function"!=typeof t)throw new Error("end() requires a callback argument");return this._ended?t(new Error("end() already called on iterator")):(this._ended=!0,"function"==typeof this._end?this._end(t):void e.nextTick(t))},t.exports=n}).call(this,e(55))},{55:55}],4:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e}var o=e(96),a=e(3),s=e(2);i.prototype.open=function(e,t){if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");return"object"!=typeof e&&(e={}),"function"==typeof this._open?this._open(e,t):void r.nextTick(t)},i.prototype.close=function(e){if("function"!=typeof e)throw new Error("close() requires a callback argument");return"function"==typeof this._close?this._close(e):void r.nextTick(e)},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKeyValue(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?i(o):(o=this._checkKeyValue(t,"value",this._isBuffer))?i(o):(this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||r.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKeyValue(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));"object"!=typeof t&&(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKeyValue(i.type,"type",this._isBuffer))return n(o);if(o=this._checkKeyValue(i.key,"key",this._isBuffer))return n(o);if("put"==i.type&&(o=this._checkKeyValue(i.value,"value",this._isBuffer)))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||(t=String(t)),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.reverse&&e.lt&&(e.start=e.lt),e.reverse&&e.lte&&(e.start=e.lte),!e.reverse&&e.gt&&(e.start=e.gt),!e.reverse&&e.gte&&(e.start=e.gte),(e.reverse&&e.lt&&!e.lte||!e.reverse&&e.gt&&!e.gte)&&(e.exclusiveStart=!0),e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._checkKeyValue=function(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(this._isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")},t.exports.AbstractLevelDOWN=i,t.exports.AbstractIterator=a,t.exports.AbstractChainedBatch=s}).call(this,{isBuffer:e(32)},e(55))},{2:2,3:3,32:32,55:55,96:96}],5:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],6:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===a||t===l?62:t===s||t===h?63:u>t?-1:u+10>t?t-u+26+26:f+26>t?t-f:c+26>t?t-c+26:void 0}function n(e){function n(e){c[l++]=e}var r,i,a,s,u,c;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var f=e.length;u="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0,c=new o(3*e.length/4-u),a=u>0?e.length-4:e.length;var l=0;for(r=0,i=0;a>r;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===u?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===u&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(s>>8&255),n(255&s)),c}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,o,a,s=e.length%3,u="";for(i=0,a=e.length-s;a>i;i+=3)o=(e[i]<<16)+(e[i+1]<<8)+e[i+2],u+=n(o);switch(s){case 1:o=e[e.length-1],u+=t(o>>2),u+=t(o<<4&63),u+="==";break;case 2:o=(e[e.length-2]<<8)+e[e.length-1],u+=t(o>>10),u+=t(o>>4&63),u+=t(o<<2&63),u+="="}return u}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="+".charCodeAt(0),s="/".charCodeAt(0),u="0".charCodeAt(0),c="a".charCodeAt(0),f="A".charCodeAt(0),l="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],7:[function(e,t,n){},{}],8:[function(e,t,n){(function(t){"use strict";function r(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(e){return this instanceof o?(o.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof e?a(this,e):"string"==typeof e?s(this,e,arguments.length>1?arguments[1]:"utf8"):u(this,e)):arguments.length>1?new o(e,arguments[1]):new o(e)}function a(e,t){if(e=g(e,0>t?0:0|v(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)e[n]=0;return e}function s(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|b(t,n);return e=g(e,r),e.write(t,n),e}function u(e,t){if(o.isBuffer(t))return c(e,t);if($(t))return f(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return l(e,t);if(t instanceof ArrayBuffer)return h(e,t)}return t.length?d(e,t):p(e,t)}function c(e,t){var n=0|v(t.length);return e=g(e,n),t.copy(e,0,0,n),e}function f(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function l(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function h(e,t){return o.TYPED_ARRAY_SUPPORT?(t.byteLength,e=o._augment(new Uint8Array(t))):e=l(e,new Uint8Array(t)),e}function d(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function p(e,t){var n,r=0;"Buffer"===t.type&&$(t.data)&&(n=t.data,r=0|v(n.length)),e=g(e,r);for(var i=0;r>i;i+=1)e[i]=255&n[i];return e}function g(e,t){o.TYPED_ARRAY_SUPPORT?(e=o._augment(new Uint8Array(t)),e.__proto__=o.prototype):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=o.poolSize>>>1;return n&&(e.parent=X),e}function v(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function y(e,t){if(!(this instanceof y))return new y(e,t);var n=new o(e,t);return delete n.parent,n}function b(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return z(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return V(e).length;default:if(r)return z(e).length;t=(""+t).toLowerCase(),r=!0}}function _(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(e){case"hex":return j(this,t,n);case"utf8":case"utf-8":return R(this,t,n);case"ascii":return L(this,t,n);case"binary":return M(this,t,n);case"base64":return B(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function m(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;r>a;a++){var s=parseInt(t.substr(2*a,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+a]=s}return a}function w(e,t,n,r){return J(z(t,e.length-n),e,n,r)}function E(e,t,n,r){return J(K(t),e,n,r)}function k(e,t,n,r){return E(e,t,n,r)}function S(e,t,n,r){return J(V(t),e,n,r)}function x(e,t,n,r){return J(Y(t,e.length-n),e,n,r)}function B(e,t,n){return 0===t&&n===e.length?H.fromByteArray(e):H.fromByteArray(e.slice(t,n))}function R(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;n>i;){var o=e[i],a=null,s=o>239?4:o>223?3:o>191?2:1;if(n>=i+s){var u,c,f,l;switch(s){case 1:128>o&&(a=o);break;case 2:u=e[i+1],128===(192&u)&&(l=(31&o)<<6|63&u,l>127&&(a=l));break;case 3:u=e[i+1],c=e[i+2],128===(192&u)&&128===(192&c)&&(l=(15&o)<<12|(63&u)<<6|63&c,l>2047&&(55296>l||l>57343)&&(a=l));break;case 4:u=e[i+1],c=e[i+2],f=e[i+3],128===(192&u)&&128===(192&c)&&128===(192&f)&&(l=(15&o)<<18|(63&u)<<12|(63&c)<<6|63&f,l>65535&&1114112>l&&(a=l))}}null===a?(a=65533,s=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),i+=s}return A(r)}function A(e){var t=e.length;if(Z>=t)return String.fromCharCode.apply(String,e);for(var n="",r=0;t>r;)n+=String.fromCharCode.apply(String,e.slice(r,r+=Z));return n}function L(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(127&e[i]);return r}function M(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(e[i]);return r}function j(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var i="",o=t;n>o;o++)i+=F(e[o]);return i}function O(e,t,n){for(var r=e.slice(t,n),i="",o=0;o<r.length;o+=2)i+=String.fromCharCode(r[o]+256*r[o+1]);return i}function T(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function C(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>i||a>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function I(e,t,n,r){0>t&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);o>i;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function D(e,t,n,r){0>t&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);o>i;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function N(e,t,n,r,i,o){if(t>i||o>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(0>n)throw new RangeError("index out of range")}function q(e,t,n,r,i){return i||N(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),G.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||N(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),G.write(e,t,n,r,52,8),n+8}function P(e){if(e=W(e).replace(ee,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function W(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function F(e){return 16>e?"0"+e.toString(16):e.toString(16)}function z(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],a=0;r>a;a++){if(n=e.charCodeAt(a),n>55295&&57344>n){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(56320>n){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,128>n){if((t-=1)<0)break;o.push(n)}else if(2048>n){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function K(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function Y(e,t){for(var n,r,i,o=[],a=0;a<e.length&&!((t-=2)<0);a++)n=e.charCodeAt(a),r=n>>8,i=n%256,o.push(i),o.push(r);return o}function V(e){return H.toByteArray(P(e))}function J(e,t,n,r){for(var i=0;r>i&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var H=e(6),G=e(29),$=e(33);n.Buffer=o,n.SlowBuffer=y,n.INSPECT_MAX_BYTES=50,o.poolSize=8192;var X={};o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),o.TYPED_ARRAY_SUPPORT?(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array):(o.prototype.length=void 0,o.prototype.parent=void 0),o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);a>i&&e[i]===t[i];)++i;return i!==a&&(n=e[i],r=t[i]),r>n?-1:n>r?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!$(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new o(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new o(t),i=0;for(n=0;n<e.length;n++){var a=e[n];a.copy(r,i),i+=a.length}return r},o.byteLength=b,o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?R(this,0,e):_.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:o.compare(this,e)},o.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[-1===r?0:i-r]){if(-1===r&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(o.isBuffer(e))return n(this,e,t);if("number"==typeof e)return o.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},o.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},o.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return E(this,e,t,n);case"binary":return k(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Z=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=o._augment(this.subarray(e,t));else{var i=t-e;r=new o(i,void 0);for(var a=0;i>a;a++)r[a]=this[a+e]}return r.length&&(r.parent=this.parent||this),r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||T(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||T(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||T(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||T(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||T(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(e,t){return t||T(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},o.prototype.readInt16LE=function(e,t){t||T(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||T(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||T(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||T(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||C(this,e,t,n,Math.pow(2,8*n),0);var i=1,o=0;for(this[t]=255&e;++o<n&&(i*=256);)this[t+o]=e/i&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||C(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):D(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);C(this,e,t,n,i-1,-i)}var o=0,a=1,s=0>e?1:0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);C(this,e,t,n,i-1,-i)}var o=n-1,a=1,s=0>e?1:0;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):D(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return q(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return q(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&n>r&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&t>n&&r>t)for(i=a-1;i>=0;i--)e[i+t]=this[i+n];else if(1e3>a||!o.TYPED_ARRAY_SUPPORT)for(i=0;a>i;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),t>n)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new RangeError("start out of bounds");if(0>n||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;n>r;r++)this[r]=e;else{var i=z(e.toString()),o=i.length;for(r=t;n>r;r++)this[r]=i[r%o]}return this}},o.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(o.TYPED_ARRAY_SUPPORT)return new o(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;n>t;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var Q=o.prototype;o._augment=function(e){return e.constructor=o,e._isBuffer=!0,e._set=e.set,e.get=Q.get,e.set=Q.set,e.write=Q.write,e.toString=Q.toString,e.toLocaleString=Q.toString,e.toJSON=Q.toJSON,e.equals=Q.equals,e.compare=Q.compare,e.indexOf=Q.indexOf,e.copy=Q.copy,e.slice=Q.slice,e.readUIntLE=Q.readUIntLE,e.readUIntBE=Q.readUIntBE,e.readUInt8=Q.readUInt8,e.readUInt16LE=Q.readUInt16LE,e.readUInt16BE=Q.readUInt16BE,e.readUInt32LE=Q.readUInt32LE,e.readUInt32BE=Q.readUInt32BE,e.readIntLE=Q.readIntLE,e.readIntBE=Q.readIntBE,e.readInt8=Q.readInt8,e.readInt16LE=Q.readInt16LE,e.readInt16BE=Q.readInt16BE,e.readInt32LE=Q.readInt32LE,e.readInt32BE=Q.readInt32BE,e.readFloatLE=Q.readFloatLE,e.readFloatBE=Q.readFloatBE,e.readDoubleLE=Q.readDoubleLE,e.readDoubleBE=Q.readDoubleBE,e.writeUInt8=Q.writeUInt8,e.writeUIntLE=Q.writeUIntLE,e.writeUIntBE=Q.writeUIntBE,e.writeUInt16LE=Q.writeUInt16LE,e.writeUInt16BE=Q.writeUInt16BE,e.writeUInt32LE=Q.writeUInt32LE,e.writeUInt32BE=Q.writeUInt32BE,e.writeIntLE=Q.writeIntLE,e.writeIntBE=Q.writeIntBE,e.writeInt8=Q.writeInt8,e.writeInt16LE=Q.writeInt16LE,e.writeInt16BE=Q.writeInt16BE,e.writeInt32LE=Q.writeInt32LE,e.writeInt32BE=Q.writeInt32BE,e.writeFloatLE=Q.writeFloatLE,e.writeFloatBE=Q.writeFloatBE,e.writeDoubleLE=Q.writeDoubleLE,e.writeDoubleBE=Q.writeDoubleBE,e.fill=Q.fill,e.inspect=Q.inspect,e.toArrayBuffer=Q.toArrayBuffer,e};var ee=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{29:29,33:33,6:6}],9:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===v(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function o(e){return null==e}function a(e){return"number"==typeof e}function s(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function c(e){return void 0===e}function f(e){return"[object RegExp]"===v(e)}function l(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===v(e)}function d(e){return"[object Error]"===v(e)||e instanceof Error}function p(e){return"function"==typeof e}function g(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function v(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=o,n.isNumber=a,n.isString=s,n.isSymbol=u,n.isUndefined=c,n.isRegExp=f,n.isObject=l,n.isDate=h,n.isError=d,n.isFunction=p,n.isPrimitive=g,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e(32)})},{32:32}],10:[function(e,t,n){var r=e(8).Buffer,i=".PYFGCRLAOEUIDHTNSQJKXBMWVZ_pyfgcrlaoeuidhtnsqjkxbmwvz1234567890".split("").sort().join("");t.exports=function(e,t){if(e=e||i,t=t||{},64!==e.length)throw new Error("a base 64 encoding requires 64 chars");var n=new r(128);n.fill();for(var o=0;64>o;o++){var a=e.charCodeAt(o);n[a]=o}return t.encode=function(t){for(var n="",r=t.length,i=0,o=0;r>o;o++){var a=t[o];switch(o%3){case 0:n+=e[a>>2],i=(3&a)<<4;break;case 1:n+=e[i|a>>4],i=(15&a)<<2;break;case 2:n+=e[i|a>>6],n+=e[63&a],i=0}}return r%3&&(n+=e[i]),n},t.decode=function(e){for(var t=e.length,i=0,o=new r(~~(t/4*3)),a=0,s=0;t>s;s++){var u=n[e.charCodeAt(s)];switch(s%4){case 0:a=u<<2;break;case 1:o[i++]=a|u>>4,a=u<<4&255;break;case 2:o[i++]=a|u>>2,a=u<<6&255;break;case 3:o[i++]=a|u}}return o},t},t.exports(i,t.exports)},{8:8}],11:[function(e,t,n){function r(e){o.call(this,e),this._options=e,this._iterator=null,this._operations=[]}var i=e(94),o=e(16).AbstractIterator;i.inherits(r,o),r.prototype.setDb=function(e){var t=this._iterator=e.iterator(this._options);this._operations.forEach(function(e){t[e.method].apply(t,e.args)})},r.prototype._operation=function(e,t){return this._iterator?this._iterator[e].apply(this._iterator,t):void this._operations.push({method:e,args:t})},"next end".split(" ").forEach(function(e){r.prototype["_"+e]=function(){this._operation(e,arguments)}}),t.exports=r},{16:16,94:94}],12:[function(e,t,n){(function(n,r){function i(e){a.call(this,"string"==typeof e?e:""),this._db=void 0,this._operations=[],this._iterators=[]}var o=e(94),a=e(16).AbstractLevelDOWN,s=e(11);o.inherits(i,a),i.prototype.setDb=function(e){this._db=e,this._operations.forEach(function(t){e[t.method].apply(e,t.args)}),this._iterators.forEach(function(t){t.setDb(e)})},i.prototype._open=function(e,t){return r.nextTick(t)},i.prototype._operation=function(e,t){return this._db?this._db[e].apply(this._db,t):void this._operations.push({method:e,args:t})},"put get del batch approximateSize".split(" ").forEach(function(e){i.prototype["_"+e]=function(){this._operation(e,arguments)}}),i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._iterator=function(e){if(this._db)return this._db.iterator.apply(this._db,arguments);var t=new s(e);return this._iterators.push(t),t},t.exports=i,t.exports.DeferredIterator=s}).call(this,{isBuffer:e(32)},e(55))},{11:11,16:16,32:32,55:55,94:94}],13:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKey(e,"key",this._db._isBuffer);if(n)throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKey(e,"key",this._db._isBuffer);if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(55))},{55:55}],14:[function(e,t,n){arguments[4][3][0].apply(n,arguments)},{3:3,55:55}],15:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e,this.status="new"}var o=e(18),a=e(14),s=e(13);i.prototype.open=function(e,t){var n=this,i=this.status;if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");"object"!=typeof e&&(e={}),e.createIfMissing=0!=e.createIfMissing,e.errorIfExists=!!e.errorIfExists,"function"==typeof this._open?(this.status="opening",this._open(e,function(e){return e?(n.status=i,t(e)):(n.status="open",void t())})):(this.status="open",r.nextTick(t))},i.prototype.close=function(e){var t=this,n=this.status;if("function"!=typeof e)throw new Error("close() requires a callback argument");"function"==typeof this._close?(this.status="closing",this._close(function(r){return r?(t.status=n,e(r)):(t.status="closed",void e())})):(this.status="closed",r.nextTick(e))},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),
+"object"!=typeof t&&(t={}),t.asBuffer=0!=t.asBuffer,"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKey(e,"key",this._isBuffer))?i(o):(this._isBuffer(e)||(e=String(e)),null==t||this._isBuffer(t)||r.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"==typeof e&&(n=e),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));t&&"object"==typeof t||(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKey(i.type,"type",this._isBuffer))return n(o);if(o=this._checkKey(i.key,"key",this._isBuffer))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||(t=String(t)),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.keys=0!=e.keys,e.values=0!=e.values,e.limit="limit"in e?e.limit:-1,e.keyAsBuffer=0!=e.keyAsBuffer,e.valueAsBuffer=0!=e.valueAsBuffer,e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._checkKey=function(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(this._isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")},t.exports=i}).call(this,{isBuffer:e(32)},e(55))},{13:13,14:14,18:18,32:32,55:55}],16:[function(e,t,n){n.AbstractLevelDOWN=e(15),n.AbstractIterator=e(14),n.AbstractChainedBatch=e(13),n.isLevelDOWN=e(17)},{13:13,14:14,15:15,17:17}],17:[function(e,t,n){function r(e){return e&&"object"==typeof e?Object.keys(i.prototype).filter(function(e){return"_"!=e[0]&&"approximateSize"!=e}).every(function(t){return"function"==typeof e[t]}):!1}var i=e(15);t.exports=r},{15:15}],18:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}],19:[function(e,t,n){"use strict";function r(e){if(this._capacity=a(e),this._length=0,this._front=0,this._makeCapacity(),s(e)){for(var t=e.length,n=0;t>n;++n)this[n]=e[n];this._length=t}}function i(e,t,n,r,i){for(var o=0;i>o;++o)n[o+r]=e[o+t]}function o(e){return e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,e+1}function a(e){if("number"!=typeof e){if(!s(e))return 16;e=e.length}return o(Math.min(Math.max(16,e),1073741824))}r.prototype.toArray=function(){for(var e=this._length,t=new Array(e),n=this._front,r=this._capacity,i=0;e>i;++i)t[i]=this[n+i&r-1];return t},r.prototype.push=function(e){var t=arguments.length,n=this._length;if(t>1){var r=this._capacity;if(n+t>r){for(var i=0;t>i;++i){this._checkCapacity(n+1);var o=this._front+n&this._capacity-1;this[o]=arguments[i],n++,this._length=n}return n}for(var o=this._front,i=0;t>i;++i)this[o+n&r-1]=arguments[i],o++;return this._length=n+t,n+t}if(0===t)return n;this._checkCapacity(n+1);var i=this._front+n&this._capacity-1;return this[i]=e,this._length=n+1,n+1},r.prototype.pop=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1,n=this[t];return this[t]=void 0,this._length=e-1,n}},r.prototype.shift=function(){var e=this._length;if(0!==e){var t=this._front,n=this[t];return this[t]=void 0,this._front=t+1&this._capacity-1,this._length=e-1,n}},r.prototype.unshift=function(e){var t=this._length,n=arguments.length;if(n>1){var r=this._capacity;if(t+n>r){for(var i=n-1;i>=0;i--){this._checkCapacity(t+1);var r=this._capacity,o=(this._front-1&r-1^r)-r;this[o]=arguments[i],t++,this._length=t,this._front=o}return t}for(var a=this._front,i=n-1;i>=0;i--){var o=(a-1&r-1^r)-r;this[o]=arguments[i],a=o}return this._front=a,this._length=t+n,t+n}if(0===n)return t;this._checkCapacity(t+1);var r=this._capacity,i=(this._front-1&r-1^r)-r;return this[i]=e,this._length=t+1,this._front=i,t+1},r.prototype.peekBack=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1;return this[t]}},r.prototype.peekFront=function(){return 0!==this._length?this[this._front]:void 0},r.prototype.get=function(e){var t=e;if(t===(0|t)){var n=this._length;if(0>t&&(t+=n),!(0>t||t>=n))return this[this._front+t&this._capacity-1]}},r.prototype.isEmpty=function(){return 0===this._length},r.prototype.clear=function(){this._length=0,this._front=0,this._makeCapacity()},r.prototype.toString=function(){return this.toArray().toString()},r.prototype.valueOf=r.prototype.toString,r.prototype.removeFront=r.prototype.shift,r.prototype.removeBack=r.prototype.pop,r.prototype.insertFront=r.prototype.unshift,r.prototype.insertBack=r.prototype.push,r.prototype.enqueue=r.prototype.push,r.prototype.dequeue=r.prototype.shift,r.prototype.toJSON=r.prototype.toArray,Object.defineProperty(r.prototype,"length",{get:function(){return this._length},set:function(){throw new RangeError("")}}),r.prototype._makeCapacity=function(){for(var e=this._capacity,t=0;e>t;++t)this[t]=void 0},r.prototype._checkCapacity=function(e){this._capacity<e&&this._resizeTo(a(1.5*this._capacity+16))},r.prototype._resizeTo=function(e){var t=this._front,n=this._capacity,r=new Array(n),o=this._length;if(i(this,0,r,0,n),this._capacity=e,this._makeCapacity(),this._front=0,n>=t+o)i(r,t,this,0,o);else{var a=o-(t+o&n-1);i(r,t,this,0,a),i(r,0,this,a,o-a)}};var s=Array.isArray;t.exports=r},{}],20:[function(e,t,n){function r(e,t,n){a(this,{type:e,name:e,cause:"string"!=typeof t?t:n,message:t&&"string"!=typeof t?t.message:t},"ewr")}function i(e,t){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee),r.call(this,"CustomError",e,t)}function o(e,t,n){var o=function(n,i){r.call(this,t,n,i),"FilesystemError"==t&&(this.code=this.cause.code,this.path=this.cause.path,this.errno=this.cause.errno,this.message=(e.errno[this.cause.errno]?e.errno[this.cause.errno].description:this.cause.message)+(this.cause.path?" ["+this.cause.path+"]":"")),Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee)};return o.prototype=n?new n:new i,o}var a=e(22);i.prototype=new Error,t.exports=function(e){var t=function(t,n){return o(e,t,n)};return{CustomError:i,FilesystemError:t("FilesystemError"),createError:t}}},{22:22}],21:[function(e,t,n){var r=t.exports.all=[{errno:-2,code:"ENOENT",description:"no such file or directory"},{errno:-1,code:"UNKNOWN",description:"unknown error"},{errno:0,code:"OK",description:"success"},{errno:1,code:"EOF",description:"end of file"},{errno:2,code:"EADDRINFO",description:"getaddrinfo error"},{errno:3,code:"EACCES",description:"permission denied"},{errno:4,code:"EAGAIN",description:"resource temporarily unavailable"},{errno:5,code:"EADDRINUSE",description:"address already in use"},{errno:6,code:"EADDRNOTAVAIL",description:"address not available"},{errno:7,code:"EAFNOSUPPORT",description:"address family not supported"},{errno:8,code:"EALREADY",description:"connection already in progress"},{errno:9,code:"EBADF",description:"bad file descriptor"},{errno:10,code:"EBUSY",description:"resource busy or locked"},{errno:11,code:"ECONNABORTED",description:"software caused connection abort"},{errno:12,code:"ECONNREFUSED",description:"connection refused"},{errno:13,code:"ECONNRESET",description:"connection reset by peer"},{errno:14,code:"EDESTADDRREQ",description:"destination address required"},{errno:15,code:"EFAULT",description:"bad address in system call argument"},{errno:16,code:"EHOSTUNREACH",description:"host is unreachable"},{errno:17,code:"EINTR",description:"interrupted system call"},{errno:18,code:"EINVAL",description:"invalid argument"},{errno:19,code:"EISCONN",description:"socket is already connected"},{errno:20,code:"EMFILE",description:"too many open files"},{errno:21,code:"EMSGSIZE",description:"message too long"},{errno:22,code:"ENETDOWN",description:"network is down"},{errno:23,code:"ENETUNREACH",description:"network is unreachable"},{errno:24,code:"ENFILE",description:"file table overflow"},{errno:25,code:"ENOBUFS",description:"no buffer space available"},{errno:26,code:"ENOMEM",description:"not enough memory"},{errno:27,code:"ENOTDIR",description:"not a directory"},{errno:28,code:"EISDIR",description:"illegal operation on a directory"},{errno:29,code:"ENONET",description:"machine is not on the network"},{errno:31,code:"ENOTCONN",description:"socket is not connected"},{errno:32,code:"ENOTSOCK",description:"socket operation on non-socket"},{errno:33,code:"ENOTSUP",description:"operation not supported on socket"},{errno:34,code:"ENOENT",description:"no such file or directory"},{errno:35,code:"ENOSYS",description:"function not implemented"},{errno:36,code:"EPIPE",description:"broken pipe"},{errno:37,code:"EPROTO",description:"protocol error"},{errno:38,code:"EPROTONOSUPPORT",description:"protocol not supported"},{errno:39,code:"EPROTOTYPE",description:"protocol wrong type for socket"},{errno:40,code:"ETIMEDOUT",description:"connection timed out"},{errno:41,code:"ECHARSET",description:"invalid Unicode character"},{errno:42,code:"EAIFAMNOSUPPORT",description:"address family for hostname not supported"},{errno:44,code:"EAISERVICE",description:"servname not supported for ai_socktype"},{errno:45,code:"EAISOCKTYPE",description:"ai_socktype not supported"},{errno:46,code:"ESHUTDOWN",description:"cannot send after transport endpoint shutdown"},{errno:47,code:"EEXIST",description:"file already exists"},{errno:48,code:"ESRCH",description:"no such process"},{errno:49,code:"ENAMETOOLONG",description:"name too long"},{errno:50,code:"EPERM",description:"operation not permitted"},{errno:51,code:"ELOOP",description:"too many symbolic links encountered"},{errno:52,code:"EXDEV",description:"cross-device link not permitted"},{errno:53,code:"ENOTEMPTY",description:"directory not empty"},{errno:54,code:"ENOSPC",description:"no space left on device"},{errno:55,code:"EIO",description:"i/o error"},{errno:56,code:"EROFS",description:"read-only file system"},{errno:57,code:"ENODEV",description:"no such device"},{errno:58,code:"ESPIPE",description:"invalid seek"},{errno:59,code:"ECANCELED",description:"operation canceled"}];t.exports.errno={},t.exports.code={},r.forEach(function(e){t.exports.errno[e.errno]=e,t.exports.code[e.code]=e}),t.exports.custom=e(20)(t.exports),t.exports.create=t.exports.custom.createError},{20:20}],22:[function(e,t,n){!function(e,n,r){"undefined"!=typeof t&&t.exports?t.exports=r():n[e]=r()}("prr",this,function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e},t=function(e,t){var n="object"==typeof t,r=!n&&"string"==typeof t,i=function(e){return n?!!t[e]:r?t.indexOf(e[0])>-1:!1};return{enumerable:i("enumerable"),configurable:i("configurable"),writable:i("writable"),value:e}},n=function(n,r,i,o){var a;if(o=t(i,o),"object"==typeof r){for(a in r)Object.hasOwnProperty.call(r,a)&&(o.value=r[a],e(n,a,o));return n}return e(n,r,o)};return n})},{}],23:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function o(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,o,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(a(n))for(o=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,u=0;r>u;u++)c[u].apply(this,o);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,a(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,o,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],o=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(s=o;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],24:[function(e,t,n){(function(e,n){"use strict";function r(e){this._dbName=e}function i(e,t){if(u[e])return s(function(){t(null,u[e])});var n=indexedDB.open(e,1);c[e]=n,n.onupgradeneeded=function(e){var t=e.target.result;1!==e.oldVersion&&t.createObjectStore(a).createIndex("fakeKey","fakeKey")},n.onsuccess=function(n){var r=u[e]=n.target.result;t(null,r)},n.onerror=function(e){var n="Failed to open indexedDB, are you in private browsing mode?";console.error(n),t(e)}}function o(e,t){try{return{txn:e.transaction(a,t)}}catch(n){return{error:n}}}var a="fruitdown",s=n.setImmediate||e.nextTick,u={},c={};r.prototype.getKeys=function(e){i(this._dbName,function(t,n){if(t)return e(t);var r=o(n,"readonly");if(r.error)return e(r.error);var i=r.txn,s=i.objectStore(a);i.onerror=e;var u=[];i.oncomplete=function(){e(null,u.sort())};var c=s.index("fakeKey").openKeyCursor();c.onsuccess=function(e){var t=e.target.result;t&&(u.push(t.primaryKey),t["continue"]())}})},r.prototype.put=function(e,t,n){i(this._dbName,function(r,i){if(r)return n(r);var s=o(i,"readwrite");if(s.error)return n(s.error);var u=s.txn,c=u.objectStore(a),f="string"==typeof t?t:t.toString();u.onerror=n,u.oncomplete=function(){n()},c.put({value:f,fakeKey:0},e)})},r.prototype.get=function(e,t){i(this._dbName,function(n,r){if(n)return t(n);var i=o(r,"readonly");if(i.error)return t(i.error);var s,u=i.txn,c=u.objectStore(a),f=c.get(e);f.onsuccess=function(e){e.target.result&&(s=e.target.result.value)},u.onerror=t,u.oncomplete=function(){t(null,s)}})},r.prototype.remove=function(e,t){i(this._dbName,function(n,r){if(n)return t(n);var i=o(r,"readwrite");if(i.error)return t(i.error);var s=i.txn,u=s.objectStore(a);u["delete"](e),s.onerror=t,s.oncomplete=function(){t()}})},r.destroy=function(e,t){s(function(){c[e]&&c[e].result&&(c[e].result.close(),delete u[e]);var n=indexedDB.deleteDatabase(e);n.onsuccess=function(){c[e]&&(c[e]=null),t(null)},n.onerror=t})},t.exports=r}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{55:55}],25:[function(e,t,n){(function(n){"use strict";function r(e){this._store=new l(e),this._queue=new h}var i="ArrayBuffer:",o=new RegExp("^"+i),a="Uint8Array:",s=new RegExp("^"+a),u="Buff:",c=new RegExp("^"+u),f=e(28),l=e(24),h=e(27),d=e(10);r.prototype.sequentialize=function(e,t){this._queue.add(t,e)},r.prototype.init=function(e){var t=this;t.sequentialize(e,function(e){t._store.getKeys(function(n,r){return n?e(n):(t._keys=r,e())})})},r.prototype.keys=function(e){var t=this;t.sequentialize(e,function(e){e(null,t._keys.slice())})},r.prototype.setItem=function(e,t,r){var i=this;i.sequentialize(r,function(r){n.isBuffer(t)&&(t=u+d.encode(t));var o=f.sortedIndexOf(i._keys,e);i._keys[o]!==e&&i._keys.splice(o,0,e),i._store.put(e,t,r)})},r.prototype.getItem=function(e,t){var n=this;n.sequentialize(t,function(t){n._store.get(e,function(e,n){return e?t(e):"undefined"==typeof n||null===n?t(new Error("NotFound")):("undefined"!=typeof n&&(c.test(n)?n=d.decode(n.substring(u.length)):o.test(n)?(n=n.substring(i.length),n=new ArrayBuffer(atob(n).split("").map(function(e){return e.charCodeAt(0)}))):s.test(n)&&(n=n.substring(a.length),n=new Uint8Array(atob(n).split("").map(function(e){return e.charCodeAt(0)})))),void t(null,n))})})},r.prototype.removeItem=function(e,t){var n=this;n.sequentialize(t,function(t){var r=f.sortedIndexOf(n._keys,e);n._keys[r]===e?(n._keys.splice(r,1),n._store.remove(e,function(e){return e?t(e):void t()})):t()})},r.prototype.length=function(e){var t=this;t.sequentialize(e,function(e){e(null,t._keys.length)})},t.exports=r}).call(this,{isBuffer:e(32)})},{10:10,24:24,27:27,28:28,32:32}],26:[function(e,t,n){(function(n,r,i){"use strict";function o(e,t){f.call(this,e),this._reverse=!!t.reverse,this._endkey=t.end,this._startkey=t.start,this._gt=t.gt,this._gte=t.gte,this._lt=t.lt,this._lte=t.lte,this._exclusiveStart=t.exclusiveStart,this._limit=t.limit,this._count=0,this.onInitCompleteListeners=[]}function a(e){return this instanceof a?(c.call(this,e),void(this.container=new l(e))):new a(e)}function s(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if("key"===t){if(e instanceof Boolean)return new Error(t+" cannot be `null` or `undefined`");if(""===e)return new Error(t+" cannot be empty")}if(0===e.toString().indexOf("[object ArrayBuffer]")&&(0===e.byteLength||void 0===e.byteLength))return new Error(t+" cannot be an empty Buffer");if(i.isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")}var u=e(31),c=e(4).AbstractLevelDOWN,f=e(4).AbstractIterator,l=e(25),h=e(24),d=e(28),p=r.setImmediate||n.nextTick;u(o,f),o.prototype._init=function(e){p(function(){e()})},o.prototype._next=function(e){function t(){if(n._pos===n._keys.length||n._pos<0)return e();var t=n._keys[n._pos];return n._endkey&&(n._reverse?t<n._endkey:t>n._endkey)?e():n._limit&&n._limit>0&&n._count++>=n._limit?e():n._lt&&t>=n._lt||n._lte&&t>n._lte||n._gt&&t<=n._gt||n._gte&&t<n._gte?e():(n._pos+=n._reverse?-1:1,void n.db.container.getItem(t,function(r,i){return r?"NotFound"===r.message?p(function(){n._next(e)}):e(r):void e(null,t,i)}))}var n=this;n.initStarted?n.initCompleted?t():n.onInitCompleteListeners.push(t):(n.initStarted=!0,n._init(function(r){return r?e(r):void n.db.container.keys(function(r,i){if(r)return e(r);if(n._keys=i,n._startkey){var o=d.sortedIndexOf(n._keys,n._startkey),a=o>=n._keys.length||0>o?void 0:n._keys[o];n._pos=o,n._reverse?(n._exclusiveStart||a!==n._startkey)&&n._pos--:n._exclusiveStart&&a===n._startkey&&n._pos++}else n._pos=n._reverse?n._keys.length-1:0;t(),n.initCompleted=!0;for(var s=-1;++s<n.onInitCompleteListeners;)p(n.onInitCompleteListeners[s])})}))},u(a,c),a.prototype._open=function(e,t){this.container.init(t)},a.prototype._put=function(e,t,n,r){var o=s(e,"key");if(o)return p(function(){r(o)});if(o=s(t,"value"))return p(function(){r(o)});if("object"==typeof t&&!i.isBuffer(t)&&void 0===t.buffer){var a={};a.storetype="json",a.data=t,t=JSON.stringify(a)}this.container.setItem(e,t,r)},a.prototype._get=function(e,t,n){var r=s(e,"key");return r?p(function(){n(r)}):(i.isBuffer(e)||(e=String(e)),void this.container.getItem(e,function(e,r){if(e)return n(e);if(t.asBuffer===!1||i.isBuffer(r)||(r=new i(r)),t.asBuffer===!1&&r.indexOf('{"storetype":"json","data"')>-1){var o=JSON.parse(r);r=o.data}n(null,r)}))},a.prototype._del=function(e,t,n){var r=s(e,"key");return r?p(function(){n(r)}):(i.isBuffer(e)||(e=String(e)),void this.container.removeItem(e,n))},a.prototype._batch=function(e,t,n){var r=this;p(function(){function o(){++l===e.length&&n(f)}var a,u,c,f,l=0;if(Array.isArray(e)&&e.length)for(var h=0;h<e.length;h++){var d=e[h];d?(u=i.isBuffer(d.key)?d.key:String(d.key),a=s(u,"key"),a?(f=a,o()):"del"===d.type?r._del(d.key,t,o):"put"===d.type&&(c=i.isBuffer(d.value)?d.value:String(d.value),a=s(c,"value"),a?(f=a,o()):r._put(u,c,t,o))):o()}else n()})},a.prototype._iterator=function(e){return new o(this,e)},a.destroy=function(e,t){h.destroy(e,t)},t.exports=a}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(8).Buffer)},{24:24,25:25,28:28,31:31,4:4,55:55,8:8}],27:[function(e,t,n){(function(n,r){"use strict";function i(){this.queue=new a,this.running=!1}var o=e(5),a=e(91),s=r.setImmediate||n.nextTick;i.prototype.add=function(e,t){this.queue.push({fun:e,callback:t}),this.processNext()},i.prototype.processNext=function(){var e=this;if(!e.running&&e.queue.length){e.running=!0;var t=e.queue.shift();s(function(){t.fun(o(function(n){t.callback.apply(null,n),e.running=!1,e.processNext()}))})}},t.exports=i}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{5:5,55:55,91:91}],28:[function(e,t,n){"use strict";n.sortedIndexOf=function(e,t){for(var n,r=0,i=e.length;i>r;)n=r+i>>>1,e[n]<t?r=n+1:i=n;return r}},{}],29:[function(e,t,n){n.read=function(e,t,n,r,i){var o,a,s=8*i-r-1,u=(1<<s)-1,c=u>>1,f=-7,l=n?i-1:0,h=n?-1:1,d=e[t+l];for(l+=h,o=d&(1<<-f)-1,d>>=-f,f+=s;f>0;o=256*o+e[t+l],l+=h,f-=8);for(a=o&(1<<-f)-1,o>>=-f,f+=r;f>0;a=256*a+e[t+l],l+=h,f-=8);if(0===o)o=1-c;else{if(o===u)return a?NaN:(d?-1:1)*(1/0);a+=Math.pow(2,r),o-=c}return(d?-1:1)*a*Math.pow(2,o-r)},n.write=function(e,t,n,r,i,o){var a,s,u,c=8*o-i-1,f=(1<<c)-1,l=f>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,g=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=f):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),t+=a+l>=1?h/u:h*Math.pow(2,1-l),t*u>=2&&(a++,u/=2),a+l>=f?(s=0,a=f):a+l>=1?(s=(t*u-1)*Math.pow(2,i),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,i),a=0));i>=8;e[n+d]=255&s,d+=p,s/=256,i-=8);for(a=a<<i|s,c+=i;c>0;e[n+d]=255&a,d+=p,a/=256,c-=8);e[n+d-p]|=128*g}},{}],30:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||i()}var i,o=e.MutationObserver||e.WebKitMutationObserver;if(o){var a=0,s=new o(n),u=e.document.createTextNode("");s.observe(u,{characterData:!0}),i=function(){u.data=a=++a%2}}else if(e.setImmediate||"undefined"==typeof e.MessageChannel)i="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var c=new e.MessageChannel;c.port1.onmessage=n,i=function(){c.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],31:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],32:[function(e,t,n){t.exports=function(e){return!(null==e||!(e._isBuffer||e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)))}},{}],33:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],34:[function(e,t,n){(function(e){e("object"==typeof n?n:this)}).call(this,function(e){var t=Array.prototype.slice,n=Array.prototype.forEach,r=function(e){if("object"!=typeof e)throw e+" is not an object";var i=t.call(arguments,1);return n.call(i,function(t){if(t)for(var n in t)"object"==typeof t[n]&&e[n]?r.call(e,e[n],t[n]):e[n]=t[n]}),e};e.extend=r})},{}],35:[function(e,t,n){function r(e){this.opts=e||{},this.encodings=i}var i=e(36);t.exports=r,r.prototype._encoding=function(e){return"string"==typeof e&&(e=i[e]),e||(e=i.id),e},r.prototype._keyEncoding=function(e,t){return this._encoding(t&&t.keyEncoding||e&&e.keyEncoding||this.opts.keyEncoding)},r.prototype._valueEncoding=function(e,t){return this._encoding(t&&(t.valueEncoding||t.encoding)||e&&(e.valueEncoding||e.encoding)||this.opts.valueEncoding||this.opts.encoding)},r.prototype.encodeKey=function(e,t,n){return this._keyEncoding(t,n).encode(e)},r.prototype.encodeValue=function(e,t,n){return this._valueEncoding(t,n).encode(e)},r.prototype.decodeKey=function(e,t){return this._keyEncoding(t).decode(e)},r.prototype.decodeValue=function(e,t){return this._valueEncoding(t).decode(e)},r.prototype.encodeBatch=function(e,t){var n=this;return e.map(function(e){var r={type:e.type,key:n.encodeKey(e.key,t,e)};return n.keyAsBuffer(t,e)&&(r.keyEncoding="binary"),e.prefix&&(r.prefix=e.prefix),"value"in e&&(r.value=n.encodeValue(e.value,t,e),n.valueAsBuffer(t,e)&&(r.valueEncoding="binary")),r})};var o=["lt","gt","lte","gte","start","end"];r.prototype.encodeLtgt=function(e){var t=this,n={};return Object.keys(e).forEach(function(r){n[r]=o.indexOf(r)>-1?t.encodeKey(e[r],e):e[r]}),n},r.prototype.createStreamDecoder=function(e){var t=this;return e.keys&&e.values?function(n,r){return{key:t.decodeKey(n,e),value:t.decodeValue(r,e)}}:e.keys?function(n){return t.decodeKey(n,e)}:e.values?function(n,r){return t.decodeValue(r,e)}:function(){}},r.prototype.keyAsBuffer=function(e){return this._keyEncoding(e).buffer},r.prototype.valueAsBuffer=function(e){return this._valueEncoding(e).buffer}},{36:36}],36:[function(e,t,n){(function(e){function t(e){return e}function r(t){return void 0===t||null===t||e.isBuffer(t)}n.utf8=n["utf-8"]={encode:function(e){return r(e)?e:String(e)},decode:t,buffer:!1,type:"utf8"},n.json={encode:JSON.stringify,decode:JSON.parse,buffer:!1,type:"json"},n.binary={encode:function(t){return r(t)?t:new e(t)},decode:t,buffer:!0,type:"binary"},n.id={encode:function(e){return e},decode:function(e){return e},buffer:!1,type:"id"};var i=["hex","ascii","base64","ucs2","ucs-2","utf16le","utf-16le"];i.forEach(function(t){n[t]={encode:function(n){return r(n)?n:new e(n,t)},decode:function(e){return e.toString(t)},buffer:!0,type:t}})}).call(this,e(8).Buffer)},{8:8}],37:[function(e,t,n){var r=e(21).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{21:21}],38:[function(e,t,n){function r(e,t){return this instanceof r?(o.call(this,a(t,{objectMode:!0})),this._iterator=e,this._destroyed=!1,this._decoder=null,t&&t.decoder&&(this._decoder=t.decoder),void this.on("end",this._cleanup.bind(this))):new r(e,t)}var i=e(31),o=e(45).Readable,a=e(46),s=e(37).EncodingError;t.exports=r,i(r,o),r.prototype._read=function(){var e=this;this._destroyed||this._iterator.next(function(t,n,r){if(!e._destroyed){if(t)return e.emit("error",t);if(void 0===n&&void 0===r)e.push(null);else{if(!e._decoder)return e.push({key:n,value:r});try{var r=e._decoder(n,r)}catch(t){return e.emit("error",new s(t)),void e.push(null)}e.push(r)}}})},r.prototype.destroy=r.prototype._cleanup=function(){var e=this;this._destroyed||(this._destroyed=!0,this._iterator.end(function(t){return t?e.emit("error",t):void e.emit("close")}))}},{31:31,37:37,45:45,46:46}],39:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],40:[function(e,t,n){(function(n){function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||n.nextTick(this.end.bind(this))}function o(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}t.exports=r;var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},s=e(9);s.inherits=e(31);var u=e(42),c=e(44);s.inherits(r,u),o(a(c.prototype),function(e){r.prototype[e]||(r.prototype[e]=c.prototype[e])})}).call(this,e(55))},{31:31,42:42,44:44,55:55,9:9}],41:[function(e,t,n){function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(43),o=e(9);o.inherits=e(31),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{31:31,43:43,9:9}],42:[function(e,t,n){(function(n){function r(t,n){var r=e(40);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),
+this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(69).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(t){e(40);return this instanceof i?(this._readableState=new r(t,this),this.readable=!0,void B.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(R.isNullOrUndefined(n))t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),i||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e)),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=M)e=M;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:isNaN(e)||R.isNull(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||R.isString(t)||R.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(L("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){L("emit readable"),e.emit("readable"),b(e)}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(L("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;L("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&x.listenerCount(e,"data")&&(t.flowing=!0,b(e))}}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,n.nextTick(function(){y(e,t)}))}function y(e,t){t.resumeScheduled=!1,e.emit("resume"),b(e),t.flowing&&!t.reading&&e.read(0)}function b(e){var t=e._readableState;if(L("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function _(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(39),S=e(8).Buffer;i.ReadableState=r;var x=e(23).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(58),R=e(9);R.inherits=e(31);var A,L=e(7);L=L&&L.debuglog?L.debuglog("stream"):function(){},R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return R.isString(e)&&!n.objectMode&&(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){return A||(A=e(69).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t,this};var M=8388608;i.prototype.read=function(e){L("read",e);var t=this._readableState,n=e;if((!R.isNumber(e)||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return L("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?m(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&m(this),null;var r=t.needReadable;L("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,L("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,L("reading or ended",r)),r&&(L("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?_(e,t):null,R.isNull(i)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&m(this),R.isNull(i)||this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){L("onunpipe"),e===l&&o()}function i(){L("onend"),e.end()}function o(){L("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){L("ondata");var n=e.write(t);!1===n&&(L("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++,l.pause())}function s(t){L("onerror",t),f(),e.removeListener("error",s),0===x.listenerCount(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){L("onfinish"),e.removeListener("close",u),f()}function f(){L("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,L("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?n.nextTick(p):l.once("end",p),e.on("unpipe",r);var v=g(l);return e.on("drain",v),l.on("data",a),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(L("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var r=B.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&this.readable){var i=this._readableState;if(!i.readableListening)if(i.readableListening=!0,i.emittedReadable=!1,i.needReadable=!0,i.reading)i.length&&l(this,i);else{var o=this;n.nextTick(function(){L("readable nexttick read 0"),o.read(0)})}}return r},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(L("resume"),e.flowing=!0,e.reading||(L("resume read 0"),this.read(0)),v(this,e)),this},i.prototype.pause=function(){return L("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(L("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(L("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(L("wrapped data"),t.decoder&&(i=t.decoder.write(i)),i&&(t.objectMode||i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)R.isFunction(e[i])&&R.isUndefined(this[i])&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){L("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=_}).call(this,e(55))},{23:23,31:31,39:39,40:40,55:55,58:58,69:69,7:7,8:8,9:9}],43:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,u.isNullOrUndefined(n)||e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(e,this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("prefinish",function(){u.isFunction(this._flush)?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(40),u=e(9);u.inherits=e(31),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;u.isNull(t.writechunk)||!t.writecb||t.transforming?t.needTransform=!0:(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform))}},{31:31,40:40,9:9}],44:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(t,n){var r=e(40);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1}function o(t){var n=e(40);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void k.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!(E.isBuffer(r)||E.isString(r)||E.isNullOrUndefined(r)||t.objectMode)){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return!e.objectMode&&e.decodeStrings!==!1&&E.isString(t)&&(t=new w(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),E.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing||t.corked?t.buffer.push(new r(n,i,o)):f(e,t,!1,a,n,i,o),s}function f(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){t.pendingcb--,o(i)}):(t.pendingcb--,o(i)),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.corked||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),t.pendingcb--,r(),_(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){if(t.bufferProcessing=!0,e._writev&&t.buffer.length>1){for(var n=[],r=0;r<t.buffer.length;r++)n.push(t.buffer[r].callback);t.pendingcb++,f(e,t,!0,t.length,t.buffer,"",function(e){for(var r=0;r<n.length;r++)t.pendingcb--,n[r](e)}),t.buffer=[]}else{for(var r=0;r<t.buffer.length;r++){var i=t.buffer[r],o=i.chunk,a=i.encoding,s=i.callback,u=t.objectMode?1:o.length;if(f(e,t,!1,u,o,a,s),t.writing){r++;break}}r<t.buffer.length?t.buffer=t.buffer.slice(r):t.buffer.length=0}t.bufferProcessing=!1}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function _(e,t){var n=y(e,t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function m(e,t,r){t.ending=!0,_(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var w=e(8).Buffer;o.WritableState=i;var E=e(9);E.inherits=e(31);var k=e(58);E.inherits(o,k),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return E.isFunction(t)&&(n=t,t=null),E.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),E.isFunction(n)||(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(r.pendingcb++,i=c(this,r,e,t,n)),i},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.buffer.length||v(this,e))},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;E.isFunction(e)?(n=e,e=null,t=null):E.isFunction(t)&&(n=t,t=null),E.isNullOrUndefined(e)||this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||m(this,r,n)}}).call(this,e(55))},{31:31,40:40,55:55,58:58,8:8,9:9}],45:[function(e,t,n){(function(r){n=t.exports=e(42),n.Stream=e(58),n.Readable=n,n.Writable=e(44),n.Duplex=e(40),n.Transform=e(43),n.PassThrough=e(41),r.browser||"disable"!==r.env.READABLE_STREAM||(t.exports=e(58))}).call(this,e(55))},{40:40,41:41,42:42,43:43,44:44,55:55,58:58}],46:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],47:[function(e,t,n){function r(e,t){this._levelup=e,this._codec=t,this.batch=e.db.batch(),this.ops=[],this.length=0}var i=e(49),o=e(37).WriteError,a=i.getOptions,s=i.dispatchError;r.prototype.put=function(e,t,n){n=a(n);var r=this._codec.encodeKey(e,n),i=this._codec.encodeValue(t,n);try{this.batch.put(r,i)}catch(s){throw new o(s)}return this.ops.push({type:"put",key:r,value:i}),this.length++,this},r.prototype.del=function(e,t){t=a(t);var n=this._codec.encodeKey(e,t);try{this.batch.del(n)}catch(r){throw new o(r)}return this.ops.push({type:"del",key:n}),this.length++,this},r.prototype.clear=function(){try{this.batch.clear()}catch(e){throw new o(e)}return this.ops=[],this.length=0,this},r.prototype.write=function(e){var t=this._levelup,n=this.ops;try{this.batch.write(function(r){return r?s(t,new o(r),e):(t.emit("batch",n),void(e&&e()))})}catch(r){throw new o(r)}},t.exports=r},{37:37,49:49}],48:[function(e,t,n){(function(n){function r(e,t){return"function"==typeof e?e:t}function i(e,t,r){if(!(this instanceof i))return new i(e,t,r);var o;if(c.call(this),this.setMaxListeners(1/0),"function"==typeof e?(t="object"==typeof t?t:{},t.db=e,e=null):"object"==typeof e&&"function"==typeof e.db&&(t=e,e=null),"function"==typeof t&&(r=t,t={}),(!t||"function"!=typeof t.db)&&"string"!=typeof e){if(o=new E("Must provide a location for the database"),r)return n.nextTick(function(){r(o)});throw o}t=B(t),this.options=h(R,t),this._codec=new x(this.options),this._status="new",d(this,"location",e,"e"),this.open(r)}function o(e,t,n){return e._isOpening()||e.isOpen()?void 0:(L(e,new b("Database is not open"),n),!0)}function a(e,t,n){L(e,new y(t),n)}function s(e,t,n){L(e,new b(t),n)}function u(e){return function(t,n){A()[e](t,n||function(){})}}var c=e(23).EventEmitter,f=e(94).inherits,l=e(94).deprecate,h=e(50),d=e(56),p=e(12),g=e(38),v=e(37),y=v.WriteError,b=v.ReadError,_=v.NotFoundError,m=v.OpenError,w=v.EncodingError,E=v.InitializationError,k=e(49),S=e(47),x=e(35),B=k.getOptions,R=k.defaultOptions,A=k.getLevelDOWN,L=k.dispatchError;k.isDefined;f(i,c),i.prototype.open=function(e){var t,r,i=this;return this.isOpen()?(e&&n.nextTick(function(){e(null,i)}),this):this._isOpening()?e&&this.once("open",function(){e(null,i)}):(this.emit("opening"),this._status="opening",this.db=new p(this.location),t=this.options.db||A(),r=t(this.location),void r.open(this.options,function(t){return t?L(i,new m(t),e):(i.db.setDb(r),i.db=r,i._status="open",e&&e(null,i),i.emit("open"),i.emit("ready"),void 0)}))},i.prototype.close=function(e){var t=this;if(this.isOpen())this._status="closing",this.db.close(function(){t._status="closed",t.emit("closed"),e&&e.apply(null,arguments)}),this.emit("closing"),this.db=new p(this.location);else{if("closed"==this._status&&e)return n.nextTick(e);"closing"==this._status&&e?this.once("closed",e):this._isOpening()&&this.once("open",function(){t.close(e)})}},i.prototype.isOpen=function(){return"open"==this._status},i.prototype._isOpening=function(){return"opening"==this._status},i.prototype.isClosed=function(){return/^clos/.test(this._status)},i.prototype.get=function(e,t,n){var i,a=this;if(n=r(t,n),!o(this,t,n)){if(null===e||void 0===e||"function"!=typeof n)return s(this,"get() requires key and callback arguments",n);t=k.getOptions(t),i=this._codec.encodeKey(e,t),t.asBuffer=this._codec.valueAsBuffer(t),this.db.get(i,t,function(r,i){if(r)return r=/notfound/i.test(r)||r.notFound?new _("Key not found in database ["+e+"]",r):new b(r),L(a,r,n);if(n){try{i=a._codec.decodeValue(i,t)}catch(o){return n(new w(o))}n(null,i)}})}},i.prototype.put=function(e,t,n,i){var s,u,c=this;return i=r(n,i),null===e||void 0===e?a(this,"put() requires a key argument",i):void(o(this,n,i)||(n=B(n),s=this._codec.encodeKey(e,n),u=this._codec.encodeValue(t,n),this.db.put(s,u,n,function(n){return n?L(c,new y(n),i):(c.emit("put",e,t),void(i&&i()))})))},i.prototype.del=function(e,t,n){var i,s=this;return n=r(t,n),null===e||void 0===e?a(this,"del() requires a key argument",n):void(o(this,t,n)||(t=B(t),i=this._codec.encodeKey(e,t),this.db.del(i,t,function(t){return t?L(s,new y(t),n):(s.emit("del",e),void(n&&n()))})))},i.prototype.batch=function(e,t,n){var i,s=this;return arguments.length?(n=r(t,n),Array.isArray(e)?void(o(this,t,n)||(t=B(t),i=s._codec.encodeBatch(e,t),i=i.map(function(e){return e.type||void 0===e.key||void 0===e.value||(e.type="put"),e}),this.db.batch(i,t,function(t){return t?L(s,new y(t),n):(s.emit("batch",e),void(n&&n()))}))):a(this,"batch() requires an array argument",n)):new S(this,this._codec)},i.prototype.approximateSize=l(function(e,t,n,i){var o,a,u=this;return i=r(n,i),n=B(n),null===e||void 0===e||null===t||void 0===t||"function"!=typeof i?s(this,"approximateSize() requires start, end and callback arguments",i):(o=this._codec.encodeKey(e,n),a=this._codec.encodeKey(t,n),void this.db.approximateSize(o,a,function(e,t){return e?L(u,new m(e),i):void(i&&i(null,t))}))},"db.approximateSize() is deprecated. Use db.db.approximateSize() instead"),i.prototype.readStream=i.prototype.createReadStream=function(e){return e=h({keys:!0,values:!0},this.options,e),e.keyEncoding=e.keyEncoding,e.valueEncoding=e.valueEncoding,e=this._codec.encodeLtgt(e),e.keyAsBuffer=this._codec.keyAsBuffer(e),e.valueAsBuffer=this._codec.valueAsBuffer(e),"number"!=typeof e.limit&&(e.limit=-1),new g(this.db.iterator(e),h(e,{decoder:this._codec.createStreamDecoder(e)}))},i.prototype.keyStream=i.prototype.createKeyStream=function(e){return this.createReadStream(h(e,{keys:!0,values:!1}))},i.prototype.valueStream=i.prototype.createValueStream=function(e){return this.createReadStream(h(e,{keys:!1,values:!0}))},i.prototype.toString=function(){return"LevelUP"},t.exports=i,t.exports.errors=e(37),t.exports.destroy=l(u("destroy"),"levelup.destroy() is deprecated. Use leveldown.destroy() instead"),t.exports.repair=l(u("repair"),"levelup.repair() is deprecated. Use leveldown.repair() instead")}).call(this,e(55))},{12:12,23:23,35:35,37:37,38:38,47:47,49:49,50:50,55:55,56:56,94:94}],49:[function(e,t,n){function r(e){return"string"==typeof e&&(e={valueEncoding:e}),"object"!=typeof e&&(e={}),e}function i(){if(u)return u;var t,n=e(51).devDependencies.leveldown;try{t=e(7).version}catch(r){throw o(r)}if(!e(7).satisfies(t,n))throw new c("Installed version of LevelDOWN ("+t+") does not match required version ("+n+")");try{return u=e(7)}catch(r){throw o(r)}}function o(e){var t="Failed to require LevelDOWN (%s). Try `npm install leveldown` if it's missing";return new c(f(t,e.message))}function a(e,t,n){"function"==typeof n?n(t):e.emit("error",t)}function s(e){return"undefined"!=typeof e}var u,c=(e(50),e(37).LevelUPError),f=e(94).format,l={createIfMissing:!0,errorIfExists:!1,keyEncoding:"utf8",valueEncoding:"utf8",compression:!0};t.exports={defaultOptions:l,getOptions:r,getLevelDOWN:i,dispatchError:a,isDefined:s}},{37:37,50:50,51:51,7:7,94:94}],50:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],51:[function(e,t,n){t.exports={_args:[["levelup@1.3.1","/Users/nolan/workspace/pouchdb"]],_from:"levelup@1.3.1",_id:"levelup@1.3.1",_inCache:!0,_installable:!0,_location:"/levelup",_nodeVersion:"4.2.2",_npmUser:{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},_npmVersion:"3.5.0",_phantomChildren:{},_requested:{name:"levelup",raw:"levelup@1.3.1",rawSpec:"1.3.1",scope:null,spec:"1.3.1",type:"version"},_requiredBy:["/","/pouchdb"],_resolved:"http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",_shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",_shrinkwrap:null,_spec:"levelup@1.3.1",_where:"/Users/nolan/workspace/pouchdb",browser:{leveldown:!1,"leveldown/package":!1,semver:!1},bugs:{url:"https://github.com/level/levelup/issues"},contributors:[{email:"r@va.gg",name:"Rod Vagg",url:"https://github.com/rvagg"},{email:"john@chesl.es",name:"John Chesley",url:"https://github.com/chesles/"},{email:"raynos2@gmail.com",name:"Jake Verbaten",url:"https://github.com/raynos"},{email:"dominic.tarr@gmail.com",name:"Dominic Tarr",url:"https://github.com/dominictarr"},{email:"max@maxogden.com",name:"Max Ogden",url:"https://github.com/maxogden"},{email:"ralphtheninja@riseup.net",name:"Lars-Magnus Skog",url:"https://github.com/ralphtheninja"},{email:"david.bjorklund@gmail.com",name:"David Björklund",url:"https://github.com/kesla"},{email:"julian@juliangruber.com",name:"Julian Gruber",url:"https://github.com/juliangruber"},{email:"paolo@async.ly",name:"Paolo Fragomeni",url:"https://github.com/hij1nx"},{email:"anton.whalley@nearform.com",name:"Anton Whalley",url:"https://github.com/No9"},{email:"matteo.collina@gmail.com",name:"Matteo Collina",url:"https://github.com/mcollina"},{email:"pedro.teixeira@gmail.com",name:"Pedro Teixeira",url:"https://github.com/pgte"},{email:"mail@substack.net",name:"James Halliday",url:"https://github.com/substack"},{email:"jcrugzz@gmail.com",name:"Jarrett Cruger",url:"https://github.com/jcrugzz"}],dependencies:{"deferred-leveldown":"~1.2.1","level-codec":"~6.1.0","level-errors":"~1.0.3","level-iterator-stream":"~1.3.0",prr:"~1.0.1",semver:"~5.1.0",xtend:"~4.0.0"},description:"Fast & simple storage - a Node.js-style LevelDB wrapper",devDependencies:{async:"~1.5.0",bustermove:"~1.0.0",delayed:"~1.0.1",faucet:"~0.0.1",leveldown:"^1.1.0",memdown:"~1.1.0","msgpack-js":"~0.3.0",referee:"~1.2.0",rimraf:"~2.4.3","slow-stream":"0.0.4",tap:"~2.3.1",tape:"~4.2.1"},directories:{},dist:{shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",tarball:"https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"},gitHead:"40bd66872974140c79a74d9411b992ddffa926a4",homepage:"https://github.com/level/levelup",keywords:["leveldb","stream","database","db","store","storage","json"],license:"MIT",main:"lib/levelup.js",maintainers:[{email:"rod@vagg.org",name:"rvagg"},{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},{email:"julian@juliangruber.com",name:"juliangruber"}],name:"levelup",optionalDependencies:{},readme:"ERROR: No README data found!",repository:{type:"git",url:"git+https://github.com/level/levelup.git"},scripts:{test:"tape test/*-test.js | faucet"},version:"1.3.1"}},{}],52:[function(e,t,n){"use strict";function r(){}function i(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=b,this.queue=[],this.outcome=void 0,e!==r&&u(this,e)}function o(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function a(e,t,n){p(function(){var r;try{r=t(n)}catch(i){return g.reject(e,i)}r===e?g.reject(e,new TypeError("Cannot resolve promise with itself")):g.resolve(e,r)})}function s(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}function u(e,t){function n(t){o||(o=!0,g.reject(e,t))}function r(t){o||(o=!0,g.resolve(e,t))}function i(){t(r,n)}var o=!1,a=c(i);"error"===a.status&&n(a.value)}function c(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}function f(e){return e instanceof this?e:g.resolve(new this(r),e)}function l(e){var t=new this(r);return g.reject(t,e)}function h(e){function t(e,t){function r(e){a[t]=e,++s!==i||o||(o=!0,g.resolve(c,a))}n.resolve(e).then(r,function(e){o||(o=!0,g.reject(c,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=new Array(i),s=0,u=-1,c=new this(r);++u<i;)t(e[u],u);return c}function d(e){function t(e){n.resolve(e).then(function(e){o||(o=!0,g.resolve(s,e))},function(e){o||(o=!0,g.reject(s,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=-1,s=new this(r);++a<i;)t(e[a]);return s}var p=e(30),g={},v=["REJECTED"],y=["FULFILLED"],b=["PENDING"];t.exports=n=i,i.prototype["catch"]=function(e){return this.then(null,e)},i.prototype.then=function(e,t){if("function"!=typeof e&&this.state===y||"function"!=typeof t&&this.state===v)return this;var n=new this.constructor(r);if(this.state!==b){var i=this.state===y?e:t;a(n,i,this.outcome)}else this.queue.push(new o(n,e,t));return n},o.prototype.callFulfilled=function(e){g.resolve(this.promise,e)},o.prototype.otherCallFulfilled=function(e){a(this.promise,this.onFulfilled,e)},o.prototype.callRejected=function(e){g.reject(this.promise,e)},o.prototype.otherCallRejected=function(e){a(this.promise,this.onRejected,e)},g.resolve=function(e,t){var n=c(s,t);if("error"===n.status)return g.reject(e,n.value);var r=n.value;if(r)u(e,r);else{e.state=y,e.outcome=t;for(var i=-1,o=e.queue.length;++i<o;)e.queue[i].callFulfilled(t)}return e},g.reject=function(e,t){e.state=v,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},n.resolve=f,n.reject=l,n.all=h,n.race=d},{30:30}],53:[function(e,t,n){"use strict";function r(){this.store={}}function i(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=i,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){for(var t=Object.keys(this.store),n=0,r=t.length;r>n;n++){var i=t[n],o=this.store[i];i=this.unmangle(i),e(o,i)}},i.prototype.add=function(e){return this.store.set(e,!0)},i.prototype.has=function(e){return this.store.has(e)},i.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],54:[function(e,t,n){(function(e){"use strict";function n(t){for(var n=new Array(arguments.length-1),r=0;r<n.length;)n[r++]=arguments[r];e.nextTick(function(){t.apply(null,n)})}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e(55))},{55:55}],55:[function(e,t,n){function r(){f=!1,s.length?c=s.concat(c):l=-1,c.length&&i()}function i(){if(!f){var e=setTimeout(r);f=!0;for(var t=c.length;t;){for(s=c,c=[];++l<t;)s&&s[l].run();l=-1,t=c.length}s=null,f=!1,clearTimeout(e)}}function o(e,t){this.fun=e,this.array=t}function a(){}var s,u=t.exports={},c=[],f=!1,l=-1;u.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new o(e,t)),1!==c.length||f||setTimeout(i,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},u.title="browser",u.browser=!0,u.env={},u.argv=[],u.version="",u.versions={},u.on=a,u.addListener=a,u.once=a,u.off=a,u.removeListener=a,u.removeAllListeners=a,u.emit=a,u.binding=function(e){throw new Error("process.binding is not supported")},u.cwd=function(){return"/"},u.chdir=function(e){throw new Error("process.chdir is not supported")},u.umask=function(){return 0}},{}],56:[function(e,t,n){arguments[4][22][0].apply(n,arguments)},{22:22}],57:[function(e,t,n){!function(e){if("object"==typeof n)t.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;try{r=window}catch(i){r=self}r.SparkMD5=e()}}(function(e){"use strict";function t(e,t,n,r,i,o){return t=_(_(t,e),_(r,o)),_(t<<i|t>>>32-i,n)}function n(e,n,r,i,o,a,s){return t(n&r|~n&i,e,n,o,a,s)}function r(e,n,r,i,o,a,s){return t(n&i|r&~i,e,n,o,a,s)}function i(e,n,r,i,o,a,s){return t(n^r^i,e,n,o,a,s)}function o(e,n,r,i,o,a,s){return t(r^(n|~i),e,n,o,a,s)}function a(e,t){var a=e[0],s=e[1],u=e[2],c=e[3];a=n(a,s,u,c,t[0],7,-680876936),c=n(c,a,s,u,t[1],12,-389564586),u=n(u,c,a,s,t[2],17,606105819),s=n(s,u,c,a,t[3],22,-1044525330),a=n(a,s,u,c,t[4],7,-176418897),c=n(c,a,s,u,t[5],12,1200080426),u=n(u,c,a,s,t[6],17,-1473231341),s=n(s,u,c,a,t[7],22,-45705983),a=n(a,s,u,c,t[8],7,1770035416),c=n(c,a,s,u,t[9],12,-1958414417),u=n(u,c,a,s,t[10],17,-42063),s=n(s,u,c,a,t[11],22,-1990404162),a=n(a,s,u,c,t[12],7,1804603682),c=n(c,a,s,u,t[13],12,-40341101),u=n(u,c,a,s,t[14],17,-1502002290),s=n(s,u,c,a,t[15],22,1236535329),a=r(a,s,u,c,t[1],5,-165796510),c=r(c,a,s,u,t[6],9,-1069501632),u=r(u,c,a,s,t[11],14,643717713),s=r(s,u,c,a,t[0],20,-373897302),a=r(a,s,u,c,t[5],5,-701558691),c=r(c,a,s,u,t[10],9,38016083),u=r(u,c,a,s,t[15],14,-660478335),s=r(s,u,c,a,t[4],20,-405537848),a=r(a,s,u,c,t[9],5,568446438),c=r(c,a,s,u,t[14],9,-1019803690),u=r(u,c,a,s,t[3],14,-187363961),s=r(s,u,c,a,t[8],20,1163531501),a=r(a,s,u,c,t[13],5,-1444681467),c=r(c,a,s,u,t[2],9,-51403784),u=r(u,c,a,s,t[7],14,1735328473),s=r(s,u,c,a,t[12],20,-1926607734),a=i(a,s,u,c,t[5],4,-378558),c=i(c,a,s,u,t[8],11,-2022574463),u=i(u,c,a,s,t[11],16,1839030562),s=i(s,u,c,a,t[14],23,-35309556),a=i(a,s,u,c,t[1],4,-1530992060),c=i(c,a,s,u,t[4],11,1272893353),u=i(u,c,a,s,t[7],16,-155497632),s=i(s,u,c,a,t[10],23,-1094730640),a=i(a,s,u,c,t[13],4,681279174),c=i(c,a,s,u,t[0],11,-358537222),u=i(u,c,a,s,t[3],16,-722521979),s=i(s,u,c,a,t[6],23,76029189),
+a=i(a,s,u,c,t[9],4,-640364487),c=i(c,a,s,u,t[12],11,-421815835),u=i(u,c,a,s,t[15],16,530742520),s=i(s,u,c,a,t[2],23,-995338651),a=o(a,s,u,c,t[0],6,-198630844),c=o(c,a,s,u,t[7],10,1126891415),u=o(u,c,a,s,t[14],15,-1416354905),s=o(s,u,c,a,t[5],21,-57434055),a=o(a,s,u,c,t[12],6,1700485571),c=o(c,a,s,u,t[3],10,-1894986606),u=o(u,c,a,s,t[10],15,-1051523),s=o(s,u,c,a,t[1],21,-2054922799),a=o(a,s,u,c,t[8],6,1873313359),c=o(c,a,s,u,t[15],10,-30611744),u=o(u,c,a,s,t[6],15,-1560198380),s=o(s,u,c,a,t[13],21,1309151649),a=o(a,s,u,c,t[4],6,-145523070),c=o(c,a,s,u,t[11],10,-1120210379),u=o(u,c,a,s,t[2],15,718787259),s=o(s,u,c,a,t[9],21,-343485551),e[0]=_(a,e[0]),e[1]=_(s,e[1]),e[2]=_(u,e[2]),e[3]=_(c,e[3])}function s(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function u(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function c(e){var t,n,r,i,o,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,s(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),u=parseInt(i[1],16)||0,r[14]=o,r[15]=u,a(f,r),f}function f(e){var t,n,r,i,o,s,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),s=parseInt(i[1],16)||0,r[14]=o,r[15]=s,a(f,r),f}function l(e){var t,n="";for(t=0;4>t;t+=1)n+=m[e>>8*t+4&15]+m[e>>8*t&15];return n}function h(e){var t;for(t=0;t<e.length;t+=1)e[t]=l(e[t]);return e.join("")}function d(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function p(e,t){var n,r=e.length,i=new ArrayBuffer(r),o=new Uint8Array(i);for(n=0;r>n;n+=1)o[n]=e.charCodeAt(n);return t?o:i}function g(e){return String.fromCharCode.apply(null,new Uint8Array(e))}function v(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}function y(e){var t,n=[],r=e.length;for(t=0;r-1>t;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function b(){this.reset()}var _=function(e,t){return e+t&4294967295},m=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==h(c("hello"))&&(_=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function t(e,t){return e=0|e||0,0>e?Math.max(e+t,0):Math.min(e,t)}ArrayBuffer.prototype.slice=function(n,r){var i,o,a,s,u=this.byteLength,c=t(n,u),f=u;return r!==e&&(f=t(r,u)),c>f?new ArrayBuffer(0):(i=f-c,o=new ArrayBuffer(i),a=new Uint8Array(o),s=new Uint8Array(this,c,i),a.set(s),o)}}(),b.prototype.append=function(e){return this.appendBinary(d(e)),this},b.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._hash,s(this._buff.substring(t-64,t)));return this._buff=this._buff.substring(t-64),this},b.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},b.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},b.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},b.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},b.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},b.prototype._finish=function(e,t){var n,r,i,o=t;if(e[o>>2]|=128<<(o%4<<3),o>55)for(a(this._hash,e),o=0;16>o;o+=1)e[o]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),i=parseInt(n[1],16)||0,e[14]=r,e[15]=i,a(this._hash,e)},b.hash=function(e,t){return b.hashBinary(d(e),t)},b.hashBinary=function(e,t){var n=c(e),r=h(n);return t?y(r):r},b.ArrayBuffer=function(){this.reset()},b.ArrayBuffer.prototype.append=function(e){var t,n=v(this._buff.buffer,e,!0),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._hash,u(n.subarray(t-64,t)));return this._buff=r>t-64?new Uint8Array(n.buffer.slice(t-64)):new Uint8Array(0),this},b.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r[t]<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},b.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},b.ArrayBuffer.prototype.getState=function(){var e=b.prototype.getState.call(this);return e.buff=g(e.buff),e},b.ArrayBuffer.prototype.setState=function(e){return e.buff=p(e.buff,!0),b.prototype.setState.call(this,e)},b.ArrayBuffer.prototype.destroy=b.prototype.destroy,b.ArrayBuffer.prototype._finish=b.prototype._finish,b.ArrayBuffer.hash=function(e,t){var n=f(new Uint8Array(e)),r=h(n);return t?y(r):r},b})},{}],58:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e(23).EventEmitter,o=e(31);o(r,i),r.Readable=e(66),r.Writable=e(68),r.Duplex=e(59),r.Transform=e(67),r.PassThrough=e(65),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&c.pause&&c.pause()}function r(){c.readable&&c.resume&&c.resume()}function o(){f||(f=!0,e.end())}function a(){f||(f=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(u(),0===i.listenerCount(this,"error"))throw e}function u(){c.removeListener("data",n),e.removeListener("drain",r),c.removeListener("end",o),c.removeListener("close",a),c.removeListener("error",s),e.removeListener("error",s),c.removeListener("end",u),c.removeListener("close",u),e.removeListener("close",u)}var c=this;c.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(c.on("end",o),c.on("close",a));var f=!1;return c.on("error",s),e.on("error",s),c.on("end",u),c.on("close",u),e.on("close",u),e.emit("pipe",c),e}},{23:23,31:31,59:59,65:65,66:66,67:67,68:68}],59:[function(e,t,n){t.exports=e(60)},{60:60}],60:[function(e,t,n){"use strict";function r(e){return this instanceof r?(c.call(this,e),f.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(o,this)}function o(e){e.end()}var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e(54),u=e(9);u.inherits=e(31);var c=e(62),f=e(64);u.inherits(r,c);for(var l=a(f.prototype),h=0;h<l.length;h++){var d=l[h];r.prototype[d]||(r.prototype[d]=f.prototype[d])}},{31:31,54:54,62:62,64:64,9:9}],61:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(63),o=e(9);o.inherits=e(31),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{31:31,63:63,9:9}],62:[function(e,t,n){(function(n){"use strict";function r(t,n){C=C||e(60),t=t||{},this.objectMode=!!t.objectMode,n instanceof C&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(T||(T=e(69).StringDecoder),this.decoder=new T(t.encoding),this.encoding=t.encoding)}function i(t){return C=C||e(60),this instanceof i?(this._readableState=new r(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void A.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n)t.reading=!1,f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e))),d(e,t)}else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){return e>=I?e=I:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(O("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?x(h,e):h(e))}function h(e){O("emit readable"),e.emit("readable"),_(e)}function d(e,t){t.readingMore||(t.readingMore=!0,x(p,e,t))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(O("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;O("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&L(e,"data")&&(t.flowing=!0,_(e))}}function v(e){O("readable nexttick read 0"),e.read(0)}function y(e,t){t.resumeScheduled||(t.resumeScheduled=!0,x(b,e,t))}function b(e,t){t.reading||(O("resume read 0"),e.read(0)),t.resumeScheduled=!1,e.emit("resume"),_(e),t.flowing&&!t.reading&&e.read(0)}function _(e){var t=e._readableState;if(O("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function m(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):1===r.length?r[0]:R.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new R(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function w(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,x(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function k(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function S(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var x=e(54),B=e(33),R=e(8).Buffer;i.ReadableState=r;var A,L=(e(23),function(e,t){return e.listeners(t).length});!function(){try{A=e("stream")}catch(t){}finally{A||(A=e(23).EventEmitter)}}();var R=e(8).Buffer,M=e(9);M.inherits=e(31);var j=e(7),O=void 0;O=j&&j.debuglog?j.debuglog("stream"):function(){};var T;M.inherits(i,A);var C,C;i.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new R(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.isPaused=function(){return this._readableState.flowing===!1},i.prototype.setEncoding=function(t){return T||(T=e(69).StringDecoder),this._readableState.decoder=new T(t),this._readableState.encoding=t,this};var I=8388608;i.prototype.read=function(e){O("read",e);var t=this._readableState,n=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return O("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?w(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&w(this),null;var r=t.needReadable;O("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,O("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,O("reading or ended",r)),r&&(O("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?m(e,t):null,null===i&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&w(this),null!==i&&this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){O("onunpipe"),e===l&&o()}function i(){O("onend"),e.end()}function o(){O("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),y=!0,!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){O("ondata");var n=e.write(t);!1===n&&(1!==h.pipesCount||h.pipes[0]!==e||1!==l.listenerCount("data")||y||(O("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++),l.pause())}function s(t){O("onerror",t),f(),e.removeListener("error",s),0===L(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){O("onfinish"),e.removeListener("close",u),f()}function f(){O("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,O("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?x(p):l.once("end",p),e.on("unpipe",r);var v=g(l);e.on("drain",v);var y=!1;return l.on("data",a),e._events&&e._events.error?B(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(O("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var o=S(t.pipes,e);return-1===o?this:(t.pipes.splice(o,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=A.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&!this._readableState.endEmitted){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):x(v,this))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(O("resume"),e.flowing=!0,y(this,e)),this},i.prototype.pause=function(){return O("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(O("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(O("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(O("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return k(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){O("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=m}).call(this,e(55))},{23:23,31:31,33:33,54:54,55:55,60:60,69:69,7:7,8:8,9:9}],63:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(60),u=e(9);u.inherits=e(31),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{31:31,60:60,9:9}],64:[function(e,t,n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){L=L||e(60),t=t||{},this.objectMode=!!t.objectMode,n instanceof L&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return L=L||e(60),this instanceof a||this instanceof L?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=b(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function b(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=b(t);return n&&(0===t.pendingcb?(_(e,t),t.finished=!0,e.emit("finish")):_(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(54),S=k,x=e(8).Buffer;a.WritableState=o;var B=e(9);B.inherits=e(31);var R,A={deprecate:e(92)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(23).EventEmitter)}}();var x=e(8).Buffer;B.inherits(a,R);var L;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var L;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}},{23:23,31:31,54:54,60:60,8:8,9:9,92:92}],65:[function(e,t,n){t.exports=e(61)},{61:61}],66:[function(e,t,n){var r=function(){try{return e("stream")}catch(t){}}();n=t.exports=e(62),n.Stream=r||n,n.Readable=n,n.Writable=e(64),n.Duplex=e(60),n.Transform=e(63),n.PassThrough=e(61)},{58:58,60:60,61:61,62:62,63:63,64:64}],67:[function(e,t,n){t.exports=e(63)},{63:63}],68:[function(e,t,n){t.exports=e(64)},{64:64}],69:[function(e,t,n){function r(e){if(e&&!u(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function o(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function a(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e(8).Buffer,u=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},c=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=o;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=a;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};c.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&56319>=r)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&56319>=r){var o=this.surrogateSize;return this.charLength+=o,this.charReceived+=o,this.charBuffer.copy(this.charBuffer,o,0,o),e.copy(this.charBuffer,0,0,o),t.substring(0,i)}return t},c.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(2>=t&&n>>4==14){this.charLength=3;break}if(3>=t&&n>>3==30){this.charLength=4;break}}this.charReceived=t},c.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{8:8}],70:[function(e,t,n){t.exports={encode:function(e){return"ÿ"+e[0]+"ÿ"+e[1]},decode:function(e){var t=e.toString(),n=t.indexOf("ÿ",1);return[t.substring(1,n),t.substring(n+1)]},lowerBound:"\x00",upperBound:"ÿ"}},{}],71:[function(e,t,n){var r=e(21).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{21:21}],72:[function(e,t,n){var r=e(73),i=e(75),o=e(35),a=new o,s=e(74),u=e(70);t.exports=function(e){return i(r(e,u,a),[],s,e.options)}},{35:35,70:70,73:73,74:74,75:75}],73:[function(e,t,n){function r(e){return"function"==typeof e}function i(e){return null==e?e:r(e.prefix)?e.prefix():e}function o(e){var t={};for(var n in e)t[n]=e[n];return t}var a=e(77);t.exports=function(e,t,n,s){function u(e,r,i,o){return t.encode([e,n.encodeKey(r,i,o)])}function c(e,t){return t&&t.options&&(e.keyEncoding=e.keyEncoding||t.options.keyEncoding,e.valueEncoding=e.valueEncoding||t.options.valueEncoding),e}function f(){for(h=!0;l.length;)l.shift()()}var l=[],h=!1;return r(e.isOpen)&&e.isOpen()?h=!0:e.open(f),{apply:function(t,r,o){for(var a=0;a<t.length;a++){var s=t[a];c(s,s.prefix),s.prefix=i(s.prefix)}if(r=r||{},"object"!=typeof r)throw new Error("opts must be object, was:"+r);"function"==typeof r&&(o=r,r={}),t.length?(e.db||e).batch(t.map(function(e){return{key:u(e.prefix,e.key,r,e),value:"del"!==e.type?n.encodeValue(e.value,r,e):void 0,type:e.type||(void 0===e.value?"del":"put")}}),r,function(e){return e?o(e):void o()}):o()},get:function(t,r,i,o){return i.asBuffer=n.valueAsBuffer(i),(e.db||e).get(u(r,t,i),i,function(e,t){e?o(e):o(null,n.decodeValue(t,i))})},createDecoder:function(e){return function(r,i){return{key:n.decodeKey(t.decode(r)[1],e),value:n.decodeValue(i,e)}}},isOpen:function(){return e.db&&r(e.db.isOpen)?e.db.isOpen():e.isOpen()},isClosed:function(){return e.db&&r(e.db.isClosed)?e.db.isClosed():e.isClosed()},close:function(t){return e.close(t)},iterator:function(r,i){function s(e){return u(d,e,f,{})}function c(e){return{next:function(t){return e.next(t)},end:function(t){e.end(t)}}}var f=o(r||{}),d=r.prefix||[];return a.toLtgt(r,f,s,t.lowerBound,t.upperBound),f.prefix=null,f.keyAsBuffer=f.valueAsBuffer=!1,"number"!=typeof f.limit&&(f.limit=-1),f.keyAsBuffer=t.buffer,f.valueAsBuffer=n.valueAsBuffer(f),h?c((e.db||e).iterator(f)):void l.push(function(){i(null,c((e.db||e).iterator(f)))})}}}},{77:77}],74:[function(e,t,n){function r(e,t){return this instanceof r?(i.call(this,{objectMode:!0,highWaterMark:e.highWaterMark}),this._waiting=!1,this._options=e,void(this._makeData=t)):new r(e,t)}var i=e(83).Readable,o=e(31),a=e(71).EncodingError;o(r,i),r.prototype.setIterator=function(e){return this._iterator=e,this._destroyed?e.end(function(){}):this._waiting?(this._waiting=!1,this._read()):this},r.prototype._read=function(){var e=this;if(!e._destroyed)return e._iterator?void e._iterator.next(function(t,n,r){if(t||void 0===n&&void 0===r)return t||e._destroyed||e.push(null),e._cleanup(t);try{r=e._makeData(n,r)}catch(i){return e._cleanup(new a(i))}e._destroyed||e.push(r)}):this._waiting=!0},r.prototype._cleanup=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;e&&t.emit("error",e),t._iterator?t._iterator.end(function(){t._iterator=null,t.emit("close")}):t.emit("close")}},r.prototype.destroy=function(){this._cleanup()},r.prototype.toString=function(){return"LevelUP.ReadStream"},t.exports=r},{31:31,71:71,83:83}],75:[function(e,t,n){(function(n){var r=e(23).EventEmitter,i=e(71),o="6.5.4",a=t.exports=function(e,t,s,u){function c(e){e&&l.emit("error",e)}function f(e){var t={};if(u)for(var n in u)void 0!=u[n]&&(t[n]=u[n]);if(e)for(var n in e)void 0!=e[n]&&(t[n]=e[n]);return t}var l=new r;return l.sublevels={},l.options=u,l.version=o,l.methods={},t=t||[],l.put=function(n,r,i,o){"function"==typeof i&&(o=i,i={}),o||(o=c),e.apply([{key:n,value:r,prefix:t.slice(),type:"put"}],f(i),function(e){return e||(l.emit("put",n,r),o(null)),e?o(e):void 0})},l.prefix=function(){return t.slice()},l.del=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),e.apply([{key:n,prefix:t.slice(),type:"del"}],f(r),function(e){return e||(l.emit("del",n),i(null)),e?i(e):void 0})},l.batch=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),n=n.map(function(e){return{key:e.key,value:e.value,prefix:e.prefix||t,keyEncoding:e.keyEncoding,valueEncoding:e.valueEncoding,type:e.type}}),e.apply(n,f(r),function(e){return e||(l.emit("batch",n),i(null)),e?i(e):void 0})},l.get=function(n,r,o){"function"==typeof r&&(o=r,r={}),e.get(n,t,f(r),function(e,t){e?o(new i.NotFoundError("Key not found in database",e)):o(null,t)})},l.clone=function(n){return a(e,t,s,f(n))},l.sublevel=function(n,r){return l.sublevels[n]=l.sublevels[n]||a(e,t.concat(n),s,f(r))},l.readStream=l.createReadStream=function(n){n=f(n),n.prefix=t;var r,i=e.iterator(n,function(e,t){r.setIterator(t)});return r=s(n,e.createDecoder(n)),
+i&&r.setIterator(i),r},l.valueStream=l.createValueStream=function(e){return e=e||{},e.values=!0,e.keys=!1,l.createReadStream(e)},l.keyStream=l.createKeyStream=function(e){return e=e||{},e.values=!1,e.keys=!0,l.createReadStream(e)},l.close=function(r){r=r||function(){},t.length?n.nextTick(r):e.close(r)},l.isOpen=e.isOpen,l.isClosed=e.isClosed,l}}).call(this,e(55))},{23:23,55:55,71:71}],76:[function(e,t,n){arguments[4][39][0].apply(n,arguments)},{39:39}],77:[function(e,t,n){(function(e){function t(e,t){return Object.hasOwnProperty.call(e,t)}function r(e){return void 0!==e&&""!==e}function t(e,t){return Object.hasOwnProperty.call(e,t)}function i(e,t){return Object.hasOwnProperty.call(e,t)&&t}function o(e){return e}n.compare=function(t,n){if(e.isBuffer(t)){for(var r=Math.min(t.length,n.length),i=0;r>i;i++){var o=t[i]-n[i];if(o)return o}return t.length-n.length}return n>t?-1:t>n?1:0};var a=n.lowerBoundKey=function(e){return i(e,"gt")||i(e,"gte")||i(e,"min")||(e.reverse?i(e,"end"):i(e,"start"))||void 0},s=n.lowerBound=function(e){var t=a(e);return t&&e[t]};n.lowerBoundInclusive=function(e){return!t(e,"gt")},n.upperBoundInclusive=function(e){return!t(e,"lt")&&e.minEx};var u=n.lowerBoundExclusive=function(e){return!(!t(e,"gt")&&!e.minEx)},c=n.upperBoundExclusive=function(e){return!!t(e,"lt")},f=n.upperBoundKey=function(e){return i(e,"lt")||i(e,"lte")||i(e,"max")||(e.reverse?i(e,"start"):i(e,"end"))||void 0},l=n.upperBound=function(e){var t=f(e);return t&&e[t]};n.toLtgt=function(e,r,i,a,s){r=r||{},i=i||o;var u=arguments.length>3,c=n.lowerBoundKey(e),f=n.upperBoundKey(e);return c?"gt"===c?r.gt=i(e.gt,!1):r.gte=i(e[c],!1):u&&(r.gte=i(a,!1)),f?"lt"===f?r.lt=i(e.lt,!0):r.lte=i(e[f],!0):u&&(r.lte=i(s,!0)),null!=e.reverse&&(r.reverse=!!e.reverse),t(r,"max")&&delete r.max,t(r,"min")&&delete r.min,t(r,"start")&&delete r.start,t(r,"end")&&delete r.end,r},n.contains=function(e,t,i){i=i||n.compare;var o=s(e);if(r(o)){var a=i(t,o);if(0>a||0===a&&u(e))return!1}var f=l(e);if(r(f)){var a=i(t,f);if(a>0||0===a&&c(e))return!1}return!0},n.filter=function(e,t){return function(r){return n.contains(e,r,t)}}}).call(this,{isBuffer:e(32)})},{32:32}],78:[function(e,t,n){arguments[4][40][0].apply(n,arguments)},{31:31,40:40,55:55,80:80,82:82,9:9}],79:[function(e,t,n){arguments[4][41][0].apply(n,arguments)},{31:31,41:41,81:81,9:9}],80:[function(e,t,n){(function(n){function r(t,n){t=t||{};var r=t.highWaterMark;this.highWaterMark=r||0===r?r:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(69).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(e){return this instanceof i?(this._readableState=new r(e,this),this.readable=!0,void B.call(this)):new i(e)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n||void 0===n)t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&l(e),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=L)e=L;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return S.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?l(e):m(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){e.emit("readable")}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&v(e)}}function v(e){function t(e,t,i){var o=e.write(n);!1===o&&r.awaitDrain++}var n,r=e._readableState;for(r.awaitDrain=0;r.pipesCount&&null!==(n=e.read());)if(1===r.pipesCount?t(r.pipes,0,null):w(r.pipes,t),e.emit("data",n),r.awaitDrain>0)return;return 0===r.pipesCount?(r.flowing=!1,void(x.listenerCount(e,"data")>0&&b(e))):void(r.ranOut=!0)}function y(){this._readableState.ranOut&&(this._readableState.ranOut=!1,v(this))}function b(e,t){var r=e._readableState;if(r.flowing)throw new Error("Cannot switch to old mode now.");var i=t||!1,o=!1;e.readable=!0,e.pipe=B.prototype.pipe,e.on=e.addListener=B.prototype.on,e.on("readable",function(){o=!0;for(var t;!i&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)}),e.pause=function(){i=!0,this.emit("pause")},e.resume=function(){i=!1,o?n.nextTick(function(){e.emit("readable")}):this.read(0),this.emit("resume")},e.emit("readable")}function _(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(76),S=e(8).Buffer;i.ReadableState=r;var x=e(23).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(58),R=e(9);R.inherits=e(31);var A;R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return"string"!=typeof e||n.objectMode||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){A||(A=e(69).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t};var L=8388608;i.prototype.read=function(e){var t=this._readableState;t.calledRead=!0;var n,r=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return l(this),null;if(e=u(e,t),0===e&&t.ended)return n=null,t.length>0&&t.decoder&&(n=_(e,t),t.length-=n.length),0===t.length&&m(this),n;var i=t.needReadable;return t.length-e<=t.highWaterMark&&(i=!0),(t.ended||t.reading)&&(i=!1),i&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),i&&!t.reading&&(e=u(r,t)),n=e>0?_(e,t):null,null===n&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&m(this),n},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){e===f&&o()}function i(){e.end()}function o(){e.removeListener("close",s),e.removeListener("finish",u),e.removeListener("drain",p),e.removeListener("error",a),e.removeListener("unpipe",r),f.removeListener("end",i),f.removeListener("end",o),e._writableState&&!e._writableState.needDrain||p()}function a(t){c(),e.removeListener("error",a),0===x.listenerCount(e,"error")&&e.emit("error",t)}function s(){e.removeListener("finish",u),c()}function u(){e.removeListener("close",s),c()}function c(){f.unpipe(e)}var f=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=e;break;case 1:l.pipes=[l.pipes,e];break;default:l.pipes.push(e)}l.pipesCount+=1;var h=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,d=h?i:o;l.endEmitted?n.nextTick(d):f.once("end",d),e.on("unpipe",r);var p=g(f);return e.on("drain",p),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(a):e._events.error=[a,e._events.error]:e.on("error",a),e.once("close",s),e.once("finish",u),e.emit("pipe",f),l.flowing||(this.on("readable",y),l.flowing=!0,n.nextTick(function(){v(f)})),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=B.prototype.on.call(this,e,t);if("data"!==e||this._readableState.flowing||b(this),"readable"===e&&this.readable){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):this.read(0))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){b(this),this.read(0),this.emit("resume")},i.prototype.pause=function(){b(this,!0),this.emit("pause")},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)"function"==typeof e[i]&&"undefined"==typeof this[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){n&&(n=!1,e.resume())},r},i._fromList=_}).call(this,e(55))},{23:23,31:31,55:55,58:58,69:69,76:76,8:8,9:9}],81:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e);var t=(this._transformState=new r(e,this),this);this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("finish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=(e._readableState,e._transformState);if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(78),u=e(9);u.inherits=e(31),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{31:31,78:78,9:9}],82:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(e,t){e=e||{};var n=e.highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var r=e.decodeStrings===!1;this.decodeStrings=!r,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(t,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.errorEmitted=!1}function o(t){var n=e(78);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void E.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!m.isBuffer(r)&&"string"!=typeof r&&null!==r&&void 0!==r&&!t.objectMode){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new m(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),m.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing?t.buffer.push(new r(n,i,o)):f(e,t,a,n,i,o),s}function f(e,t,n,r,i,o){t.writelen=n,t.writecb=o,t.writing=!0,t.sync=!0,e._write(r,i,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){o(i)}):o(i),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),r(),n&&b(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){t.bufferProcessing=!0;for(var n=0;n<t.buffer.length;n++){var r=t.buffer[n],i=r.chunk,o=r.encoding,a=r.callback,s=t.objectMode?1:i.length;if(f(e,t,s,i,o,a),t.writing){n++;break}}t.bufferProcessing=!1,n<t.buffer.length?t.buffer=t.buffer.slice(n):t.buffer.length=0}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function b(e,t){var n=y(e,t);return n&&(t.finished=!0,e.emit("finish")),n}function _(e,t,r){t.ending=!0,b(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var m=e(8).Buffer;o.WritableState=i;var w=e(9);w.inherits=e(31);var E=e(58);w.inherits(o,E),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return"function"==typeof t&&(n=t,t=null),m.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(i=c(this,r,e,t,n)),i},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),"undefined"!=typeof e&&null!==e&&this.write(e,t),r.ending||r.finished||_(this,r,n)}}).call(this,e(55))},{31:31,55:55,58:58,78:78,8:8,9:9}],83:[function(e,t,n){var r=e(58);n=t.exports=e(80),n.Stream=r,n.Readable=n,n.Writable=e(82),n.Duplex=e(78),n.Transform=e(81),n.PassThrough=e(79)},{58:58,78:78,79:79,80:80,81:81,82:82}],84:[function(e,t,n){arguments[4][60][0].apply(n,arguments)},{31:31,54:54,60:60,85:85,87:87,9:9}],85:[function(e,t,n){arguments[4][62][0].apply(n,arguments)},{23:23,31:31,33:33,54:54,55:55,62:62,69:69,7:7,8:8,84:84,9:9}],86:[function(e,t,n){arguments[4][63][0].apply(n,arguments)},{31:31,63:63,84:84,9:9}],87:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){L=L||e(84),t=t||{},this.objectMode=!!t.objectMode,n instanceof L&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return L=L||e(84),this instanceof a||this instanceof L?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=b(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function b(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=b(t);return n&&(0===t.pendingcb?(_(e,t),t.finished=!0,e.emit("finish")):_(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(54),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:k,x=e(8).Buffer;a.WritableState=o;var B=e(9);B.inherits=e(31);var R,A={deprecate:e(92)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(23).EventEmitter)}}();var x=e(8).Buffer;B.inherits(a,R);var L;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var L;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}}).call(this,e(55))},{23:23,31:31,54:54,55:55,8:8,84:84,9:9,92:92}],88:[function(e,t,n){arguments[4][67][0].apply(n,arguments)},{67:67,86:86}],89:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],90:[function(e,t,n){(function(n){function r(e){a.call(this,e),this._destroyed=!1}function i(e,t,n){n(null,e)}function o(e){return function(t,n,r){return"function"==typeof t&&(r=n,n=t,t={}),"function"!=typeof n&&(n=i),"function"!=typeof r&&(r=null),e(t,n,r)}}var a=e(88),s=e(94).inherits,u=e(89);s(r,a),r.prototype.destroy=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;n.nextTick(function(){e&&t.emit("error",e),t.emit("close")})}},t.exports=o(function(e,t,n){var i=new r(e);return i._transform=t,n&&(i._flush=n),i}),t.exports.ctor=o(function(e,t,n){function i(t){return this instanceof i?(this.options=u(e,t),void r.call(this,this.options)):new i(t)}return s(i,r),i.prototype._transform=t,n&&(i.prototype._flush=n),i}),t.exports.obj=o(function(e,t,n){var i=new r(u({objectMode:!0,highWaterMark:16},e));return i._transform=t,n&&(i._flush=n),i})}).call(this,e(55))},{55:55,88:88,89:89,94:94}],91:[function(e,t,n){"use strict";function r(){this.length=0}r.prototype.push=function(e){var t={item:e};this.last?this.last=this.last.next=t:this.last=this.first=t,this.length++},r.prototype.shift=function(){var e=this.first;return e?(this.first=e.next,--this.length||(this.last=void 0),e.item):void 0},r.prototype.slice=function(e,t){e="undefined"==typeof e?0:e,t="undefined"==typeof t?1/0:t;for(var n=[],r=0,i=this.first;i&&!(--t<0);i=i.next)++r>e&&n.push(i.item);return n},t.exports=r},{}],92:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null==r?!1:"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],93:[function(e,t,n){t.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},{}],94:[function(e,t,n){(function(t,r){function i(e,t){var r={seen:[],stylize:a};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),g(t)?r.showHidden=t:t&&n._extend(r,t),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,e,r.depth)}function o(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function u(e,t,r){if(e.customInspect&&t&&B(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return _(i)||(i=u(e,i,r)),i}var o=c(e,t);if(o)return o;var a=Object.keys(t),g=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(t)),x(t)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(t);if(0===a.length){if(B(t)){var v=t.name?": "+t.name:"";return e.stylize("[Function"+v+"]","special")}if(E(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(S(t))return e.stylize(Date.prototype.toString.call(t),"date");if(x(t))return f(t)}var y="",b=!1,m=["{","}"];if(p(t)&&(b=!0,m=["[","]"]),B(t)){var w=t.name?": "+t.name:"";y=" [Function"+w+"]"}if(E(t)&&(y=" "+RegExp.prototype.toString.call(t)),S(t)&&(y=" "+Date.prototype.toUTCString.call(t)),x(t)&&(y=" "+f(t)),0===a.length&&(!b||0==t.length))return m[0]+y+m[1];if(0>r)return E(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var k;return k=b?l(e,t,r,g,a):a.map(function(n){return h(e,t,r,g,n,b)}),e.seen.pop(),d(k,y,m)}function c(e,t){if(w(t))return e.stylize("undefined","undefined");if(_(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return b(t)?e.stylize(""+t,"number"):g(t)?e.stylize(""+t,"boolean"):v(t)?e.stylize("null","null"):void 0}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function l(e,t,n,r,i){for(var o=[],a=0,s=t.length;s>a;++a)j(t,String(a))?o.push(h(e,t,n,r,String(a),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(h(e,t,n,r,i,!0))}),o}function h(e,t,n,r,i,o){var a,s,c;if(c=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},c.get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),j(r,i)||(a="["+i+"]"),s||(e.seen.indexOf(c.value)<0?(s=v(n)?u(e,c.value,null):u(e,c.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return"  "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return"   "+e}).join("\n"))):s=e.stylize("[Circular]","special")),w(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function d(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n  ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function p(e){return Array.isArray(e)}function g(e){return"boolean"==typeof e}function v(e){return null===e}function y(e){return null==e}function b(e){return"number"==typeof e}function _(e){return"string"==typeof e}function m(e){return"symbol"==typeof e}function w(e){return void 0===e}function E(e){return k(e)&&"[object RegExp]"===A(e)}function k(e){return"object"==typeof e&&null!==e}function S(e){return k(e)&&"[object Date]"===A(e)}function x(e){return k(e)&&("[object Error]"===A(e)||e instanceof Error)}function B(e){return"function"==typeof e}function R(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function A(e){return Object.prototype.toString.call(e)}function L(e){return 10>e?"0"+e.toString(10):e.toString(10)}function M(){var e=new Date,t=[L(e.getHours()),L(e.getMinutes()),L(e.getSeconds())].join(":");return[e.getDate(),I[e.getMonth()],t].join(" ")}function j(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var O=/%[sdj%]/g;n.format=function(e){if(!_(e)){for(var t=[],n=0;n<arguments.length;n++)t.push(i(arguments[n]));return t.join(" ")}for(var n=1,r=arguments,o=r.length,a=String(e).replace(O,function(e){if("%%"===e)return"%";if(n>=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])a+=v(s)||!k(s)?" "+s:" "+i(s);return a},n.deprecate=function(e,i){function o(){if(!a){if(t.throwDeprecation)throw new Error(i);t.traceDeprecation?console.trace(i):console.error(i),a=!0}return e.apply(this,arguments)}if(w(r.process))return function(){return n.deprecate(e,i).apply(this,arguments)};if(t.noDeprecation===!0)return e;var a=!1;return o};var T,C={};n.debuglog=function(e){if(w(T)&&(T=t.env.NODE_DEBUG||""),e=e.toUpperCase(),!C[e])if(new RegExp("\\b"+e+"\\b","i").test(T)){var r=t.pid;C[e]=function(){var t=n.format.apply(n,arguments);console.error("%s %d: %s",e,r,t)}}else C[e]=function(){};return C[e]},n.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=p,n.isBoolean=g,n.isNull=v,n.isNullOrUndefined=y,n.isNumber=b,n.isString=_,n.isSymbol=m,n.isUndefined=w,n.isRegExp=E,n.isObject=k,n.isDate=S,n.isError=x,n.isFunction=B,n.isPrimitive=R,n.isBuffer=e(93);var I=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",M(),n.format.apply(n,arguments))},n.inherits=e(31),n._extend=function(e,t){if(!t||!k(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{31:31,55:55,93:93}],95:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var i=r.element,o=r.index;if(Array.isArray(i))i.push(e);else if(o===t.length-2){var a=t.pop();i[a]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,i,o,a,s,u,c,f,l,h,d="";n=t.pop();)if(r=n.obj,i=n.prefix||"",o=n.val||"",d+=i,o)d+=o;else if("object"!=typeof r)d+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)d+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),a=r.length-1;a>=0;a--)s=0===a?"":",",t.push({obj:r[a],prefix:s});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),a=u.length-1;a>=0;a--)f=u[a],l=r[f],h=a>0?",":"",h+=JSON.stringify(f)+":",t.push({obj:l,prefix:h});t.push({val:"{"})}return d},n.parse=function(e){for(var t,n,i,o,a,s,u,c,f,l=[],h=[],d=0;;)if(t=e[d++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":d+=3,r(null,l,h);break;case"t":d+=3,r(!0,l,h);break;case"f":d+=4,r(!1,l,h);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",d--;;){if(i=e[d++],!/[\d\.\-e\+]/.test(i)){d--;break}n+=i}r(parseFloat(n),l,h);break;case'"':for(o="",a=void 0,s=0;;){if(u=e[d++],'"'===u&&("\\"!==a||s%2!==1))break;o+=u,a=u,"\\"===a?s++:s=0}r(JSON.parse('"'+o+'"'),l,h);break;case"[":c={element:[],index:l.length},l.push(c.element),h.push(c);break;case"{":f={
+element:{},index:l.length},l.push(f.element),h.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,h)}}},{}],96:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)n.hasOwnProperty(r)&&(e[r]=n[r])}return e}t.exports=r},{}]},{},[1]);
diff --git a/dist/pouchdb.js b/dist/pouchdb.js
new file mode 100644
index 0000000..4a04a93
--- /dev/null
+++ b/dist/pouchdb.js
@@ -0,0 +1,13220 @@
+// PouchDB 5.3.2
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PouchDB = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+  return function () {
+    var len = arguments.length;
+    if (len) {
+      var args = [];
+      var i = -1;
+      while (++i < len) {
+        args[i] = arguments[i];
+      }
+      return fun.call(this, args);
+    } else {
+      return fun.call(this, []);
+    }
+  };
+}
+},{}],2:[function(_dereq_,module,exports){
+
+/**
+ * This is the web browser implementation of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+exports = module.exports = _dereq_(3);
+exports.log = log;
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.storage = 'undefined' != typeof chrome
+               && 'undefined' != typeof chrome.storage
+                  ? chrome.storage.local
+                  : localstorage();
+
+/**
+ * Colors.
+ */
+
+exports.colors = [
+  'lightseagreen',
+  'forestgreen',
+  'goldenrod',
+  'dodgerblue',
+  'darkorchid',
+  'crimson'
+];
+
+/**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+function useColors() {
+  // is webkit? http://stackoverflow.com/a/16459606/376773
+  return ('WebkitAppearance' in document.documentElement.style) ||
+    // is firebug? http://stackoverflow.com/a/398120/376773
+    (window.console && (console.firebug || (console.exception && console.table))) ||
+    // is firefox >= v31?
+    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+    (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
+}
+
+/**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+exports.formatters.j = function(v) {
+  return JSON.stringify(v);
+};
+
+
+/**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs() {
+  var args = arguments;
+  var useColors = this.useColors;
+
+  args[0] = (useColors ? '%c' : '')
+    + this.namespace
+    + (useColors ? ' %c' : ' ')
+    + args[0]
+    + (useColors ? '%c ' : ' ')
+    + '+' + exports.humanize(this.diff);
+
+  if (!useColors) return args;
+
+  var c = 'color: ' + this.color;
+  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
+
+  // the final "%c" is somewhat tricky, because there could be other
+  // arguments passed either before or after the %c, so we need to
+  // figure out the correct index to insert the CSS into
+  var index = 0;
+  var lastC = 0;
+  args[0].replace(/%[a-z%]/g, function(match) {
+    if ('%%' === match) return;
+    index++;
+    if ('%c' === match) {
+      // we only are interested in the *last* %c
+      // (the user may have provided their own)
+      lastC = index;
+    }
+  });
+
+  args.splice(lastC, 0, c);
+  return args;
+}
+
+/**
+ * Invokes `console.log()` when available.
+ * No-op when `console.log` is not a "function".
+ *
+ * @api public
+ */
+
+function log() {
+  // this hackery is required for IE8/9, where
+  // the `console.log` function doesn't have 'apply'
+  return 'object' === typeof console
+    && console.log
+    && Function.prototype.apply.call(console.log, console, arguments);
+}
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+
+function save(namespaces) {
+  try {
+    if (null == namespaces) {
+      exports.storage.removeItem('debug');
+    } else {
+      exports.storage.debug = namespaces;
+    }
+  } catch(e) {}
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+function load() {
+  var r;
+  try {
+    r = exports.storage.debug;
+  } catch(e) {}
+  return r;
+}
+
+/**
+ * Enable namespaces listed in `localStorage.debug` initially.
+ */
+
+exports.enable(load());
+
+/**
+ * Localstorage attempts to return the localstorage.
+ *
+ * This is necessary because safari throws
+ * when a user disables cookies/localstorage
+ * and you attempt to access it.
+ *
+ * @return {LocalStorage}
+ * @api private
+ */
+
+function localstorage(){
+  try {
+    return window.localStorage;
+  } catch (e) {}
+}
+
+},{"3":3}],3:[function(_dereq_,module,exports){
+
+/**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+exports = module.exports = debug;
+exports.coerce = coerce;
+exports.disable = disable;
+exports.enable = enable;
+exports.enabled = enabled;
+exports.humanize = _dereq_(9);
+
+/**
+ * The currently active debug mode names, and names to skip.
+ */
+
+exports.names = [];
+exports.skips = [];
+
+/**
+ * Map of special "%n" handling functions, for the debug "format" argument.
+ *
+ * Valid key names are a single, lowercased letter, i.e. "n".
+ */
+
+exports.formatters = {};
+
+/**
+ * Previously assigned color.
+ */
+
+var prevColor = 0;
+
+/**
+ * Previous log timestamp.
+ */
+
+var prevTime;
+
+/**
+ * Select a color.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+function selectColor() {
+  return exports.colors[prevColor++ % exports.colors.length];
+}
+
+/**
+ * Create a debugger with the given `namespace`.
+ *
+ * @param {String} namespace
+ * @return {Function}
+ * @api public
+ */
+
+function debug(namespace) {
+
+  // define the `disabled` version
+  function disabled() {
+  }
+  disabled.enabled = false;
+
+  // define the `enabled` version
+  function enabled() {
+
+    var self = enabled;
+
+    // set `diff` timestamp
+    var curr = +new Date();
+    var ms = curr - (prevTime || curr);
+    self.diff = ms;
+    self.prev = prevTime;
+    self.curr = curr;
+    prevTime = curr;
+
+    // add the `color` if not set
+    if (null == self.useColors) self.useColors = exports.useColors();
+    if (null == self.color && self.useColors) self.color = selectColor();
+
+    var args = Array.prototype.slice.call(arguments);
+
+    args[0] = exports.coerce(args[0]);
+
+    if ('string' !== typeof args[0]) {
+      // anything else let's inspect with %o
+      args = ['%o'].concat(args);
+    }
+
+    // apply any `formatters` transformations
+    var index = 0;
+    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
+      // if we encounter an escaped % then don't increase the array index
+      if (match === '%%') return match;
+      index++;
+      var formatter = exports.formatters[format];
+      if ('function' === typeof formatter) {
+        var val = args[index];
+        match = formatter.call(self, val);
+
+        // now we need to remove `args[index]` since it's inlined in the `format`
+        args.splice(index, 1);
+        index--;
+      }
+      return match;
+    });
+
+    if ('function' === typeof exports.formatArgs) {
+      args = exports.formatArgs.apply(self, args);
+    }
+    var logFn = enabled.log || exports.log || console.log.bind(console);
+    logFn.apply(self, args);
+  }
+  enabled.enabled = true;
+
+  var fn = exports.enabled(namespace) ? enabled : disabled;
+
+  fn.namespace = namespace;
+
+  return fn;
+}
+
+/**
+ * Enables a debug mode by namespaces. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} namespaces
+ * @api public
+ */
+
+function enable(namespaces) {
+  exports.save(namespaces);
+
+  var split = (namespaces || '').split(/[\s,]+/);
+  var len = split.length;
+
+  for (var i = 0; i < len; i++) {
+    if (!split[i]) continue; // ignore empty strings
+    namespaces = split[i].replace(/\*/g, '.*?');
+    if (namespaces[0] === '-') {
+      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
+    } else {
+      exports.names.push(new RegExp('^' + namespaces + '$'));
+    }
+  }
+}
+
+/**
+ * Disable debug output.
+ *
+ * @api public
+ */
+
+function disable() {
+  exports.enable('');
+}
+
+/**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+
+function enabled(name) {
+  var i, len;
+  for (i = 0, len = exports.skips.length; i < len; i++) {
+    if (exports.skips[i].test(name)) {
+      return false;
+    }
+  }
+  for (i = 0, len = exports.names.length; i < len; i++) {
+    if (exports.names[i].test(name)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * Coerce `val`.
+ *
+ * @param {Mixed} val
+ * @return {Mixed}
+ * @api private
+ */
+
+function coerce(val) {
+  if (val instanceof Error) return val.stack || val.message;
+  return val;
+}
+
+},{"9":9}],4:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      }
+      throw TypeError('Uncaught, unspecified "error" event.');
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],5:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
+
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
+
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
+  }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],6:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
+
+},{}],7:[function(_dereq_,module,exports){
+(function(factory) {
+  if(typeof exports === 'object') {
+    factory(exports);
+  } else {
+    factory(this);
+  }
+}).call(this, function(root) { 
+
+  var slice   = Array.prototype.slice,
+      each    = Array.prototype.forEach;
+
+  var extend = function(obj) {
+    if(typeof obj !== 'object') throw obj + ' is not an object' ;
+
+    var sources = slice.call(arguments, 1); 
+
+    each.call(sources, function(source) {
+      if(source) {
+        for(var prop in source) {
+          if(typeof source[prop] === 'object' && obj[prop]) {
+            extend.call(obj, obj[prop], source[prop]);
+          } else {
+            obj[prop] = source[prop];
+          }
+        } 
+      }
+    });
+
+    return obj;
+  }
+
+  root.extend = extend;
+});
+
+},{}],8:[function(_dereq_,module,exports){
+'use strict';
+var immediate = _dereq_(5);
+
+/* istanbul ignore next */
+function INTERNAL() {}
+
+var handlers = {};
+
+var REJECTED = ['REJECTED'];
+var FULFILLED = ['FULFILLED'];
+var PENDING = ['PENDING'];
+
+module.exports = exports = Promise;
+
+function Promise(resolver) {
+  if (typeof resolver !== 'function') {
+    throw new TypeError('resolver must be a function');
+  }
+  this.state = PENDING;
+  this.queue = [];
+  this.outcome = void 0;
+  if (resolver !== INTERNAL) {
+    safelyResolveThenable(this, resolver);
+  }
+}
+
+Promise.prototype["catch"] = function (onRejected) {
+  return this.then(null, onRejected);
+};
+Promise.prototype.then = function (onFulfilled, onRejected) {
+  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
+    typeof onRejected !== 'function' && this.state === REJECTED) {
+    return this;
+  }
+  var promise = new this.constructor(INTERNAL);
+  if (this.state !== PENDING) {
+    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
+    unwrap(promise, resolver, this.outcome);
+  } else {
+    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
+  }
+
+  return promise;
+};
+function QueueItem(promise, onFulfilled, onRejected) {
+  this.promise = promise;
+  if (typeof onFulfilled === 'function') {
+    this.onFulfilled = onFulfilled;
+    this.callFulfilled = this.otherCallFulfilled;
+  }
+  if (typeof onRejected === 'function') {
+    this.onRejected = onRejected;
+    this.callRejected = this.otherCallRejected;
+  }
+}
+QueueItem.prototype.callFulfilled = function (value) {
+  handlers.resolve(this.promise, value);
+};
+QueueItem.prototype.otherCallFulfilled = function (value) {
+  unwrap(this.promise, this.onFulfilled, value);
+};
+QueueItem.prototype.callRejected = function (value) {
+  handlers.reject(this.promise, value);
+};
+QueueItem.prototype.otherCallRejected = function (value) {
+  unwrap(this.promise, this.onRejected, value);
+};
+
+function unwrap(promise, func, value) {
+  immediate(function () {
+    var returnValue;
+    try {
+      returnValue = func(value);
+    } catch (e) {
+      return handlers.reject(promise, e);
+    }
+    if (returnValue === promise) {
+      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
+    } else {
+      handlers.resolve(promise, returnValue);
+    }
+  });
+}
+
+handlers.resolve = function (self, value) {
+  var result = tryCatch(getThen, value);
+  if (result.status === 'error') {
+    return handlers.reject(self, result.value);
+  }
+  var thenable = result.value;
+
+  if (thenable) {
+    safelyResolveThenable(self, thenable);
+  } else {
+    self.state = FULFILLED;
+    self.outcome = value;
+    var i = -1;
+    var len = self.queue.length;
+    while (++i < len) {
+      self.queue[i].callFulfilled(value);
+    }
+  }
+  return self;
+};
+handlers.reject = function (self, error) {
+  self.state = REJECTED;
+  self.outcome = error;
+  var i = -1;
+  var len = self.queue.length;
+  while (++i < len) {
+    self.queue[i].callRejected(error);
+  }
+  return self;
+};
+
+function getThen(obj) {
+  // Make sure we only access the accessor once as required by the spec
+  var then = obj && obj.then;
+  if (obj && typeof obj === 'object' && typeof then === 'function') {
+    return function appyThen() {
+      then.apply(obj, arguments);
+    };
+  }
+}
+
+function safelyResolveThenable(self, thenable) {
+  // Either fulfill, reject or reject with error
+  var called = false;
+  function onError(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.reject(self, value);
+  }
+
+  function onSuccess(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.resolve(self, value);
+  }
+
+  function tryToUnwrap() {
+    thenable(onSuccess, onError);
+  }
+
+  var result = tryCatch(tryToUnwrap);
+  if (result.status === 'error') {
+    onError(result.value);
+  }
+}
+
+function tryCatch(func, value) {
+  var out = {};
+  try {
+    out.value = func(value);
+    out.status = 'success';
+  } catch (e) {
+    out.status = 'error';
+    out.value = e;
+  }
+  return out;
+}
+
+exports.resolve = resolve;
+function resolve(value) {
+  if (value instanceof this) {
+    return value;
+  }
+  return handlers.resolve(new this(INTERNAL), value);
+}
+
+exports.reject = reject;
+function reject(reason) {
+  var promise = new this(INTERNAL);
+  return handlers.reject(promise, reason);
+}
+
+exports.all = all;
+function all(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var values = new Array(len);
+  var resolved = 0;
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    allResolver(iterable[i], i);
+  }
+  return promise;
+  function allResolver(value, i) {
+    self.resolve(value).then(resolveFromAll, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+    function resolveFromAll(outValue) {
+      values[i] = outValue;
+      if (++resolved === len && !called) {
+        called = true;
+        handlers.resolve(promise, values);
+      }
+    }
+  }
+}
+
+exports.race = race;
+function race(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    resolver(iterable[i]);
+  }
+  return promise;
+  function resolver(value) {
+    self.resolve(value).then(function (response) {
+      if (!called) {
+        called = true;
+        handlers.resolve(promise, response);
+      }
+    }, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+  }
+}
+
+},{"5":5}],9:[function(_dereq_,module,exports){
+/**
+ * Helpers.
+ */
+
+var s = 1000;
+var m = s * 60;
+var h = m * 60;
+var d = h * 24;
+var y = d * 365.25;
+
+/**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ *  - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} options
+ * @return {String|Number}
+ * @api public
+ */
+
+module.exports = function(val, options){
+  options = options || {};
+  if ('string' == typeof val) return parse(val);
+  return options.long
+    ? long(val)
+    : short(val);
+};
+
+/**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+function parse(str) {
+  str = '' + str;
+  if (str.length > 10000) return;
+  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
+  if (!match) return;
+  var n = parseFloat(match[1]);
+  var type = (match[2] || 'ms').toLowerCase();
+  switch (type) {
+    case 'years':
+    case 'year':
+    case 'yrs':
+    case 'yr':
+    case 'y':
+      return n * y;
+    case 'days':
+    case 'day':
+    case 'd':
+      return n * d;
+    case 'hours':
+    case 'hour':
+    case 'hrs':
+    case 'hr':
+    case 'h':
+      return n * h;
+    case 'minutes':
+    case 'minute':
+    case 'mins':
+    case 'min':
+    case 'm':
+      return n * m;
+    case 'seconds':
+    case 'second':
+    case 'secs':
+    case 'sec':
+    case 's':
+      return n * s;
+    case 'milliseconds':
+    case 'millisecond':
+    case 'msecs':
+    case 'msec':
+    case 'ms':
+      return n;
+  }
+}
+
+/**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function short(ms) {
+  if (ms >= d) return Math.round(ms / d) + 'd';
+  if (ms >= h) return Math.round(ms / h) + 'h';
+  if (ms >= m) return Math.round(ms / m) + 'm';
+  if (ms >= s) return Math.round(ms / s) + 's';
+  return ms + 'ms';
+}
+
+/**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function long(ms) {
+  return plural(ms, d, 'day')
+    || plural(ms, h, 'hour')
+    || plural(ms, m, 'minute')
+    || plural(ms, s, 'second')
+    || ms + ' ms';
+}
+
+/**
+ * Pluralization helper.
+ */
+
+function plural(ms, n, name) {
+  if (ms < n) return;
+  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
+  return Math.ceil(ms / n) + ' ' + name + 's';
+}
+
+},{}],10:[function(_dereq_,module,exports){
+'use strict';
+
+var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
+var MAGNITUDE_DIGITS = 3; // ditto
+var SEP = ''; // set to '_' for easier debugging 
+
+var utils = _dereq_(11);
+
+exports.collate = function (a, b) {
+
+  if (a === b) {
+    return 0;
+  }
+
+  a = exports.normalizeKey(a);
+  b = exports.normalizeKey(b);
+
+  var ai = collationIndex(a);
+  var bi = collationIndex(b);
+  if ((ai - bi) !== 0) {
+    return ai - bi;
+  }
+  if (a === null) {
+    return 0;
+  }
+  switch (typeof a) {
+    case 'number':
+      return a - b;
+    case 'boolean':
+      return a === b ? 0 : (a < b ? -1 : 1);
+    case 'string':
+      return stringCollate(a, b);
+  }
+  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
+};
+
+// couch considers null/NaN/Infinity/-Infinity === undefined,
+// for the purposes of mapreduce indexes. also, dates get stringified.
+exports.normalizeKey = function (key) {
+  switch (typeof key) {
+    case 'undefined':
+      return null;
+    case 'number':
+      if (key === Infinity || key === -Infinity || isNaN(key)) {
+        return null;
+      }
+      return key;
+    case 'object':
+      var origKey = key;
+      if (Array.isArray(key)) {
+        var len = key.length;
+        key = new Array(len);
+        for (var i = 0; i < len; i++) {
+          key[i] = exports.normalizeKey(origKey[i]);
+        }
+      } else if (key instanceof Date) {
+        return key.toJSON();
+      } else if (key !== null) { // generic object
+        key = {};
+        for (var k in origKey) {
+          if (origKey.hasOwnProperty(k)) {
+            var val = origKey[k];
+            if (typeof val !== 'undefined') {
+              key[k] = exports.normalizeKey(val);
+            }
+          }
+        }
+      }
+  }
+  return key;
+};
+
+function indexify(key) {
+  if (key !== null) {
+    switch (typeof key) {
+      case 'boolean':
+        return key ? 1 : 0;
+      case 'number':
+        return numToIndexableString(key);
+      case 'string':
+        // We've to be sure that key does not contain \u0000
+        // Do order-preserving replacements:
+        // 0 -> 1, 1
+        // 1 -> 1, 2
+        // 2 -> 2, 2
+        return key
+          .replace(/\u0002/g, '\u0002\u0002')
+          .replace(/\u0001/g, '\u0001\u0002')
+          .replace(/\u0000/g, '\u0001\u0001');
+      case 'object':
+        var isArray = Array.isArray(key);
+        var arr = isArray ? key : Object.keys(key);
+        var i = -1;
+        var len = arr.length;
+        var result = '';
+        if (isArray) {
+          while (++i < len) {
+            result += exports.toIndexableString(arr[i]);
+          }
+        } else {
+          while (++i < len) {
+            var objKey = arr[i];
+            result += exports.toIndexableString(objKey) +
+                exports.toIndexableString(key[objKey]);
+          }
+        }
+        return result;
+    }
+  }
+  return '';
+}
+
+// convert the given key to a string that would be appropriate
+// for lexical sorting, e.g. within a database, where the
+// sorting is the same given by the collate() function.
+exports.toIndexableString = function (key) {
+  var zero = '\u0000';
+  key = exports.normalizeKey(key);
+  return collationIndex(key) + SEP + indexify(key) + zero;
+};
+
+function parseNumber(str, i) {
+  var originalIdx = i;
+  var num;
+  var zero = str[i] === '1';
+  if (zero) {
+    num = 0;
+    i++;
+  } else {
+    var neg = str[i] === '0';
+    i++;
+    var numAsString = '';
+    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
+    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
+    if (neg) {
+      magnitude = -magnitude;
+    }
+    i += MAGNITUDE_DIGITS;
+    while (true) {
+      var ch = str[i];
+      if (ch === '\u0000') {
+        break;
+      } else {
+        numAsString += ch;
+      }
+      i++;
+    }
+    numAsString = numAsString.split('.');
+    if (numAsString.length === 1) {
+      num = parseInt(numAsString, 10);
+    } else {
+      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
+    }
+    if (neg) {
+      num = num - 10;
+    }
+    if (magnitude !== 0) {
+      // parseFloat is more reliable than pow due to rounding errors
+      // e.g. Number.MAX_VALUE would return Infinity if we did
+      // num * Math.pow(10, magnitude);
+      num = parseFloat(num + 'e' + magnitude);
+    }
+  }
+  return {num: num, length : i - originalIdx};
+}
+
+// move up the stack while parsing
+// this function moved outside of parseIndexableString for performance
+function pop(stack, metaStack) {
+  var obj = stack.pop();
+
+  if (metaStack.length) {
+    var lastMetaElement = metaStack[metaStack.length - 1];
+    if (obj === lastMetaElement.element) {
+      // popping a meta-element, e.g. an object whose value is another object
+      metaStack.pop();
+      lastMetaElement = metaStack[metaStack.length - 1];
+    }
+    var element = lastMetaElement.element;
+    var lastElementIndex = lastMetaElement.index;
+    if (Array.isArray(element)) {
+      element.push(obj);
+    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+      var key = stack.pop();
+      element[key] = obj;
+    } else {
+      stack.push(obj); // obj with key only
+    }
+  }
+}
+
+exports.parseIndexableString = function (str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
+
+  while (true) {
+    var collationIndex = str[i++];
+    if (collationIndex === '\u0000') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case '1':
+        stack.push(null);
+        break;
+      case '2':
+        stack.push(str[i] === '1');
+        i++;
+        break;
+      case '3':
+        var parsedNum = parseNumber(str, i);
+        stack.push(parsedNum.num);
+        i += parsedNum.length;
+        break;
+      case '4':
+        var parsedStr = '';
+        while (true) {
+          var ch = str[i];
+          if (ch === '\u0000') {
+            break;
+          }
+          parsedStr += ch;
+          i++;
+        }
+        // perform the reverse of the order-preserving replacement
+        // algorithm (see above)
+        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
+          .replace(/\u0001\u0002/g, '\u0001')
+          .replace(/\u0002\u0002/g, '\u0002');
+        stack.push(parsedStr);
+        break;
+      case '5':
+        var arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '6':
+        var objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      default:
+        throw new Error(
+          'bad collationIndex or unexpectedly reached end of input: ' + collationIndex);
+    }
+  }
+};
+
+function arrayCollate(a, b) {
+  var len = Math.min(a.length, b.length);
+  for (var i = 0; i < len; i++) {
+    var sort = exports.collate(a[i], b[i]);
+    if (sort !== 0) {
+      return sort;
+    }
+  }
+  return (a.length === b.length) ? 0 :
+    (a.length > b.length) ? 1 : -1;
+}
+function stringCollate(a, b) {
+  // See: https://github.com/daleharvey/pouchdb/issues/40
+  // This is incompatible with the CouchDB implementation, but its the
+  // best we can do for now
+  return (a === b) ? 0 : ((a > b) ? 1 : -1);
+}
+function objectCollate(a, b) {
+  var ak = Object.keys(a), bk = Object.keys(b);
+  var len = Math.min(ak.length, bk.length);
+  for (var i = 0; i < len; i++) {
+    // First sort the keys
+    var sort = exports.collate(ak[i], bk[i]);
+    if (sort !== 0) {
+      return sort;
+    }
+    // if the keys are equal sort the values
+    sort = exports.collate(a[ak[i]], b[bk[i]]);
+    if (sort !== 0) {
+      return sort;
+    }
+
+  }
+  return (ak.length === bk.length) ? 0 :
+    (ak.length > bk.length) ? 1 : -1;
+}
+// The collation is defined by erlangs ordered terms
+// the atoms null, true, false come first, then numbers, strings,
+// arrays, then objects
+// null/undefined/NaN/Infinity/-Infinity are all considered null
+function collationIndex(x) {
+  var id = ['boolean', 'number', 'string', 'object'];
+  var idx = id.indexOf(typeof x);
+  //false if -1 otherwise true, but fast!!!!1
+  if (~idx) {
+    if (x === null) {
+      return 1;
+    }
+    if (Array.isArray(x)) {
+      return 5;
+    }
+    return idx < 3 ? (idx + 2) : (idx + 3);
+  }
+  if (Array.isArray(x)) {
+    return 5;
+  }
+}
+
+// conversion:
+// x yyy zz...zz
+// x = 0 for negative, 1 for 0, 2 for positive
+// y = exponent (for negative numbers negated) moved so that it's >= 0
+// z = mantisse
+function numToIndexableString(num) {
+
+  if (num === 0) {
+    return '1';
+  }
+
+  // convert number to exponential format for easier and
+  // more succinct string sorting
+  var expFormat = num.toExponential().split(/e\+?/);
+  var magnitude = parseInt(expFormat[1], 10);
+
+  var neg = num < 0;
+
+  var result = neg ? '0' : '2';
+
+  // first sort by magnitude
+  // it's easier if all magnitudes are positive
+  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
+  var magString = utils.padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
+
+  result += SEP + magString;
+
+  // then sort by the factor
+  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
+  if (neg) { // for negative reverse ordering
+    factor = 10 - factor;
+  }
+
+  var factorStr = factor.toFixed(20);
+
+  // strip zeros from the end
+  factorStr = factorStr.replace(/\.?0+$/, '');
+
+  result += SEP + factorStr;
+
+  return result;
+}
+
+},{"11":11}],11:[function(_dereq_,module,exports){
+'use strict';
+
+function pad(str, padWith, upToLength) {
+  var padding = '';
+  var targetLength = upToLength - str.length;
+  while (padding.length < targetLength) {
+    padding += padWith;
+  }
+  return padding;
+}
+
+exports.padLeft = function (str, padWith, upToLength) {
+  var padding = pad(str, padWith, upToLength);
+  return padding + str;
+};
+
+exports.padRight = function (str, padWith, upToLength) {
+  var padding = pad(str, padWith, upToLength);
+  return str + padding;
+};
+
+exports.stringLexCompare = function (a, b) {
+
+  var aLen = a.length;
+  var bLen = b.length;
+
+  var i;
+  for (i = 0; i < aLen; i++) {
+    if (i === bLen) {
+      // b is shorter substring of a
+      return 1;
+    }
+    var aChar = a.charAt(i);
+    var bChar = b.charAt(i);
+    if (aChar !== bChar) {
+      return aChar < bChar ? -1 : 1;
+    }
+  }
+
+  if (aLen < bLen) {
+    // a is shorter substring of b
+    return -1;
+  }
+
+  return 0;
+};
+
+/*
+ * returns the decimal form for the given integer, i.e. writes
+ * out all the digits (in base-10) instead of using scientific notation
+ */
+exports.intToDecimalForm = function (int) {
+
+  var isNeg = int < 0;
+  var result = '';
+
+  do {
+    var remainder = isNeg ? -Math.ceil(int % 10) : Math.floor(int % 10);
+
+    result = remainder + result;
+    int = isNeg ? Math.ceil(int / 10) : Math.floor(int / 10);
+  } while (int);
+
+
+  if (isNeg && result !== '0') {
+    result = '-' + result;
+  }
+
+  return result;
+};
+},{}],12:[function(_dereq_,module,exports){
+'use strict';
+exports.Map = LazyMap; // TODO: use ES6 map
+exports.Set = LazySet; // TODO: use ES6 set
+// based on https://github.com/montagejs/collections
+function LazyMap() {
+  this.store = {};
+}
+LazyMap.prototype.mangle = function (key) {
+  if (typeof key !== "string") {
+    throw new TypeError("key must be a string but Got " + key);
+  }
+  return '$' + key;
+};
+LazyMap.prototype.unmangle = function (key) {
+  return key.substring(1);
+};
+LazyMap.prototype.get = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    return this.store[mangled];
+  }
+  return void 0;
+};
+LazyMap.prototype.set = function (key, value) {
+  var mangled = this.mangle(key);
+  this.store[mangled] = value;
+  return true;
+};
+LazyMap.prototype.has = function (key) {
+  var mangled = this.mangle(key);
+  return mangled in this.store;
+};
+LazyMap.prototype.delete = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    delete this.store[mangled];
+    return true;
+  }
+  return false;
+};
+LazyMap.prototype.forEach = function (cb) {
+  var keys = Object.keys(this.store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this.store[key];
+    key = this.unmangle(key);
+    cb(value, key);
+  }
+};
+
+function LazySet(array) {
+  this.store = new LazyMap();
+
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
+    }
+  }
+}
+LazySet.prototype.add = function (key) {
+  return this.store.set(key, true);
+};
+LazySet.prototype.has = function (key) {
+  return this.store.has(key);
+};
+LazySet.prototype.delete = function (key) {
+  return this.store.delete(key);
+};
+
+},{}],13:[function(_dereq_,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = setTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    clearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],14:[function(_dereq_,module,exports){
+// Generated by CoffeeScript 1.9.2
+(function() {
+  var hasProp = {}.hasOwnProperty,
+    slice = [].slice;
+
+  module.exports = function(source, scope) {
+    var key, keys, value, values;
+    keys = [];
+    values = [];
+    for (key in scope) {
+      if (!hasProp.call(scope, key)) continue;
+      value = scope[key];
+      if (key === 'this') {
+        continue;
+      }
+      keys.push(key);
+      values.push(value);
+    }
+    return Function.apply(null, slice.call(keys).concat([source])).apply(scope["this"], values);
+  };
+
+}).call(this);
+
+},{}],15:[function(_dereq_,module,exports){
+(function (factory) {
+    if (typeof exports === 'object') {
+        // Node/CommonJS
+        module.exports = factory();
+    } else if (typeof define === 'function' && define.amd) {
+        // AMD
+        define(factory);
+    } else {
+        // Browser globals (with support for web workers)
+        var glob;
+
+        try {
+            glob = window;
+        } catch (e) {
+            glob = self;
+        }
+
+        glob.SparkMD5 = factory();
+    }
+}(function (undefined) {
+
+    'use strict';
+
+    /*
+     * Fastest md5 implementation around (JKM md5).
+     * Credits: Joseph Myers
+     *
+     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+     * @see http://jsperf.com/md5-shootout/7
+     */
+
+    /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+    var add32 = function (a, b) {
+        return (a + b) & 0xFFFFFFFF;
+    },
+        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+    function cmn(q, a, b, x, s, t) {
+        a = add32(add32(a, q), add32(x, t));
+        return add32((a << s) | (a >>> (32 - s)), b);
+    }
+
+    function ff(a, b, c, d, x, s, t) {
+        return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+    }
+
+    function gg(a, b, c, d, x, s, t) {
+        return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+    }
+
+    function hh(a, b, c, d, x, s, t) {
+        return cmn(b ^ c ^ d, a, b, x, s, t);
+    }
+
+    function ii(a, b, c, d, x, s, t) {
+        return cmn(c ^ (b | (~d)), a, b, x, s, t);
+    }
+
+    function md5cycle(x, k) {
+        var a = x[0],
+            b = x[1],
+            c = x[2],
+            d = x[3];
+
+        a = ff(a, b, c, d, k[0], 7, -680876936);
+        d = ff(d, a, b, c, k[1], 12, -389564586);
+        c = ff(c, d, a, b, k[2], 17, 606105819);
+        b = ff(b, c, d, a, k[3], 22, -1044525330);
+        a = ff(a, b, c, d, k[4], 7, -176418897);
+        d = ff(d, a, b, c, k[5], 12, 1200080426);
+        c = ff(c, d, a, b, k[6], 17, -1473231341);
+        b = ff(b, c, d, a, k[7], 22, -45705983);
+        a = ff(a, b, c, d, k[8], 7, 1770035416);
+        d = ff(d, a, b, c, k[9], 12, -1958414417);
+        c = ff(c, d, a, b, k[10], 17, -42063);
+        b = ff(b, c, d, a, k[11], 22, -1990404162);
+        a = ff(a, b, c, d, k[12], 7, 1804603682);
+        d = ff(d, a, b, c, k[13], 12, -40341101);
+        c = ff(c, d, a, b, k[14], 17, -1502002290);
+        b = ff(b, c, d, a, k[15], 22, 1236535329);
+
+        a = gg(a, b, c, d, k[1], 5, -165796510);
+        d = gg(d, a, b, c, k[6], 9, -1069501632);
+        c = gg(c, d, a, b, k[11], 14, 643717713);
+        b = gg(b, c, d, a, k[0], 20, -373897302);
+        a = gg(a, b, c, d, k[5], 5, -701558691);
+        d = gg(d, a, b, c, k[10], 9, 38016083);
+        c = gg(c, d, a, b, k[15], 14, -660478335);
+        b = gg(b, c, d, a, k[4], 20, -405537848);
+        a = gg(a, b, c, d, k[9], 5, 568446438);
+        d = gg(d, a, b, c, k[14], 9, -1019803690);
+        c = gg(c, d, a, b, k[3], 14, -187363961);
+        b = gg(b, c, d, a, k[8], 20, 1163531501);
+        a = gg(a, b, c, d, k[13], 5, -1444681467);
+        d = gg(d, a, b, c, k[2], 9, -51403784);
+        c = gg(c, d, a, b, k[7], 14, 1735328473);
+        b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+        a = hh(a, b, c, d, k[5], 4, -378558);
+        d = hh(d, a, b, c, k[8], 11, -2022574463);
+        c = hh(c, d, a, b, k[11], 16, 1839030562);
+        b = hh(b, c, d, a, k[14], 23, -35309556);
+        a = hh(a, b, c, d, k[1], 4, -1530992060);
+        d = hh(d, a, b, c, k[4], 11, 1272893353);
+        c = hh(c, d, a, b, k[7], 16, -155497632);
+        b = hh(b, c, d, a, k[10], 23, -1094730640);
+        a = hh(a, b, c, d, k[13], 4, 681279174);
+        d = hh(d, a, b, c, k[0], 11, -358537222);
+        c = hh(c, d, a, b, k[3], 16, -722521979);
+        b = hh(b, c, d, a, k[6], 23, 76029189);
+        a = hh(a, b, c, d, k[9], 4, -640364487);
+        d = hh(d, a, b, c, k[12], 11, -421815835);
+        c = hh(c, d, a, b, k[15], 16, 530742520);
+        b = hh(b, c, d, a, k[2], 23, -995338651);
+
+        a = ii(a, b, c, d, k[0], 6, -198630844);
+        d = ii(d, a, b, c, k[7], 10, 1126891415);
+        c = ii(c, d, a, b, k[14], 15, -1416354905);
+        b = ii(b, c, d, a, k[5], 21, -57434055);
+        a = ii(a, b, c, d, k[12], 6, 1700485571);
+        d = ii(d, a, b, c, k[3], 10, -1894986606);
+        c = ii(c, d, a, b, k[10], 15, -1051523);
+        b = ii(b, c, d, a, k[1], 21, -2054922799);
+        a = ii(a, b, c, d, k[8], 6, 1873313359);
+        d = ii(d, a, b, c, k[15], 10, -30611744);
+        c = ii(c, d, a, b, k[6], 15, -1560198380);
+        b = ii(b, c, d, a, k[13], 21, 1309151649);
+        a = ii(a, b, c, d, k[4], 6, -145523070);
+        d = ii(d, a, b, c, k[11], 10, -1120210379);
+        c = ii(c, d, a, b, k[2], 15, 718787259);
+        b = ii(b, c, d, a, k[9], 21, -343485551);
+
+        x[0] = add32(a, x[0]);
+        x[1] = add32(b, x[1]);
+        x[2] = add32(c, x[2]);
+        x[3] = add32(d, x[3]);
+    }
+
+    function md5blk(s) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+        }
+        return md5blks;
+    }
+
+    function md5blk_array(a) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+        }
+        return md5blks;
+    }
+
+    function md51(s) {
+        var n = s.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk(s.substring(i - 64, i)));
+        }
+        s = s.substring(i - 64);
+        length = s.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+        }
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+        return state;
+    }
+
+    function md51_array(a) {
+        var n = a.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+        }
+
+        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+        // containing the last element of the parent array if the sub array specified starts
+        // beyond the length of the parent array - weird.
+        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+        length = a.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= a[i] << ((i % 4) << 3);
+        }
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+
+        return state;
+    }
+
+    function rhex(n) {
+        var s = '',
+            j;
+        for (j = 0; j < 4; j += 1) {
+            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+        }
+        return s;
+    }
+
+    function hex(x) {
+        var i;
+        for (i = 0; i < x.length; i += 1) {
+            x[i] = rhex(x[i]);
+        }
+        return x.join('');
+    }
+
+    // In some cases the fast add32 function cannot be used..
+    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+        add32 = function (x, y) {
+            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+            return (msw << 16) | (lsw & 0xFFFF);
+        };
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * ArrayBuffer slice polyfill.
+     *
+     * @see https://github.com/ttaubert/node-arraybuffer-slice
+     */
+
+    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+        (function () {
+            function clamp(val, length) {
+                val = (val | 0) || 0;
+
+                if (val < 0) {
+                    return Math.max(val + length, 0);
+                }
+
+                return Math.min(val, length);
+            }
+
+            ArrayBuffer.prototype.slice = function (from, to) {
+                var length = this.byteLength,
+                    begin = clamp(from, length),
+                    end = length,
+                    num,
+                    target,
+                    targetArray,
+                    sourceArray;
+
+                if (to !== undefined) {
+                    end = clamp(to, length);
+                }
+
+                if (begin > end) {
+                    return new ArrayBuffer(0);
+                }
+
+                num = end - begin;
+                target = new ArrayBuffer(num);
+                targetArray = new Uint8Array(target);
+
+                sourceArray = new Uint8Array(this, begin, num);
+                targetArray.set(sourceArray);
+
+                return target;
+            };
+        })();
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * Helpers.
+     */
+
+    function toUtf8(str) {
+        if (/[\u0080-\uFFFF]/.test(str)) {
+            str = unescape(encodeURIComponent(str));
+        }
+
+        return str;
+    }
+
+    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+        var length = str.length,
+           buff = new ArrayBuffer(length),
+           arr = new Uint8Array(buff),
+           i;
+
+        for (i = 0; i < length; i += 1) {
+            arr[i] = str.charCodeAt(i);
+        }
+
+        return returnUInt8Array ? arr : buff;
+    }
+
+    function arrayBuffer2Utf8Str(buff) {
+        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    }
+
+    function concatenateArrayBuffers(first, second, returnUInt8Array) {
+        var result = new Uint8Array(first.byteLength + second.byteLength);
+
+        result.set(new Uint8Array(first));
+        result.set(new Uint8Array(second), first.byteLength);
+
+        return returnUInt8Array ? result : result.buffer;
+    }
+
+    function hexToBinaryString(hex) {
+        var bytes = [],
+            length = hex.length,
+            x;
+
+        for (x = 0; x < length - 1; x += 2) {
+            bytes.push(parseInt(hex.substr(x, 2), 16));
+        }
+
+        return String.fromCharCode.apply(String, bytes);
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation.
+     *
+     * Use this class to perform an incremental md5, otherwise use the
+     * static methods instead.
+     */
+
+    function SparkMD5() {
+        // call reset to init the instance
+        this.reset();
+    }
+
+    /**
+     * Appends a string.
+     * A conversion will be applied if an utf8 string is detected.
+     *
+     * @param {String} str The string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.append = function (str) {
+        // Converts the string to utf8 bytes if necessary
+        // Then append as binary
+        this.appendBinary(toUtf8(str));
+
+        return this;
+    };
+
+    /**
+     * Appends a binary string.
+     *
+     * @param {String} contents The binary string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.appendBinary = function (contents) {
+        this._buff += contents;
+        this._length += contents.length;
+
+        var length = this._buff.length,
+            i;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+        }
+
+        this._buff = this._buff.substring(i - 64);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            i,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.reset = function () {
+        this._buff = '';
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.prototype.getState = function () {
+        return {
+            buff: this._buff,
+            length: this._length,
+            hash: this._hash
+        };
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.setState = function (state) {
+        this._buff = state.buff;
+        this._length = state.length;
+        this._hash = state.hash;
+
+        return this;
+    };
+
+    /**
+     * Releases memory used by the incremental buffer and other additional
+     * resources. If you plan to use the instance again, use reset instead.
+     */
+    SparkMD5.prototype.destroy = function () {
+        delete this._hash;
+        delete this._buff;
+        delete this._length;
+    };
+
+    /**
+     * Finish the final calculation based on the tail.
+     *
+     * @param {Array}  tail   The tail (will be modified)
+     * @param {Number} length The length of the remaining buffer
+     */
+    SparkMD5.prototype._finish = function (tail, length) {
+        var i = length,
+            tmp,
+            lo,
+            hi;
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(this._hash, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Do the final computation based on the tail and length
+        // Beware that the final length may not fit in 32 bits so we take care of that
+        tmp = this._length * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+        md5cycle(this._hash, tail);
+    };
+
+    /**
+     * Performs the md5 hash on a string.
+     * A conversion will be applied if utf8 string is detected.
+     *
+     * @param {String}  str The string
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hash = function (str, raw) {
+        // Converts the string to utf8 bytes if necessary
+        // Then compute it using the binary function
+        return SparkMD5.hashBinary(toUtf8(str), raw);
+    };
+
+    /**
+     * Performs the md5 hash on a binary string.
+     *
+     * @param {String}  content The binary string
+     * @param {Boolean} raw     True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hashBinary = function (content, raw) {
+        var hash = md51(content),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation for array buffers.
+     *
+     * Use this class to perform an incremental md5 ONLY for array buffers.
+     */
+    SparkMD5.ArrayBuffer = function () {
+        // call reset to init the instance
+        this.reset();
+    };
+
+    /**
+     * Appends an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array to be appended
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+            length = buff.length,
+            i;
+
+        this._length += arr.byteLength;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+        }
+
+        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            i,
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.reset = function () {
+        this._buff = new Uint8Array(0);
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.ArrayBuffer.prototype.getState = function () {
+        var state = SparkMD5.prototype.getState.call(this);
+
+        // Convert buffer to a string
+        state.buff = arrayBuffer2Utf8Str(state.buff);
+
+        return state;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+        // Convert string to buffer
+        state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+        return SparkMD5.prototype.setState.call(this, state);
+    };
+
+    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+    /**
+     * Performs the md5 hash on an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array buffer
+     * @param {Boolean}     raw True to get the raw string, false to get the hex one
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+        var hash = md51_array(new Uint8Array(arr)),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    return SparkMD5;
+}));
+
+},{}],16:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+  var queue = [];
+  queue.push({obj: input});
+
+  var res = '';
+  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+  while ((next = queue.pop())) {
+    obj = next.obj;
+    prefix = next.prefix || '';
+    val = next.val || '';
+    res += prefix;
+    if (val) {
+      res += val;
+    } else if (typeof obj !== 'object') {
+      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+    } else if (obj === null) {
+      res += 'null';
+    } else if (Array.isArray(obj)) {
+      queue.push({val: ']'});
+      for (i = obj.length - 1; i >= 0; i--) {
+        arrayPrefix = i === 0 ? '' : ',';
+        queue.push({obj: obj[i], prefix: arrayPrefix});
+      }
+      queue.push({val: '['});
+    } else { // object
+      keys = [];
+      for (k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          keys.push(k);
+        }
+      }
+      queue.push({val: '}'});
+      for (i = keys.length - 1; i >= 0; i--) {
+        key = keys[i];
+        value = obj[key];
+        objPrefix = (i > 0 ? ',' : '');
+        objPrefix += JSON.stringify(key) + ':';
+        queue.push({obj: value, prefix: objPrefix});
+      }
+      queue.push({val: '{'});
+    }
+  }
+  return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+  var lastMetaElement = metaStack[metaStack.length - 1];
+  if (obj === lastMetaElement.element) {
+    // popping a meta-element, e.g. an object whose value is another object
+    metaStack.pop();
+    lastMetaElement = metaStack[metaStack.length - 1];
+  }
+  var element = lastMetaElement.element;
+  var lastElementIndex = lastMetaElement.index;
+  if (Array.isArray(element)) {
+    element.push(obj);
+  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+    var key = stack.pop();
+    element[key] = obj;
+  } else {
+    stack.push(obj); // obj with key only
+  }
+}
+
+exports.parse = function (str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
+  var collationIndex,parsedNum,numChar;
+  var parsedString,lastCh,numConsecutiveSlashes,ch;
+  var arrayElement, objElement;
+  while (true) {
+    collationIndex = str[i++];
+    if (collationIndex === '}' ||
+        collationIndex === ']' ||
+        typeof collationIndex === 'undefined') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack.pop(), stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case ' ':
+      case '\t':
+      case '\n':
+      case ':':
+      case ',':
+        break;
+      case 'n':
+        i += 3; // 'ull'
+        pop(null, stack, metaStack);
+        break;
+      case 't':
+        i += 3; // 'rue'
+        pop(true, stack, metaStack);
+        break;
+      case 'f':
+        i += 4; // 'alse'
+        pop(false, stack, metaStack);
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '-':
+        parsedNum = '';
+        i--;
+        while (true) {
+          numChar = str[i++];
+          if (/[\d\.\-e\+]/.test(numChar)) {
+            parsedNum += numChar;
+          } else {
+            i--;
+            break;
+          }
+        }
+        pop(parseFloat(parsedNum), stack, metaStack);
+        break;
+      case '"':
+        parsedString = '';
+        lastCh = void 0;
+        numConsecutiveSlashes = 0;
+        while (true) {
+          ch = str[i++];
+          if (ch !== '"' || (lastCh === '\\' &&
+              numConsecutiveSlashes % 2 === 1)) {
+            parsedString += ch;
+            lastCh = ch;
+            if (lastCh === '\\') {
+              numConsecutiveSlashes++;
+            } else {
+              numConsecutiveSlashes = 0;
+            }
+          } else {
+            break;
+          }
+        }
+        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+        break;
+      case '[':
+        arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '{':
+        objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      default:
+        throw new Error(
+          'unexpectedly reached end of input: ' + collationIndex);
+    }
+  }
+};
+
+},{}],17:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var jsExtend = _dereq_(7);
+var jsExtend__default = _interopDefault(jsExtend);
+var debug = _interopDefault(_dereq_(2));
+var inherits = _interopDefault(_dereq_(6));
+var lie = _interopDefault(_dereq_(8));
+var pouchdbCollections = _dereq_(12);
+var getArguments = _interopDefault(_dereq_(1));
+var events = _dereq_(4);
+var scopedEval = _interopDefault(_dereq_(14));
+var pouchCollate = _dereq_(10);
+var pouchCollate__default = _interopDefault(pouchCollate);
+var Md5 = _interopDefault(_dereq_(15));
+var vuvuzela = _interopDefault(_dereq_(16));
+
+/* istanbul ignore next */
+var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
+
+function isBinaryObject(object) {
+  return object instanceof ArrayBuffer ||
+    (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+  if (typeof buff.slice === 'function') {
+    return buff.slice(0);
+  }
+  // IE10-11 slice() polyfill
+  var target = new ArrayBuffer(buff.byteLength);
+  var targetArray = new Uint8Array(target);
+  var sourceArray = new Uint8Array(buff);
+  targetArray.set(sourceArray);
+  return target;
+}
+
+function cloneBinaryObject(object) {
+  if (object instanceof ArrayBuffer) {
+    return cloneArrayBuffer(object);
+  }
+  var size = object.size;
+  var type = object.type;
+  // Blob
+  if (typeof object.slice === 'function') {
+    return object.slice(0, size, type);
+  }
+  // PhantomJS slice() replacement
+  return object.webkitSlice(0, size, type);
+}
+
+function clone(object) {
+  var newObject;
+  var i;
+  var len;
+
+  if (!object || typeof object !== 'object') {
+    return object;
+  }
+
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone(object[i]);
+    }
+    return newObject;
+  }
+
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
+
+  if (isBinaryObject(object)) {
+    return cloneBinaryObject(object);
+  }
+
+  newObject = {};
+  for (i in object) {
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
+      }
+    }
+  }
+  return newObject;
+}
+
+function once(fun) {
+  var called = false;
+  return getArguments(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
+    }
+  });
+}
+
+function toPromise(func) {
+  //create the function we will be returning
+  return getArguments(function (args) {
+    // Clone arguments
+    args = clone(args);
+    var self = this;
+    var tempCB =
+      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    // if the last argument is a function, assume its a callback
+    var usedCB;
+    if (tempCB) {
+      // if it was a callback, create a new callback which calls it,
+      // but do so async so we don't trap any errors
+      usedCB = function (err, resp) {
+        process.nextTick(function () {
+          tempCB(err, resp);
+        });
+      };
+    }
+    var promise = new PouchPromise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
+      }
+    });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
+    }
+    return promise;
+  });
+}
+
+var log = debug('pouchdb:api');
+
+function adapterFun(name, callback) {
+  function logApiCall(self, name, args) {
+    /* istanbul ignore if */
+    if (log.enabled) {
+      var logArgs = [self._db_name, name];
+      for (var i = 0; i < args.length - 1; i++) {
+        logArgs.push(args[i]);
+      }
+      log.apply(null, logArgs);
+
+      // override the callback itself to log the response
+      var origCallback = args[args.length - 1];
+      args[args.length - 1] = function (err, res) {
+        var responseArgs = [self._db_name, name];
+        responseArgs = responseArgs.concat(
+          err ? ['error', err] : ['success', res]
+        );
+        log.apply(null, responseArgs);
+        origCallback(err, res);
+      };
+    }
+  }
+
+  return toPromise(getArguments(function (args) {
+    if (this._closed) {
+      return PouchPromise.reject(new Error('database is closed'));
+    }
+    if (this._destroyed) {
+      return PouchPromise.reject(new Error('database is destroyed'));
+    }
+    var self = this;
+    logApiCall(self, name, args);
+    if (!this.taskqueue.isReady) {
+      return new PouchPromise(function (fulfill, reject) {
+        self.taskqueue.addTask(function (failed) {
+          if (failed) {
+            reject(failed);
+          } else {
+            fulfill(self[name].apply(self, args));
+          }
+        });
+      });
+    }
+    return callback.apply(this, args);
+  }));
+}
+
+// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
+// the diffFun tells us what delta to apply to the doc.  it either returns
+// the doc, or false if it doesn't need to do an update after all
+function upsert(db, docId, diffFun) {
+  return new PouchPromise(function (fulfill, reject) {
+    db.get(docId, function (err, doc) {
+      if (err) {
+        /* istanbul ignore next */
+        if (err.status !== 404) {
+          return reject(err);
+        }
+        doc = {};
+      }
+
+      // the user might change the _rev, so save it for posterity
+      var docRev = doc._rev;
+      var newDoc = diffFun(doc);
+
+      if (!newDoc) {
+        // if the diffFun returns falsy, we short-circuit as
+        // an optimization
+        return fulfill({updated: false, rev: docRev});
+      }
+
+      // users aren't allowed to modify these values,
+      // so reset them here
+      newDoc._id = docId;
+      newDoc._rev = docRev;
+      fulfill(tryAndPut(db, newDoc, diffFun));
+    });
+  });
+}
+
+function tryAndPut(db, doc, diffFun) {
+  return db.put(doc).then(function (res) {
+    return {
+      updated: true,
+      rev: res.rev
+    };
+  }, function (err) {
+    /* istanbul ignore next */
+    if (err.status !== 409) {
+      throw err;
+    }
+    return upsert(db, doc._id, diffFun);
+  });
+}
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+  var winningId;
+  var winningPos;
+  var winningDeleted;
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var tree = node.ids;
+    var branches = tree[2];
+    var pos = node.pos;
+    if (branches.length) { // non-leaf
+      for (var i = 0, len = branches.length; i < len; i++) {
+        toVisit.push({pos: pos + 1, ids: branches[i]});
+      }
+      continue;
+    }
+    var deleted = !!tree[1].deleted;
+    var id = tree[0];
+    // sort by deleted, then pos, then id
+    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+        winningPos !== pos ? winningPos < pos : winningId < id)) {
+      winningId = id;
+      winningPos = pos;
+      winningDeleted = deleted;
+    }
+  }
+
+  return winningPos + '-' + winningId;
+}
+
+function getTrees(node) {
+  return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+//  - metadata: the metadata object from the doc store
+//  - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+  if (!rev) {
+    rev = winningRev(metadata);
+  }
+  var id = rev.substring(rev.indexOf('-') + 1);
+  var toVisit = metadata.rev_tree.map(getTrees);
+
+  var tree;
+  while ((tree = toVisit.pop())) {
+    if (tree[0] === id) {
+      return !!tree[1].deleted;
+    }
+    toVisit = toVisit.concat(tree[2]);
+  }
+}
+
+function evalFilter(input) {
+  return scopedEval('return ' + input + ';', {});
+}
+
+function evalView(input) {
+  /* jshint evil:true */
+  return new Function('doc', [
+    'var emitted = false;',
+    'var emit = function (a, b) {',
+    '  emitted = true;',
+    '};',
+    'var view = ' + input + ';',
+    'view(doc);',
+    'if (emitted) {',
+    '  return true;',
+    '}'
+  ].join('\n'));
+}
+
+function parseDesignDocFunctionName(s) {
+  if (!s) {
+    return null;
+  }
+  var parts = s.split('/');
+  if (parts.length === 2) {
+    return parts;
+  }
+  if (parts.length === 1) {
+    return [s, s];
+  }
+  return null;
+}
+
+function normalizeDesignDocFunctionName(s) {
+  var normalized = parseDesignDocFunctionName(s);
+  return normalized ? normalized.join('/') : null;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+  var toVisit = revs.slice();
+
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var branches = tree[2];
+    var newCtx =
+      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+    }
+  }
+}
+
+function sortByPos(a, b) {
+  return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+  var leaves = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+    if (isLeaf) {
+      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+    }
+  });
+  leaves.sort(sortByPos).reverse();
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    delete leaves[i].pos;
+  }
+  return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+  var win = winningRev(metadata);
+  var leaves = collectLeaves(metadata.rev_tree);
+  var conflicts = [];
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    var leaf = leaves[i];
+    if (leaf.rev !== win && !leaf.opts.deleted) {
+      conflicts.push(leaf.rev);
+    }
+  }
+  return conflicts;
+}
+
+inherits(PouchError, Error);
+
+function PouchError(opts) {
+  Error.call(this, opts.reason);
+  this.status = opts.status;
+  this.name = opts.error;
+  this.message = opts.reason;
+  this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
+
+var UNAUTHORIZED = new PouchError({
+  status: 401,
+  error: 'unauthorized',
+  reason: "Name or password is incorrect."
+});
+
+var MISSING_BULK_DOCS = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: "Missing JSON list of 'docs'"
+});
+
+var MISSING_DOC = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'missing'
+});
+
+var REV_CONFLICT = new PouchError({
+  status: 409,
+  error: 'conflict',
+  reason: 'Document update conflict'
+});
+
+var INVALID_ID = new PouchError({
+  status: 400,
+  error: 'invalid_id',
+  reason: '_id field must contain a string'
+});
+
+var MISSING_ID = new PouchError({
+  status: 412,
+  error: 'missing_id',
+  reason: '_id is required for puts'
+});
+
+var RESERVED_ID = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Only reserved document ids may start with underscore.'
+});
+
+var NOT_OPEN = new PouchError({
+  status: 412,
+  error: 'precondition_failed',
+  reason: 'Database not open'
+});
+
+var UNKNOWN_ERROR = new PouchError({
+  status: 500,
+  error: 'unknown_error',
+  reason: 'Database encountered an unknown error'
+});
+
+var BAD_ARG = new PouchError({
+  status: 500,
+  error: 'badarg',
+  reason: 'Some query argument is invalid'
+});
+
+var INVALID_REQUEST = new PouchError({
+  status: 400,
+  error: 'invalid_request',
+  reason: 'Request was invalid'
+});
+
+var QUERY_PARSE_ERROR = new PouchError({
+  status: 400,
+  error: 'query_parse_error',
+  reason: 'Some query parameter is invalid'
+});
+
+var DOC_VALIDATION = new PouchError({
+  status: 500,
+  error: 'doc_validation',
+  reason: 'Bad special document member'
+});
+
+var BAD_REQUEST = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Something wrong with the request'
+});
+
+var NOT_AN_OBJECT = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Document must be a JSON object'
+});
+
+var DB_MISSING = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'Database not found'
+});
+
+var IDB_ERROR = new PouchError({
+  status: 500,
+  error: 'indexed_db_went_bad',
+  reason: 'unknown'
+});
+
+var WSQ_ERROR = new PouchError({
+  status: 500,
+  error: 'web_sql_went_bad',
+  reason: 'unknown'
+});
+
+var LDB_ERROR = new PouchError({
+  status: 500,
+  error: 'levelDB_went_went_bad',
+  reason: 'unknown'
+});
+
+var FORBIDDEN = new PouchError({
+  status: 403,
+  error: 'forbidden',
+  reason: 'Forbidden by design doc validate_doc_update function'
+});
+
+var INVALID_REV = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Invalid rev format'
+});
+
+var FILE_EXISTS = new PouchError({
+  status: 412,
+  error: 'file_exists',
+  reason: 'The database could not be created, the file already exists.'
+});
+
+var MISSING_STUB = new PouchError({
+  status: 412,
+  error: 'missing_stub'
+});
+
+var INVALID_URL = new PouchError({
+  status: 413,
+  error: 'invalid_url',
+  reason: 'Provided URL is invalid'
+});
+
+var allErrors = {
+  UNAUTHORIZED: UNAUTHORIZED,
+  MISSING_BULK_DOCS: MISSING_BULK_DOCS,
+  MISSING_DOC: MISSING_DOC,
+  REV_CONFLICT: REV_CONFLICT,
+  INVALID_ID: INVALID_ID,
+  MISSING_ID: MISSING_ID,
+  RESERVED_ID: RESERVED_ID,
+  NOT_OPEN: NOT_OPEN,
+  UNKNOWN_ERROR: UNKNOWN_ERROR,
+  BAD_ARG: BAD_ARG,
+  INVALID_REQUEST: INVALID_REQUEST,
+  QUERY_PARSE_ERROR: QUERY_PARSE_ERROR,
+  DOC_VALIDATION: DOC_VALIDATION,
+  BAD_REQUEST: BAD_REQUEST,
+  NOT_AN_OBJECT: NOT_AN_OBJECT,
+  DB_MISSING: DB_MISSING,
+  WSQ_ERROR: WSQ_ERROR,
+  LDB_ERROR: LDB_ERROR,
+  FORBIDDEN: FORBIDDEN,
+  INVALID_REV: INVALID_REV,
+  FILE_EXISTS: FILE_EXISTS,
+  MISSING_STUB: MISSING_STUB,
+  IDB_ERROR: IDB_ERROR,
+  INVALID_URL: INVALID_URL
+};
+
+function createError(error, reason, name) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
+    }
+    /* jshint ignore:end */
+    if (name !== undefined) {
+      this.name = name;
+    }
+    if (reason !== undefined) {
+      this.reason = reason;
+    }
+  }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
+
+// Find one of the errors defined above based on the value
+// of the specified property.
+// If reason is provided prefer the error matching that reason.
+// This is for differentiating between errors with the same name and status,
+// eg, bad_request.
+var getErrorTypeByProp = function (prop, value, reason) {
+  var keys = Object.keys(allErrors).filter(function (key) {
+    var error = allErrors[key];
+    return typeof error !== 'function' && error[prop] === value;
+  });
+  var key = reason && keys.filter(function (key) {
+        var error = allErrors[key];
+        return error.message === reason;
+      })[0] || keys[0];
+  return (key) ? allErrors[key] : null;
+};
+
+function generateErrorFromResponse(res) {
+  var error, errName, errType, errMsg, errReason;
+
+  errName = (res.error === true && typeof res.name === 'string') ?
+              res.name :
+              res.error;
+  errReason = res.reason;
+  errType = getErrorTypeByProp('name', errName, errReason);
+
+  if (res.missing ||
+      errReason === 'missing' ||
+      errReason === 'deleted' ||
+      errName === 'not_found') {
+    errType = MISSING_DOC;
+  } else if (errName === 'doc_validation') {
+    // doc validation needs special treatment since
+    // res.reason depends on the validation error.
+    // see utils.js
+    errType = DOC_VALIDATION;
+    errMsg = errReason;
+  } else if (errName === 'bad_request' && errType.message !== errReason) {
+    // if bad_request error already found based on reason don't override.
+    errType = BAD_REQUEST;
+  }
+
+  // fallback to error by status or unknown error.
+  if (!errType) {
+    errType = getErrorTypeByProp('status', res.status, errReason) ||
+                UNKNOWN_ERROR;
+  }
+
+  error = createError(errType, errReason, errName);
+
+  // Keep custom message.
+  if (errMsg) {
+    error.message = errMsg;
+  }
+
+  // Keep helpful response data in our error messages.
+  if (res.id) {
+    error.id = res.id;
+  }
+  if (res.status) {
+    error.status = res.status;
+  }
+  if (res.missing) {
+    error.missing = res.missing;
+  }
+
+  return error;
+}
+
+inherits(Changes, events.EventEmitter);
+
+function Changes(db, opts, callback) {
+  events.EventEmitter.call(this);
+  var self = this;
+  this.db = db;
+  opts = opts ? clone(opts) : {};
+  var complete = opts.complete = once(function (err, resp) {
+    if (err) {
+      self.emit('error', err);
+    } else {
+      self.emit('complete', resp);
+    }
+    self.removeAllListeners();
+    db.removeListener('destroyed', onDestroy);
+  });
+  if (callback) {
+    self.on('complete', function (resp) {
+      callback(null, resp);
+    });
+    self.on('error', callback);
+  }
+  function onDestroy() {
+    self.cancel();
+  }
+  db.once('destroyed', onDestroy);
+
+  opts.onChange = function (change) {
+    /* istanbul ignore if */
+    if (opts.isCancelled) {
+      return;
+    }
+    self.emit('change', change);
+    if (self.startSeq && self.startSeq <= change.seq) {
+      self.startSeq = false;
+    }
+  };
+
+  var promise = new PouchPromise(function (fulfill, reject) {
+    opts.complete = function (err, res) {
+      if (err) {
+        reject(err);
+      } else {
+        fulfill(res);
+      }
+    };
+  });
+  self.once('cancel', function () {
+    db.removeListener('destroyed', onDestroy);
+    opts.complete(null, {status: 'cancelled'});
+  });
+  this.then = promise.then.bind(promise);
+  this['catch'] = promise['catch'].bind(promise);
+  this.then(function (result) {
+    complete(null, result);
+  }, complete);
+
+
+
+  if (!db.taskqueue.isReady) {
+    db.taskqueue.addTask(function () {
+      if (self.isCancelled) {
+        self.emit('cancel');
+      } else {
+        self.doChanges(opts);
+      }
+    });
+  } else {
+    self.doChanges(opts);
+  }
+}
+Changes.prototype.cancel = function () {
+  this.isCancelled = true;
+  if (this.db.taskqueue.isReady) {
+    this.emit('cancel');
+  }
+};
+function processChange(doc, metadata, opts) {
+  var changeList = [{rev: doc._rev}];
+  if (opts.style === 'all_docs') {
+    changeList = collectLeaves(metadata.rev_tree)
+    .map(function (x) { return {rev: x.rev}; });
+  }
+  var change = {
+    id: metadata.id,
+    changes: changeList,
+    doc: doc
+  };
+
+  if (isDeleted(metadata, doc._rev)) {
+    change.deleted = true;
+  }
+  if (opts.conflicts) {
+    change.doc._conflicts = collectConflicts(metadata);
+    if (!change.doc._conflicts.length) {
+      delete change.doc._conflicts;
+    }
+  }
+  return change;
+}
+
+Changes.prototype.doChanges = function (opts) {
+  var self = this;
+  var callback = opts.complete;
+
+  opts = clone(opts);
+  if ('live' in opts && !('continuous' in opts)) {
+    opts.continuous = opts.live;
+  }
+  opts.processChange = processChange;
+
+  if (opts.since === 'latest') {
+    opts.since = 'now';
+  }
+  if (!opts.since) {
+    opts.since = 0;
+  }
+  if (opts.since === 'now') {
+    this.db.info().then(function (info) {
+      /* istanbul ignore if */
+      if (self.isCancelled) {
+        callback(null, {status: 'cancelled'});
+        return;
+      }
+      opts.since = info.update_seq;
+      self.doChanges(opts);
+    }, callback);
+    return;
+  }
+
+  if (opts.continuous && opts.since !== 'now') {
+    this.db.info().then(function (info) {
+      self.startSeq = info.update_seq;
+    /* istanbul ignore next */
+    }, function (err) {
+      if (err.id === 'idbNull') {
+        // db closed before this returned thats ok
+        return;
+      }
+      throw err;
+    });
+  }
+
+  if (opts.filter && typeof opts.filter === 'string') {
+    if (opts.filter === '_view') {
+      opts.view = normalizeDesignDocFunctionName(opts.view);
+    } else {
+      opts.filter = normalizeDesignDocFunctionName(opts.filter);
+    }
+
+    if (this.db.type() !== 'http' && !opts.doc_ids) {
+      return this.filterChanges(opts);
+    }
+  }
+
+  if (!('descending' in opts)) {
+    opts.descending = false;
+  }
+
+  // 0 and 1 should return 1 document
+  opts.limit = opts.limit === 0 ? 1 : opts.limit;
+  opts.complete = callback;
+  var newPromise = this.db._changes(opts);
+  if (newPromise && typeof newPromise.cancel === 'function') {
+    var cancel = self.cancel;
+    self.cancel = getArguments(function (args) {
+      newPromise.cancel();
+      cancel.apply(this, args);
+    });
+  }
+};
+
+Changes.prototype.filterChanges = function (opts) {
+  var self = this;
+  var callback = opts.complete;
+  if (opts.filter === '_view') {
+    if (!opts.view || typeof opts.view !== 'string') {
+      var err = createError(BAD_REQUEST,
+        '`view` filter parameter not found or invalid.');
+      return callback(err);
+    }
+    // fetch a view from a design doc, make it behave like a filter
+    var viewName = parseDesignDocFunctionName(opts.view);
+    this.db.getView(viewName[0], viewName[1], function (err, view) {
+      /* istanbul ignore if */
+      if (self.isCancelled) {
+        return callback(null, {status: 'cancelled'});
+      }
+      /* istanbul ignore next */
+      if (err) {
+        return callback(generateErrorFromResponse(err));
+      }
+      if (!view.map) {
+        return callback(createError(MISSING_DOC));
+      }
+      opts.filter = evalView(view.map);
+      self.doChanges(opts);
+    });
+  } else {
+    // fetch a filter from a design doc
+    var filterName = parseDesignDocFunctionName(opts.filter);
+    if (!filterName) {
+      return self.doChanges(opts);
+    }
+    this.db.getFilter(filterName[0], filterName[1], function (err, filterFun) {
+      /* istanbul ignore if */
+      if (self.isCancelled) {
+        return callback(null, {status: 'cancelled'});
+      }
+      /* istanbul ignore next */
+      if (err) {
+        return callback(generateErrorFromResponse(err));
+      }
+      opts.filter = evalFilter(filterFun);
+      self.doChanges(opts);
+    });
+  }
+};
+
+// shim for P/CouchDB adapters that don't directly implement _bulk_get
+function bulkGet(db, opts, callback) {
+  var requests = Array.isArray(opts) ? opts : opts.docs;
+
+  // consolidate into one request per doc if possible
+  var requestsById = {};
+  requests.forEach(function (request) {
+    if (request.id in requestsById) {
+      requestsById[request.id].push(request);
+    } else {
+      requestsById[request.id] = [request];
+    }
+  });
+
+  var numDocs = Object.keys(requestsById).length;
+  var numDone = 0;
+  var perDocResults = new Array(numDocs);
+
+  function collapseResults() {
+    var results = [];
+    perDocResults.forEach(function (res) {
+      res.docs.forEach(function (info) {
+        results.push({
+          id: res.id,
+          docs: [info]
+        });
+      });
+    });
+    callback(null, {results: results});
+  }
+
+  function checkDone() {
+    if (++numDone === numDocs) {
+      collapseResults();
+    }
+  }
+
+  function gotResult(i, id, docs) {
+    perDocResults[i] = {id: id, docs: docs};
+    checkDone();
+  }
+
+  Object.keys(requestsById).forEach(function (docId, i) {
+
+    var docRequests = requestsById[docId];
+
+    // just use the first request as the "template"
+    // TODO: The _bulk_get API allows for more subtle use cases than this,
+    // but for now it is unlikely that there will be a mix of different
+    // "atts_since" or "attachments" in the same request, since it's just
+    // replicate.js that is using this for the moment.
+    // Also, atts_since is aspirational, since we don't support it yet.
+    var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
+    docOpts.open_revs = docRequests.map(function (request) {
+      // rev is optional, open_revs disallowed
+      return request.rev;
+    });
+
+    // remove falsey / undefined revisions
+    docOpts.open_revs = docOpts.open_revs.filter(function (e) { return e; });
+
+    var formatResult = function (result) { return result; };
+
+    if (docOpts.open_revs.length === 0) {
+      delete docOpts.open_revs;
+
+      // when fetching only the "winning" leaf,
+      // transform the result so it looks like an open_revs
+      // request
+      formatResult = function (result) {
+        return [{
+          ok: result
+        }];
+      };
+    }
+
+    // globally-supplied options
+    ['revs', 'attachments', 'binary', 'ajax'].forEach(function (param) {
+      if (param in opts) {
+        docOpts[param] = opts[param];
+      }
+    });
+    db.get(docId, docOpts, function (err, res) {
+      gotResult(i, docId, err ? [{error: err}] : formatResult(res));
+    });
+  });
+}
+
+function isLocalId(id) {
+  return (/^_local/).test(id);
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+  var paths = [];
+  var toVisit = revs.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
+
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, opts: opts});
+    if (isLeaf) {
+      paths.push({pos: (pos + 1 - history.length), ids: history});
+    }
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+    }
+  }
+  return paths.reverse();
+}
+
+// BEGIN Math.uuid.js
+
+/*!
+Math.uuid.js (v1.4)
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+*/
+
+/*
+ * Generate a random uuid.
+ *
+ * USAGE: Math.uuid(length, radix)
+ *   length - the desired number of characters
+ *   radix  - the number of allowable values for each character.
+ *
+ * EXAMPLES:
+ *   // No arguments  - returns RFC4122, version 4 ID
+ *   >>> Math.uuid()
+ *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ *   // One argument - returns ID of the specified length
+ *   >>> Math.uuid(15)     // 15 character ID (default base=62)
+ *   "VcydxgltxrVZSTV"
+ *
+ *   // Two arguments - returns ID of the specified length, and radix. 
+ *   // (Radix must be <= 62)
+ *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
+ *   "01001010"
+ *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
+ *   "47473046"
+ *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
+ *   "098F4D35"
+ */
+var chars = (
+  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
+  'abcdefghijklmnopqrstuvwxyz'
+).split('');
+function getValue(radix) {
+  return 0 | Math.random() * radix;
+}
+function uuid(len, radix) {
+  radix = radix || chars.length;
+  var out = '';
+  var i = -1;
+
+  if (len) {
+    // Compact form
+    while (++i < len) {
+      out += chars[getValue(radix)];
+    }
+    return out;
+  }
+    // rfc4122, version 4 form
+    // Fill in random data.  At i==19 set the high bits of clock sequence as
+    // per rfc4122, sec. 4.1.5
+  while (++i < 36) {
+    switch (i) {
+      case 8:
+      case 13:
+      case 18:
+      case 23:
+        out += '-';
+        break;
+      case 19:
+        out += chars[(getValue(16) & 0x3) | 0x8];
+        break;
+      default:
+        out += chars[getValue(16)];
+    }
+  }
+
+  return out;
+}
+
+function toObject(array) {
+  return array.reduce(function (obj, item) {
+    obj[item] = true;
+    return obj;
+  }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+  '_id',
+  '_rev',
+  '_attachments',
+  '_deleted',
+  '_revisions',
+  '_revs_info',
+  '_conflicts',
+  '_deleted_conflicts',
+  '_local_seq',
+  '_rev_tree',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats',
+  // Specific to Couchbase Sync Gateway
+  '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+  '_attachments',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats'
+]);
+
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = createError(MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = createError(INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = createError(RESERVED_ID);
+  }
+  if (err) {
+    throw err;
+  }
+}
+
+function parseRevisionInfo(rev) {
+  if (!/^\d+\-./.test(rev)) {
+    return createError(INVALID_REV);
+  }
+  var idx = rev.indexOf('-');
+  var left = rev.substring(0, idx);
+  var right = rev.substring(idx + 1);
+  return {
+    prefix: parseInt(left, 10),
+    id: right
+  };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+  var pos = revisions.start - revisions.ids.length + 1;
+
+  var revisionIds = revisions.ids;
+  var ids = [revisionIds[0], opts, []];
+
+  for (var i = 1, len = revisionIds.length; i < len; i++) {
+    ids = [revisionIds[i], {status: 'missing'}, [ids]];
+  }
+
+  return [{
+    pos: pos,
+    ids: ids
+  }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits) {
+
+  var nRevNum;
+  var newRevId;
+  var revInfo;
+  var opts = {status: 'available'};
+  if (doc._deleted) {
+    opts.deleted = true;
+  }
+
+  if (newEdits) {
+    if (!doc._id) {
+      doc._id = uuid();
+    }
+    newRevId = uuid(32, 16).toLowerCase();
+    if (doc._rev) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      doc._rev_tree = [{
+        pos: revInfo.prefix,
+        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+      }];
+      nRevNum = revInfo.prefix + 1;
+    } else {
+      doc._rev_tree = [{
+        pos: 1,
+        ids : [newRevId, opts, []]
+      }];
+      nRevNum = 1;
+    }
+  } else {
+    if (doc._revisions) {
+      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+      nRevNum = doc._revisions.start;
+      newRevId = doc._revisions.ids[0];
+    }
+    if (!doc._rev_tree) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      nRevNum = revInfo.prefix;
+      newRevId = revInfo.id;
+      doc._rev_tree = [{
+        pos: nRevNum,
+        ids: [newRevId, opts, []]
+      }];
+    }
+  }
+
+  invalidIdError(doc._id);
+
+  doc._rev = nRevNum + '-' + newRevId;
+
+  var result = {metadata : {}, data : {}};
+  for (var key in doc) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(doc, key)) {
+      var specialKey = key[0] === '_';
+      if (specialKey && !reservedWords[key]) {
+        var error = createError(DOC_VALIDATION, key);
+        error.message = DOC_VALIDATION.message + ': ' + key;
+        throw error;
+      } else if (specialKey && !dataWords[key]) {
+        result.metadata[key.slice(1)] = doc[key];
+      } else {
+        result.data[key] = doc[key];
+      }
+    }
+  }
+  return result;
+}
+
+/*
+ * A generic pouch adapter
+ */
+
+function compare(left, right) {
+  return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// returns first element of arr satisfying callback predicate
+function arrayFirst(arr, callback) {
+  for (var i = 0; i < arr.length; i++) {
+    if (callback(arr[i], i) === true) {
+      return arr[i];
+    }
+  }
+}
+
+// Wrapper for functions that call the bulkdocs api with a single doc,
+// if the first result is an error, return an error
+function yankError(callback) {
+  return function (err, results) {
+    if (err || (results[0] && results[0].error)) {
+      callback(err || results[0]);
+    } else {
+      callback(null, results.length ? results[0]  : results);
+    }
+  };
+}
+
+// clean docs given to us by the user
+function cleanDocs(docs) {
+  for (var i = 0; i < docs.length; i++) {
+    var doc = docs[i];
+    if (doc._deleted) {
+      delete doc._attachments; // ignore atts for deleted docs
+    } else if (doc._attachments) {
+      // filter out extraneous keys from _attachments
+      var atts = Object.keys(doc._attachments);
+      for (var j = 0; j < atts.length; j++) {
+        var att = atts[j];
+        doc._attachments[att] = pick(doc._attachments[att],
+          ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']);
+      }
+    }
+  }
+}
+
+// compare two docs, first by _id then by _rev
+function compareByIdThenRev(a, b) {
+  var idCompare = compare(a._id, b._id);
+  if (idCompare !== 0) {
+    return idCompare;
+  }
+  var aStart = a._revisions ? a._revisions.start : 0;
+  var bStart = b._revisions ? b._revisions.start : 0;
+  return compare(aStart, bStart);
+}
+
+// for every node in a revision tree computes its distance from the closest
+// leaf
+function computeHeight(revs) {
+  var height = {};
+  var edges = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
+    var rev = pos + "-" + id;
+    if (isLeaf) {
+      height[rev] = 0;
+    }
+    if (prnt !== undefined) {
+      edges.push({from: prnt, to: rev});
+    }
+    return rev;
+  });
+
+  edges.reverse();
+  edges.forEach(function (edge) {
+    if (height[edge.from] === undefined) {
+      height[edge.from] = 1 + height[edge.to];
+    } else {
+      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
+    }
+  });
+  return height;
+}
+
+function allDocsKeysQuery(api, opts, callback) {
+  var keys =  ('limit' in opts) ?
+      opts.keys.slice(opts.skip, opts.limit + opts.skip) :
+      (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
+  if (opts.descending) {
+    keys.reverse();
+  }
+  if (!keys.length) {
+    return api._allDocs({limit: 0}, callback);
+  }
+  var finalResults = {
+    offset: opts.skip
+  };
+  return PouchPromise.all(keys.map(function (key) {
+    var subOpts = jsExtend.extend({key: key, deleted: 'ok'}, opts);
+    ['limit', 'skip', 'keys'].forEach(function (optKey) {
+      delete subOpts[optKey];
+    });
+    return new PouchPromise(function (resolve, reject) {
+      api._allDocs(subOpts, function (err, res) {
+        /* istanbul ignore if */
+        if (err) {
+          return reject(err);
+        }
+        finalResults.total_rows = res.total_rows;
+        resolve(res.rows[0] || {key: key, error: 'not_found'});
+      });
+    });
+  })).then(function (results) {
+    finalResults.rows = results;
+    return finalResults;
+  });
+}
+
+// all compaction is done in a queue, to avoid attaching
+// too many listeners at once
+function doNextCompaction(self) {
+  var task = self._compactionQueue[0];
+  var opts = task.opts;
+  var callback = task.callback;
+  self.get('_local/compaction')["catch"](function () {
+    return false;
+  }).then(function (doc) {
+    if (doc && doc.last_seq) {
+      opts.last_seq = doc.last_seq;
+    }
+    self._compact(opts, function (err, res) {
+      /* istanbul ignore if */
+      if (err) {
+        callback(err);
+      } else {
+        callback(null, res);
+      }
+      process.nextTick(function () {
+        self._compactionQueue.shift();
+        if (self._compactionQueue.length) {
+          doNextCompaction(self);
+        }
+      });
+    });
+  });
+}
+
+function attachmentNameError(name) {
+  if (name.charAt(0) === '_') {
+    return name + 'is not a valid attachment name, attachment ' +
+      'names cannot start with \'_\'';
+  }
+  return false;
+}
+
+function cacheUpdateRequired(api, cache, designDocName, callback) {
+  cache.seq = cache.seq || 0;
+  var changesOpts = {
+    doc_ids: [ '_design/' + designDocName ],
+    limit: 1,
+    since: cache.seq
+  };
+  api.changes(changesOpts).then(function (res) {
+    var latestSeq = res.results && res.results.length && res.results[0].seq;
+    if (latestSeq && latestSeq > cache.seq) {
+      // invalidate the cache
+      cache.seq = latestSeq;
+      delete cache.promise;
+    }
+    callback();
+  })["catch"](callback);
+}
+
+function getDesignDocCache(api, designDocName, callback) {
+  api._ddocCache = api._ddocCache || {};
+  api._ddocCache[designDocName] = api._ddocCache[designDocName] || {};
+  var cache = api._ddocCache[designDocName];
+  cacheUpdateRequired(api, cache, designDocName, function (err) {
+    if (err) {
+      return callback(err);
+    }
+    if (!cache.promise) {
+      cache.promise = new PouchPromise(function (resolve, reject) {
+        api._get('_design/' + designDocName, {}, function (err, res) {
+          if (err) {
+            return reject(err);
+          }
+          var cache = {};
+          ['views', 'filters'].forEach(function (propertyName) {
+            cache[propertyName] = res.doc[propertyName];
+          });
+          resolve(cache);
+        });
+      });
+    }
+    cache.promise.then(function (cache) {
+      callback(null, cache);
+    })["catch"](callback);
+  });
+}
+
+function getDesignDocProperty(api, designDocName, propertyName,
+                              propertyElement, callback) {
+  getDesignDocCache(api, designDocName, function (err, designDoc) {
+    if (err) {
+      return callback(err);
+    }
+    var element = designDoc[propertyName] &&
+                  designDoc[propertyName][propertyElement];
+    if (!element) {
+      return callback(createError(MISSING_DOC));
+    }
+    callback(null, element);
+  });
+}
+
+inherits(AbstractPouchDB, events.EventEmitter);
+
+function AbstractPouchDB() {
+  events.EventEmitter.call(this);
+}
+
+AbstractPouchDB.prototype.post =
+  adapterFun('post', function (doc, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  if (typeof doc !== 'object' || Array.isArray(doc)) {
+    return callback(createError(NOT_AN_OBJECT));
+  }
+  this.bulkDocs({docs: [doc]}, opts, yankError(callback));
+});
+
+AbstractPouchDB.prototype.put =
+  adapterFun('put', getArguments(function (args) {
+  var temp, temptype, opts, callback;
+  var doc = args.shift();
+  var id = '_id' in doc;
+  if (typeof doc !== 'object' || Array.isArray(doc)) {
+    callback = args.pop();
+    return callback(createError(NOT_AN_OBJECT));
+  }
+
+  /* eslint no-constant-condition: 0 */
+  while (true) {
+    temp = args.shift();
+    temptype = typeof temp;
+    if (temptype === "string" && !id) {
+      doc._id = temp;
+      id = true;
+    } else if (temptype === "string" && id && !('_rev' in doc)) {
+      doc._rev = temp;
+    } else if (temptype === "object") {
+      opts = temp;
+    } else if (temptype === "function") {
+      callback = temp;
+    }
+    if (!args.length) {
+      break;
+    }
+  }
+  opts = opts || {};
+  invalidIdError(doc._id);
+  if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
+    if (doc._deleted) {
+      return this._removeLocal(doc, callback);
+    } else {
+      return this._putLocal(doc, callback);
+    }
+  }
+  this.bulkDocs({docs: [doc]}, opts, yankError(callback));
+}));
+
+AbstractPouchDB.prototype.putAttachment =
+  adapterFun('putAttachment', function (docId, attachmentId, rev,
+                                              blob, type) {
+  var api = this;
+  if (typeof type === 'function') {
+    type = blob;
+    blob = rev;
+    rev = null;
+  }
+  // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267
+  /* istanbul ignore if */
+  if (typeof type === 'undefined') {
+    type = blob;
+    blob = rev;
+    rev = null;
+  }
+
+  function createAttachment(doc) {
+    var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0;
+    doc._attachments = doc._attachments || {};
+    doc._attachments[attachmentId] = {
+      content_type: type,
+      data: blob,
+      revpos: ++prevrevpos
+    };
+    return api.put(doc);
+  }
+
+  return api.get(docId).then(function (doc) {
+    if (doc._rev !== rev) {
+      throw createError(REV_CONFLICT);
+    }
+
+    return createAttachment(doc);
+  }, function (err) {
+     // create new doc
+    /* istanbul ignore else */
+    if (err.reason === MISSING_DOC.message) {
+      return createAttachment({_id: docId});
+    } else {
+      throw err;
+    }
+  });
+});
+
+AbstractPouchDB.prototype.removeAttachment =
+  adapterFun('removeAttachment', function (docId, attachmentId, rev,
+                                                 callback) {
+  var self = this;
+  self.get(docId, function (err, obj) {
+    /* istanbul ignore if */
+    if (err) {
+      callback(err);
+      return;
+    }
+    if (obj._rev !== rev) {
+      callback(createError(REV_CONFLICT));
+      return;
+    }
+    /* istanbul ignore if */
+    if (!obj._attachments) {
+      return callback();
+    }
+    delete obj._attachments[attachmentId];
+    if (Object.keys(obj._attachments).length === 0) {
+      delete obj._attachments;
+    }
+    self.put(obj, callback);
+  });
+});
+
+AbstractPouchDB.prototype.remove =
+  adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
+  var doc;
+  if (typeof optsOrRev === 'string') {
+    // id, rev, opts, callback style
+    doc = {
+      _id: docOrId,
+      _rev: optsOrRev
+    };
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+  } else {
+    // doc, opts, callback style
+    doc = docOrId;
+    if (typeof optsOrRev === 'function') {
+      callback = optsOrRev;
+      opts = {};
+    } else {
+      callback = opts;
+      opts = optsOrRev;
+    }
+  }
+  opts = opts || {};
+  opts.was_delete = true;
+  var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
+  newDoc._deleted = true;
+  if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
+    return this._removeLocal(doc, callback);
+  }
+  this.bulkDocs({docs: [newDoc]}, opts, yankError(callback));
+});
+
+AbstractPouchDB.prototype.revsDiff =
+  adapterFun('revsDiff', function (req, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  var ids = Object.keys(req);
+
+  if (!ids.length) {
+    return callback(null, {});
+  }
+
+  var count = 0;
+  var missing = new pouchdbCollections.Map();
+
+  function addToMissing(id, revId) {
+    if (!missing.has(id)) {
+      missing.set(id, {missing: []});
+    }
+    missing.get(id).missing.push(revId);
+  }
+
+  function processDoc(id, rev_tree) {
+    // Is this fast enough? Maybe we should switch to a set simulated by a map
+    var missingForId = req[id].slice(0);
+    traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
+      opts) {
+        var rev = pos + '-' + revHash;
+        var idx = missingForId.indexOf(rev);
+        if (idx === -1) {
+          return;
+        }
+
+        missingForId.splice(idx, 1);
+        /* istanbul ignore if */
+        if (opts.status !== 'available') {
+          addToMissing(id, rev);
+        }
+      });
+
+    // Traversing the tree is synchronous, so now `missingForId` contains
+    // revisions that were not found in the tree
+    missingForId.forEach(function (rev) {
+      addToMissing(id, rev);
+    });
+  }
+
+  ids.map(function (id) {
+    this._getRevisionTree(id, function (err, rev_tree) {
+      if (err && err.status === 404 && err.message === 'missing') {
+        missing.set(id, {missing: req[id]});
+      } else if (err) {
+        /* istanbul ignore next */
+        return callback(err);
+      } else {
+        processDoc(id, rev_tree);
+      }
+
+      if (++count === ids.length) {
+        // convert LazyMap to object
+        var missingObj = {};
+        missing.forEach(function (value, key) {
+          missingObj[key] = value;
+        });
+        return callback(null, missingObj);
+      }
+    });
+  }, this);
+});
+
+// _bulk_get API for faster replication, as described in
+// https://github.com/apache/couchdb-chttpd/pull/33
+// At the "abstract" level, it will just run multiple get()s in
+// parallel, because this isn't much of a performance cost
+// for local databases (except the cost of multiple transactions, which is
+// small). The http adapter overrides this in order
+// to do a more efficient single HTTP request.
+AbstractPouchDB.prototype.bulkGet =
+  adapterFun('bulkGet', function (opts, callback) {
+  bulkGet(this, opts, callback);
+});
+
+// compact one document and fire callback
+// by compacting we mean removing all revisions which
+// are further from the leaf in revision tree than max_height
+AbstractPouchDB.prototype.compactDocument =
+  adapterFun('compactDocument', function (docId, maxHeight, callback) {
+  var self = this;
+  this._getRevisionTree(docId, function (err, revTree) {
+    /* istanbul ignore if */
+    if (err) {
+      return callback(err);
+    }
+    var height = computeHeight(revTree);
+    var candidates = [];
+    var revs = [];
+    Object.keys(height).forEach(function (rev) {
+      if (height[rev] > maxHeight) {
+        candidates.push(rev);
+      }
+    });
+
+    traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) {
+      var rev = pos + '-' + revHash;
+      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
+        revs.push(rev);
+      }
+    });
+    self._doCompaction(docId, revs, callback);
+  });
+});
+
+// compact the whole database using single document
+// compaction
+AbstractPouchDB.prototype.compact =
+  adapterFun('compact', function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+
+  var self = this;
+  opts = opts || {};
+
+  self._compactionQueue = self._compactionQueue || [];
+  self._compactionQueue.push({opts: opts, callback: callback});
+  if (self._compactionQueue.length === 1) {
+    doNextCompaction(self);
+  }
+});
+AbstractPouchDB.prototype._compact = function (opts, callback) {
+  var self = this;
+  var changesOpts = {
+    return_docs: false,
+    last_seq: opts.last_seq || 0
+  };
+  var promises = [];
+
+  function onChange(row) {
+    promises.push(self.compactDocument(row.id, 0));
+  }
+  function onComplete(resp) {
+    var lastSeq = resp.last_seq;
+    PouchPromise.all(promises).then(function () {
+      return upsert(self, '_local/compaction', function deltaFunc(doc) {
+        if (!doc.last_seq || doc.last_seq < lastSeq) {
+          doc.last_seq = lastSeq;
+          return doc;
+        }
+        return false; // somebody else got here first, don't update
+      });
+    }).then(function () {
+      callback(null, {ok: true});
+    })["catch"](callback);
+  }
+  self.changes(changesOpts)
+    .on('change', onChange)
+    .on('complete', onComplete)
+    .on('error', callback);
+};
+/* Begin api wrappers. Specific functionality to storage belongs in the
+   _[method] */
+AbstractPouchDB.prototype.get =
+  adapterFun('get', function (id, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  if (typeof id !== 'string') {
+    return callback(createError(INVALID_ID));
+  }
+  if (isLocalId(id) && typeof this._getLocal === 'function') {
+    return this._getLocal(id, callback);
+  }
+  var leaves = [], self = this;
+
+  function finishOpenRevs() {
+    var result = [];
+    var count = leaves.length;
+    /* istanbul ignore if */
+    if (!count) {
+      return callback(null, result);
+    }
+    // order with open_revs is unspecified
+    leaves.forEach(function (leaf) {
+      self.get(id, {
+        rev: leaf,
+        revs: opts.revs,
+        attachments: opts.attachments
+      }, function (err, doc) {
+        if (!err) {
+          result.push({ok: doc});
+        } else {
+          result.push({missing: leaf});
+        }
+        count--;
+        if (!count) {
+          callback(null, result);
+        }
+      });
+    });
+  }
+
+  if (opts.open_revs) {
+    if (opts.open_revs === "all") {
+      this._getRevisionTree(id, function (err, rev_tree) {
+        if (err) {
+          return callback(err);
+        }
+        leaves = collectLeaves(rev_tree).map(function (leaf) {
+          return leaf.rev;
+        });
+        finishOpenRevs();
+      });
+    } else {
+      if (Array.isArray(opts.open_revs)) {
+        leaves = opts.open_revs;
+        for (var i = 0; i < leaves.length; i++) {
+          var l = leaves[i];
+          // looks like it's the only thing couchdb checks
+          if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
+            return callback(createError(INVALID_REV));
+          }
+        }
+        finishOpenRevs();
+      } else {
+        return callback(createError(UNKNOWN_ERROR,
+          'function_clause'));
+      }
+    }
+    return; // open_revs does not like other options
+  }
+
+  return this._get(id, opts, function (err, result) {
+    if (err) {
+      return callback(err);
+    }
+
+    var doc = result.doc;
+    var metadata = result.metadata;
+    var ctx = result.ctx;
+
+    if (opts.conflicts) {
+      var conflicts = collectConflicts(metadata);
+      if (conflicts.length) {
+        doc._conflicts = conflicts;
+      }
+    }
+
+    if (isDeleted(metadata, doc._rev)) {
+      doc._deleted = true;
+    }
+
+    if (opts.revs || opts.revs_info) {
+      var paths = rootToLeaf(metadata.rev_tree);
+      var path = arrayFirst(paths, function (arr) {
+        return arr.ids.map(function (x) { return x.id; })
+          .indexOf(doc._rev.split('-')[1]) !== -1;
+      });
+
+      var indexOfRev = path.ids.map(function (x) {return x.id; })
+        .indexOf(doc._rev.split('-')[1]) + 1;
+      var howMany = path.ids.length - indexOfRev;
+      path.ids.splice(indexOfRev, howMany);
+      path.ids.reverse();
+
+      if (opts.revs) {
+        doc._revisions = {
+          start: (path.pos + path.ids.length) - 1,
+          ids: path.ids.map(function (rev) {
+            return rev.id;
+          })
+        };
+      }
+      if (opts.revs_info) {
+        var pos =  path.pos + path.ids.length;
+        doc._revs_info = path.ids.map(function (rev) {
+          pos--;
+          return {
+            rev: pos + '-' + rev.id,
+            status: rev.opts.status
+          };
+        });
+      }
+    }
+
+    if (opts.attachments && doc._attachments) {
+      var attachments = doc._attachments;
+      var count = Object.keys(attachments).length;
+      if (count === 0) {
+        return callback(null, doc);
+      }
+      Object.keys(attachments).forEach(function (key) {
+        this._getAttachment(attachments[key], {
+          binary: opts.binary,
+          ctx: ctx
+        }, function (err, data) {
+          var att = doc._attachments[key];
+          att.data = data;
+          delete att.stub;
+          delete att.length;
+          if (!--count) {
+            callback(null, doc);
+          }
+        });
+      }, self);
+    } else {
+      if (doc._attachments) {
+        for (var key in doc._attachments) {
+          /* istanbul ignore else */
+          if (doc._attachments.hasOwnProperty(key)) {
+            doc._attachments[key].stub = true;
+          }
+        }
+      }
+      callback(null, doc);
+    }
+  });
+});
+
+AbstractPouchDB.prototype.getView =
+  adapterFun('getView', function (designDocName, viewName, callback) {
+  getDesignDocProperty(this, designDocName, 'views', viewName, callback);
+});
+
+AbstractPouchDB.prototype.getFilter =
+  adapterFun('getFilter', function (designDocName, filterName, callback) {
+  getDesignDocProperty(this, designDocName, 'filters', filterName, callback);
+});
+
+AbstractPouchDB.prototype.getAttachment =
+  adapterFun('getAttachment', function (docId, attachmentId, opts,
+                                              callback) {
+  var self = this;
+  if (opts instanceof Function) {
+    callback = opts;
+    opts = {};
+  }
+  this._get(docId, opts, function (err, res) {
+    if (err) {
+      return callback(err);
+    }
+    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
+      opts.ctx = res.ctx;
+      opts.binary = true;
+      self._getAttachment(res.doc._attachments[attachmentId], opts, callback);
+    } else {
+      return callback(createError(MISSING_DOC));
+    }
+  });
+});
+
+AbstractPouchDB.prototype.allDocs =
+  adapterFun('allDocs', function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
+  if (opts.start_key) {
+    opts.startkey = opts.start_key;
+  }
+  if (opts.end_key) {
+    opts.endkey = opts.end_key;
+  }
+  if ('keys' in opts) {
+    if (!Array.isArray(opts.keys)) {
+      return callback(new TypeError('options.keys must be an array'));
+    }
+    var incompatibleOpt =
+      ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
+      return incompatibleOpt in opts;
+    })[0];
+    if (incompatibleOpt) {
+      callback(createError(QUERY_PARSE_ERROR,
+        'Query parameter `' + incompatibleOpt +
+        '` is not compatible with multi-get'
+      ));
+      return;
+    }
+    if (this.type() !== 'http') {
+      return allDocsKeysQuery(this, opts, callback);
+    }
+  }
+
+  return this._allDocs(opts, callback);
+});
+
+AbstractPouchDB.prototype.changes = function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return new Changes(this, opts, callback);
+};
+
+AbstractPouchDB.prototype.close =
+  adapterFun('close', function (callback) {
+  this._closed = true;
+  return this._close(callback);
+});
+
+AbstractPouchDB.prototype.info = adapterFun('info', function (callback) {
+  var self = this;
+  this._info(function (err, info) {
+    if (err) {
+      return callback(err);
+    }
+    // assume we know better than the adapter, unless it informs us
+    info.db_name = info.db_name || self._db_name;
+    info.auto_compaction = !!(self.auto_compaction && self.type() !== 'http');
+    info.adapter = self.type();
+    callback(null, info);
+  });
+});
+
+AbstractPouchDB.prototype.id = adapterFun('id', function (callback) {
+  return this._id(callback);
+});
+
+AbstractPouchDB.prototype.type = function () {
+  /* istanbul ignore next */
+  return (typeof this._type === 'function') ? this._type() : this.adapter;
+};
+
+AbstractPouchDB.prototype.bulkDocs =
+  adapterFun('bulkDocs', function (req, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+
+  opts = opts || {};
+
+  if (Array.isArray(req)) {
+    req = {
+      docs: req
+    };
+  }
+
+  if (!req || !req.docs || !Array.isArray(req.docs)) {
+    return callback(createError(MISSING_BULK_DOCS));
+  }
+
+  for (var i = 0; i < req.docs.length; ++i) {
+    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
+      return callback(createError(NOT_AN_OBJECT));
+    }
+  }
+
+  var attachmentError;
+  req.docs.forEach(function (doc) {
+    if (doc._attachments) {
+      Object.keys(doc._attachments).forEach(function (name) {
+        attachmentError = attachmentError || attachmentNameError(name);
+      });
+    }
+  });
+
+  if (attachmentError) {
+    return callback(createError(BAD_REQUEST, attachmentError));
+  }
+
+  if (!('new_edits' in opts)) {
+    if ('new_edits' in req) {
+      opts.new_edits = req.new_edits;
+    } else {
+      opts.new_edits = true;
+    }
+  }
+
+  if (!opts.new_edits && this.type() !== 'http') {
+    // ensure revisions of the same doc are sorted, so that
+    // the local adapter processes them correctly (#2935)
+    req.docs.sort(compareByIdThenRev);
+  }
+
+  cleanDocs(req.docs);
+
+  return this._bulkDocs(req, opts, function (err, res) {
+    if (err) {
+      return callback(err);
+    }
+    if (!opts.new_edits) {
+      // this is what couch does when new_edits is false
+      res = res.filter(function (x) {
+        return x.error;
+      });
+    }
+    callback(null, res);
+  });
+});
+
+AbstractPouchDB.prototype.registerDependentDatabase =
+  adapterFun('registerDependentDatabase', function (dependentDb,
+                                                          callback) {
+  var depDB = new this.constructor(dependentDb, this.__opts);
+
+  function diffFun(doc) {
+    doc.dependentDbs = doc.dependentDbs || {};
+    if (doc.dependentDbs[dependentDb]) {
+      return false; // no update required
+    }
+    doc.dependentDbs[dependentDb] = true;
+    return doc;
+  }
+  upsert(this, '_local/_pouch_dependentDbs', diffFun)
+    .then(function () {
+      callback(null, {db: depDB});
+    })["catch"](callback);
+});
+
+AbstractPouchDB.prototype.destroy =
+  adapterFun('destroy', function (opts, callback) {
+
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+
+  var self = this;
+  var usePrefix = 'use_prefix' in self ? self.use_prefix : true;
+
+  function destroyDb() {
+    // call destroy method of the particular adaptor
+    self._destroy(opts, function (err, resp) {
+      if (err) {
+        return callback(err);
+      }
+      self._destroyed = true;
+      self.emit('destroyed');
+      callback(null, resp || { 'ok': true });
+    });
+  }
+
+  if (self.type() === 'http') {
+    // no need to check for dependent DBs if it's a remote DB
+    return destroyDb();
+  }
+
+  self.get('_local/_pouch_dependentDbs', function (err, localDoc) {
+    if (err) {
+      /* istanbul ignore if */
+      if (err.status !== 404) {
+        return callback(err);
+      } else { // no dependencies
+        return destroyDb();
+      }
+    }
+    var dependentDbs = localDoc.dependentDbs;
+    var PouchDB = self.constructor;
+    var deletedMap = Object.keys(dependentDbs).map(function (name) {
+      // use_prefix is only false in the browser
+      /* istanbul ignore next */
+      var trueName = usePrefix ?
+        name.replace(new RegExp('^' + PouchDB.prefix), '') : name;
+      return new PouchDB(trueName, self.__opts).destroy();
+    });
+    PouchPromise.all(deletedMap).then(destroyDb, callback);
+  });
+});
+
+function TaskQueue() {
+  this.isReady = false;
+  this.failed = false;
+  this.queue = [];
+}
+
+TaskQueue.prototype.execute = function () {
+  var fun;
+  if (this.failed) {
+    while ((fun = this.queue.shift())) {
+      fun(this.failed);
+    }
+  } else {
+    while ((fun = this.queue.shift())) {
+      fun();
+    }
+  }
+};
+
+TaskQueue.prototype.fail = function (err) {
+  this.failed = err;
+  this.execute();
+};
+
+TaskQueue.prototype.ready = function (db) {
+  this.isReady = true;
+  this.db = db;
+  this.execute();
+};
+
+TaskQueue.prototype.addTask = function (fun) {
+  this.queue.push(fun);
+  if (this.failed) {
+    this.execute();
+  }
+};
+
+function defaultCallback(err) {
+  /* istanbul ignore next */
+  if (err && global.debug) {
+    console.error(err);
+  }
+}
+
+// OK, so here's the deal. Consider this code:
+//     var db1 = new PouchDB('foo');
+//     var db2 = new PouchDB('foo');
+//     db1.destroy();
+// ^ these two both need to emit 'destroyed' events,
+// as well as the PouchDB constructor itself.
+// So we have one db object (whichever one got destroy() called on it)
+// responsible for emitting the initial event, which then gets emitted
+// by the constructor, which then broadcasts it to any other dbs
+// that may have been created with the same name.
+function prepareForDestruction(self, opts) {
+  var name = opts.originalName;
+  var ctor = self.constructor;
+  var destructionListeners = ctor._destructionListeners;
+
+  function onDestroyed() {
+    ctor.emit('destroyed', name);
+  }
+
+  function onConstructorDestroyed() {
+    self.removeListener('destroyed', onDestroyed);
+    self.emit('destroyed', self);
+  }
+
+  self.once('destroyed', onDestroyed);
+
+  // in setup.js, the constructor is primed to listen for destroy events
+  if (!destructionListeners.has(name)) {
+    destructionListeners.set(name, []);
+  }
+  destructionListeners.get(name).push(onConstructorDestroyed);
+}
+
+inherits(PouchDB, AbstractPouchDB);
+function PouchDB(name, opts, callback) {
+
+  if (!(this instanceof PouchDB)) {
+    return new PouchDB(name, opts, callback);
+  }
+  var self = this;
+  if (typeof opts === 'function' || typeof opts === 'undefined') {
+    callback = opts;
+    opts = {};
+  }
+
+  if (name && typeof name === 'object') {
+    opts = name;
+    name = undefined;
+  }
+  if (typeof callback === 'undefined') {
+    callback = defaultCallback;
+  }
+  name = name || opts.name;
+  opts = clone(opts);
+  // if name was specified via opts, ignore for the sake of dependentDbs
+  delete opts.name;
+  this.__opts = opts;
+  var oldCB = callback;
+  self.auto_compaction = opts.auto_compaction;
+  self.prefix = PouchDB.prefix;
+  AbstractPouchDB.call(self);
+  self.taskqueue = new TaskQueue();
+  var promise = new PouchPromise(function (fulfill, reject) {
+    callback = function (err, resp) {
+      /* istanbul ignore if */
+      if (err) {
+        return reject(err);
+      }
+      delete resp.then;
+      fulfill(resp);
+    };
+  
+    opts = clone(opts);
+    var originalName = opts.name || name;
+    var backend, error;
+    (function () {
+      try {
+
+        if (typeof originalName !== 'string') {
+          error = new Error('Missing/invalid DB name');
+          error.code = 400;
+          throw error;
+        }
+
+        backend = PouchDB.parseAdapter(originalName, opts);
+        
+        opts.originalName = originalName;
+        opts.name = backend.name;
+        if (opts.prefix && backend.adapter !== 'http' &&
+            backend.adapter !== 'https') {
+          opts.name = opts.prefix + opts.name;
+        }
+        opts.adapter = opts.adapter || backend.adapter;
+        self._adapter = opts.adapter;
+        debug('pouchdb:adapter')('Picked adapter: ' + opts.adapter);
+
+        self._db_name = originalName;
+        if (!PouchDB.adapters[opts.adapter]) {
+          error = new Error('Adapter is missing');
+          error.code = 404;
+          throw error;
+        }
+
+        /* istanbul ignore if */
+        if (!PouchDB.adapters[opts.adapter].valid()) {
+          error = new Error('Invalid Adapter');
+          error.code = 404;
+          throw error;
+        }
+      } catch (err) {
+        self.taskqueue.fail(err);
+      }
+    }());
+    if (error) {
+      return reject(error); // constructor error, see above
+    }
+    self.adapter = opts.adapter;
+
+    // needs access to PouchDB;
+    self.replicate = {};
+
+    self.replicate.from = function (url, opts, callback) {
+      return self.constructor.replicate(url, self, opts, callback);
+    };
+
+    self.replicate.to = function (url, opts, callback) {
+      return self.constructor.replicate(self, url, opts, callback);
+    };
+
+    self.sync = function (dbName, opts, callback) {
+      return self.constructor.sync(self, dbName, opts, callback);
+    };
+
+    self.replicate.sync = self.sync;
+
+    PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        self.taskqueue.fail(err);
+        callback(err);
+        return;
+      }
+      prepareForDestruction(self, opts);
+
+      self.emit('created', self);
+      PouchDB.emit('created', opts.originalName);
+      self.taskqueue.ready(self);
+      callback(null, self);
+    });
+
+  });
+  promise.then(function (resp) {
+    oldCB(null, resp);
+  }, oldCB);
+  self.then = promise.then.bind(promise);
+  self["catch"] = promise["catch"].bind(promise);
+}
+
+PouchDB.debug = debug;
+
+function isChromeApp() {
+  return (typeof chrome !== "undefined" &&
+    typeof chrome.storage !== "undefined" &&
+    typeof chrome.storage.local !== "undefined");
+}
+
+var hasLocal;
+
+if (isChromeApp()) {
+  hasLocal = false;
+} else {
+  try {
+    localStorage.setItem('_pouch_check_localstorage', 1);
+    hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+  } catch (e) {
+    hasLocal = false;
+  }
+}
+
+function hasLocalStorage() {
+  return hasLocal;
+}
+
+PouchDB.adapters = {};
+PouchDB.preferredAdapters = [];
+
+PouchDB.prefix = '_pouch_';
+
+var eventEmitter = new events.EventEmitter();
+
+function setUpEventEmitter(Pouch) {
+  Object.keys(events.EventEmitter.prototype).forEach(function (key) {
+    if (typeof events.EventEmitter.prototype[key] === 'function') {
+      Pouch[key] = eventEmitter[key].bind(eventEmitter);
+    }
+  });
+
+  // these are created in constructor.js, and allow us to notify each DB with
+  // the same name that it was destroyed, via the constructor object
+  var destructListeners = Pouch._destructionListeners = new pouchdbCollections.Map();
+  Pouch.on('destroyed', function onConstructorDestroyed(name) {
+    if (!destructListeners.has(name)) {
+      return;
+    }
+    destructListeners.get(name).forEach(function (callback) {
+      callback();
+    });
+    destructListeners["delete"](name);
+  });
+}
+
+setUpEventEmitter(PouchDB);
+
+PouchDB.parseAdapter = function (name, opts) {
+  var match = name.match(/([a-z\-]*):\/\/(.*)/);
+  var adapter, adapterName;
+  if (match) {
+    // the http adapter expects the fully qualified name
+    name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
+    adapter = match[1];
+    /* istanbul ignore if */
+    if (!PouchDB.adapters[adapter].valid()) {
+      throw 'Invalid adapter';
+    }
+    return {name: name, adapter: match[1]};
+  }
+
+  // check for browsers that have been upgraded from websql-only to websql+idb
+  var skipIdb = 'idb' in PouchDB.adapters && 'websql' in PouchDB.adapters &&
+    hasLocalStorage() &&
+    localStorage['_pouch__websqldb_' + PouchDB.prefix + name];
+
+
+  if (opts.adapter) {
+    adapterName = opts.adapter;
+  } else if (typeof opts !== 'undefined' && opts.db) {
+    adapterName = 'leveldb';
+  } else { // automatically determine adapter
+    for (var i = 0; i < PouchDB.preferredAdapters.length; ++i) {
+      adapterName = PouchDB.preferredAdapters[i];
+      if (adapterName in PouchDB.adapters) {
+        /* istanbul ignore if */
+        if (skipIdb && adapterName === 'idb') {
+          // log it, because this can be confusing during development
+          console.log('PouchDB is downgrading "' + name + '" to WebSQL to' +
+            ' avoid data loss, because it was already opened with WebSQL.');
+          continue; // keep using websql to avoid user data loss
+        }
+        break;
+      }
+    }
+  }
+
+  adapter = PouchDB.adapters[adapterName];
+
+  // if adapter is invalid, then an error will be thrown later
+  var usePrefix = (adapter && 'use_prefix' in adapter) ?
+      adapter.use_prefix : true;
+
+  return {
+    name: usePrefix ? (PouchDB.prefix + name) : name,
+    adapter: adapterName
+  };
+};
+
+PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
+  if (obj.valid()) {
+    PouchDB.adapters[id] = obj;
+    if (addToPreferredAdapters) {
+      PouchDB.preferredAdapters.push(id);
+    }
+  }
+};
+
+PouchDB.plugin = function (obj) {
+  Object.keys(obj).forEach(function (id) {
+    PouchDB.prototype[id] = obj[id];
+  });
+
+  return PouchDB;
+};
+
+PouchDB.defaults = function (defaultOpts) {
+  function PouchAlt(name, opts, callback) {
+    if (!(this instanceof PouchAlt)) {
+      return new PouchAlt(name, opts, callback);
+    }
+
+    if (typeof opts === 'function' || typeof opts === 'undefined') {
+      callback = opts;
+      opts = {};
+    }
+    if (name && typeof name === 'object') {
+      opts = name;
+      name = undefined;
+    }
+
+    opts = jsExtend.extend({}, defaultOpts, opts);
+    PouchDB.call(this, name, opts, callback);
+  }
+
+  inherits(PouchAlt, PouchDB);
+
+  setUpEventEmitter(PouchAlt);
+
+  PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
+  Object.keys(PouchDB).forEach(function (key) {
+    if (!(key in PouchAlt)) {
+      PouchAlt[key] = PouchDB[key];
+    }
+  });
+
+  return PouchAlt;
+};
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+  parts = parts || [];
+  properties = properties || {};
+  try {
+    return new Blob(parts, properties);
+  } catch (e) {
+    if (e.name !== "TypeError") {
+      throw e;
+    }
+    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+                  WebKitBlobBuilder;
+    var builder = new Builder();
+    for (var i = 0; i < parts.length; i += 1) {
+      builder.append(parts[i]);
+    }
+    return builder.getBlob(properties.type);
+  }
+}
+
+// simplified API. universal browser support is assumed
+function readAsArrayBuffer(blob, callback) {
+  if (typeof FileReader === 'undefined') {
+    // fix for Firefox in a web worker:
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+    return callback(new FileReaderSync().readAsArrayBuffer(blob));
+  }
+
+  var reader = new FileReader();
+  reader.onloadend = function (e) {
+    var result = e.target.result || new ArrayBuffer(0);
+    callback(result);
+  };
+  reader.readAsArrayBuffer(blob);
+}
+
+function wrappedFetch() {
+  var wrappedPromise = {};
+
+  var promise = new PouchPromise(function (resolve, reject) {
+    wrappedPromise.resolve = resolve;
+    wrappedPromise.reject = reject;
+  });
+
+  var args = new Array(arguments.length);
+
+  for (var i = 0; i < args.length; i++) {
+    args[i] = arguments[i];
+  }
+
+  wrappedPromise.promise = promise;
+
+  PouchPromise.resolve().then(function () {
+    return fetch.apply(null, args);
+  }).then(function (response) {
+    wrappedPromise.resolve(response);
+  })["catch"](function (error) {
+    wrappedPromise.reject(error);
+  });
+
+  return wrappedPromise;
+}
+
+function fetchRequest(options, callback) {
+  var wrappedPromise, timer, response;
+
+  var headers = new Headers();
+
+  var fetchOptions = {
+    method: options.method,
+    credentials: 'include',
+    headers: headers
+  };
+
+  if (options.json) {
+    headers.set('Accept', 'application/json');
+    headers.set('Content-Type', options.headers['Content-Type'] ||
+      'application/json');
+  }
+
+  if (options.body && (options.body instanceof Blob)) {
+    readAsArrayBuffer(options.body, function (arrayBuffer) {
+      fetchOptions.body = arrayBuffer;
+    });
+  } else if (options.body &&
+             options.processData &&
+             typeof options.body !== 'string') {
+    fetchOptions.body = JSON.stringify(options.body);
+  } else if ('body' in options) {
+    fetchOptions.body = options.body;
+  } else {
+    fetchOptions.body = null;
+  }
+
+  Object.keys(options.headers).forEach(function (key) {
+    if (options.headers.hasOwnProperty(key)) {
+      headers.set(key, options.headers[key]);
+    }
+  });
+
+  wrappedPromise = wrappedFetch(options.url, fetchOptions);
+
+  if (options.timeout > 0) {
+    timer = setTimeout(function () {
+      wrappedPromise.reject(new Error('Load timeout for resource: ' +
+        options.url));
+    }, options.timeout);
+  }
+
+  wrappedPromise.promise.then(function (fetchResponse) {
+    response = {
+      statusCode: fetchResponse.status
+    };
+
+    if (options.timeout > 0) {
+      clearTimeout(timer);
+    }
+
+    if (response.statusCode >= 200 && response.statusCode < 300) {
+      return options.binary ? fetchResponse.blob() : fetchResponse.text();
+    }
+
+    return fetchResponse.json();
+  }).then(function (result) {
+    if (response.statusCode >= 200 && response.statusCode < 300) {
+      callback(null, response, result);
+    } else {
+      callback(result, response);
+    }
+  })["catch"](function (error) {
+    callback(error, response);
+  });
+
+  return {abort: wrappedPromise.reject};
+}
+
+function xhRequest(options, callback) {
+
+  var xhr, timer;
+  var timedout = false;
+
+  var abortReq = function () {
+    xhr.abort();
+  };
+
+  var timeoutReq = function () {
+    timedout = true;
+    xhr.abort();
+  };
+
+  if (options.xhr) {
+    xhr = new options.xhr();
+  } else {
+    xhr = new XMLHttpRequest();
+  }
+
+  try {
+    xhr.open(options.method, options.url);
+  } catch (exception) {
+   /* error code hardcoded to throw INVALID_URL */
+    callback(exception, {statusCode: 413});
+  }
+
+  xhr.withCredentials = ('withCredentials' in options) ?
+    options.withCredentials : true;
+
+  if (options.method === 'GET') {
+    delete options.headers['Content-Type'];
+  } else if (options.json) {
+    options.headers.Accept = 'application/json';
+    options.headers['Content-Type'] = options.headers['Content-Type'] ||
+      'application/json';
+    if (options.body &&
+        options.processData &&
+        typeof options.body !== "string") {
+      options.body = JSON.stringify(options.body);
+    }
+  }
+
+  if (options.binary) {
+    xhr.responseType = 'arraybuffer';
+  }
+
+  if (!('body' in options)) {
+    options.body = null;
+  }
+
+  for (var key in options.headers) {
+    if (options.headers.hasOwnProperty(key)) {
+      xhr.setRequestHeader(key, options.headers[key]);
+    }
+  }
+
+  if (options.timeout > 0) {
+    timer = setTimeout(timeoutReq, options.timeout);
+    xhr.onprogress = function () {
+      clearTimeout(timer);
+      if(xhr.readyState !== 4) {
+        timer = setTimeout(timeoutReq, options.timeout);
+      }
+    };
+    if (typeof xhr.upload !== 'undefined') { // does not exist in ie9
+      xhr.upload.onprogress = xhr.onprogress;
+    }
+  }
+
+  xhr.onreadystatechange = function () {
+    if (xhr.readyState !== 4) {
+      return;
+    }
+
+    var response = {
+      statusCode: xhr.status
+    };
+
+    if (xhr.status >= 200 && xhr.status < 300) {
+      var data;
+      if (options.binary) {
+        data = createBlob([xhr.response || ''], {
+          type: xhr.getResponseHeader('Content-Type')
+        });
+      } else {
+        data = xhr.responseText;
+      }
+      callback(null, response, data);
+    } else {
+      var err = {};
+      if(timedout) {
+        err = new Error('ETIMEDOUT');
+        response.statusCode = 400;      // for consistency with node request
+      } else {
+        try {
+          err = JSON.parse(xhr.response);
+        } catch(e) {}
+      }
+      callback(err, response);
+    }
+  };
+
+  if (options.body && (options.body instanceof Blob)) {
+    readAsArrayBuffer(options.body, function (arrayBuffer) {
+      xhr.send(arrayBuffer);
+    });
+  } else {
+    xhr.send(options.body);
+  }
+
+  return {abort: abortReq};
+}
+
+function testXhr() {
+  try {
+    new XMLHttpRequest();
+    return true;
+  } catch (err) {
+    return false;
+  }
+}
+
+var hasXhr = testXhr();
+
+function ajax$1(options, callback) {
+  if (hasXhr || options.xhr) {
+    return xhRequest(options, callback);
+  } else {
+    return fetchRequest(options, callback);
+  }
+}
+
+// the blob already has a type; do nothing
+var res = function () {};
+
+function defaultBody() {
+  return '';
+}
+
+function ajaxCore(options, callback) {
+
+  options = clone(options);
+
+  var defaultOptions = {
+    method : "GET",
+    headers: {},
+    json: true,
+    processData: true,
+    timeout: 10000,
+    cache: false
+  };
+
+  options = jsExtend.extend(defaultOptions, options);
+
+  function onSuccess(obj, resp, cb) {
+    if (!options.binary && options.json && typeof obj === 'string') {
+      try {
+        obj = JSON.parse(obj);
+      } catch (e) {
+        // Probably a malformed JSON from server
+        return cb(e);
+      }
+    }
+    if (Array.isArray(obj)) {
+      obj = obj.map(function (v) {
+        if (v.error || v.missing) {
+          return generateErrorFromResponse(v);
+        } else {
+          return v;
+        }
+      });
+    }
+    if (options.binary) {
+      res(obj, resp);
+    }
+    cb(null, obj, resp);
+  }
+
+  function onError(err, cb) {
+    var errParsed, errObj;
+    if (err.code && err.status) {
+      var err2 = new Error(err.message || err.code);
+      err2.status = err.status;
+      return cb(err2);
+    }
+    if (err.message && err.message === 'ETIMEDOUT') {
+      return cb(err);
+    }
+    // We always get code && status in node
+    /* istanbul ignore next */
+    try {
+      errParsed = JSON.parse(err.responseText);
+      //would prefer not to have a try/catch clause
+      errObj = generateErrorFromResponse(errParsed);
+    } catch (e) {
+      errObj = generateErrorFromResponse(err);
+    }
+    /* istanbul ignore next */
+    cb(errObj);
+  }
+
+
+  if (options.json) {
+    if (!options.binary) {
+      options.headers.Accept = 'application/json';
+    }
+    options.headers['Content-Type'] = options.headers['Content-Type'] ||
+      'application/json';
+  }
+
+  if (options.binary) {
+    options.encoding = null;
+    options.json = false;
+  }
+
+  if (!options.processData) {
+    options.json = false;
+  }
+
+  return ajax$1(options, function (err, response, body) {
+    if (err) {
+      err.status = response ? response.statusCode : 400;
+      return onError(err, callback);
+    }
+
+    var error;
+    var content_type = response.headers && response.headers['content-type'];
+    var data = body || defaultBody();
+
+    // CouchDB doesn't always return the right content-type for JSON data, so
+    // we check for ^{ and }$ (ignoring leading/trailing whitespace)
+    if (!options.binary && (options.json || !options.processData) &&
+        typeof data !== 'object' &&
+        (/json/.test(content_type) ||
+         (/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
+      try {
+        data = JSON.parse(data.toString());
+      } catch (e) {}
+    }
+
+    if (response.statusCode >= 200 && response.statusCode < 300) {
+      onSuccess(data, response, callback);
+    } else {
+      error = generateErrorFromResponse(data);
+      error.status = response.statusCode;
+      callback(error);
+    }
+  });
+}
+
+function ajax(opts, callback) {
+
+  // cache-buster, specifically designed to work around IE's aggressive caching
+  // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/
+  // Also Safari caches POSTs, so we need to cache-bust those too.
+  var ua = (navigator && navigator.userAgent) ?
+    navigator.userAgent.toLowerCase() : '';
+
+  var isSafari = ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1;
+  var isIE = ua.indexOf('msie') !== -1;
+  var isEdge = ua.indexOf('edge') !== -1;
+
+  // it appears the new version of safari also caches GETs,
+  // see https://github.com/pouchdb/pouchdb/issues/5010
+  var shouldCacheBust = (isSafari ||
+    ((isIE || isEdge) && opts.method === 'GET'));
+
+  var cache = 'cache' in opts ? opts.cache : true;
+
+  var isBlobUrl = /^blob:/.test(opts.url); // don't append nonces for blob URLs
+
+  if (!isBlobUrl && (shouldCacheBust || !cache)) {
+    var hasArgs = opts.url.indexOf('?') !== -1;
+    opts.url += (hasArgs ? '&' : '?') + '_nonce=' + Date.now();
+  }
+
+  return ajaxCore(opts, callback);
+}
+
+// originally parseUri 1.2.2, now patched by us
+// (c) Steven Levithan <stevenlevithan.com>
+// MIT License
+var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
+    "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
+var qName ="queryKey";
+var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
+
+// use the "loose" parser
+/* jshint maxlen: false */
+var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+
+function parseUri(str) {
+  var m = parser.exec(str);
+  var uri = {};
+  var i = 14;
+
+  while (i--) {
+    var key = keys[i];
+    var value = m[i] || "";
+    var encoded = ['user', 'password'].indexOf(key) !== -1;
+    uri[key] = encoded ? decodeURIComponent(value) : value;
+  }
+
+  uri[qName] = {};
+  uri[keys[12]].replace(qParser, function ($0, $1, $2) {
+    if ($1) {
+      uri[qName][$1] = $2;
+    }
+  });
+
+  return uri;
+}
+
+var atob$1 = function (str) {
+  return atob(str);
+};
+
+var btoa$1 = function (str) {
+  return btoa(str);
+};
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
+  }
+  return buf;
+}
+
+function binStringToBluffer(binString, type) {
+  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+var extend$1 = jsExtend__default.extend;
+
+var utils = {
+  ajax: ajax,
+  parseUri: parseUri,
+  uuid: uuid,
+  Promise: PouchPromise,
+  atob: atob$1,
+  btoa: btoa$1,
+  binaryStringToBlobOrBuffer: binStringToBluffer,
+  clone: clone,
+  extend: extend$1,
+  createError: createError
+};
+
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return createError(BAD_REQUEST, msg);
+  }
+}
+
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
+
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
+    }
+
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
+
+    if (filterReturn) {
+      return false;
+    }
+
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
+  };
+}
+
+// designed to give info to browser users, who are disturbed
+// when they see http errors in the console
+function explainError(status, str) {
+  if ('console' in global && 'info' in console) {
+    console.info('The above ' + status + ' is totally normal. ' + str);
+  }
+}
+
+var collate$1 = pouchCollate__default.collate;
+
+var CHECKPOINT_VERSION = 1;
+var REPLICATOR = "pouchdb";
+// This is an arbitrary number to limit the
+// amount of replication history we save in the checkpoint.
+// If we save too much, the checkpoing docs will become very big,
+// if we save fewer, we'll run a greater risk of having to
+// read all the changes from 0 when checkpoint PUTs fail
+// CouchDB 2.0 has a more involved history pruning,
+// but let's go for the simple version for now.
+var CHECKPOINT_HISTORY_SIZE = 5;
+var LOWEST_SEQ = 0;
+
+function updateCheckpoint(db, id, checkpoint, session, returnValue) {
+  return db.get(id)["catch"](function (err) {
+    if (err.status === 404) {
+      if (db.type() === 'http') {
+        explainError(
+          404, 'PouchDB is just checking if a remote checkpoint exists.'
+        );
+      }
+      return {
+        session_id: session,
+        _id: id,
+        history: [],
+        replicator: REPLICATOR,
+        version: CHECKPOINT_VERSION
+      };
+    }
+    throw err;
+  }).then(function (doc) {
+    if (returnValue.cancelled) {
+      return;
+    }
+    // Filter out current entry for this replication
+    doc.history = (doc.history || []).filter(function (item) {
+      return item.session_id !== session;
+    });
+
+    // Add the latest checkpoint to history
+    doc.history.unshift({
+      last_seq: checkpoint,
+      session_id: session
+    });
+
+    // Just take the last pieces in history, to
+    // avoid really big checkpoint docs.
+    // see comment on history size above
+    doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE);
+
+    doc.version = CHECKPOINT_VERSION;
+    doc.replicator = REPLICATOR;
+
+    doc.session_id = session;
+    doc.last_seq = checkpoint;
+
+    return db.put(doc)["catch"](function (err) {
+      if (err.status === 409) {
+        // retry; someone is trying to write a checkpoint simultaneously
+        return updateCheckpoint(db, id, checkpoint, session, returnValue);
+      }
+      throw err;
+    });
+  });
+}
+
+function Checkpointer(src, target, id, returnValue) {
+  this.src = src;
+  this.target = target;
+  this.id = id;
+  this.returnValue = returnValue;
+}
+
+Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) {
+  var self = this;
+  return this.updateTarget(checkpoint, session).then(function () {
+    return self.updateSource(checkpoint, session);
+  });
+};
+
+Checkpointer.prototype.updateTarget = function (checkpoint, session) {
+  return updateCheckpoint(this.target, this.id, checkpoint,
+      session, this.returnValue);
+};
+
+Checkpointer.prototype.updateSource = function (checkpoint, session) {
+  var self = this;
+  if (this.readOnlySource) {
+    return PouchPromise.resolve(true);
+  }
+  return updateCheckpoint(this.src, this.id, checkpoint,
+      session, this.returnValue)[
+    "catch"](function (err) {
+      if (isForbiddenError(err)) {
+        self.readOnlySource = true;
+        return true;
+      }
+      throw err;
+    });
+};
+
+var comparisons = {
+  "undefined": function (targetDoc, sourceDoc) {
+    // This is the previous comparison function
+    if (collate$1(targetDoc.last_seq, sourceDoc.last_seq) === 0) {
+      return sourceDoc.last_seq;
+    }
+    /* istanbul ignore next */
+    return 0;
+  },
+  "1": function (targetDoc, sourceDoc) {
+    // This is the comparison function ported from CouchDB
+    return compareReplicationLogs(sourceDoc, targetDoc).last_seq;
+  }
+};
+
+Checkpointer.prototype.getCheckpoint = function () {
+  var self = this;
+  return self.target.get(self.id).then(function (targetDoc) {
+    if (self.readOnlySource) {
+      return PouchPromise.resolve(targetDoc.last_seq);
+    }
+
+    return self.src.get(self.id).then(function (sourceDoc) {
+      // Since we can't migrate an old version doc to a new one
+      // (no session id), we just go with the lowest seq in this case
+      /* istanbul ignore if */
+      if (targetDoc.version !== sourceDoc.version) {
+        return LOWEST_SEQ;
+      }
+
+      var version;
+      if (targetDoc.version) {
+        version = targetDoc.version.toString();
+      } else {
+        version = "undefined";
+      }
+
+      if (version in comparisons) {
+        return comparisons[version](targetDoc, sourceDoc);
+      }
+      /* istanbul ignore next */
+      return LOWEST_SEQ;
+    }, function (err) {
+      if (err.status === 404 && targetDoc.last_seq) {
+        return self.src.put({
+          _id: self.id,
+          last_seq: LOWEST_SEQ
+        }).then(function () {
+          return LOWEST_SEQ;
+        }, function (err) {
+          if (isForbiddenError(err)) {
+            self.readOnlySource = true;
+            return targetDoc.last_seq;
+          }
+          /* istanbul ignore next */
+          return LOWEST_SEQ;
+        });
+      }
+      throw err;
+    });
+  })["catch"](function (err) {
+    if (err.status !== 404) {
+      throw err;
+    }
+    return LOWEST_SEQ;
+  });
+};
+// This checkpoint comparison is ported from CouchDBs source
+// they come from here:
+// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906
+
+function compareReplicationLogs(srcDoc, tgtDoc) {
+  if (srcDoc.session_id === tgtDoc.session_id) {
+    return {
+      last_seq: srcDoc.last_seq,
+      history: srcDoc.history || []
+    };
+  }
+
+  var sourceHistory = srcDoc.history || [];
+  var targetHistory = tgtDoc.history || [];
+  return compareReplicationHistory(sourceHistory, targetHistory);
+}
+
+function compareReplicationHistory(sourceHistory, targetHistory) {
+  // the erlang loop via function arguments is not so easy to repeat in JS
+  // therefore, doing this as recursion
+  var S = sourceHistory[0];
+  var sourceRest = sourceHistory.slice(1);
+  var T = targetHistory[0];
+  var targetRest = targetHistory.slice(1);
+
+  if (!S || targetHistory.length === 0) {
+    return {
+      last_seq: LOWEST_SEQ,
+      history: []
+    };
+  }
+
+  var sourceId = S.session_id;
+  /* istanbul ignore if */
+  if (hasSessionId(sourceId, targetHistory)) {
+    return {
+      last_seq: S.last_seq,
+      history: sourceHistory
+    };
+  }
+
+  var targetId = T.session_id;
+  if (hasSessionId(targetId, sourceRest)) {
+    return {
+      last_seq: T.last_seq,
+      history: targetRest
+    };
+  }
+
+  return compareReplicationHistory(sourceRest, targetRest);
+}
+
+function hasSessionId(sessionId, history) {
+  var props = history[0];
+  var rest = history.slice(1);
+
+  if (!sessionId || history.length === 0) {
+    return false;
+  }
+
+  if (sessionId === props.session_id) {
+    return true;
+  }
+
+  return hasSessionId(sessionId, rest);
+}
+
+function isForbiddenError(err) {
+  return typeof err.status === 'number' && Math.floor(err.status / 100) === 4;
+}
+
+var STARTING_BACK_OFF = 0;
+
+function randomNumber(min, max) {
+  min = parseInt(min, 10) || 0;
+  max = parseInt(max, 10);
+  if (max !== max || max <= min) {
+    max = (min || 1) << 1; //doubling
+  } else {
+    max = max + 1;
+  }
+  var ratio = Math.random();
+  var range = max - min;
+
+  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
+}
+
+function defaultBackOff(min) {
+  var max = 0;
+  if (!min) {
+    max = 2000;
+  }
+  return randomNumber(min, max);
+}
+
+function backOff(opts, returnValue, error, callback) {
+  if (opts.retry === false) {
+    returnValue.emit('error', error);
+    returnValue.removeAllListeners();
+    return;
+  }
+  if (typeof opts.back_off_function !== 'function') {
+    opts.back_off_function = defaultBackOff;
+  }
+  returnValue.emit('requestError', error);
+  if (returnValue.state === 'active' || returnValue.state === 'pending') {
+    returnValue.emit('paused', error);
+    returnValue.state = 'stopped';
+    returnValue.once('active', function () {
+      opts.current_back_off = STARTING_BACK_OFF;
+    });
+  }
+
+  opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF;
+  opts.current_back_off = opts.back_off_function(opts.current_back_off);
+  setTimeout(callback, opts.current_back_off);
+}
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+  return btoa$1(raw);
+}
+
+function appendBuffer(buffer, data, start, end) {
+  if (start > 0 || end < data.byteLength) {
+    // only create a subarray if we really need to
+    data = new Uint8Array(data, start,
+      Math.min(end, data.byteLength) - start);
+  }
+  buffer.append(data);
+}
+
+function appendString(buffer, data, start, end) {
+  if (start > 0 || end < data.length) {
+    // only create a substring if we really need to
+    data = data.substring(start, end);
+  }
+  buffer.appendBinary(data);
+}
+
+var md5 = toPromise(function (data, callback) {
+  var inputIsString = typeof data === 'string';
+  var len = inputIsString ? data.length : data.byteLength;
+  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+  var chunks = Math.ceil(len / chunkSize);
+  var currentChunk = 0;
+  var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+  var append = inputIsString ? appendString : appendBuffer;
+
+  function loadNextChunk() {
+    var start = currentChunk * chunkSize;
+    var end = start + chunkSize;
+    currentChunk++;
+    if (currentChunk < chunks) {
+      append(buffer, data, start, end);
+      setImmediateShim(loadNextChunk);
+    } else {
+      append(buffer, data, start, end);
+      var raw = buffer.end(true);
+      var base64 = rawToBase64(raw);
+      callback(null, base64);
+      buffer.destroy();
+    }
+  }
+  loadNextChunk();
+});
+
+function sortObjectPropertiesByKey(queryParams) {
+  return Object.keys(queryParams).sort(pouchCollate.collate).reduce(function (result, key) {
+    result[key] = queryParams[key];
+    return result;
+  }, {});
+}
+
+// Generate a unique id particular to this replication.
+// Not guaranteed to align perfectly with CouchDB's rep ids.
+function generateReplicationId(src, target, opts) {
+  var docIds = opts.doc_ids ? opts.doc_ids.sort(pouchCollate.collate) : '';
+  var filterFun = opts.filter ? opts.filter.toString() : '';
+  var queryParams = '';
+  var filterViewName =  '';
+
+  if (opts.filter && opts.query_params) {
+    queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params));
+  }
+
+  if (opts.filter && opts.filter === '_view') {
+    filterViewName = opts.view.toString();
+  }
+
+  return PouchPromise.all([src.id(), target.id()]).then(function (res) {
+    var queryData = res[0] + res[1] + filterFun + filterViewName +
+      queryParams + docIds;
+    return md5(queryData);
+  }).then(function (md5sum) {
+    // can't use straight-up md5 alphabet, because
+    // the char '/' is interpreted as being for attachments,
+    // and + is also not url-safe
+    md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_');
+    return '_local/' + md5sum;
+  });
+}
+
+function isGenOne(rev) {
+  return /^1-/.test(rev);
+}
+
+function createBulkGetOpts(diffs) {
+  var requests = [];
+  Object.keys(diffs).forEach(function (id) {
+    var missingRevs = diffs[id].missing;
+    missingRevs.forEach(function (missingRev) {
+      requests.push({
+        id: id,
+        rev: missingRev
+      });
+    });
+  });
+
+  return {
+    docs: requests,
+    revs: true,
+    attachments: true,
+    binary: true
+  };
+}
+
+//
+// Fetch all the documents from the src as described in the "diffs",
+// which is a mapping of docs IDs to revisions. If the state ever
+// changes to "cancelled", then the returned promise will be rejected.
+// Else it will be resolved with a list of fetched documents.
+//
+function getDocs(src, diffs, state) {
+  diffs = clone(diffs); // we do not need to modify this
+
+  var resultDocs = [],
+      ok = true;
+
+  function getAllDocs() {
+
+    var bulkGetOpts = createBulkGetOpts(diffs);
+
+    if (!bulkGetOpts.docs.length) { // optimization: skip empty requests
+      return;
+    }
+
+    return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
+      /* istanbul ignore if */
+      if (state.cancelled) {
+        throw new Error('cancelled');
+      }
+      bulkGetResponse.results.forEach(function (bulkGetInfo) {
+        bulkGetInfo.docs.forEach(function (doc) {
+          if (doc.ok) {
+            resultDocs.push(doc.ok);
+          } else if (doc.error !== undefined) {
+            ok = false;
+          }
+          // else: when AUTO_COMPACTION is set, docs can be returned which look
+          // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"}
+        });
+      });
+    });
+  }
+
+  function hasAttachments(doc) {
+    return doc._attachments && Object.keys(doc._attachments).length > 0;
+  }
+
+  function fetchRevisionOneDocs(ids) {
+    // Optimization: fetch gen-1 docs and attachments in
+    // a single request using _all_docs
+    return src.allDocs({
+      keys: ids,
+      include_docs: true
+    }).then(function (res) {
+      if (state.cancelled) {
+        throw new Error('cancelled');
+      }
+      res.rows.forEach(function (row) {
+        if (row.deleted || !row.doc || !isGenOne(row.value.rev) ||
+            hasAttachments(row.doc)) {
+          // if any of these conditions apply, we need to fetch using get()
+          return;
+        }
+
+        // the doc we got back from allDocs() is sufficient
+        resultDocs.push(row.doc);
+        delete diffs[row.id];
+      });
+    });
+  }
+
+  function getRevisionOneDocs() {
+    // filter out the generation 1 docs and get them
+    // leaving the non-generation one docs to be got otherwise
+    var ids = Object.keys(diffs).filter(function (id) {
+      var missing = diffs[id].missing;
+      return missing.length === 1 && isGenOne(missing[0]);
+    });
+    if (ids.length > 0) {
+      return fetchRevisionOneDocs(ids);
+    }
+  }
+
+  function returnResult() {
+    return { ok:ok, docs:resultDocs };
+  }
+
+  return PouchPromise.resolve()
+    .then(getRevisionOneDocs)
+    .then(getAllDocs)
+    .then(returnResult);
+}
+
+function replicate(src, target, opts, returnValue, result) {
+  var batches = [];               // list of batches to be processed
+  var currentBatch;               // the batch currently being processed
+  var pendingBatch = {
+    seq: 0,
+    changes: [],
+    docs: []
+  }; // next batch, not yet ready to be processed
+  var writingCheckpoint = false;  // true while checkpoint is being written
+  var changesCompleted = false;   // true when all changes received
+  var replicationCompleted = false; // true when replication has completed
+  var last_seq = 0;
+  var continuous = opts.continuous || opts.live || false;
+  var batch_size = opts.batch_size || 100;
+  var batches_limit = opts.batches_limit || 10;
+  var changesPending = false;     // true while src.changes is running
+  var doc_ids = opts.doc_ids;
+  var repId;
+  var checkpointer;
+  var allErrors = [];
+  var changedDocs = [];
+  // Like couchdb, every replication gets a unique session id
+  var session = uuid();
+
+  result = result || {
+    ok: true,
+    start_time: new Date(),
+    docs_read: 0,
+    docs_written: 0,
+    doc_write_failures: 0,
+    errors: []
+  };
+
+  var changesOpts = {};
+  returnValue.ready(src, target);
+
+  function initCheckpointer() {
+    if (checkpointer) {
+      return PouchPromise.resolve();
+    }
+    return generateReplicationId(src, target, opts).then(function (res) {
+      repId = res;
+      checkpointer = new Checkpointer(src, target, repId, returnValue);
+    });
+  }
+
+  function writeDocs() {
+    changedDocs = [];
+
+    if (currentBatch.docs.length === 0) {
+      return;
+    }
+    var docs = currentBatch.docs;
+    return target.bulkDocs({docs: docs, new_edits: false}).then(function (res) {
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
+      }
+      var errors = [];
+      var errorsById = {};
+      res.forEach(function (res) {
+        if (res.error) {
+          result.doc_write_failures++;
+          errors.push(res);
+          errorsById[res.id] = res;
+        }
+      });
+      allErrors = allErrors.concat(errors);
+      result.docs_written += currentBatch.docs.length - errors.length;
+      var non403s = errors.filter(function (error) {
+        return error.name !== 'unauthorized' && error.name !== 'forbidden';
+      });
+
+      docs.forEach(function (doc) {
+        var error = errorsById[doc._id];
+        if (error) {
+          returnValue.emit('denied', clone(error));
+        } else {
+          changedDocs.push(doc);
+        }
+      });
+
+      if (non403s.length > 0) {
+        var error = new Error('bulkDocs error');
+        error.other_errors = errors;
+        abortReplication('target.bulkDocs failed to write docs', error);
+        throw new Error('bulkWrite partial failure');
+      }
+    }, function (err) {
+      result.doc_write_failures += docs.length;
+      throw err;
+    });
+  }
+
+  function finishBatch() {
+    if (currentBatch.error) {
+      throw new Error('There was a problem getting docs.');
+    }
+    result.last_seq = last_seq = currentBatch.seq;
+    var outResult = clone(result);
+    if (changedDocs.length) {
+      outResult.docs = changedDocs;
+      returnValue.emit('change', outResult);
+    }
+    writingCheckpoint = true;
+    return checkpointer.writeCheckpoint(currentBatch.seq,
+        session).then(function () {
+      writingCheckpoint = false;
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
+      }
+      currentBatch = undefined;
+      getChanges();
+    })["catch"](function (err) {
+      writingCheckpoint = false;
+      abortReplication('writeCheckpoint completed with error', err);
+      throw err;
+    });
+  }
+
+  function getDiffs() {
+    var diff = {};
+    currentBatch.changes.forEach(function (change) {
+      // Couchbase Sync Gateway emits these, but we can ignore them
+      /* istanbul ignore if */
+      if (change.id === "_user/") {
+        return;
+      }
+      diff[change.id] = change.changes.map(function (x) {
+        return x.rev;
+      });
+    });
+    return target.revsDiff(diff).then(function (diffs) {
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
+      }
+      // currentBatch.diffs elements are deleted as the documents are written
+      currentBatch.diffs = diffs;
+    });
+  }
+
+  function getBatchDocs() {
+    return getDocs(src, currentBatch.diffs, returnValue).then(function (got) {
+      currentBatch.error = !got.ok;
+      got.docs.forEach(function (doc) {
+        delete currentBatch.diffs[doc._id];
+        result.docs_read++;
+        currentBatch.docs.push(doc);
+      });
+    });
+  }
+
+  function startNextBatch() {
+    if (returnValue.cancelled || currentBatch) {
+      return;
+    }
+    if (batches.length === 0) {
+      processPendingBatch(true);
+      return;
+    }
+    currentBatch = batches.shift();
+    getDiffs()
+      .then(getBatchDocs)
+      .then(writeDocs)
+      .then(finishBatch)
+      .then(startNextBatch)[
+      "catch"](function (err) {
+        abortReplication('batch processing terminated with error', err);
+      });
+  }
+
+
+  function processPendingBatch(immediate) {
+    if (pendingBatch.changes.length === 0) {
+      if (batches.length === 0 && !currentBatch) {
+        if ((continuous && changesOpts.live) || changesCompleted) {
+          returnValue.state = 'pending';
+          returnValue.emit('paused');
+        }
+        if (changesCompleted) {
+          completeReplication();
+        }
+      }
+      return;
+    }
+    if (
+      immediate ||
+      changesCompleted ||
+      pendingBatch.changes.length >= batch_size
+    ) {
+      batches.push(pendingBatch);
+      pendingBatch = {
+        seq: 0,
+        changes: [],
+        docs: []
+      };
+      if (returnValue.state === 'pending' || returnValue.state === 'stopped') {
+        returnValue.state = 'active';
+        returnValue.emit('active');
+      }
+      startNextBatch();
+    }
+  }
+
+
+  function abortReplication(reason, err) {
+    if (replicationCompleted) {
+      return;
+    }
+    if (!err.message) {
+      err.message = reason;
+    }
+    result.ok = false;
+    result.status = 'aborting';
+    result.errors.push(err);
+    allErrors = allErrors.concat(err);
+    batches = [];
+    pendingBatch = {
+      seq: 0,
+      changes: [],
+      docs: []
+    };
+    completeReplication();
+  }
+
+
+  function completeReplication() {
+    if (replicationCompleted) {
+      return;
+    }
+    if (returnValue.cancelled) {
+      result.status = 'cancelled';
+      if (writingCheckpoint) {
+        return;
+      }
+    }
+    result.status = result.status || 'complete';
+    result.end_time = new Date();
+    result.last_seq = last_seq;
+    replicationCompleted = true;
+    var non403s = allErrors.filter(function (error) {
+      return error.name !== 'unauthorized' && error.name !== 'forbidden';
+    });
+    if (non403s.length > 0) {
+      var error = allErrors.pop();
+      if (allErrors.length > 0) {
+        error.other_errors = allErrors;
+      }
+      error.result = result;
+      backOff(opts, returnValue, error, function () {
+        replicate(src, target, opts, returnValue);
+      });
+    } else {
+      result.errors = allErrors;
+      returnValue.emit('complete', result);
+      returnValue.removeAllListeners();
+    }
+  }
+
+
+  function onChange(change) {
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
+    var filter = filterChange(opts)(change);
+    if (!filter) {
+      return;
+    }
+    pendingBatch.seq = change.seq;
+    pendingBatch.changes.push(change);
+    processPendingBatch(changesOpts.live);
+  }
+
+
+  function onChangesComplete(changes) {
+    changesPending = false;
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
+
+    // if no results were returned then we're done,
+    // else fetch more
+    if (changes.results.length > 0) {
+      changesOpts.since = changes.last_seq;
+      getChanges();
+    } else {
+      if (continuous) {
+        changesOpts.live = true;
+        getChanges();
+      } else {
+        changesCompleted = true;
+      }
+    }
+    processPendingBatch(true);
+  }
+
+
+  function onChangesError(err) {
+    changesPending = false;
+    /* istanbul ignore if */
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
+    abortReplication('changes rejected', err);
+  }
+
+
+  function getChanges() {
+    if (!(
+      !changesPending &&
+      !changesCompleted &&
+      batches.length < batches_limit
+      )) {
+      return;
+    }
+    changesPending = true;
+    function abortChanges() {
+      changes.cancel();
+    }
+    function removeListener() {
+      returnValue.removeListener('cancel', abortChanges);
+    }
+
+    if (returnValue._changes) { // remove old changes() and listeners
+      returnValue.removeListener('cancel', returnValue._abortChanges);
+      returnValue._changes.cancel();
+    }
+    returnValue.once('cancel', abortChanges);
+
+    var changes = src.changes(changesOpts)
+      .on('change', onChange);
+    changes.then(removeListener, removeListener);
+    changes.then(onChangesComplete)[
+      "catch"](onChangesError);
+
+    if (opts.retry) {
+      // save for later so we can cancel if necessary
+      returnValue._changes = changes;
+      returnValue._abortChanges = abortChanges;
+    }
+  }
+
+
+  function startChanges() {
+    initCheckpointer().then(function () {
+      if (returnValue.cancelled) {
+        completeReplication();
+        return;
+      }
+      return checkpointer.getCheckpoint().then(function (checkpoint) {
+        last_seq = checkpoint;
+        changesOpts = {
+          since: last_seq,
+          limit: batch_size,
+          batch_size: batch_size,
+          style: 'all_docs',
+          doc_ids: doc_ids,
+          return_docs: true // required so we know when we're done
+        };
+        if (opts.filter) {
+          if (typeof opts.filter !== 'string') {
+            // required for the client-side filter in onChange
+            changesOpts.include_docs = true;
+          } else { // ddoc filter
+            changesOpts.filter = opts.filter;
+          }
+        }
+        if ('heartbeat' in opts) {
+          changesOpts.heartbeat = opts.heartbeat;
+        }
+        if ('timeout' in opts) {
+          changesOpts.timeout = opts.timeout;
+        }
+        if (opts.query_params) {
+          changesOpts.query_params = opts.query_params;
+        }
+        if (opts.view) {
+          changesOpts.view = opts.view;
+        }
+        getChanges();
+      });
+    })["catch"](function (err) {
+      abortReplication('getCheckpoint rejected with ', err);
+    });
+  }
+
+  /* istanbul ignore next */
+  function onCheckpointError(err) {
+    writingCheckpoint = false;
+    abortReplication('writeCheckpoint completed with error', err);
+    throw err;
+  }
+
+  /* istanbul ignore if */
+  if (returnValue.cancelled) { // cancelled immediately
+    completeReplication();
+    return;
+  }
+
+  if (!returnValue._addedListeners) {
+    returnValue.once('cancel', completeReplication);
+
+    if (typeof opts.complete === 'function') {
+      returnValue.once('error', opts.complete);
+      returnValue.once('complete', function (result) {
+        opts.complete(null, result);
+      });
+    }
+    returnValue._addedListeners = true;
+  }
+
+  if (typeof opts.since === 'undefined') {
+    startChanges();
+  } else {
+    initCheckpointer().then(function () {
+      writingCheckpoint = true;
+      return checkpointer.writeCheckpoint(opts.since, session);
+    }).then(function () {
+      writingCheckpoint = false;
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        return;
+      }
+      last_seq = opts.since;
+      startChanges();
+    })["catch"](onCheckpointError);
+  }
+}
+
+// We create a basic promise so the caller can cancel the replication possibly
+// before we have actually started listening to changes etc
+inherits(Replication, events.EventEmitter);
+function Replication() {
+  events.EventEmitter.call(this);
+  this.cancelled = false;
+  this.state = 'pending';
+  var self = this;
+  var promise = new PouchPromise(function (fulfill, reject) {
+    self.once('complete', fulfill);
+    self.once('error', reject);
+  });
+  self.then = function (resolve, reject) {
+    return promise.then(resolve, reject);
+  };
+  self["catch"] = function (reject) {
+    return promise["catch"](reject);
+  };
+  // As we allow error handling via "error" event as well,
+  // put a stub in here so that rejecting never throws UnhandledError.
+  self["catch"](function () {});
+}
+
+Replication.prototype.cancel = function () {
+  this.cancelled = true;
+  this.state = 'cancelled';
+  this.emit('cancel');
+};
+
+Replication.prototype.ready = function (src, target) {
+  var self = this;
+  if (self._readyCalled) {
+    return;
+  }
+  self._readyCalled = true;
+
+  function onDestroy() {
+    self.cancel();
+  }
+  src.once('destroyed', onDestroy);
+  target.once('destroyed', onDestroy);
+  function cleanup() {
+    src.removeListener('destroyed', onDestroy);
+    target.removeListener('destroyed', onDestroy);
+  }
+  self.once('complete', cleanup);
+};
+
+function toPouch(db, opts) {
+  var PouchConstructor = opts.PouchConstructor;
+  if (typeof db === 'string') {
+    return new PouchConstructor(db, opts);
+  } else {
+    return db;
+  }
+}
+
+function replicateWrapper(src, target, opts, callback) {
+
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  if (typeof opts === 'undefined') {
+    opts = {};
+  }
+
+  if (opts.doc_ids && !Array.isArray(opts.doc_ids)) {
+    throw createError(BAD_REQUEST,
+                       "`doc_ids` filter parameter is not a list.");
+  }
+
+  opts.complete = callback;
+  opts = clone(opts);
+  opts.continuous = opts.continuous || opts.live;
+  opts.retry = ('retry' in opts) ? opts.retry : false;
+  /*jshint validthis:true */
+  opts.PouchConstructor = opts.PouchConstructor || this;
+  var replicateRet = new Replication(opts);
+  var srcPouch = toPouch(src, opts);
+  var targetPouch = toPouch(target, opts);
+  replicate(srcPouch, targetPouch, opts, replicateRet);
+  return replicateRet;
+}
+
+var replication = {
+  replicate: replicateWrapper,
+  toPouch: toPouch
+};
+
+var replicate$1 = replication.replicate;
+inherits(Sync, events.EventEmitter);
+function sync(src, target, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  if (typeof opts === 'undefined') {
+    opts = {};
+  }
+  opts = clone(opts);
+  /*jshint validthis:true */
+  opts.PouchConstructor = opts.PouchConstructor || this;
+  src = replication.toPouch(src, opts);
+  target = replication.toPouch(target, opts);
+  return new Sync(src, target, opts, callback);
+}
+
+function Sync(src, target, opts, callback) {
+  var self = this;
+  this.canceled = false;
+
+  var optsPush = opts.push ? jsExtend.extend({}, opts, opts.push) : opts;
+  var optsPull = opts.pull ? jsExtend.extend({}, opts, opts.pull) : opts;
+
+  this.push = replicate$1(src, target, optsPush);
+  this.pull = replicate$1(target, src, optsPull);
+
+  this.pushPaused = true;
+  this.pullPaused = true;
+
+  function pullChange(change) {
+    self.emit('change', {
+      direction: 'pull',
+      change: change
+    });
+  }
+  function pushChange(change) {
+    self.emit('change', {
+      direction: 'push',
+      change: change
+    });
+  }
+  function pushDenied(doc) {
+    self.emit('denied', {
+      direction: 'push',
+      doc: doc
+    });
+  }
+  function pullDenied(doc) {
+    self.emit('denied', {
+      direction: 'pull',
+      doc: doc
+    });
+  }
+  function pushPaused() {
+    self.pushPaused = true;
+    if (self.pullPaused) {
+      self.emit('paused');
+    }
+  }
+  function pullPaused() {
+    self.pullPaused = true;
+    if (self.pushPaused) {
+      self.emit('paused');
+    }
+  }
+  function pushActive() {
+    self.pushPaused = false;
+    if (self.pullPaused) {
+      self.emit('active', {
+        direction: 'push'
+      });
+    }
+  }
+  function pullActive() {
+    self.pullPaused = false;
+    /* istanbul ignore if */
+    if (self.pushPaused) {
+      self.emit('active', {
+        direction: 'pull'
+      });
+    }
+  }
+
+  var removed = {};
+
+  function removeAll(type) { // type is 'push' or 'pull'
+    return function (event, func) {
+      var isChange = event === 'change' &&
+        (func === pullChange || func === pushChange);
+      var isDenied = event === 'denied' &&
+        (func === pullDenied || func === pushDenied);
+      var isPaused = event === 'paused' &&
+        (func === pullPaused || func === pushPaused);
+      var isActive = event === 'active' &&
+        (func === pullActive || func === pushActive);
+
+      if (isChange || isDenied || isPaused || isActive) {
+        if (!(event in removed)) {
+          removed[event] = {};
+        }
+        removed[event][type] = true;
+        if (Object.keys(removed[event]).length === 2) {
+          // both push and pull have asked to be removed
+          self.removeAllListeners(event);
+        }
+      }
+    };
+  }
+
+  if (opts.live) {
+    this.push.on('complete', self.pull.cancel.bind(self.pull));
+    this.pull.on('complete', self.push.cancel.bind(self.push));
+  }
+
+  this.on('newListener', function (event) {
+    if (event === 'change') {
+      self.pull.on('change', pullChange);
+      self.push.on('change', pushChange);
+    } else if (event === 'denied') {
+      self.pull.on('denied', pullDenied);
+      self.push.on('denied', pushDenied);
+    } else if (event === 'active') {
+      self.pull.on('active', pullActive);
+      self.push.on('active', pushActive);
+    } else if (event === 'paused') {
+      self.pull.on('paused', pullPaused);
+      self.push.on('paused', pushPaused);
+    }
+  });
+
+  this.on('removeListener', function (event) {
+    if (event === 'change') {
+      self.pull.removeListener('change', pullChange);
+      self.push.removeListener('change', pushChange);
+    } else if (event === 'denied') {
+      self.pull.removeListener('denied', pullDenied);
+      self.push.removeListener('denied', pushDenied);
+    } else if (event === 'active') {
+      self.pull.removeListener('active', pullActive);
+      self.push.removeListener('active', pushActive);
+    } else if (event === 'paused') {
+      self.pull.removeListener('paused', pullPaused);
+      self.push.removeListener('paused', pushPaused);
+    }
+  });
+
+  this.pull.on('removeListener', removeAll('pull'));
+  this.push.on('removeListener', removeAll('push'));
+
+  var promise = PouchPromise.all([
+    this.push,
+    this.pull
+  ]).then(function (resp) {
+    var out = {
+      push: resp[0],
+      pull: resp[1]
+    };
+    self.emit('complete', out);
+    if (callback) {
+      callback(null, out);
+    }
+    self.removeAllListeners();
+    return out;
+  }, function (err) {
+    self.cancel();
+    if (callback) {
+      // if there's a callback, then the callback can receive
+      // the error event
+      callback(err);
+    } else {
+      // if there's no callback, then we're safe to emit an error
+      // event, which would otherwise throw an unhandled error
+      // due to 'error' being a special event in EventEmitters
+      self.emit('error', err);
+    }
+    self.removeAllListeners();
+    if (callback) {
+      // no sense throwing if we're already emitting an 'error' event
+      throw err;
+    }
+  });
+
+  this.then = function (success, err) {
+    return promise.then(success, err);
+  };
+
+  this["catch"] = function (err) {
+    return promise["catch"](err);
+  };
+}
+
+Sync.prototype.cancel = function () {
+  if (!this.canceled) {
+    this.canceled = true;
+    this.push.cancel();
+    this.pull.cancel();
+  }
+};
+
+function b64ToBluffer(b64, type) {
+  return binStringToBluffer(atob$1(b64), type);
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
+  }
+  return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  if (typeof FileReader === 'undefined') {
+    // fix for Firefox in a web worker
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+    return callback(arrayBufferToBinaryString(
+      new FileReaderSync().readAsArrayBuffer(blob)));
+  }
+
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
+    }
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
+  }
+}
+
+function blobToBase64(blobOrBuffer) {
+  return new PouchPromise(function (resolve) {
+    readAsBinaryString(blobOrBuffer, function (bin) {
+      resolve(btoa$1(bin));
+    });
+  });
+}
+
+function flatten(arrs) {
+  var res = [];
+  for (var i = 0, len = arrs.length; i < len; i++) {
+    res = res.concat(arrs[i]);
+  }
+  return res;
+}
+
+var CHANGES_BATCH_SIZE = 25;
+var MAX_SIMULTANEOUS_REVS = 50;
+
+var supportsBulkGetMap = {};
+
+// according to http://stackoverflow.com/a/417184/680742,
+// the de facto URL length limit is 2000 characters.
+// but since most of our measurements don't take the full
+// URL into account, we fudge it a bit.
+// TODO: we could measure the full URL to enforce exactly 2000 chars
+var MAX_URL_LENGTH = 1800;
+
+var log$1 = debug('pouchdb:http');
+function readAttachmentsAsBlobOrBuffer(row) {
+  var atts = row.doc && row.doc._attachments;
+  if (!atts) {
+    return;
+  }
+  Object.keys(atts).forEach(function (filename) {
+    var att = atts[filename];
+    att.data = b64ToBluffer(att.data, att.content_type);
+  });
+}
+
+function encodeDocId(id) {
+  if (/^_design/.test(id)) {
+    return '_design/' + encodeURIComponent(id.slice(8));
+  }
+  if (/^_local/.test(id)) {
+    return '_local/' + encodeURIComponent(id.slice(7));
+  }
+  return encodeURIComponent(id);
+}
+
+function preprocessAttachments(doc) {
+  if (!doc._attachments || !Object.keys(doc._attachments)) {
+    return PouchPromise.resolve();
+  }
+
+  return PouchPromise.all(Object.keys(doc._attachments).map(function (key) {
+    var attachment = doc._attachments[key];
+    if (attachment.data && typeof attachment.data !== 'string') {
+      return blobToBase64(attachment.data).then(function (b64) {
+        attachment.data = b64;
+      });
+    }
+  }));
+}
+
+// Get all the information you possibly can about the URI given by name and
+// return it as a suitable object.
+function getHost(name) {
+  // Prase the URI into all its little bits
+  var uri = parseUri(name);
+
+  // Store the user and password as a separate auth object
+  if (uri.user || uri.password) {
+    uri.auth = {username: uri.user, password: uri.password};
+  }
+
+  // Split the path part of the URI into parts using '/' as the delimiter
+  // after removing any leading '/' and any trailing '/'
+  var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
+
+  // Store the first part as the database name and remove it from the parts
+  // array
+  uri.db = parts.pop();
+  // Prevent double encoding of URI component
+  if (uri.db.indexOf('%') === -1) {
+    uri.db = encodeURIComponent(uri.db);
+  }
+
+  // Restore the path by joining all the remaining parts (all the parts
+  // except for the database name) with '/'s
+  uri.path = parts.join('/');
+
+  return uri;
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genDBUrl(opts, path) {
+  return genUrl(opts, opts.db + '/' + path);
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genUrl(opts, path) {
+  // If the host already has a path, then we need to have a path delimiter
+  // Otherwise, the path delimiter is the empty string
+  var pathDel = !opts.path ? '' : '/';
+
+  // If the host already has a path, then we need to have a path delimiter
+  // Otherwise, the path delimiter is the empty string
+  return opts.protocol + '://' + opts.host +
+         (opts.port ? (':' + opts.port) : '') +
+         '/' + opts.path + pathDel + path;
+}
+
+function paramsToStr(params) {
+  return '?' + Object.keys(params).map(function (k) {
+    return k + '=' + encodeURIComponent(params[k]);
+  }).join('&');
+}
+
+// Implements the PouchDB API for dealing with CouchDB instances over HTTP
+function HttpPouch(opts, callback) {
+  // The functions that will be publicly available for HttpPouch
+  var api = this;
+
+  // Parse the URI given by opts.name into an easy-to-use object
+  var getHostFun = getHost;
+
+  // TODO: this seems to only be used by yarong for the Thali project.
+  // Verify whether or not it's still needed.
+  /* istanbul ignore if */
+  if (opts.getHost) {
+    getHostFun = opts.getHost;
+  }
+
+  var host = getHostFun(opts.name, opts);
+  var dbUrl = genDBUrl(host, '');
+
+  opts = clone(opts);
+  var ajaxOpts = opts.ajax || {};
+
+  api.getUrl = function () { return dbUrl; };
+  api.getHeaders = function () { return ajaxOpts.headers || {}; };
+
+  if (opts.auth || host.auth) {
+    var nAuth = opts.auth || host.auth;
+    var str = nAuth.username + ':' + nAuth.password;
+    var token = btoa$1(unescape(encodeURIComponent(str)));
+    ajaxOpts.headers = ajaxOpts.headers || {};
+    ajaxOpts.headers.Authorization = 'Basic ' + token;
+  }
+
+  function ajax(userOpts, options, callback) {
+    var reqAjax = userOpts.ajax || {};
+    var reqOpts = jsExtend.extend(clone(ajaxOpts), reqAjax, options);
+    log$1(reqOpts.method + ' ' + reqOpts.url);
+    return utils.ajax(reqOpts, callback);
+  }
+
+  function ajaxPromise(userOpts, opts) {
+    return new PouchPromise(function (resolve, reject) {
+      ajax(userOpts, opts, function (err, res) {
+        if (err) {
+          return reject(err);
+        }
+        resolve(res);
+      });
+    });
+  }
+
+  function adapterFun$$(name, fun) {
+    return adapterFun(name, getArguments(function (args) {
+      setup().then(function () {
+        return fun.apply(this, args);
+      })["catch"](function (e) {
+        var callback = args.pop();
+        callback(e);
+      });
+    }));
+  }
+
+  var setupPromise;
+
+  function setup() {
+    // TODO: Remove `skipSetup` in favor of `skip_setup` in a future release
+    if (opts.skipSetup || opts.skip_setup) {
+      return PouchPromise.resolve();
+    }
+
+    // If there is a setup in process or previous successful setup
+    // done then we will use that
+    // If previous setups have been rejected we will try again
+    if (setupPromise) {
+      return setupPromise;
+    }
+
+    var checkExists = {method: 'GET', url: dbUrl};
+    setupPromise = ajaxPromise({}, checkExists)["catch"](function (err) {
+      if (err && err.status && err.status === 404) {
+        // Doesnt exist, create it
+        explainError(404, 'PouchDB is just detecting if the remote exists.');
+        return ajaxPromise({}, {method: 'PUT', url: dbUrl});
+      } else {
+        return PouchPromise.reject(err);
+      }
+    })["catch"](function (err) {
+      // If we try to create a database that already exists
+      if (err && err.status && err.status === 412) {
+        return true;
+      }
+      return PouchPromise.reject(err);
+    });
+
+    setupPromise["catch"](function () {
+      setupPromise = null;
+    });
+
+    return setupPromise;
+  }
+
+  setTimeout(function () {
+    callback(null, api);
+  });
+
+  api.type = function () {
+    return 'http';
+  };
+
+  api.id = adapterFun$$('id', function (callback) {
+    ajax({}, {method: 'GET', url: genUrl(host, '')}, function (err, result) {
+      var uuid = (result && result.uuid) ?
+        (result.uuid + host.db) : genDBUrl(host, '');
+      callback(null, uuid);
+    });
+  });
+
+  api.request = adapterFun$$('request', function (options, callback) {
+    options.url = genDBUrl(host, options.url);
+    ajax({}, options, callback);
+  });
+
+  // Sends a POST request to the host calling the couchdb _compact function
+  //    version: The version of CouchDB it is running
+  api.compact = adapterFun$$('compact', function (opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = clone(opts);
+    ajax(opts, {
+      url: genDBUrl(host, '_compact'),
+      method: 'POST'
+    }, function () {
+      function ping() {
+        api.info(function (err, res) {
+          if (res && !res.compact_running) {
+            callback(null, {ok: true});
+          } else {
+            setTimeout(ping, opts.interval || 200);
+          }
+        });
+      }
+      // Ping the http if it's finished compaction
+      ping();
+    });
+  });
+
+  api.bulkGet = adapterFun('bulkGet', function (opts, callback) {
+    var self = this;
+
+    function doBulkGet(cb) {
+      var params = {};
+      if (opts.revs) {
+        params.revs = true;
+      }
+      if (opts.attachments) {
+        params.attachments = true;
+      }
+      ajax({}, {
+        url: genDBUrl(host, '_bulk_get' + paramsToStr(params)),
+        method: 'POST',
+        body: { docs: opts.docs}
+      }, cb);
+    }
+
+    function doBulkGetShim() {
+      // avoid "url too long error" by splitting up into multiple requests
+      var batchSize = MAX_SIMULTANEOUS_REVS;
+      var numBatches = Math.ceil(opts.docs.length / batchSize);
+      var numDone = 0;
+      var results = new Array(numBatches);
+
+      function onResult(batchNum) {
+        return function (err, res) {
+          // err is impossible because shim returns a list of errs in that case
+          results[batchNum] = res.results;
+          if (++numDone === numBatches) {
+            callback(null, {results: flatten(results)});
+          }
+        };
+      }
+
+      for (var i = 0; i < numBatches; i++) {
+        var subOpts = pick(opts, ['revs', 'attachments']);
+        subOpts.ajax = ajaxOpts;
+        subOpts.docs = opts.docs.slice(i * batchSize,
+          Math.min(opts.docs.length, (i + 1) * batchSize));
+        bulkGet(self, subOpts, onResult(i));
+      }
+    }
+
+    // mark the whole database as either supporting or not supporting _bulk_get
+    var dbUrl = genUrl(host, '');
+    var supportsBulkGet = supportsBulkGetMap[dbUrl];
+
+    if (typeof supportsBulkGet !== 'boolean') {
+      // check if this database supports _bulk_get
+      doBulkGet(function (err, res) {
+        /* istanbul ignore else */
+        if (err) {
+          var status = Math.floor(err.status / 100);
+          /* istanbul ignore else */
+          if (status === 4 || status === 5) { // 40x or 50x
+            supportsBulkGetMap[dbUrl] = false;
+            explainError(
+              err.status,
+              'PouchDB is just detecting if the remote ' +
+              'supports the _bulk_get API.'
+            );
+            doBulkGetShim();
+          } else {
+            callback(err);
+          }
+        } else {
+          supportsBulkGetMap[dbUrl] = true;
+          callback(null, res);
+        }
+      });
+    } else if (supportsBulkGet) {
+      /* istanbul ignore next */
+      doBulkGet(callback);
+    } else {
+      doBulkGetShim();
+    }
+  });
+
+  // Calls GET on the host, which gets back a JSON string containing
+  //    couchdb: A welcome string
+  //    version: The version of CouchDB it is running
+  api._info = function (callback) {
+    setup().then(function () {
+      ajax({}, {
+        method: 'GET',
+        url: genDBUrl(host, '')
+      }, function (err, res) {
+        /* istanbul ignore next */
+        if (err) {
+        return callback(err);
+        }
+        res.host = genDBUrl(host, '');
+        callback(null, res);
+      });
+    })["catch"](callback);
+  };
+
+  // Get the document with the given id from the database given by host.
+  // The id could be solely the _id in the database, or it may be a
+  // _design/ID or _local/ID path
+  api.get = adapterFun$$('get', function (id, opts, callback) {
+    // If no options were given, set the callback to the second parameter
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = clone(opts);
+
+    // List of parameters to add to the GET request
+    var params = {};
+
+    if (opts.revs) {
+      params.revs = true;
+    }
+
+    if (opts.revs_info) {
+      params.revs_info = true;
+    }
+
+    if (opts.open_revs) {
+      if (opts.open_revs !== "all") {
+        opts.open_revs = JSON.stringify(opts.open_revs);
+      }
+      params.open_revs = opts.open_revs;
+    }
+
+    if (opts.rev) {
+      params.rev = opts.rev;
+    }
+
+    if (opts.conflicts) {
+      params.conflicts = opts.conflicts;
+    }
+
+    id = encodeDocId(id);
+
+    // Set the options for the ajax call
+    var options = {
+      method: 'GET',
+      url: genDBUrl(host, id + paramsToStr(params))
+    };
+
+    function fetchAttachments(doc) {
+      var atts = doc._attachments;
+      var filenames = atts && Object.keys(atts);
+      if (!atts || !filenames.length) {
+        return;
+      }
+      // we fetch these manually in separate XHRs, because
+      // Sync Gateway would normally send it back as multipart/mixed,
+      // which we cannot parse. Also, this is more efficient than
+      // receiving attachments as base64-encoded strings.
+      return PouchPromise.all(filenames.map(function (filename) {
+        var att = atts[filename];
+        var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
+          '?rev=' + doc._rev;
+        return ajaxPromise(opts, {
+          method: 'GET',
+          url: genDBUrl(host, path),
+          binary: true
+        }).then(function (blob) {
+          if (opts.binary) {
+            return blob;
+          }
+          return blobToBase64(blob);
+        }).then(function (data) {
+          delete att.stub;
+          delete att.length;
+          att.data = data;
+        });
+      }));
+    }
+
+    function fetchAllAttachments(docOrDocs) {
+      if (Array.isArray(docOrDocs)) {
+        return PouchPromise.all(docOrDocs.map(function (doc) {
+          if (doc.ok) {
+            return fetchAttachments(doc.ok);
+          }
+        }));
+      }
+      return fetchAttachments(docOrDocs);
+    }
+
+    ajaxPromise(opts, options).then(function (res) {
+      return PouchPromise.resolve().then(function () {
+        if (opts.attachments) {
+          return fetchAllAttachments(res);
+        }
+      }).then(function () {
+        callback(null, res);
+      });
+    })["catch"](callback);
+  });
+
+  // Delete the document given by doc from the database given by host.
+  api.remove = adapterFun$$('remove',
+      function (docOrId, optsOrRev, opts, callback) {
+    var doc;
+    if (typeof optsOrRev === 'string') {
+      // id, rev, opts, callback style
+      doc = {
+        _id: docOrId,
+        _rev: optsOrRev
+      };
+      if (typeof opts === 'function') {
+        callback = opts;
+        opts = {};
+      }
+    } else {
+      // doc, opts, callback style
+      doc = docOrId;
+      if (typeof optsOrRev === 'function') {
+        callback = optsOrRev;
+        opts = {};
+      } else {
+        callback = opts;
+        opts = optsOrRev;
+      }
+    }
+
+    var rev = (doc._rev || opts.rev);
+
+    // Delete the document
+    ajax(opts, {
+      method: 'DELETE',
+      url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev
+    }, callback);
+  });
+
+  function encodeAttachmentId(attachmentId) {
+    return attachmentId.split("/").map(encodeURIComponent).join("/");
+  }
+
+  // Get the attachment
+  api.getAttachment =
+    adapterFun$$('getAttachment', function (docId, attachmentId, opts,
+                                                callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var params = opts.rev ? ('?rev=' + opts.rev) : '';
+    var url = genDBUrl(host, encodeDocId(docId)) + '/' +
+      encodeAttachmentId(attachmentId) + params;
+    ajax(opts, {
+      method: 'GET',
+      url: url,
+      binary: true
+    }, callback);
+  });
+
+  // Remove the attachment given by the id and rev
+  api.removeAttachment =
+    adapterFun$$('removeAttachment', function (docId, attachmentId, rev,
+                                                   callback) {
+
+    var url = genDBUrl(host, encodeDocId(docId) + '/' +
+      encodeAttachmentId(attachmentId)) + '?rev=' + rev;
+
+    ajax({}, {
+      method: 'DELETE',
+      url: url
+    }, callback);
+  });
+
+  // Add the attachment given by blob and its contentType property
+  // to the document with the given id, the revision given by rev, and
+  // add it to the database given by host.
+  api.putAttachment =
+    adapterFun$$('putAttachment', function (docId, attachmentId, rev, blob,
+                                                type, callback) {
+    if (typeof type === 'function') {
+      callback = type;
+      type = blob;
+      blob = rev;
+      rev = null;
+    }
+    var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId);
+    var url = genDBUrl(host, id);
+    if (rev) {
+      url += '?rev=' + rev;
+    }
+
+    if (typeof blob === 'string') {
+      // input is assumed to be a base64 string
+      var binary;
+      try {
+        binary = atob$1(blob);
+      } catch (err) {
+        return callback(createError(BAD_ARG,
+                        'Attachment is not a valid base64 string'));
+      }
+      blob = binary ? binStringToBluffer(binary, type) : '';
+    }
+
+    var opts = {
+      headers: {'Content-Type': type},
+      method: 'PUT',
+      url: url,
+      processData: false,
+      body: blob,
+      timeout: ajaxOpts.timeout || 60000
+    };
+    // Add the attachment
+    ajax({}, opts, callback);
+  });
+
+  // Update/create multiple documents given by req in the database
+  // given by host.
+  api._bulkDocs = function (req, opts, callback) {
+    // If new_edits=false then it prevents the database from creating
+    // new revision numbers for the documents. Instead it just uses
+    // the old ones. This is used in database replication.
+    req.new_edits = opts.new_edits;
+
+    setup().then(function () {
+      return PouchPromise.all(req.docs.map(preprocessAttachments));
+    }).then(function () {
+      // Update/create the documents
+      ajax(opts, {
+        method: 'POST',
+        url: genDBUrl(host, '_bulk_docs'),
+        body: req
+      }, function (err, results) {
+        if (err) {
+          return callback(err);
+        }
+        results.forEach(function (result) {
+          result.ok = true; // smooths out cloudant not adding this
+        });
+        callback(null, results);
+      });
+    })["catch"](callback);
+  };
+
+  // Get a listing of the documents in the database given
+  // by host and ordered by increasing id.
+  api.allDocs = adapterFun$$('allDocs', function (opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = clone(opts);
+
+    // List of parameters to add to the GET request
+    var params = {};
+    var body;
+    var method = 'GET';
+
+    if (opts.conflicts) {
+      params.conflicts = true;
+    }
+
+    if (opts.descending) {
+      params.descending = true;
+    }
+
+    if (opts.include_docs) {
+      params.include_docs = true;
+    }
+
+    // added in CouchDB 1.6.0
+    if (opts.attachments) {
+      params.attachments = true;
+    }
+
+    if (opts.key) {
+      params.key = JSON.stringify(opts.key);
+    }
+
+    if (opts.start_key) {
+      opts.startkey = opts.start_key;
+    }
+
+    if (opts.startkey) {
+      params.startkey = JSON.stringify(opts.startkey);
+    }
+
+    if (opts.end_key) {
+      opts.endkey = opts.end_key;
+    }
+
+    if (opts.endkey) {
+      params.endkey = JSON.stringify(opts.endkey);
+    }
+
+    if (typeof opts.inclusive_end !== 'undefined') {
+      params.inclusive_end = !!opts.inclusive_end;
+    }
+
+    if (typeof opts.limit !== 'undefined') {
+      params.limit = opts.limit;
+    }
+
+    if (typeof opts.skip !== 'undefined') {
+      params.skip = opts.skip;
+    }
+
+    var paramStr = paramsToStr(params);
+
+    if (typeof opts.keys !== 'undefined') {
+
+      var keysAsString =
+        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+      if (keysAsString.length + paramStr.length + 1 <= MAX_URL_LENGTH) {
+        // If the keys are short enough, do a GET. we do this to work around
+        // Safari not understanding 304s on POSTs (see issue #1239)
+        paramStr += '&' + keysAsString;
+      } else {
+        // If keys are too long, issue a POST request to circumvent GET
+        // query string limits
+        // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+        method = 'POST';
+        body = {keys: opts.keys};
+      }
+    }
+
+    // Get the document listing
+    ajaxPromise(opts, {
+      method: method,
+      url: genDBUrl(host, '_all_docs' + paramStr),
+      body: body
+    }).then(function (res) {
+      if (opts.include_docs && opts.attachments && opts.binary) {
+        res.rows.forEach(readAttachmentsAsBlobOrBuffer);
+      }
+      callback(null, res);
+    })["catch"](callback);
+  });
+
+  // Get a list of changes made to documents in the database given by host.
+  // TODO According to the README, there should be two other methods here,
+  // api.changes.addListener and api.changes.removeListener.
+  api._changes = function (opts) {
+
+    // We internally page the results of a changes request, this means
+    // if there is a large set of changes to be returned we can start
+    // processing them quicker instead of waiting on the entire
+    // set of changes to return and attempting to process them at once
+    var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
+
+    opts = clone(opts);
+    opts.timeout = ('timeout' in opts) ? opts.timeout :
+      ('timeout' in ajaxOpts) ? ajaxOpts.timeout :
+      30 * 1000;
+
+    // We give a 5 second buffer for CouchDB changes to respond with
+    // an ok timeout (if a timeout it set)
+    var params = opts.timeout ? {timeout: opts.timeout - (5 * 1000)} : {};
+    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+    //
+    var leftToFetch = limit;
+
+    if (opts.style) {
+      params.style = opts.style;
+    }
+
+    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
+      params.include_docs = true;
+    }
+
+    if (opts.attachments) {
+      params.attachments = true;
+    }
+
+    if (opts.continuous) {
+      params.feed = 'longpoll';
+    }
+
+    if (opts.conflicts) {
+      params.conflicts = true;
+    }
+
+    if (opts.descending) {
+      params.descending = true;
+    }
+
+    if ('heartbeat' in opts) {
+      // If the heartbeat value is false, it disables the default heartbeat
+      if (opts.heartbeat) {
+        params.heartbeat = opts.heartbeat;
+      }
+    } else {
+      // Default heartbeat to 10 seconds
+      params.heartbeat = 10000;
+    }
+
+    if (opts.filter && typeof opts.filter === 'string') {
+      params.filter = opts.filter;
+      if (opts.filter === '_view' &&
+          opts.view &&
+          typeof opts.view === 'string') {
+        params.view = opts.view;
+      }
+    }
+
+    // If opts.query_params exists, pass it through to the changes request.
+    // These parameters may be used by the filter on the source database.
+    if (opts.query_params && typeof opts.query_params === 'object') {
+      for (var param_name in opts.query_params) {
+        /* istanbul ignore else */
+        if (opts.query_params.hasOwnProperty(param_name)) {
+          params[param_name] = opts.query_params[param_name];
+        }
+      }
+    }
+
+    var method = 'GET';
+    var body;
+
+    if (opts.doc_ids) {
+      // set this automagically for the user; it's annoying that couchdb
+      // requires both a "filter" and a "doc_ids" param.
+      params.filter = '_doc_ids';
+
+      var docIdsJson = JSON.stringify(opts.doc_ids);
+
+      if (docIdsJson.length < MAX_URL_LENGTH) {
+        params.doc_ids = docIdsJson;
+      } else {
+        // anything greater than ~2000 is unsafe for gets, so
+        // use POST instead
+        method = 'POST';
+        body = {doc_ids: opts.doc_ids };
+      }
+    }
+
+    var xhr;
+    var lastFetchedSeq;
+
+    // Get all the changes starting wtih the one immediately after the
+    // sequence number given by since.
+    var fetch = function (since, callback) {
+      if (opts.aborted) {
+        return;
+      }
+      params.since = since;
+      // "since" can be any kind of json object in Coudant/CouchDB 2.x
+      /* istanbul ignore next */
+      if (typeof params.since === "object") {
+        params.since = JSON.stringify(params.since);
+      }
+
+      if (opts.descending) {
+        if (limit) {
+          params.limit = leftToFetch;
+        }
+      } else {
+        params.limit = (!limit || leftToFetch > batchSize) ?
+          batchSize : leftToFetch;
+      }
+
+      // Set the options for the ajax call
+      var xhrOpts = {
+        method: method,
+        url: genDBUrl(host, '_changes' + paramsToStr(params)),
+        timeout: opts.timeout,
+        body: body
+      };
+      lastFetchedSeq = since;
+
+      /* istanbul ignore if */
+      if (opts.aborted) {
+        return;
+      }
+
+      // Get the changes
+      setup().then(function () {
+        xhr = ajax(opts, xhrOpts, callback);
+      })["catch"](callback);
+    };
+
+    // If opts.since exists, get all the changes from the sequence
+    // number given by opts.since. Otherwise, get all the changes
+    // from the sequence number 0.
+    var results = {results: []};
+
+    var fetched = function (err, res) {
+      if (opts.aborted) {
+        return;
+      }
+      var raw_results_length = 0;
+      // If the result of the ajax call (res) contains changes (res.results)
+      if (res && res.results) {
+        raw_results_length = res.results.length;
+        results.last_seq = res.last_seq;
+        // For each change
+        var req = {};
+        req.query = opts.query_params;
+        res.results = res.results.filter(function (c) {
+          leftToFetch--;
+          var ret = filterChange(opts)(c);
+          if (ret) {
+            if (opts.include_docs && opts.attachments && opts.binary) {
+              readAttachmentsAsBlobOrBuffer(c);
+            }
+            if (returnDocs) {
+              results.results.push(c);
+            }
+            opts.onChange(c);
+          }
+          return ret;
+        });
+      } else if (err) {
+        // In case of an error, stop listening for changes and call
+        // opts.complete
+        opts.aborted = true;
+        opts.complete(err);
+        return;
+      }
+
+      // The changes feed may have timed out with no results
+      // if so reuse last update sequence
+      if (res && res.last_seq) {
+        lastFetchedSeq = res.last_seq;
+      }
+
+      var finished = (limit && leftToFetch <= 0) ||
+        (res && raw_results_length < batchSize) ||
+        (opts.descending);
+
+      if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
+        // Queue a call to fetch again with the newest sequence number
+        setTimeout(function () { fetch(lastFetchedSeq, fetched); }, 0);
+      } else {
+        // We're done, call the callback
+        opts.complete(null, results);
+      }
+    };
+
+    fetch(opts.since || 0, fetched);
+
+    // Return a method to cancel this method from processing any more
+    return {
+      cancel: function () {
+        opts.aborted = true;
+        if (xhr) {
+          xhr.abort();
+        }
+      }
+    };
+  };
+
+  // Given a set of document/revision IDs (given by req), tets the subset of
+  // those that do NOT correspond to revisions stored in the database.
+  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
+  api.revsDiff = adapterFun$$('revsDiff', function (req, opts, callback) {
+    // If no options were given, set the callback to be the second parameter
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+
+    // Get the missing document/revision IDs
+    ajax(opts, {
+      method: 'POST',
+      url: genDBUrl(host, '_revs_diff'),
+      body: req
+    }, callback);
+  });
+
+  api._close = function (callback) {
+    callback();
+  };
+
+  api._destroy = function (options, callback) {
+    ajax(options, {
+      url: genDBUrl(host, ''),
+      method: 'DELETE'
+    }, function (err, resp) {
+      if (err && err.status && err.status !== 404) {
+        return callback(err);
+      }
+      api.emit('destroyed');
+      api.constructor.emit('destroyed', opts.name);
+      callback(null, resp);
+    });
+  };
+}
+
+// HttpPouch is a valid adapter.
+HttpPouch.valid = function () {
+  return true;
+};
+
+function TaskQueue$1() {
+  this.promise = new PouchPromise(function (fulfill) {fulfill(); });
+}
+TaskQueue$1.prototype.add = function (promiseFactory) {
+  this.promise = this.promise["catch"](function () {
+    // just recover
+  }).then(function () {
+    return promiseFactory();
+  });
+  return this.promise;
+};
+TaskQueue$1.prototype.finish = function () {
+  return this.promise;
+};
+
+function md5$1(string) {
+  return Md5.hash(string);
+}
+
+function createView(opts) {
+  var sourceDB = opts.db;
+  var viewName = opts.viewName;
+  var mapFun = opts.map;
+  var reduceFun = opts.reduce;
+  var temporary = opts.temporary;
+
+  // the "undefined" part is for backwards compatibility
+  var viewSignature = mapFun.toString() + (reduceFun && reduceFun.toString()) +
+    'undefined';
+
+  if (!temporary && sourceDB._cachedViews) {
+    var cachedView = sourceDB._cachedViews[viewSignature];
+    if (cachedView) {
+      return PouchPromise.resolve(cachedView);
+    }
+  }
+
+  return sourceDB.info().then(function (info) {
+
+    var depDbName = info.db_name + '-mrview-' +
+      (temporary ? 'temp' : md5$1(viewSignature));
+
+    // save the view name in the source db so it can be cleaned up if necessary
+    // (e.g. when the _design doc is deleted, remove all associated view data)
+    function diffFunction(doc) {
+      doc.views = doc.views || {};
+      var fullViewName = viewName;
+      if (fullViewName.indexOf('/') === -1) {
+        fullViewName = viewName + '/' + viewName;
+      }
+      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
+      /* istanbul ignore if */
+      if (depDbs[depDbName]) {
+        return; // no update necessary
+      }
+      depDbs[depDbName] = true;
+      return doc;
+    }
+    return upsert(sourceDB, '_local/mrviews', diffFunction).then(function () {
+      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
+        var db = res.db;
+        db.auto_compaction = true;
+        var view = {
+          name: depDbName,
+          db: db,
+          sourceDB: sourceDB,
+          adapter: sourceDB.adapter,
+          mapFun: mapFun,
+          reduceFun: reduceFun
+        };
+        return view.db.get('_local/lastSeq')["catch"](function (err) {
+          /* istanbul ignore if */
+          if (err.status !== 404) {
+            throw err;
+          }
+        }).then(function (lastSeqDoc) {
+          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
+          if (!temporary) {
+            sourceDB._cachedViews = sourceDB._cachedViews || {};
+            sourceDB._cachedViews[viewSignature] = view;
+            view.db.once('destroyed', function () {
+              delete sourceDB._cachedViews[viewSignature];
+            });
+          }
+          return view;
+        });
+      });
+    });
+  });
+}
+
+function evalfunc(func, emit, sum, log, isArray, toJSON) {
+  return scopedEval(
+    "return (" + func.replace(/;\s*$/, "") + ");",
+    {
+      emit: emit,
+      sum: sum,
+      log: log,
+      isArray: isArray,
+      toJSON: toJSON
+    }
+  );
+}
+
+var promisedCallback$1 = function (promise, callback) {
+  if (callback) {
+    promise.then(function (res) {
+      process.nextTick(function () {
+        callback(null, res);
+      });
+    }, function (reason) {
+      process.nextTick(function () {
+        callback(reason);
+      });
+    });
+  }
+  return promise;
+};
+
+var callbackify$1 = function (fun) {
+  return getArguments(function (args) {
+    var cb = args.pop();
+    var promise = fun.apply(this, args);
+    if (typeof cb === 'function') {
+      promisedCallback$1(promise, cb);
+    }
+    return promise;
+  });
+};
+
+// Promise finally util similar to Q.finally
+var fin$1 = function (promise, finalPromiseFactory) {
+  return promise.then(function (res) {
+    return finalPromiseFactory().then(function () {
+      return res;
+    });
+  }, function (reason) {
+    return finalPromiseFactory().then(function () {
+      throw reason;
+    });
+  });
+};
+
+var sequentialize$1 = function (queue, promiseFactory) {
+  return function () {
+    var args = arguments;
+    var that = this;
+    return queue.add(function () {
+      return promiseFactory.apply(that, args);
+    });
+  };
+};
+
+// uniq an array of strings, order not guaranteed
+// similar to underscore/lodash _.uniq
+var uniq$1 = function (arr) {
+  var map = {};
+
+  for (var i = 0, len = arr.length; i < len; i++) {
+    map['$' + arr[i]] = true;
+  }
+
+  var keys = Object.keys(map);
+  var output = new Array(keys.length);
+
+  for (i = 0, len = keys.length; i < len; i++) {
+    output[i] = keys[i].substring(1);
+  }
+  return output;
+};
+
+var utils$1 = {
+  uniq: uniq$1,
+  sequentialize: sequentialize$1,
+  fin: fin$1,
+  callbackify: callbackify$1,
+  promisedCallback: promisedCallback$1
+};
+
+var collate$2 = pouchCollate__default.collate;
+var toIndexableString = pouchCollate__default.toIndexableString;
+var normalizeKey = pouchCollate__default.normalizeKey;
+var parseIndexableString = pouchCollate__default.parseIndexableString;
+var log$2;
+/* istanbul ignore else */
+if ((typeof console !== 'undefined') && (typeof console.log === 'function')) {
+  log$2 = Function.prototype.bind.call(console.log, console);
+} else {
+  log$2 = function () {};
+}
+var callbackify = utils$1.callbackify;
+var sequentialize = utils$1.sequentialize;
+var uniq = utils$1.uniq;
+var fin = utils$1.fin;
+var promisedCallback = utils$1.promisedCallback;
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue$1();
+var CHANGES_BATCH_SIZE$1 = 50;
+
+function parseViewName(name) {
+  // can be either 'ddocname/viewname' or just 'viewname'
+  // (where the ddoc name is the same)
+  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+}
+
+function isGenOne$1(changes) {
+  // only return true if the current change is 1-
+  // and there are no other leafs
+  return changes.length === 1 && /^1-/.test(changes[0].rev);
+}
+
+function emitError(db, e) {
+  try {
+    db.emit('error', e);
+  } catch (err) {
+    console.error(
+      'The user\'s map/reduce function threw an uncaught error.\n' +
+      'You can debug this error by doing:\n' +
+      'myDatabase.on(\'error\', function (err) { debugger; });\n' +
+      'Please double-check your map/reduce function.');
+    console.error(e);
+  }
+}
+
+function tryCode(db, fun, args) {
+  // emit an event if there was an error thrown by a map/reduce function.
+  // putting try/catches in a single function also avoids deoptimizations.
+  try {
+    return {
+      output : fun.apply(null, args)
+    };
+  } catch (e) {
+    emitError(db, e);
+    return {error: e};
+  }
+}
+
+function sortByKeyThenValue(x, y) {
+  var keyCompare = collate$2(x.key, y.key);
+  return keyCompare !== 0 ? keyCompare : collate$2(x.value, y.value);
+}
+
+function sliceResults(results, limit, skip) {
+  skip = skip || 0;
+  if (typeof limit === 'number') {
+    return results.slice(skip, limit + skip);
+  } else if (skip > 0) {
+    return results.slice(skip);
+  }
+  return results;
+}
+
+function rowToDocId(row) {
+  var val = row.value;
+  // Users can explicitly specify a joined doc _id, or it
+  // defaults to the doc _id that emitted the key/value.
+  var docId = (val && typeof val === 'object' && val._id) || row.id;
+  return docId;
+}
+
+function readAttachmentsAsBlobOrBuffer$1(res) {
+  res.rows.forEach(function (row) {
+    var atts = row.doc && row.doc._attachments;
+    if (!atts) {
+      return;
+    }
+    Object.keys(atts).forEach(function (filename) {
+      var att = atts[filename];
+      atts[filename].data = b64ToBluffer(att.data, att.content_type);
+    });
+  });
+}
+
+function postprocessAttachments(opts) {
+  return function (res) {
+    if (opts.include_docs && opts.attachments && opts.binary) {
+      readAttachmentsAsBlobOrBuffer$1(res);
+    }
+    return res;
+  };
+}
+
+function createBuiltInError(name) {
+  var message = 'builtin ' + name +
+    ' function requires map values to be numbers' +
+    ' or number arrays';
+  return new BuiltInError(message);
+}
+
+function sum(values) {
+  var result = 0;
+  for (var i = 0, len = values.length; i < len; i++) {
+    var num = values[i];
+    if (typeof num !== 'number') {
+      if (Array.isArray(num)) {
+        // lists of numbers are also allowed, sum them separately
+        result = typeof result === 'number' ? [result] : result;
+        for (var j = 0, jLen = num.length; j < jLen; j++) {
+          var jNum = num[j];
+          if (typeof jNum !== 'number') {
+            throw createBuiltInError('_sum');
+          } else if (typeof result[j] === 'undefined') {
+            result.push(jNum);
+          } else {
+            result[j] += jNum;
+          }
+        }
+      } else { // not array/number
+        throw createBuiltInError('_sum');
+      }
+    } else if (typeof result === 'number') {
+      result += num;
+    } else { // add number to array
+      result[0] += num;
+    }
+  }
+  return result;
+}
+
+var builtInReduce = {
+  _sum: function (keys, values) {
+    return sum(values);
+  },
+
+  _count: function (keys, values) {
+    return values.length;
+  },
+
+  _stats: function (keys, values) {
+    // no need to implement rereduce=true, because Pouch
+    // will never call it
+    function sumsqr(values) {
+      var _sumsqr = 0;
+      for (var i = 0, len = values.length; i < len; i++) {
+        var num = values[i];
+        _sumsqr += (num * num);
+      }
+      return _sumsqr;
+    }
+    return {
+      sum     : sum(values),
+      min     : Math.min.apply(null, values),
+      max     : Math.max.apply(null, values),
+      count   : values.length,
+      sumsqr : sumsqr(values)
+    };
+  }
+};
+
+function addHttpParam(paramName, opts, params, asJson) {
+  // add an http param from opts to params, optionally json-encoded
+  var val = opts[paramName];
+  if (typeof val !== 'undefined') {
+    if (asJson) {
+      val = encodeURIComponent(JSON.stringify(val));
+    }
+    params.push(paramName + '=' + val);
+  }
+}
+
+function coerceInteger(integerCandidate) {
+  if (typeof integerCandidate !== 'undefined') {
+    var asNumber = Number(integerCandidate);
+    // prevents e.g. '1foo' or '1.1' being coerced to 1
+    if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
+      return asNumber;
+    } else {
+      return integerCandidate;
+    }
+  }
+}
+
+function coerceOptions(opts) {
+  opts.group_level = coerceInteger(opts.group_level);
+  opts.limit = coerceInteger(opts.limit);
+  opts.skip = coerceInteger(opts.skip);
+  return opts;
+}
+
+function checkPositiveInteger(number) {
+  if (number) {
+    if (typeof number !== 'number') {
+      return  new QueryParseError('Invalid value for integer: "' +
+      number + '"');
+    }
+    if (number < 0) {
+      return new QueryParseError('Invalid value for positive integer: ' +
+        '"' + number + '"');
+    }
+  }
+}
+
+function checkQueryParseError(options, fun) {
+  var startkeyName = options.descending ? 'endkey' : 'startkey';
+  var endkeyName = options.descending ? 'startkey' : 'endkey';
+
+  if (typeof options[startkeyName] !== 'undefined' &&
+    typeof options[endkeyName] !== 'undefined' &&
+    collate$2(options[startkeyName], options[endkeyName]) > 0) {
+    throw new QueryParseError('No rows can match your key range, ' +
+    'reverse your start_key and end_key or set {descending : true}');
+  } else if (fun.reduce && options.reduce !== false) {
+    if (options.include_docs) {
+      throw new QueryParseError('{include_docs:true} is invalid for reduce');
+    } else if (options.keys && options.keys.length > 1 &&
+        !options.group && !options.group_level) {
+      throw new QueryParseError('Multi-key fetches for reduce views must use ' +
+      '{group: true}');
+    }
+  }
+  ['group_level', 'limit', 'skip'].forEach(function (optionName) {
+    var error = checkPositiveInteger(options[optionName]);
+    if (error) {
+      throw error;
+    }
+  });
+}
+
+function httpQuery(db, fun, opts) {
+  // List of parameters to add to the PUT request
+  var params = [];
+  var body;
+  var method = 'GET';
+
+  // If opts.reduce exists and is defined, then add it to the list
+  // of parameters.
+  // If reduce=false then the results are that of only the map function
+  // not the final result of map and reduce.
+  addHttpParam('reduce', opts, params);
+  addHttpParam('include_docs', opts, params);
+  addHttpParam('attachments', opts, params);
+  addHttpParam('limit', opts, params);
+  addHttpParam('descending', opts, params);
+  addHttpParam('group', opts, params);
+  addHttpParam('group_level', opts, params);
+  addHttpParam('skip', opts, params);
+  addHttpParam('stale', opts, params);
+  addHttpParam('conflicts', opts, params);
+  addHttpParam('startkey', opts, params, true);
+  addHttpParam('start_key', opts, params, true);
+  addHttpParam('endkey', opts, params, true);
+  addHttpParam('end_key', opts, params, true);
+  addHttpParam('inclusive_end', opts, params);
+  addHttpParam('key', opts, params, true);
+
+  // Format the list of parameters into a valid URI query string
+  params = params.join('&');
+  params = params === '' ? '' : '?' + params;
+
+  // If keys are supplied, issue a POST to circumvent GET query string limits
+  // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+  if (typeof opts.keys !== 'undefined') {
+    var MAX_URL_LENGTH = 2000;
+    // according to http://stackoverflow.com/a/417184/680742,
+    // the de facto URL length limit is 2000 characters
+
+    var keysAsString =
+      'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+    if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
+      // If the keys are short enough, do a GET. we do this to work around
+      // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
+      params += (params[0] === '?' ? '&' : '?') + keysAsString;
+    } else {
+      method = 'POST';
+      if (typeof fun === 'string') {
+        body = {keys: opts.keys};
+      } else { // fun is {map : mapfun}, so append to this
+        fun.keys = opts.keys;
+      }
+    }
+  }
+
+  // We are referencing a query defined in the design doc
+  if (typeof fun === 'string') {
+    var parts = parseViewName(fun);
+    return db.request({
+      method: method,
+      url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
+      body: body
+    }).then(postprocessAttachments(opts));
+  }
+
+  // We are using a temporary view, terrible for performance, good for testing
+  body = body || {};
+  Object.keys(fun).forEach(function (key) {
+    if (Array.isArray(fun[key])) {
+      body[key] = fun[key];
+    } else {
+      body[key] = fun[key].toString();
+    }
+  });
+  return db.request({
+    method: 'POST',
+    url: '_temp_view' + params,
+    body: body
+  }).then(postprocessAttachments(opts));
+}
+
+// custom adapters can define their own api._query
+// and override the default behavior
+/* istanbul ignore next */
+function customQuery(db, fun, opts) {
+  return new PouchPromise(function (resolve, reject) {
+    db._query(fun, opts, function (err, res) {
+      if (err) {
+        return reject(err);
+      }
+      resolve(res);
+    });
+  });
+}
+
+// custom adapters can define their own api._viewCleanup
+// and override the default behavior
+/* istanbul ignore next */
+function customViewCleanup(db) {
+  return new PouchPromise(function (resolve, reject) {
+    db._viewCleanup(function (err, res) {
+      if (err) {
+        return reject(err);
+      }
+      resolve(res);
+    });
+  });
+}
+
+function defaultsTo(value) {
+  return function (reason) {
+    /* istanbul ignore else */
+    if (reason.status === 404) {
+      return value;
+    } else {
+      throw reason;
+    }
+  };
+}
+
+// returns a promise for a list of docs to update, based on the input docId.
+// the order doesn't matter, because post-3.2.0, bulkDocs
+// is an atomic operation in all three adapters.
+function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
+  var metaDocId = '_local/doc_' + docId;
+  var defaultMetaDoc = {_id: metaDocId, keys: []};
+  var docData = docIdsToChangesAndEmits[docId];
+  var indexableKeysToKeyValues = docData.indexableKeysToKeyValues;
+  var changes = docData.changes;
+
+  function getMetaDoc() {
+    if (isGenOne$1(changes)) {
+      // generation 1, so we can safely assume initial state
+      // for performance reasons (avoids unnecessary GETs)
+      return PouchPromise.resolve(defaultMetaDoc);
+    }
+    return view.db.get(metaDocId)["catch"](defaultsTo(defaultMetaDoc));
+  }
+
+  function getKeyValueDocs(metaDoc) {
+    if (!metaDoc.keys.length) {
+      // no keys, no need for a lookup
+      return PouchPromise.resolve({rows: []});
+    }
+    return view.db.allDocs({
+      keys: metaDoc.keys,
+      include_docs: true
+    });
+  }
+
+  function processKvDocs(metaDoc, kvDocsRes) {
+    var kvDocs = [];
+    var oldKeysMap = {};
+
+    for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
+      var row = kvDocsRes.rows[i];
+      var doc = row.doc;
+      if (!doc) { // deleted
+        continue;
+      }
+      kvDocs.push(doc);
+      oldKeysMap[doc._id] = true;
+      doc._deleted = !indexableKeysToKeyValues[doc._id];
+      if (!doc._deleted) {
+        var keyValue = indexableKeysToKeyValues[doc._id];
+        if ('value' in keyValue) {
+          doc.value = keyValue.value;
+        }
+      }
+    }
+
+    var newKeys = Object.keys(indexableKeysToKeyValues);
+    newKeys.forEach(function (key) {
+      if (!oldKeysMap[key]) {
+        // new doc
+        var kvDoc = {
+          _id: key
+        };
+        var keyValue = indexableKeysToKeyValues[key];
+        if ('value' in keyValue) {
+          kvDoc.value = keyValue.value;
+        }
+        kvDocs.push(kvDoc);
+      }
+    });
+    metaDoc.keys = uniq(newKeys.concat(metaDoc.keys));
+    kvDocs.push(metaDoc);
+
+    return kvDocs;
+  }
+
+  return getMetaDoc().then(function (metaDoc) {
+    return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
+      return processKvDocs(metaDoc, kvDocsRes);
+    });
+  });
+}
+
+// updates all emitted key/value docs and metaDocs in the mrview database
+// for the given batch of documents from the source database
+function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
+  var seqDocId = '_local/lastSeq';
+  return view.db.get(seqDocId)[
+  "catch"](defaultsTo({_id: seqDocId, seq: 0}))
+  .then(function (lastSeqDoc) {
+    var docIds = Object.keys(docIdsToChangesAndEmits);
+    return PouchPromise.all(docIds.map(function (docId) {
+      return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
+    })).then(function (listOfDocsToPersist) {
+      var docsToPersist = flatten(listOfDocsToPersist);
+      lastSeqDoc.seq = seq;
+      docsToPersist.push(lastSeqDoc);
+      // write all docs in a single operation, update the seq once
+      return view.db.bulkDocs({docs : docsToPersist});
+    });
+  });
+}
+
+function getQueue(view) {
+  var viewName = typeof view === 'string' ? view : view.name;
+  var queue = persistentQueues[viewName];
+  if (!queue) {
+    queue = persistentQueues[viewName] = new TaskQueue$1();
+  }
+  return queue;
+}
+
+function updateView(view) {
+  return sequentialize(getQueue(view), function () {
+    return updateViewInQueue(view);
+  })();
+}
+
+function updateViewInQueue(view) {
+  // bind the emit function once
+  var mapResults;
+  var doc;
+
+  function emit(key, value) {
+    var output = {id: doc._id, key: normalizeKey(key)};
+    // Don't explicitly store the value unless it's defined and non-null.
+    // This saves on storage space, because often people don't use it.
+    if (typeof value !== 'undefined' && value !== null) {
+      output.value = normalizeKey(value);
+    }
+    mapResults.push(output);
+  }
+
+  var mapFun;
+  // for temp_views one can use emit(doc, emit), see #38
+  if (typeof view.mapFun === "function" && view.mapFun.length === 2) {
+    var origMap = view.mapFun;
+    mapFun = function (doc) {
+      return origMap(doc, emit);
+    };
+  } else {
+    mapFun = evalfunc(view.mapFun.toString(), emit, sum, log$2, Array.isArray,
+      JSON.parse);
+  }
+
+  var currentSeq = view.seq || 0;
+
+  function processChange(docIdsToChangesAndEmits, seq) {
+    return function () {
+      return saveKeyValues(view, docIdsToChangesAndEmits, seq);
+    };
+  }
+
+  var queue = new TaskQueue$1();
+  // TODO(neojski): https://github.com/daleharvey/pouchdb/issues/1521
+
+  return new PouchPromise(function (resolve, reject) {
+
+    function complete() {
+      queue.finish().then(function () {
+        view.seq = currentSeq;
+        resolve();
+      });
+    }
+
+    function processNextBatch() {
+      view.sourceDB.changes({
+        conflicts: true,
+        include_docs: true,
+        style: 'all_docs',
+        since: currentSeq,
+        limit: CHANGES_BATCH_SIZE$1
+      }).on('complete', function (response) {
+        var results = response.results;
+        if (!results.length) {
+          return complete();
+        }
+        var docIdsToChangesAndEmits = {};
+        for (var i = 0, l = results.length; i < l; i++) {
+          var change = results[i];
+          if (change.doc._id[0] !== '_') {
+            mapResults = [];
+            doc = change.doc;
+
+            if (!doc._deleted) {
+              tryCode(view.sourceDB, mapFun, [doc]);
+            }
+            mapResults.sort(sortByKeyThenValue);
+
+            var indexableKeysToKeyValues = {};
+            var lastKey;
+            for (var j = 0, jl = mapResults.length; j < jl; j++) {
+              var obj = mapResults[j];
+              var complexKey = [obj.key, obj.id];
+              if (collate$2(obj.key, lastKey) === 0) {
+                complexKey.push(j); // dup key+id, so make it unique
+              }
+              var indexableKey = toIndexableString(complexKey);
+              indexableKeysToKeyValues[indexableKey] = obj;
+              lastKey = obj.key;
+            }
+            docIdsToChangesAndEmits[change.doc._id] = {
+              indexableKeysToKeyValues: indexableKeysToKeyValues,
+              changes: change.changes
+            };
+          }
+          currentSeq = change.seq;
+        }
+        queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
+        if (results.length < CHANGES_BATCH_SIZE$1) {
+          return complete();
+        }
+        return processNextBatch();
+      }).on('error', onError);
+      /* istanbul ignore next */
+      function onError(err) {
+        reject(err);
+      }
+    }
+
+    processNextBatch();
+  });
+}
+
+function reduceView(view, results, options) {
+  if (options.group_level === 0) {
+    delete options.group_level;
+  }
+
+  var shouldGroup = options.group || options.group_level;
+
+  var reduceFun;
+  if (builtInReduce[view.reduceFun]) {
+    reduceFun = builtInReduce[view.reduceFun];
+  } else {
+    reduceFun = evalfunc(
+      view.reduceFun.toString(), null, sum, log$2, Array.isArray, JSON.parse);
+  }
+
+  var groups = [];
+  var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
+    options.group_level;
+  results.forEach(function (e) {
+    var last = groups[groups.length - 1];
+    var groupKey = shouldGroup ? e.key : null;
+
+    // only set group_level for array keys
+    if (shouldGroup && Array.isArray(groupKey)) {
+      groupKey = groupKey.slice(0, lvl);
+    }
+
+    if (last && collate$2(last.groupKey, groupKey) === 0) {
+      last.keys.push([e.key, e.id]);
+      last.values.push(e.value);
+      return;
+    }
+    groups.push({
+      keys: [[e.key, e.id]],
+      values: [e.value],
+      groupKey: groupKey
+    });
+  });
+  results = [];
+  for (var i = 0, len = groups.length; i < len; i++) {
+    var e = groups[i];
+    var reduceTry = tryCode(view.sourceDB, reduceFun,
+      [e.keys, e.values, false]);
+    if (reduceTry.error && reduceTry.error instanceof BuiltInError) {
+      // CouchDB returns an error if a built-in errors out
+      throw reduceTry.error;
+    }
+    results.push({
+      // CouchDB just sets the value to null if a non-built-in errors out
+      value: reduceTry.error ? null : reduceTry.output,
+      key: e.groupKey
+    });
+  }
+  // no total_rows/offset when reducing
+  return {rows: sliceResults(results, options.limit, options.skip)};
+}
+
+function queryView(view, opts) {
+  return sequentialize(getQueue(view), function () {
+    return queryViewInQueue(view, opts);
+  })();
+}
+
+function queryViewInQueue(view, opts) {
+  var totalRows;
+  var shouldReduce = view.reduceFun && opts.reduce !== false;
+  var skip = opts.skip || 0;
+  if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
+    // equivalent query
+    opts.limit = 0;
+    delete opts.keys;
+  }
+
+  function fetchFromView(viewOpts) {
+    viewOpts.include_docs = true;
+    return view.db.allDocs(viewOpts).then(function (res) {
+      totalRows = res.total_rows;
+      return res.rows.map(function (result) {
+
+        // implicit migration - in older versions of PouchDB,
+        // we explicitly stored the doc as {id: ..., key: ..., value: ...}
+        // this is tested in a migration test
+        /* istanbul ignore next */
+        if ('value' in result.doc && typeof result.doc.value === 'object' &&
+            result.doc.value !== null) {
+          var keys = Object.keys(result.doc.value).sort();
+          // this detection method is not perfect, but it's unlikely the user
+          // emitted a value which was an object with these 3 exact keys
+          var expectedKeys = ['id', 'key', 'value'];
+          if (!(keys < expectedKeys || keys > expectedKeys)) {
+            return result.doc.value;
+          }
+        }
+
+        var parsedKeyAndDocId = parseIndexableString(result.doc._id);
+        return {
+          key: parsedKeyAndDocId[0],
+          id: parsedKeyAndDocId[1],
+          value: ('value' in result.doc ? result.doc.value : null)
+        };
+      });
+    });
+  }
+
+  function onMapResultsReady(rows) {
+    var finalResults;
+    if (shouldReduce) {
+      finalResults = reduceView(view, rows, opts);
+    } else {
+      finalResults = {
+        total_rows: totalRows,
+        offset: skip,
+        rows: rows
+      };
+    }
+    if (opts.include_docs) {
+      var docIds = uniq(rows.map(rowToDocId));
+
+      return view.sourceDB.allDocs({
+        keys: docIds,
+        include_docs: true,
+        conflicts: opts.conflicts,
+        attachments: opts.attachments,
+        binary: opts.binary
+      }).then(function (allDocsRes) {
+        var docIdsToDocs = {};
+        allDocsRes.rows.forEach(function (row) {
+          if (row.doc) {
+            docIdsToDocs['$' + row.id] = row.doc;
+          }
+        });
+        rows.forEach(function (row) {
+          var docId = rowToDocId(row);
+          var doc = docIdsToDocs['$' + docId];
+          if (doc) {
+            row.doc = doc;
+          }
+        });
+        return finalResults;
+      });
+    } else {
+      return finalResults;
+    }
+  }
+
+  if (typeof opts.keys !== 'undefined') {
+    var keys = opts.keys;
+    var fetchPromises = keys.map(function (key) {
+      var viewOpts = {
+        startkey : toIndexableString([key]),
+        endkey   : toIndexableString([key, {}])
+      };
+      return fetchFromView(viewOpts);
+    });
+    return PouchPromise.all(fetchPromises).then(flatten).then(onMapResultsReady);
+  } else { // normal query, no 'keys'
+    var viewOpts = {
+      descending : opts.descending
+    };
+    if (opts.start_key) {
+        opts.startkey = opts.start_key;
+    }
+    if (opts.end_key) {
+        opts.endkey = opts.end_key;
+    }
+    if (typeof opts.startkey !== 'undefined') {
+      viewOpts.startkey = opts.descending ?
+        toIndexableString([opts.startkey, {}]) :
+        toIndexableString([opts.startkey]);
+    }
+    if (typeof opts.endkey !== 'undefined') {
+      var inclusiveEnd = opts.inclusive_end !== false;
+      if (opts.descending) {
+        inclusiveEnd = !inclusiveEnd;
+      }
+
+      viewOpts.endkey = toIndexableString(
+        inclusiveEnd ? [opts.endkey, {}] : [opts.endkey]);
+    }
+    if (typeof opts.key !== 'undefined') {
+      var keyStart = toIndexableString([opts.key]);
+      var keyEnd = toIndexableString([opts.key, {}]);
+      if (viewOpts.descending) {
+        viewOpts.endkey = keyStart;
+        viewOpts.startkey = keyEnd;
+      } else {
+        viewOpts.startkey = keyStart;
+        viewOpts.endkey = keyEnd;
+      }
+    }
+    if (!shouldReduce) {
+      if (typeof opts.limit === 'number') {
+        viewOpts.limit = opts.limit;
+      }
+      viewOpts.skip = skip;
+    }
+    return fetchFromView(viewOpts).then(onMapResultsReady);
+  }
+}
+
+function httpViewCleanup(db) {
+  return db.request({
+    method: 'POST',
+    url: '_view_cleanup'
+  });
+}
+
+function localViewCleanup(db) {
+  return db.get('_local/mrviews').then(function (metaDoc) {
+    var docsToViews = {};
+    Object.keys(metaDoc.views).forEach(function (fullViewName) {
+      var parts = parseViewName(fullViewName);
+      var designDocName = '_design/' + parts[0];
+      var viewName = parts[1];
+      docsToViews[designDocName] = docsToViews[designDocName] || {};
+      docsToViews[designDocName][viewName] = true;
+    });
+    var opts = {
+      keys : Object.keys(docsToViews),
+      include_docs : true
+    };
+    return db.allDocs(opts).then(function (res) {
+      var viewsToStatus = {};
+      res.rows.forEach(function (row) {
+        var ddocName = row.key.substring(8);
+        Object.keys(docsToViews[row.key]).forEach(function (viewName) {
+          var fullViewName = ddocName + '/' + viewName;
+          /* istanbul ignore if */
+          if (!metaDoc.views[fullViewName]) {
+            // new format, without slashes, to support PouchDB 2.2.0
+            // migration test in pouchdb's browser.migration.js verifies this
+            fullViewName = viewName;
+          }
+          var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
+          // design doc deleted, or view function nonexistent
+          var statusIsGood = row.doc && row.doc.views &&
+            row.doc.views[viewName];
+          viewDBNames.forEach(function (viewDBName) {
+            viewsToStatus[viewDBName] =
+              viewsToStatus[viewDBName] || statusIsGood;
+          });
+        });
+      });
+      var dbsToDelete = Object.keys(viewsToStatus).filter(
+        function (viewDBName) { return !viewsToStatus[viewDBName]; });
+      var destroyPromises = dbsToDelete.map(function (viewDBName) {
+        return sequentialize(getQueue(viewDBName), function () {
+          return new db.constructor(viewDBName, db.__opts).destroy();
+        })();
+      });
+      return PouchPromise.all(destroyPromises).then(function () {
+        return {ok: true};
+      });
+    });
+  }, defaultsTo({ok: true}));
+}
+
+var viewCleanup = callbackify(function () {
+  var db = this;
+  if (db._ddocCache) {
+    delete db._ddocCache;
+  }
+  if (db.type() === 'http') {
+    return httpViewCleanup(db);
+  }
+  /* istanbul ignore next */
+  if (typeof db._viewCleanup === 'function') {
+    return customViewCleanup(db);
+  }
+  return localViewCleanup(db);
+});
+
+function queryPromised(db, fun, opts) {
+  if (db.type() === 'http') {
+    return httpQuery(db, fun, opts);
+  }
+
+  /* istanbul ignore next */
+  if (typeof db._query === 'function') {
+    return customQuery(db, fun, opts);
+  }
+
+  if (typeof fun !== 'string') {
+    // temp_view
+    checkQueryParseError(opts, fun);
+
+    var createViewOpts = {
+      db : db,
+      viewName : 'temp_view/temp_view',
+      map : fun.map,
+      reduce : fun.reduce,
+      temporary : true
+    };
+    tempViewQueue.add(function () {
+      return createView(createViewOpts).then(function (view) {
+        function cleanup() {
+          return view.db.destroy();
+        }
+        return fin(updateView(view).then(function () {
+          return queryView(view, opts);
+        }), cleanup);
+      });
+    });
+    return tempViewQueue.finish();
+  } else {
+    // persistent view
+    var fullViewName = fun;
+    var parts = parseViewName(fullViewName);
+    var designDocName = parts[0];
+    var viewName = parts[1];
+    return db.getView(designDocName, viewName).then(function (fun) {
+      checkQueryParseError(opts, fun);
+
+      var createViewOpts = {
+        db : db,
+        viewName : fullViewName,
+        map : fun.map,
+        reduce : fun.reduce
+      };
+      return createView(createViewOpts).then(function (view) {
+        if (opts.stale === 'ok' || opts.stale === 'update_after') {
+          if (opts.stale === 'update_after') {
+            process.nextTick(function () {
+              updateView(view);
+            });
+          }
+          return queryView(view, opts);
+        } else { // stale not ok
+          return updateView(view).then(function () {
+            return queryView(view, opts);
+          });
+        }
+      });
+    });
+  }
+}
+
+var query = function (fun, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  opts = opts ? coerceOptions(opts) : {};
+
+  if (typeof fun === 'function') {
+    fun = {map : fun};
+  }
+
+  var db = this;
+  var promise = PouchPromise.resolve().then(function () {
+    return queryPromised(db, fun, opts);
+  });
+  promisedCallback(promise, callback);
+  return promise;
+};
+
+function QueryParseError(message) {
+  this.status = 400;
+  this.name = 'query_parse_error';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, QueryParseError);
+  } catch (e) {}
+}
+
+inherits(QueryParseError, Error);
+
+function BuiltInError(message) {
+  this.status = 500;
+  this.name = 'invalid_value';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, BuiltInError);
+  } catch (e) {}
+}
+
+inherits(BuiltInError, Error);
+
+var mapreduce = {
+  query: query,
+  viewCleanup: viewCleanup
+};
+
+function arrayBufferToBase64(buffer) {
+  return btoa$1(arrayBufferToBinaryString(buffer));
+}
+
+function preprocessAttachments$1(docInfos, blobType, callback) {
+
+  if (!docInfos.length) {
+    return callback();
+  }
+
+  var docv = 0;
+
+  function parseBase64(data) {
+    try {
+      return atob$1(data);
+    } catch (e) {
+      var err = createError(BAD_ARG,
+        'Attachment is not a valid base64 string');
+      return {error: err};
+    }
+  }
+
+  function preprocessAttachment(att, callback) {
+    if (att.stub) {
+      return callback();
+    }
+    if (typeof att.data === 'string') {
+      // input is assumed to be a base64 string
+
+      var asBinary = parseBase64(att.data);
+      if (asBinary.error) {
+        return callback(asBinary.error);
+      }
+
+      att.length = asBinary.length;
+      if (blobType === 'blob') {
+        att.data = binStringToBluffer(asBinary, att.content_type);
+      } else if (blobType === 'base64') {
+        att.data = btoa$1(asBinary);
+      } else { // binary
+        att.data = asBinary;
+      }
+      md5(asBinary).then(function (result) {
+        att.digest = 'md5-' + result;
+        callback();
+      });
+    } else { // input is a blob
+      readAsArrayBuffer(att.data, function (buff) {
+        if (blobType === 'binary') {
+          att.data = arrayBufferToBinaryString(buff);
+        } else if (blobType === 'base64') {
+          att.data = arrayBufferToBase64(buff);
+        }
+        md5(buff).then(function (result) {
+          att.digest = 'md5-' + result;
+          att.length = buff.byteLength;
+          callback();
+        });
+      });
+    }
+  }
+
+  var overallErr;
+
+  docInfos.forEach(function (docInfo) {
+    var attachments = docInfo.data && docInfo.data._attachments ?
+      Object.keys(docInfo.data._attachments) : [];
+    var recv = 0;
+
+    if (!attachments.length) {
+      return done();
+    }
+
+    function processedAttachment(err) {
+      overallErr = err;
+      recv++;
+      if (recv === attachments.length) {
+        done();
+      }
+    }
+
+    for (var key in docInfo.data._attachments) {
+      if (docInfo.data._attachments.hasOwnProperty(key)) {
+        preprocessAttachment(docInfo.data._attachments[key],
+          processedAttachment);
+      }
+    }
+  });
+
+  function done() {
+    docv++;
+    if (docInfos.length === docv) {
+      if (overallErr) {
+        callback(overallErr);
+      } else {
+        callback();
+      }
+    }
+  }
+}
+
+function sortByPos$1(a, b) {
+  return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (comparator(arr[mid], item) < 0) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+  var idx = binarySearch(arr, item, comparator);
+  arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+  var root;
+  var leaf;
+  for (var i = numStemmed, len = path.length; i < len; i++) {
+    var node = path[i];
+    var currentLeaf = [node.id, node.opts, []];
+    if (leaf) {
+      leaf[2].push(currentLeaf);
+      leaf = currentLeaf;
+    } else {
+      root = leaf = currentLeaf;
+    }
+  }
+  return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+  return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+  var queue = [{tree1: in_tree1, tree2: in_tree2}];
+  var conflicts = false;
+  while (queue.length > 0) {
+    var item = queue.pop();
+    var tree1 = item.tree1;
+    var tree2 = item.tree2;
+
+    if (tree1[1].status || tree2[1].status) {
+      tree1[1].status =
+        (tree1[1].status ===  'available' ||
+        tree2[1].status === 'available') ? 'available' : 'missing';
+    }
+
+    for (var i = 0; i < tree2[2].length; i++) {
+      if (!tree1[2][0]) {
+        conflicts = 'new_leaf';
+        tree1[2][0] = tree2[2][i];
+        continue;
+      }
+
+      var merged = false;
+      for (var j = 0; j < tree1[2].length; j++) {
+        if (tree1[2][j][0] === tree2[2][i][0]) {
+          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+          merged = true;
+        }
+      }
+      if (!merged) {
+        conflicts = 'new_branch';
+        insertSorted(tree1[2], tree2[2][i], compareTree);
+      }
+    }
+  }
+  return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+  var restree = [];
+  var conflicts = false;
+  var merged = false;
+  var res;
+
+  if (!tree.length) {
+    return {tree: [path], conflicts: 'new_leaf'};
+  }
+
+  for (var i = 0, len = tree.length; i < len; i++) {
+    var branch = tree[i];
+    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+      // Paths start at the same position and have the same root, so they need
+      // merged
+      res = mergeTree(branch.ids, path.ids);
+      restree.push({pos: branch.pos, ids: res.tree});
+      conflicts = conflicts || res.conflicts;
+      merged = true;
+    } else if (dontExpand !== true) {
+      // The paths start at a different position, take the earliest path and
+      // traverse up until it as at the same point from root as the path we
+      // want to merge.  If the keys match we return the longer path with the
+      // other merged After stemming we dont want to expand the trees
+
+      var t1 = branch.pos < path.pos ? branch : path;
+      var t2 = branch.pos < path.pos ? path : branch;
+      var diff = t2.pos - t1.pos;
+
+      var candidateParents = [];
+
+      var trees = [];
+      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+      while (trees.length > 0) {
+        var item = trees.pop();
+        if (item.diff === 0) {
+          if (item.ids[0] === t2.ids[0]) {
+            candidateParents.push(item);
+          }
+          continue;
+        }
+        var elements = item.ids[2];
+        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+          trees.push({
+            ids: elements[j],
+            diff: item.diff - 1,
+            parent: item.ids,
+            parentIdx: j
+          });
+        }
+      }
+
+      var el = candidateParents[0];
+
+      if (!el) {
+        restree.push(branch);
+      } else {
+        res = mergeTree(el.ids, t2.ids);
+        el.parent[2][el.parentIdx] = res.tree;
+        restree.push({pos: t1.pos, ids: t1.ids});
+        conflicts = conflicts || res.conflicts;
+        merged = true;
+      }
+    } else {
+      restree.push(branch);
+    }
+  }
+
+  // We didnt find
+  if (!merged) {
+    restree.push(path);
+  }
+
+  restree.sort(sortByPos$1);
+
+  return {
+    tree: restree,
+    conflicts: conflicts || 'internal_node'
+  };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+  // First we break out the tree into a complete list of root to leaf paths
+  var paths = rootToLeaf(tree);
+  var maybeStem = {};
+
+  var result;
+  for (var i = 0, len = paths.length; i < len; i++) {
+    // Then for each path, we cut off the start of the path based on the
+    // `depth` to stem to, and generate a new set of flat trees
+    var path = paths[i];
+    var stemmed = path.ids;
+    var numStemmed = Math.max(0, stemmed.length - depth);
+    var stemmedNode = {
+      pos: path.pos + numStemmed,
+      ids: pathToTree(stemmed, numStemmed)
+    };
+
+    for (var s = 0; s < numStemmed; s++) {
+      var rev = (path.pos + s) + '-' + stemmed[s].id;
+      maybeStem[rev] = true;
+    }
+
+    // Then we remerge all those flat trees together, ensuring that we dont
+    // connect trees that would go beyond the depth limit
+    if (result) {
+      result = doMerge(result, stemmedNode, true).tree;
+    } else {
+      result = [stemmedNode];
+    }
+  }
+
+  traverseRevTree(result, function (isLeaf, pos, revHash) {
+    // some revisions may have been removed in a branch but not in another
+    delete maybeStem[pos + '-' + revHash];
+  });
+
+  return {
+    tree: result,
+    revs: Object.keys(maybeStem)
+  };
+}
+
+function merge(tree, path, depth) {
+  var newTree = doMerge(tree, path);
+  var stemmed = stem(newTree.tree, depth);
+  return {
+    tree: stemmed.tree,
+    stemmedRevs: stemmed.revs,
+    conflicts: newTree.conflicts
+  };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+  var toVisit = revs.slice();
+  var splitRev = rev.split('-');
+  var targetPos = parseInt(splitRev[0], 10);
+  var targetId = splitRev[1];
+
+  var node;
+  while ((node = toVisit.pop())) {
+    if (node.pos === targetPos && node.ids[0] === targetId) {
+      return true;
+    }
+    var branches = node.ids[2];
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: node.pos + 1, ids: branches[i]});
+    }
+  }
+  return false;
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+                   i, cb, writeDoc, newEdits) {
+
+  if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
+    results[i] = docInfo;
+    return cb();
+  }
+
+  // sometimes this is pre-calculated. historically not always
+  var previousWinningRev = prev.winningRev || winningRev(prev);
+  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+    isDeleted(prev, previousWinningRev);
+  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+    isDeleted(docInfo.metadata);
+  var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+  if (previouslyDeleted && !deleted && newEdits && isRoot) {
+    var newDoc = docInfo.data;
+    newDoc._rev = previousWinningRev;
+    newDoc._id = docInfo.metadata.id;
+    docInfo = parseDoc(newDoc, newEdits);
+  }
+
+  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+  var inConflict = newEdits && (((previouslyDeleted && deleted) ||
+    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+  if (inConflict) {
+    var err = createError(REV_CONFLICT);
+    results[i] = err;
+    return cb();
+  }
+
+  var newRev = docInfo.metadata.rev;
+  docInfo.metadata.rev_tree = merged.tree;
+  docInfo.stemmedRevs = merged.stemmedRevs || [];
+  /* istanbul ignore else */
+  if (prev.rev_map) {
+    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+  }
+
+  // recalculate
+  var winningRev$$ = winningRev(docInfo.metadata);
+  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$);
+
+  // calculate the total number of documents that were added/removed,
+  // from the perspective of total_rows/doc_count
+  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+  var newRevIsDeleted;
+  if (newRev === winningRev$$) {
+    // if the new rev is the same as the winning rev, we can reuse that value
+    newRevIsDeleted = winningRevIsDeleted;
+  } else {
+    // if they're not the same, then we need to recalculate
+    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+  }
+
+  writeDoc(docInfo, winningRev$$, winningRevIsDeleted, newRevIsDeleted,
+    true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+                     writeDoc, opts, overallCallback) {
+
+  // Default to 1000 locally
+  revLimit = revLimit || 1000;
+
+  function insertDoc(docInfo, resultsIdx, callback) {
+    // Cant insert new deleted documents
+    var winningRev$$ = winningRev(docInfo.metadata);
+    var deleted = isDeleted(docInfo.metadata, winningRev$$);
+    if ('was_delete' in opts && deleted) {
+      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+      return callback();
+    }
+
+    // 4712 - detect whether a new document was inserted with a _rev
+    var inConflict = newEdits && rootIsMissing(docInfo);
+
+    if (inConflict) {
+      var err = createError(REV_CONFLICT);
+      results[resultsIdx] = err;
+      return callback();
+    }
+
+    var delta = deleted ? 0 : 1;
+
+    writeDoc(docInfo, winningRev$$, deleted, deleted, false,
+      delta, resultsIdx, callback);
+  }
+
+  var newEdits = opts.new_edits;
+  var idsToDocs = new pouchdbCollections.Map();
+
+  var docsDone = 0;
+  var docsToDo = docInfos.length;
+
+  function checkAllDocsDone() {
+    if (++docsDone === docsToDo && overallCallback) {
+      overallCallback();
+    }
+  }
+
+  docInfos.forEach(function (currentDoc, resultsIdx) {
+
+    if (currentDoc._id && isLocalId(currentDoc._id)) {
+      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+      api[fun](currentDoc, {ctx: tx}, function (err, res) {
+        results[resultsIdx] = err || res;
+        checkAllDocsDone();
+      });
+      return;
+    }
+
+    var id = currentDoc.metadata.id;
+    if (idsToDocs.has(id)) {
+      docsToDo--; // duplicate
+      idsToDocs.get(id).push([currentDoc, resultsIdx]);
+    } else {
+      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+    }
+  });
+
+  // in the case of new_edits, the user can provide multiple docs
+  // with the same id. these need to be processed sequentially
+  idsToDocs.forEach(function (docs, id) {
+    var numDone = 0;
+
+    function docWritten() {
+      if (++numDone < docs.length) {
+        nextDoc();
+      } else {
+        checkAllDocsDone();
+      }
+    }
+    function nextDoc() {
+      var value = docs[numDone];
+      var currentDoc = value[0];
+      var resultsIdx = value[1];
+
+      if (fetchedDocs.has(id)) {
+        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+          resultsIdx, docWritten, writeDoc, newEdits);
+      } else {
+        // Ensure stemming applies to new writes as well
+        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+        currentDoc.metadata.rev_tree = merged.tree;
+        currentDoc.stemmedRevs = merged.stemmedRevs || [];
+        insertDoc(currentDoc, resultsIdx, docWritten);
+      }
+    }
+    nextDoc();
+  });
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+  var revs = [];
+  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                               revHash, ctx, opts) {
+    if (opts.status === 'available' && !isLeaf) {
+      revs.push(pos + '-' + revHash);
+      opts.status = 'missing';
+    }
+  });
+  return revs;
+}
+
+// IndexedDB requires a versioned database structure, so we use the
+// version here to manage migrations.
+var ADAPTER_VERSION = 5;
+
+// The object stores created for each database
+// DOC_STORE stores the document meta data, its revision history and state
+// Keyed by document id
+var DOC_STORE = 'document-store';
+// BY_SEQ_STORE stores a particular version of a document, keyed by its
+// sequence id
+var BY_SEQ_STORE = 'by-sequence';
+// Where we store attachments
+var ATTACH_STORE = 'attach-store';
+// Where we store many-to-many relations
+// between attachment digests and seqs
+var ATTACH_AND_SEQ_STORE = 'attach-seq-store';
+
+// Where we store database-wide meta data in a single record
+// keyed by id: META_STORE
+var META_STORE = 'meta-store';
+// Where we store local documents
+var LOCAL_STORE = 'local-store';
+// Where we detect blob support
+var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
+
+function slowJsonParse(str) {
+  try {
+    return JSON.parse(str);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.parse(str);
+  }
+}
+
+function safeJsonParse(str) {
+  // try/catch is deoptimized in V8, leading to slower
+  // times than we'd like to have. Most documents are _not_
+  // huge, and do not require a slower code path just to parse them.
+  // We can be pretty sure that a document under 50000 characters
+  // will not be so deeply nested as to throw a stack overflow error
+  // (depends on the engine and available memory, though, so this is
+  // just a hunch). 50000 was chosen based on the average length
+  // of this string in our test suite, to try to find a number that covers
+  // most of our test cases (26 over this size, 26378 under it).
+  if (str.length < 50000) {
+    return JSON.parse(str);
+  }
+  return slowJsonParse(str);
+}
+
+function safeJsonStringify(json) {
+  try {
+    return JSON.stringify(json);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.stringify(json);
+  }
+}
+
+function tryCode$1(fun, that, args, PouchDB) {
+  try {
+    fun.apply(that, args);
+  } catch (err) {
+    // Shouldn't happen, but in some odd cases
+    // IndexedDB implementations might throw a sync
+    // error, in which case this will at least log it.
+    PouchDB.emit('error', err);
+  }
+}
+
+var taskQueue = {
+  running: false,
+  queue: []
+};
+
+function applyNext(PouchDB) {
+  if (taskQueue.running || !taskQueue.queue.length) {
+    return;
+  }
+  taskQueue.running = true;
+  var item = taskQueue.queue.shift();
+  item.action(function (err, res) {
+    tryCode$1(item.callback, this, [err, res], PouchDB);
+    taskQueue.running = false;
+    process.nextTick(function () {
+      applyNext(PouchDB);
+    });
+  });
+}
+
+function idbError(callback) {
+  return function (evt) {
+    var message = 'unknown_error';
+    if (evt.target && evt.target.error) {
+      message = evt.target.error.name || evt.target.error.message;
+    }
+    callback(createError(IDB_ERROR, message, evt.type));
+  };
+}
+
+// Unfortunately, the metadata has to be stringified
+// when it is put into the database, because otherwise
+// IndexedDB can throw errors for deeply-nested objects.
+// Originally we just used JSON.parse/JSON.stringify; now
+// we use this custom vuvuzela library that avoids recursion.
+// If we could do it all over again, we'd probably use a
+// format for the revision trees other than JSON.
+function encodeMetadata(metadata, winningRev, deleted) {
+  return {
+    data: safeJsonStringify(metadata),
+    winningRev: winningRev,
+    deletedOrLocal: deleted ? '1' : '0',
+    seq: metadata.seq, // highest seq for this doc
+    id: metadata.id
+  };
+}
+
+function decodeMetadata(storedObject) {
+  if (!storedObject) {
+    return null;
+  }
+  var metadata = safeJsonParse(storedObject.data);
+  metadata.winningRev = storedObject.winningRev;
+  metadata.deleted = storedObject.deletedOrLocal === '1';
+  metadata.seq = storedObject.seq;
+  return metadata;
+}
+
+// read the doc back out from the database. we don't store the
+// _id or _rev because we already have _doc_id_rev.
+function decodeDoc(doc) {
+  if (!doc) {
+    return doc;
+  }
+  var idx = doc._doc_id_rev.lastIndexOf(':');
+  doc._id = doc._doc_id_rev.substring(0, idx - 1);
+  doc._rev = doc._doc_id_rev.substring(idx + 1);
+  delete doc._doc_id_rev;
+  return doc;
+}
+
+// Read a blob from the database, encoding as necessary
+// and translating from base64 if the IDB doesn't support
+// native Blobs
+function readBlobData(body, type, asBlob, callback) {
+  if (asBlob) {
+    if (!body) {
+      callback(createBlob([''], {type: type}));
+    } else if (typeof body !== 'string') { // we have blob support
+      callback(body);
+    } else { // no blob support
+      callback(b64ToBluffer(body, type));
+    }
+  } else { // as base64 string
+    if (!body) {
+      callback('');
+    } else if (typeof body !== 'string') { // we have blob support
+      readAsBinaryString(body, function (binary) {
+        callback(btoa$1(binary));
+      });
+    } else { // no blob support
+      callback(body);
+    }
+  }
+}
+
+function fetchAttachmentsIfNecessary(doc, opts, txn, cb) {
+  var attachments = Object.keys(doc._attachments || {});
+  if (!attachments.length) {
+    return cb && cb();
+  }
+  var numDone = 0;
+
+  function checkDone() {
+    if (++numDone === attachments.length && cb) {
+      cb();
+    }
+  }
+
+  function fetchAttachment(doc, att) {
+    var attObj = doc._attachments[att];
+    var digest = attObj.digest;
+    var req = txn.objectStore(ATTACH_STORE).get(digest);
+    req.onsuccess = function (e) {
+      attObj.body = e.target.result.body;
+      checkDone();
+    };
+  }
+
+  attachments.forEach(function (att) {
+    if (opts.attachments && opts.include_docs) {
+      fetchAttachment(doc, att);
+    } else {
+      doc._attachments[att].stub = true;
+      checkDone();
+    }
+  });
+}
+
+// IDB-specific postprocessing necessary because
+// we don't know whether we stored a true Blob or
+// a base64-encoded string, and if it's a Blob it
+// needs to be read outside of the transaction context
+function postProcessAttachments(results, asBlob) {
+  return PouchPromise.all(results.map(function (row) {
+    if (row.doc && row.doc._attachments) {
+      var attNames = Object.keys(row.doc._attachments);
+      return PouchPromise.all(attNames.map(function (att) {
+        var attObj = row.doc._attachments[att];
+        if (!('body' in attObj)) { // already processed
+          return;
+        }
+        var body = attObj.body;
+        var type = attObj.content_type;
+        return new PouchPromise(function (resolve) {
+          readBlobData(body, type, asBlob, function (data) {
+            row.doc._attachments[att] = jsExtend.extend(
+              pick(attObj, ['digest', 'content_type']),
+              {data: data}
+            );
+            resolve();
+          });
+        });
+      }));
+    }
+  }));
+}
+
+function compactRevs(revs, docId, txn) {
+
+  var possiblyOrphanedDigests = [];
+  var seqStore = txn.objectStore(BY_SEQ_STORE);
+  var attStore = txn.objectStore(ATTACH_STORE);
+  var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+  var count = revs.length;
+
+  function checkDone() {
+    count--;
+    if (!count) { // done processing all revs
+      deleteOrphanedAttachments();
+    }
+  }
+
+  function deleteOrphanedAttachments() {
+    if (!possiblyOrphanedDigests.length) {
+      return;
+    }
+    possiblyOrphanedDigests.forEach(function (digest) {
+      var countReq = attAndSeqStore.index('digestSeq').count(
+        IDBKeyRange.bound(
+          digest + '::', digest + '::\uffff', false, false));
+      countReq.onsuccess = function (e) {
+        var count = e.target.result;
+        if (!count) {
+          // orphaned
+          attStore["delete"](digest);
+        }
+      };
+    });
+  }
+
+  revs.forEach(function (rev) {
+    var index = seqStore.index('_doc_id_rev');
+    var key = docId + "::" + rev;
+    index.getKey(key).onsuccess = function (e) {
+      var seq = e.target.result;
+      if (typeof seq !== 'number') {
+        return checkDone();
+      }
+      seqStore["delete"](seq);
+
+      var cursor = attAndSeqStore.index('seq')
+        .openCursor(IDBKeyRange.only(seq));
+
+      cursor.onsuccess = function (event) {
+        var cursor = event.target.result;
+        if (cursor) {
+          var digest = cursor.value.digestSeq.split('::')[0];
+          possiblyOrphanedDigests.push(digest);
+          attAndSeqStore["delete"](cursor.primaryKey);
+          cursor["continue"]();
+        } else { // done
+          checkDone();
+        }
+      };
+    };
+  });
+}
+
+function openTransactionSafely(idb, stores, mode) {
+  try {
+    return {
+      txn: idb.transaction(stores, mode)
+    };
+  } catch (err) {
+    return {
+      error: err
+    };
+  }
+}
+
+function idbBulkDocs(dbOpts, req, opts, api, idb, idbChanges, callback) {
+  var docInfos = req.docs;
+  var txn;
+  var docStore;
+  var bySeqStore;
+  var attachStore;
+  var attachAndSeqStore;
+  var docInfoError;
+  var docCountDelta = 0;
+
+  for (var i = 0, len = docInfos.length; i < len; i++) {
+    var doc = docInfos[i];
+    if (doc._id && isLocalId(doc._id)) {
+      continue;
+    }
+    doc = docInfos[i] = parseDoc(doc, opts.new_edits);
+    if (doc.error && !docInfoError) {
+      docInfoError = doc;
+    }
+  }
+
+  if (docInfoError) {
+    return callback(docInfoError);
+  }
+
+  var results = new Array(docInfos.length);
+  var fetchedDocs = new pouchdbCollections.Map();
+  var preconditionErrored = false;
+  var blobType = api._meta.blobSupport ? 'blob' : 'base64';
+
+  preprocessAttachments$1(docInfos, blobType, function (err) {
+    if (err) {
+      return callback(err);
+    }
+    startTransaction();
+  });
+
+  function startTransaction() {
+
+    var stores = [
+      DOC_STORE, BY_SEQ_STORE,
+      ATTACH_STORE,
+      LOCAL_STORE, ATTACH_AND_SEQ_STORE
+    ];
+    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    txn = txnResult.txn;
+    txn.onabort = idbError(callback);
+    txn.ontimeout = idbError(callback);
+    txn.oncomplete = complete;
+    docStore = txn.objectStore(DOC_STORE);
+    bySeqStore = txn.objectStore(BY_SEQ_STORE);
+    attachStore = txn.objectStore(ATTACH_STORE);
+    attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+
+    verifyAttachments(function (err) {
+      if (err) {
+        preconditionErrored = true;
+        return callback(err);
+      }
+      fetchExistingDocs();
+    });
+  }
+
+  function idbProcessDocs() {
+    processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
+                txn, results, writeDoc, opts);
+  }
+
+  function fetchExistingDocs() {
+
+    if (!docInfos.length) {
+      return;
+    }
+
+    var numFetched = 0;
+
+    function checkDone() {
+      if (++numFetched === docInfos.length) {
+        idbProcessDocs();
+      }
+    }
+
+    function readMetadata(event) {
+      var metadata = decodeMetadata(event.target.result);
+
+      if (metadata) {
+        fetchedDocs.set(metadata.id, metadata);
+      }
+      checkDone();
+    }
+
+    for (var i = 0, len = docInfos.length; i < len; i++) {
+      var docInfo = docInfos[i];
+      if (docInfo._id && isLocalId(docInfo._id)) {
+        checkDone(); // skip local docs
+        continue;
+      }
+      var req = docStore.get(docInfo.metadata.id);
+      req.onsuccess = readMetadata;
+    }
+  }
+
+  function complete() {
+    if (preconditionErrored) {
+      return;
+    }
+
+    idbChanges.notify(api._meta.name);
+    api._meta.docCount += docCountDelta;
+    callback(null, results);
+  }
+
+  function verifyAttachment(digest, callback) {
+
+    var req = attachStore.get(digest);
+    req.onsuccess = function (e) {
+      if (!e.target.result) {
+        var err = createError(MISSING_STUB,
+          'unknown stub attachment with digest ' +
+          digest);
+        err.status = 412;
+        callback(err);
+      } else {
+        callback();
+      }
+    };
+  }
+
+  function verifyAttachments(finish) {
+
+
+    var digests = [];
+    docInfos.forEach(function (docInfo) {
+      if (docInfo.data && docInfo.data._attachments) {
+        Object.keys(docInfo.data._attachments).forEach(function (filename) {
+          var att = docInfo.data._attachments[filename];
+          if (att.stub) {
+            digests.push(att.digest);
+          }
+        });
+      }
+    });
+    if (!digests.length) {
+      return finish();
+    }
+    var numDone = 0;
+    var err;
+
+    function checkDone() {
+      if (++numDone === digests.length) {
+        finish(err);
+      }
+    }
+    digests.forEach(function (digest) {
+      verifyAttachment(digest, function (attErr) {
+        if (attErr && !err) {
+          err = attErr;
+        }
+        checkDone();
+      });
+    });
+  }
+
+  function writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
+                    isUpdate, delta, resultsIdx, callback) {
+
+    docCountDelta += delta;
+
+    docInfo.metadata.winningRev = winningRev;
+    docInfo.metadata.deleted = winningRevIsDeleted;
+
+    var doc = docInfo.data;
+    doc._id = docInfo.metadata.id;
+    doc._rev = docInfo.metadata.rev;
+
+    if (newRevIsDeleted) {
+      doc._deleted = true;
+    }
+
+    var hasAttachments = doc._attachments &&
+      Object.keys(doc._attachments).length;
+    if (hasAttachments) {
+      return writeAttachments(docInfo, winningRev, winningRevIsDeleted,
+        isUpdate, resultsIdx, callback);
+    }
+
+    finishDoc(docInfo, winningRev, winningRevIsDeleted,
+      isUpdate, resultsIdx, callback);
+  }
+
+  function autoCompact(docInfo) {
+
+    var revsToDelete = compactTree(docInfo.metadata);
+    compactRevs(revsToDelete, docInfo.metadata.id, txn);
+  }
+
+  function finishDoc(docInfo, winningRev, winningRevIsDeleted,
+                     isUpdate, resultsIdx, callback) {
+
+    var doc = docInfo.data;
+    var metadata = docInfo.metadata;
+
+    doc._doc_id_rev = metadata.id + '::' + metadata.rev;
+    delete doc._id;
+    delete doc._rev;
+
+    function afterPutDoc(e) {
+      if (isUpdate && api.auto_compaction) {
+        autoCompact(docInfo);
+      } else if (docInfo.stemmedRevs.length) {
+        compactRevs(docInfo.stemmedRevs, docInfo.metadata.id, txn);
+      }
+
+      metadata.seq = e.target.result;
+      // Current _rev is calculated from _rev_tree on read
+      delete metadata.rev;
+      var metadataToStore = encodeMetadata(metadata, winningRev,
+        winningRevIsDeleted);
+      var metaDataReq = docStore.put(metadataToStore);
+      metaDataReq.onsuccess = afterPutMetadata;
+    }
+
+    function afterPutDocError(e) {
+      // ConstraintError, need to update, not put (see #1638 for details)
+      e.preventDefault(); // avoid transaction abort
+      e.stopPropagation(); // avoid transaction onerror
+      var index = bySeqStore.index('_doc_id_rev');
+      var getKeyReq = index.getKey(doc._doc_id_rev);
+      getKeyReq.onsuccess = function (e) {
+        var putReq = bySeqStore.put(doc, e.target.result);
+        putReq.onsuccess = afterPutDoc;
+      };
+    }
+
+    function afterPutMetadata() {
+      results[resultsIdx] = {
+        ok: true,
+        id: metadata.id,
+        rev: winningRev
+      };
+      fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+      insertAttachmentMappings(docInfo, metadata.seq, callback);
+    }
+
+    var putReq = bySeqStore.put(doc);
+
+    putReq.onsuccess = afterPutDoc;
+    putReq.onerror = afterPutDocError;
+  }
+
+  function writeAttachments(docInfo, winningRev, winningRevIsDeleted,
+                            isUpdate, resultsIdx, callback) {
+
+
+    var doc = docInfo.data;
+
+    var numDone = 0;
+    var attachments = Object.keys(doc._attachments);
+
+    function collectResults() {
+      if (numDone === attachments.length) {
+        finishDoc(docInfo, winningRev, winningRevIsDeleted,
+          isUpdate, resultsIdx, callback);
+      }
+    }
+
+    function attachmentSaved() {
+      numDone++;
+      collectResults();
+    }
+
+    attachments.forEach(function (key) {
+      var att = docInfo.data._attachments[key];
+      if (!att.stub) {
+        var data = att.data;
+        delete att.data;
+        att.revpos = parseInt(winningRev, 10);
+        var digest = att.digest;
+        saveAttachment(digest, data, attachmentSaved);
+      } else {
+        numDone++;
+        collectResults();
+      }
+    });
+  }
+
+  // map seqs to attachment digests, which
+  // we will need later during compaction
+  function insertAttachmentMappings(docInfo, seq, callback) {
+
+    var attsAdded = 0;
+    var attsToAdd = Object.keys(docInfo.data._attachments || {});
+
+    if (!attsToAdd.length) {
+      return callback();
+    }
+
+    function checkDone() {
+      if (++attsAdded === attsToAdd.length) {
+        callback();
+      }
+    }
+
+    function add(att) {
+      var digest = docInfo.data._attachments[att].digest;
+      var req = attachAndSeqStore.put({
+        seq: seq,
+        digestSeq: digest + '::' + seq
+      });
+
+      req.onsuccess = checkDone;
+      req.onerror = function (e) {
+        // this callback is for a constaint error, which we ignore
+        // because this docid/rev has already been associated with
+        // the digest (e.g. when new_edits == false)
+        e.preventDefault(); // avoid transaction abort
+        e.stopPropagation(); // avoid transaction onerror
+        checkDone();
+      };
+    }
+    for (var i = 0; i < attsToAdd.length; i++) {
+      add(attsToAdd[i]); // do in parallel
+    }
+  }
+
+  function saveAttachment(digest, data, callback) {
+
+
+    var getKeyReq = attachStore.count(digest);
+    getKeyReq.onsuccess = function (e) {
+      var count = e.target.result;
+      if (count) {
+        return callback(); // already exists
+      }
+      var newAtt = {
+        digest: digest,
+        body: data
+      };
+      var putReq = attachStore.put(newAtt);
+      putReq.onsuccess = callback;
+    };
+  }
+}
+
+function createKeyRange(start, end, inclusiveEnd, key, descending) {
+  try {
+    if (start && end) {
+      if (descending) {
+        return IDBKeyRange.bound(end, start, !inclusiveEnd, false);
+      } else {
+        return IDBKeyRange.bound(start, end, false, !inclusiveEnd);
+      }
+    } else if (start) {
+      if (descending) {
+        return IDBKeyRange.upperBound(start);
+      } else {
+        return IDBKeyRange.lowerBound(start);
+      }
+    } else if (end) {
+      if (descending) {
+        return IDBKeyRange.lowerBound(end, !inclusiveEnd);
+      } else {
+        return IDBKeyRange.upperBound(end, !inclusiveEnd);
+      }
+    } else if (key) {
+      return IDBKeyRange.only(key);
+    }
+  } catch (e) {
+    return {error: e};
+  }
+  return null;
+}
+
+function handleKeyRangeError(api, opts, err, callback) {
+  if (err.name === "DataError" && err.code === 0) {
+    // data error, start is less than end
+    return callback(null, {
+      total_rows: api._meta.docCount,
+      offset: opts.skip,
+      rows: []
+    });
+  }
+  callback(createError(IDB_ERROR, err.name, err.message));
+}
+
+function idbAllDocs(opts, api, idb, callback) {
+
+  function allDocsQuery(opts, callback) {
+    var start = 'startkey' in opts ? opts.startkey : false;
+    var end = 'endkey' in opts ? opts.endkey : false;
+    var key = 'key' in opts ? opts.key : false;
+    var skip = opts.skip || 0;
+    var limit = typeof opts.limit === 'number' ? opts.limit : -1;
+    var inclusiveEnd = opts.inclusive_end !== false;
+    var descending = 'descending' in opts && opts.descending ? 'prev' : null;
+
+    var keyRange = createKeyRange(start, end, inclusiveEnd, key, descending);
+    if (keyRange && keyRange.error) {
+      return handleKeyRangeError(api, opts, keyRange.error, callback);
+    }
+
+    var stores = [DOC_STORE, BY_SEQ_STORE];
+
+    if (opts.attachments) {
+      stores.push(ATTACH_STORE);
+    }
+    var txnResult = openTransactionSafely(idb, stores, 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+    var docStore = txn.objectStore(DOC_STORE);
+    var seqStore = txn.objectStore(BY_SEQ_STORE);
+    var cursor = descending ?
+      docStore.openCursor(keyRange, descending) :
+      docStore.openCursor(keyRange);
+    var docIdRevIndex = seqStore.index('_doc_id_rev');
+    var results = [];
+    var docCount = 0;
+
+    // if the user specifies include_docs=true, then we don't
+    // want to block the main cursor while we're fetching the doc
+    function fetchDocAsynchronously(metadata, row, winningRev) {
+      var key = metadata.id + "::" + winningRev;
+      docIdRevIndex.get(key).onsuccess =  function onGetDoc(e) {
+        row.doc = decodeDoc(e.target.result);
+        if (opts.conflicts) {
+          row.doc._conflicts = collectConflicts(metadata);
+        }
+        fetchAttachmentsIfNecessary(row.doc, opts, txn);
+      };
+    }
+
+    function allDocsInner(cursor, winningRev, metadata) {
+      var row = {
+        id: metadata.id,
+        key: metadata.id,
+        value: {
+          rev: winningRev
+        }
+      };
+      var deleted = metadata.deleted;
+      if (opts.deleted === 'ok') {
+        results.push(row);
+        // deleted docs are okay with "keys" requests
+        if (deleted) {
+          row.value.deleted = true;
+          row.doc = null;
+        } else if (opts.include_docs) {
+          fetchDocAsynchronously(metadata, row, winningRev);
+        }
+      } else if (!deleted && skip-- <= 0) {
+        results.push(row);
+        if (opts.include_docs) {
+          fetchDocAsynchronously(metadata, row, winningRev);
+        }
+        if (--limit === 0) {
+          return;
+        }
+      }
+      cursor["continue"]();
+    }
+
+    function onGetCursor(e) {
+      docCount = api._meta.docCount; // do this within the txn for consistency
+      var cursor = e.target.result;
+      if (!cursor) {
+        return;
+      }
+      var metadata = decodeMetadata(cursor.value);
+      var winningRev = metadata.winningRev;
+
+      allDocsInner(cursor, winningRev, metadata);
+    }
+
+    function onResultsReady() {
+      callback(null, {
+        total_rows: docCount,
+        offset: opts.skip,
+        rows: results
+      });
+    }
+
+    function onTxnComplete() {
+      if (opts.attachments) {
+        postProcessAttachments(results, opts.binary).then(onResultsReady);
+      } else {
+        onResultsReady();
+      }
+    }
+
+    txn.oncomplete = onTxnComplete;
+    cursor.onsuccess = onGetCursor;
+  }
+
+  function allDocs(opts, callback) {
+
+    if (opts.limit === 0) {
+      return callback(null, {
+        total_rows: api._meta.docCount,
+        offset: opts.skip,
+        rows: []
+      });
+    }
+    allDocsQuery(opts, callback);
+  }
+
+  allDocs(opts, callback);
+}
+
+//
+// Blobs are not supported in all versions of IndexedDB, notably
+// Chrome <37 and Android <5. In those versions, storing a blob will throw.
+//
+// Various other blob bugs exist in Chrome v37-42 (inclusive).
+// Detecting them is expensive and confusing to users, and Chrome 37-42
+// is at very low usage worldwide, so we do a hacky userAgent check instead.
+//
+// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120
+// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916
+// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836
+//
+function checkBlobSupport(txn) {
+  return new PouchPromise(function (resolve) {
+    var blob = createBlob(['']);
+    txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');
+
+    txn.onabort = function (e) {
+      // If the transaction aborts now its due to not being able to
+      // write to the database, likely due to the disk being full
+      e.preventDefault();
+      e.stopPropagation();
+      resolve(false);
+    };
+
+    txn.oncomplete = function () {
+      var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
+      var matchedEdge = navigator.userAgent.match(/Edge\//);
+      // MS Edge pretends to be Chrome 42:
+      // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
+      resolve(matchedEdge || !matchedChrome ||
+        parseInt(matchedChrome[1], 10) >= 43);
+    };
+  })["catch"](function () {
+    return false; // error, so assume unsupported
+  });
+}
+
+inherits(Changes$1, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (isChromeApp()) {
+    chrome.storage.onChanged.addListener(function (e) {
+      // make sure it's event addressed to us
+      if (e.db_name != null) {
+        //object only has oldValue, newValue members
+        self.emit(e.dbName.newValue);
+      }
+    });
+  } else if (hasLocalStorage()) {
+    if (typeof addEventListener !== 'undefined') {
+      addEventListener("storage", function (e) {
+        self.emit(e.key);
+      });
+    } else { // old IE
+      window.attachEvent("storage", function (e) {
+        self.emit(e.key);
+      });
+    }
+  }
+}
+
+function Changes$1() {
+  events.EventEmitter.call(this);
+  this._listeners = {};
+
+  attachBrowserEvents(this);
+}
+Changes$1.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
+  }
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
+    }
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
+    }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary'
+    ]);
+
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
+    }
+
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        setTimeout(function (){
+          eventFunction();
+        },0);
+      }
+      inprogress = false;
+    }).on('error', onError);
+  }
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
+
+Changes$1.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
+    return;
+  }
+  events.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+};
+
+
+/* istanbul ignore next */
+Changes$1.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (isChromeApp()) {
+    chrome.storage.local.set({dbName: dbName});
+  } else if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
+
+Changes$1.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
+
+var cachedDBs = new pouchdbCollections.Map();
+var blobSupportPromise;
+var idbChanges = new Changes$1();
+var openReqList = new pouchdbCollections.Map();
+
+function IdbPouch(opts, callback) {
+  var api = this;
+
+  taskQueue.queue.push({
+    action: function (thisCallback) {
+      init(api, opts, thisCallback);
+    },
+    callback: callback
+  });
+  applyNext(api.constructor);
+}
+
+function init(api, opts, callback) {
+
+  var dbName = opts.name;
+
+  var idb = null;
+  api._meta = null;
+
+  // called when creating a fresh new database
+  function createSchema(db) {
+    var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'});
+    db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
+      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
+    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
+    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
+
+    // added in v2
+    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+    // added in v3
+    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'});
+
+    // added in v4
+    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+      {autoIncrement: true});
+    attAndSeqStore.createIndex('seq', 'seq');
+    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+  }
+
+  // migration to version 2
+  // unfortunately "deletedOrLocal" is a misnomer now that we no longer
+  // store local docs in the main doc-store, but whaddyagonnado
+  function addDeletedOrLocalIndex(txn, callback) {
+    var docStore = txn.objectStore(DOC_STORE);
+    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+    docStore.openCursor().onsuccess = function (event) {
+      var cursor = event.target.result;
+      if (cursor) {
+        var metadata = cursor.value;
+        var deleted = isDeleted(metadata);
+        metadata.deletedOrLocal = deleted ? "1" : "0";
+        docStore.put(metadata);
+        cursor["continue"]();
+      } else {
+        callback();
+      }
+    };
+  }
+
+  // migration to version 3 (part 1)
+  function createLocalStoreSchema(db) {
+    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
+      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+  }
+
+  // migration to version 3 (part 2)
+  function migrateLocalStore(txn, cb) {
+    var localStore = txn.objectStore(LOCAL_STORE);
+    var docStore = txn.objectStore(DOC_STORE);
+    var seqStore = txn.objectStore(BY_SEQ_STORE);
+
+    var cursor = docStore.openCursor();
+    cursor.onsuccess = function (event) {
+      var cursor = event.target.result;
+      if (cursor) {
+        var metadata = cursor.value;
+        var docId = metadata.id;
+        var local = isLocalId(docId);
+        var rev = winningRev(metadata);
+        if (local) {
+          var docIdRev = docId + "::" + rev;
+          // remove all seq entries
+          // associated with this docId
+          var start = docId + "::";
+          var end = docId + "::~";
+          var index = seqStore.index('_doc_id_rev');
+          var range = IDBKeyRange.bound(start, end, false, false);
+          var seqCursor = index.openCursor(range);
+          seqCursor.onsuccess = function (e) {
+            seqCursor = e.target.result;
+            if (!seqCursor) {
+              // done
+              docStore["delete"](cursor.primaryKey);
+              cursor["continue"]();
+            } else {
+              var data = seqCursor.value;
+              if (data._doc_id_rev === docIdRev) {
+                localStore.put(data);
+              }
+              seqStore["delete"](seqCursor.primaryKey);
+              seqCursor["continue"]();
+            }
+          };
+        } else {
+          cursor["continue"]();
+        }
+      } else if (cb) {
+        cb();
+      }
+    };
+  }
+
+  // migration to version 4 (part 1)
+  function addAttachAndSeqStore(db) {
+    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+      {autoIncrement: true});
+    attAndSeqStore.createIndex('seq', 'seq');
+    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+  }
+
+  // migration to version 4 (part 2)
+  function migrateAttsAndSeqs(txn, callback) {
+    var seqStore = txn.objectStore(BY_SEQ_STORE);
+    var attStore = txn.objectStore(ATTACH_STORE);
+    var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+
+    // need to actually populate the table. this is the expensive part,
+    // so as an optimization, check first that this database even
+    // contains attachments
+    var req = attStore.count();
+    req.onsuccess = function (e) {
+      var count = e.target.result;
+      if (!count) {
+        return callback(); // done
+      }
+
+      seqStore.openCursor().onsuccess = function (e) {
+        var cursor = e.target.result;
+        if (!cursor) {
+          return callback(); // done
+        }
+        var doc = cursor.value;
+        var seq = cursor.primaryKey;
+        var atts = Object.keys(doc._attachments || {});
+        var digestMap = {};
+        for (var j = 0; j < atts.length; j++) {
+          var att = doc._attachments[atts[j]];
+          digestMap[att.digest] = true; // uniq digests, just in case
+        }
+        var digests = Object.keys(digestMap);
+        for (j = 0; j < digests.length; j++) {
+          var digest = digests[j];
+          attAndSeqStore.put({
+            seq: seq,
+            digestSeq: digest + '::' + seq
+          });
+        }
+        cursor["continue"]();
+      };
+    };
+  }
+
+  // migration to version 5
+  // Instead of relying on on-the-fly migration of metadata,
+  // this brings the doc-store to its modern form:
+  // - metadata.winningrev
+  // - metadata.seq
+  // - stringify the metadata when storing it
+  function migrateMetadata(txn) {
+
+    function decodeMetadataCompat(storedObject) {
+      if (!storedObject.data) {
+        // old format, when we didn't store it stringified
+        storedObject.deleted = storedObject.deletedOrLocal === '1';
+        return storedObject;
+      }
+      return decodeMetadata(storedObject);
+    }
+
+    // ensure that every metadata has a winningRev and seq,
+    // which was previously created on-the-fly but better to migrate
+    var bySeqStore = txn.objectStore(BY_SEQ_STORE);
+    var docStore = txn.objectStore(DOC_STORE);
+    var cursor = docStore.openCursor();
+    cursor.onsuccess = function (e) {
+      var cursor = e.target.result;
+      if (!cursor) {
+        return; // done
+      }
+      var metadata = decodeMetadataCompat(cursor.value);
+
+      metadata.winningRev = metadata.winningRev ||
+        winningRev(metadata);
+
+      function fetchMetadataSeq() {
+        // metadata.seq was added post-3.2.0, so if it's missing,
+        // we need to fetch it manually
+        var start = metadata.id + '::';
+        var end = metadata.id + '::\uffff';
+        var req = bySeqStore.index('_doc_id_rev').openCursor(
+          IDBKeyRange.bound(start, end));
+
+        var metadataSeq = 0;
+        req.onsuccess = function (e) {
+          var cursor = e.target.result;
+          if (!cursor) {
+            metadata.seq = metadataSeq;
+            return onGetMetadataSeq();
+          }
+          var seq = cursor.primaryKey;
+          if (seq > metadataSeq) {
+            metadataSeq = seq;
+          }
+          cursor["continue"]();
+        };
+      }
+
+      function onGetMetadataSeq() {
+        var metadataToStore = encodeMetadata(metadata,
+          metadata.winningRev, metadata.deleted);
+
+        var req = docStore.put(metadataToStore);
+        req.onsuccess = function () {
+          cursor["continue"]();
+        };
+      }
+
+      if (metadata.seq) {
+        return onGetMetadataSeq();
+      }
+
+      fetchMetadataSeq();
+    };
+
+  }
+
+  api.type = function () {
+    return 'idb';
+  };
+
+  api._id = toPromise(function (callback) {
+    callback(null, api._meta.instanceId);
+  });
+
+  api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
+    idbBulkDocs(opts, req, reqOpts, api, idb, idbChanges, callback);
+  };
+
+  // First we look up the metadata in the ids database, then we fetch the
+  // current revision(s) from the by sequence store
+  api._get = function idb_get(id, opts, callback) {
+    var doc;
+    var metadata;
+    var err;
+    var txn = opts.ctx;
+    if (!txn) {
+      var txnResult = openTransactionSafely(idb,
+        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      txn = txnResult.txn;
+    }
+
+    function finish() {
+      callback(err, {doc: doc, metadata: metadata, ctx: txn});
+    }
+
+    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
+      metadata = decodeMetadata(e.target.result);
+      // we can determine the result here if:
+      // 1. there is no such document
+      // 2. the document is deleted and we don't ask about specific rev
+      // When we ask with opts.rev we expect the answer to be either
+      // doc (possibly with _deleted=true) or missing error
+      if (!metadata) {
+        err = createError(MISSING_DOC, 'missing');
+        return finish();
+      }
+      if (isDeleted(metadata) && !opts.rev) {
+        err = createError(MISSING_DOC, "deleted");
+        return finish();
+      }
+      var objectStore = txn.objectStore(BY_SEQ_STORE);
+
+      var rev = opts.rev || metadata.winningRev;
+      var key = metadata.id + '::' + rev;
+
+      objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
+        doc = e.target.result;
+        if (doc) {
+          doc = decodeDoc(doc);
+        }
+        if (!doc) {
+          err = createError(MISSING_DOC, 'missing');
+          return finish();
+        }
+        finish();
+      };
+    };
+  };
+
+  api._getAttachment = function (attachment, opts, callback) {
+    var txn;
+    if (opts.ctx) {
+      txn = opts.ctx;
+    } else {
+      var txnResult = openTransactionSafely(idb,
+        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      txn = txnResult.txn;
+    }
+    var digest = attachment.digest;
+    var type = attachment.content_type;
+
+    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
+      var body = e.target.result.body;
+      readBlobData(body, type, opts.binary, function (blobData) {
+        callback(null, blobData);
+      });
+    };
+  };
+
+  api._info = function idb_info(callback) {
+
+    if (idb === null || !cachedDBs.has(dbName)) {
+      var error = new Error('db isn\'t open');
+      error.id = 'idbNull';
+      return callback(error);
+    }
+    var updateSeq;
+    var docCount;
+
+    var txnResult = openTransactionSafely(idb, [BY_SEQ_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+    var cursor = txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev');
+    cursor.onsuccess = function (event) {
+      var cursor = event.target.result;
+      updateSeq = cursor ? cursor.key : 0;
+      // count within the same txn for consistency
+      docCount = api._meta.docCount;
+    };
+
+    txn.oncomplete = function () {
+      callback(null, {
+        doc_count: docCount,
+        update_seq: updateSeq,
+        // for debugging
+        idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64')
+      });
+    };
+  };
+
+  api._allDocs = function idb_allDocs(opts, callback) {
+    idbAllDocs(opts, api, idb, callback);
+  };
+
+  api._changes = function (opts) {
+    opts = clone(opts);
+
+    if (opts.continuous) {
+      var id = dbName + ':' + uuid();
+      idbChanges.addListener(dbName, id, api, opts);
+      idbChanges.notify(dbName);
+      return {
+        cancel: function () {
+          idbChanges.removeListener(dbName, id);
+        }
+      };
+    }
+
+    var docIds = opts.doc_ids && new pouchdbCollections.Set(opts.doc_ids);
+
+    opts.since = opts.since || 0;
+    var lastSeq = opts.since;
+
+    var limit = 'limit' in opts ? opts.limit : -1;
+    if (limit === 0) {
+      limit = 1; // per CouchDB _changes spec
+    }
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+
+    var results = [];
+    var numResults = 0;
+    var filter = filterChange(opts);
+    var docIdsToMetadata = new pouchdbCollections.Map();
+
+    var txn;
+    var bySeqStore;
+    var docStore;
+    var docIdRevIndex;
+
+    function onGetCursor(cursor) {
+
+      var doc = decodeDoc(cursor.value);
+      var seq = cursor.key;
+
+      if (docIds && !docIds.has(doc._id)) {
+        return cursor["continue"]();
+      }
+
+      var metadata;
+
+      function onGetMetadata() {
+        if (metadata.seq !== seq) {
+          // some other seq is later
+          return cursor["continue"]();
+        }
+
+        lastSeq = seq;
+
+        if (metadata.winningRev === doc._rev) {
+          return onGetWinningDoc(doc);
+        }
+
+        fetchWinningDoc();
+      }
+
+      function fetchWinningDoc() {
+        var docIdRev = doc._id + '::' + metadata.winningRev;
+        var req = docIdRevIndex.get(docIdRev);
+        req.onsuccess = function (e) {
+          onGetWinningDoc(decodeDoc(e.target.result));
+        };
+      }
+
+      function onGetWinningDoc(winningDoc) {
+
+        var change = opts.processChange(winningDoc, metadata, opts);
+        change.seq = metadata.seq;
+
+        var filtered = filter(change);
+        if (typeof filtered === 'object') {
+          return opts.complete(filtered);
+        }
+
+        if (filtered) {
+          numResults++;
+          if (returnDocs) {
+            results.push(change);
+          }
+          // process the attachment immediately
+          // for the benefit of live listeners
+          if (opts.attachments && opts.include_docs) {
+            fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () {
+              postProcessAttachments([change], opts.binary).then(function () {
+                opts.onChange(change);
+              });
+            });
+          } else {
+            opts.onChange(change);
+          }
+        }
+        if (numResults !== limit) {
+          cursor["continue"]();
+        }
+      }
+
+      metadata = docIdsToMetadata.get(doc._id);
+      if (metadata) { // cached
+        return onGetMetadata();
+      }
+      // metadata not cached, have to go fetch it
+      docStore.get(doc._id).onsuccess = function (event) {
+        metadata = decodeMetadata(event.target.result);
+        docIdsToMetadata.set(doc._id, metadata);
+        onGetMetadata();
+      };
+    }
+
+    function onsuccess(event) {
+      var cursor = event.target.result;
+
+      if (!cursor) {
+        return;
+      }
+      onGetCursor(cursor);
+    }
+
+    function fetchChanges() {
+      var objectStores = [DOC_STORE, BY_SEQ_STORE];
+      if (opts.attachments) {
+        objectStores.push(ATTACH_STORE);
+      }
+      var txnResult = openTransactionSafely(idb, objectStores, 'readonly');
+      if (txnResult.error) {
+        return opts.complete(txnResult.error);
+      }
+      txn = txnResult.txn;
+      txn.onabort = idbError(opts.complete);
+      txn.oncomplete = onTxnComplete;
+
+      bySeqStore = txn.objectStore(BY_SEQ_STORE);
+      docStore = txn.objectStore(DOC_STORE);
+      docIdRevIndex = bySeqStore.index('_doc_id_rev');
+
+      var req;
+
+      if (opts.descending) {
+        req = bySeqStore.openCursor(null, 'prev');
+      } else {
+        req = bySeqStore.openCursor(IDBKeyRange.lowerBound(opts.since, true));
+      }
+
+      req.onsuccess = onsuccess;
+    }
+
+    fetchChanges();
+
+    function onTxnComplete() {
+
+      function finish() {
+        opts.complete(null, {
+          results: results,
+          last_seq: lastSeq
+        });
+      }
+
+      if (!opts.continuous && opts.attachments) {
+        // cannot guarantee that postProcessing was already done,
+        // so do it again
+        postProcessAttachments(results).then(finish);
+      } else {
+        finish();
+      }
+    }
+  };
+
+  api._close = function (callback) {
+    if (idb === null) {
+      return callback(createError(NOT_OPEN));
+    }
+
+    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
+    // "Returns immediately and closes the connection in a separate thread..."
+    idb.close();
+    cachedDBs["delete"](dbName);
+    idb = null;
+    callback();
+  };
+
+  api._getRevisionTree = function (docId, callback) {
+    var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+    var req = txn.objectStore(DOC_STORE).get(docId);
+    req.onsuccess = function (event) {
+      var doc = decodeMetadata(event.target.result);
+      if (!doc) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, doc.rev_tree);
+      }
+    };
+  };
+
+  // This function removes revisions of document docId
+  // which are listed in revs and sets this document
+  // revision to to rev_tree
+  api._doCompaction = function (docId, revs, callback) {
+    var stores = [
+      DOC_STORE,
+      BY_SEQ_STORE,
+      ATTACH_STORE,
+      ATTACH_AND_SEQ_STORE
+    ];
+    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+
+    var docStore = txn.objectStore(DOC_STORE);
+
+    docStore.get(docId).onsuccess = function (event) {
+      var metadata = decodeMetadata(event.target.result);
+      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                         revHash, ctx, opts) {
+        var rev = pos + '-' + revHash;
+        if (revs.indexOf(rev) !== -1) {
+          opts.status = 'missing';
+        }
+      });
+      compactRevs(revs, docId, txn);
+      var winningRev = metadata.winningRev;
+      var deleted = metadata.deleted;
+      txn.objectStore(DOC_STORE).put(
+        encodeMetadata(metadata, winningRev, deleted));
+    };
+    txn.onabort = idbError(callback);
+    txn.oncomplete = function () {
+      callback();
+    };
+  };
+
+
+  api._getLocal = function (id, callback) {
+    var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var tx = txnResult.txn;
+    var req = tx.objectStore(LOCAL_STORE).get(id);
+
+    req.onerror = idbError(callback);
+    req.onsuccess = function (e) {
+      var doc = e.target.result;
+      if (!doc) {
+        callback(createError(MISSING_DOC));
+      } else {
+        delete doc['_doc_id_rev']; // for backwards compat
+        callback(null, doc);
+      }
+    };
+  };
+
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+    if (!oldRev) {
+      doc._rev = '0-1';
+    } else {
+      doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
+    }
+
+    var tx = opts.ctx;
+    var ret;
+    if (!tx) {
+      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      tx = txnResult.txn;
+      tx.onerror = idbError(callback);
+      tx.oncomplete = function () {
+        if (ret) {
+          callback(null, ret);
+        }
+      };
+    }
+
+    var oStore = tx.objectStore(LOCAL_STORE);
+    var req;
+    if (oldRev) {
+      req = oStore.get(id);
+      req.onsuccess = function (e) {
+        var oldDoc = e.target.result;
+        if (!oldDoc || oldDoc._rev !== oldRev) {
+          callback(createError(REV_CONFLICT));
+        } else { // update
+          var req = oStore.put(doc);
+          req.onsuccess = function () {
+            ret = {ok: true, id: doc._id, rev: doc._rev};
+            if (opts.ctx) { // return immediately
+              callback(null, ret);
+            }
+          };
+        }
+      };
+    } else { // new doc
+      req = oStore.add(doc);
+      req.onerror = function (e) {
+        // constraint error, already exists
+        callback(createError(REV_CONFLICT));
+        e.preventDefault(); // avoid transaction abort
+        e.stopPropagation(); // avoid transaction onerror
+      };
+      req.onsuccess = function () {
+        ret = {ok: true, id: doc._id, rev: doc._rev};
+        if (opts.ctx) { // return immediately
+          callback(null, ret);
+        }
+      };
+    }
+  };
+
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var tx = opts.ctx;
+    if (!tx) {
+      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      tx = txnResult.txn;
+      tx.oncomplete = function () {
+        if (ret) {
+          callback(null, ret);
+        }
+      };
+    }
+    var ret;
+    var id = doc._id;
+    var oStore = tx.objectStore(LOCAL_STORE);
+    var req = oStore.get(id);
+
+    req.onerror = idbError(callback);
+    req.onsuccess = function (e) {
+      var oldDoc = e.target.result;
+      if (!oldDoc || oldDoc._rev !== doc._rev) {
+        callback(createError(MISSING_DOC));
+      } else {
+        oStore["delete"](id);
+        ret = {ok: true, id: id, rev: '0-0'};
+        if (opts.ctx) { // return immediately
+          callback(null, ret);
+        }
+      }
+    };
+  };
+
+  api._destroy = function (opts, callback) {
+    idbChanges.removeAllListeners(dbName);
+
+    //Close open request for "dbName" database to fix ie delay.
+    var openReq = openReqList.get(dbName);
+    if (openReq && openReq.result) {
+      openReq.result.close();
+      cachedDBs["delete"](dbName);
+    }
+    var req = indexedDB.deleteDatabase(dbName);
+
+    req.onsuccess = function () {
+      //Remove open request from the list.
+      openReqList["delete"](dbName);
+      if (hasLocalStorage() && (dbName in localStorage)) {
+        delete localStorage[dbName];
+      }
+      callback(null, { 'ok': true });
+    };
+
+    req.onerror = idbError(callback);
+  };
+
+  var cached = cachedDBs.get(dbName);
+
+  if (cached) {
+    idb = cached.idb;
+    api._meta = cached.global;
+    process.nextTick(function () {
+      callback(null, api);
+    });
+    return;
+  }
+
+  var req;
+  if (opts.storage) {
+    req = tryStorageOption(dbName, opts.storage);
+  } else {
+    req = indexedDB.open(dbName, ADAPTER_VERSION);
+  }
+
+  openReqList.set(dbName, req);
+
+  req.onupgradeneeded = function (e) {
+    var db = e.target.result;
+    if (e.oldVersion < 1) {
+      return createSchema(db); // new db, initial schema
+    }
+    // do migrations
+
+    var txn = e.currentTarget.transaction;
+    // these migrations have to be done in this function, before
+    // control is returned to the event loop, because IndexedDB
+
+    if (e.oldVersion < 3) {
+      createLocalStoreSchema(db); // v2 -> v3
+    }
+    if (e.oldVersion < 4) {
+      addAttachAndSeqStore(db); // v3 -> v4
+    }
+
+    var migrations = [
+      addDeletedOrLocalIndex, // v1 -> v2
+      migrateLocalStore,      // v2 -> v3
+      migrateAttsAndSeqs,     // v3 -> v4
+      migrateMetadata         // v4 -> v5
+    ];
+
+    var i = e.oldVersion;
+
+    function next() {
+      var migration = migrations[i - 1];
+      i++;
+      if (migration) {
+        migration(txn, next);
+      }
+    }
+
+    next();
+  };
+
+  req.onsuccess = function (e) {
+
+    idb = e.target.result;
+
+    idb.onversionchange = function () {
+      idb.close();
+      cachedDBs["delete"](dbName);
+    };
+
+    idb.onabort = function (e) {
+      console.error('Database has a global failure', e.target.error);
+      idb.close();
+      cachedDBs["delete"](dbName);
+    };
+
+    var txn = idb.transaction([
+      META_STORE,
+      DETECT_BLOB_SUPPORT_STORE,
+      DOC_STORE
+    ], 'readwrite');
+
+    var req = txn.objectStore(META_STORE).get(META_STORE);
+
+    var blobSupport = null;
+    var docCount = null;
+    var instanceId = null;
+
+    req.onsuccess = function (e) {
+
+      var checkSetupComplete = function () {
+        if (blobSupport === null || docCount === null ||
+            instanceId === null) {
+          return;
+        } else {
+          api._meta = {
+            name: dbName,
+            instanceId: instanceId,
+            blobSupport: blobSupport,
+            docCount: docCount
+          };
+
+          cachedDBs.set(dbName, {
+            idb: idb,
+            global: api._meta
+          });
+          callback(null, api);
+        }
+      };
+
+      //
+      // fetch/store the id
+      //
+
+      var meta = e.target.result || {id: META_STORE};
+      if (dbName  + '_id' in meta) {
+        instanceId = meta[dbName + '_id'];
+        checkSetupComplete();
+      } else {
+        instanceId = uuid();
+        meta[dbName + '_id'] = instanceId;
+        txn.objectStore(META_STORE).put(meta).onsuccess = function () {
+          checkSetupComplete();
+        };
+      }
+
+      //
+      // check blob support
+      //
+
+      if (!blobSupportPromise) {
+        // make sure blob support is only checked once
+        blobSupportPromise = checkBlobSupport(txn);
+      }
+
+      blobSupportPromise.then(function (val) {
+        blobSupport = val;
+        checkSetupComplete();
+      });
+
+      //
+      // count docs
+      //
+
+      var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
+      index.count(IDBKeyRange.only('0')).onsuccess = function (e) {
+        docCount = e.target.result;
+        checkSetupComplete();
+      };
+
+    };
+  };
+
+  req.onerror = function () {
+    var msg = 'Failed to open indexedDB, are you in private browsing mode?';
+    console.error(msg);
+    callback(createError(IDB_ERROR, msg));
+  };
+}
+
+IdbPouch.valid = function () {
+  // Issue #2533, we finally gave up on doing bug
+  // detection instead of browser sniffing. Safari brought us
+  // to our knees.
+  var isSafari = typeof openDatabase !== 'undefined' &&
+    /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) &&
+    !/Chrome/.test(navigator.userAgent) &&
+    !/BlackBerry/.test(navigator.platform);
+
+  // some outdated implementations of IDB that appear on Samsung
+  // and HTC Android devices <4.4 are missing IDBKeyRange
+  return !isSafari && typeof indexedDB !== 'undefined' &&
+    typeof IDBKeyRange !== 'undefined';
+};
+
+function tryStorageOption(dbName, storage) {
+  try { // option only available in Firefox 26+
+    return indexedDB.open(dbName, {
+      version: ADAPTER_VERSION,
+      storage: storage
+    });
+  } catch(err) {
+      return indexedDB.open(dbName, ADAPTER_VERSION);
+  }
+}
+
+//
+// Parsing hex strings. Yeah.
+//
+// So basically we need this because of a bug in WebSQL:
+// https://code.google.com/p/chromium/issues/detail?id=422690
+// https://bugs.webkit.org/show_bug.cgi?id=137637
+//
+// UTF-8 and UTF-16 are provided as separate functions
+// for meager performance improvements
+//
+
+function decodeUtf8(str) {
+  return decodeURIComponent(window.escape(str));
+}
+
+function hexToInt(charCode) {
+  // '0'-'9' is 48-57
+  // 'A'-'F' is 65-70
+  // SQLite will only give us uppercase hex
+  return charCode < 65 ? (charCode - 48) : (charCode - 55);
+}
+
+
+// Example:
+// pragma encoding=utf8;
+// select hex('A');
+// returns '41'
+function parseHexUtf8(str, start, end) {
+  var result = '';
+  while (start < end) {
+    result += String.fromCharCode(
+      (hexToInt(str.charCodeAt(start++)) << 4) |
+        hexToInt(str.charCodeAt(start++)));
+  }
+  return result;
+}
+
+// Example:
+// pragma encoding=utf16;
+// select hex('A');
+// returns '4100'
+// notice that the 00 comes after the 41 (i.e. it's swizzled)
+function parseHexUtf16(str, start, end) {
+  var result = '';
+  while (start < end) {
+    // UTF-16, so swizzle the bytes
+    result += String.fromCharCode(
+      (hexToInt(str.charCodeAt(start + 2)) << 12) |
+        (hexToInt(str.charCodeAt(start + 3)) << 8) |
+        (hexToInt(str.charCodeAt(start)) << 4) |
+        hexToInt(str.charCodeAt(start + 1)));
+    start += 4;
+  }
+  return result;
+}
+
+function parseHexString(str, encoding) {
+  if (encoding === 'UTF-8') {
+    return decodeUtf8(parseHexUtf8(str, 0, str.length));
+  } else {
+    return parseHexUtf16(str, 0, str.length);
+  }
+}
+
+function quote(str) {
+  return "'" + str + "'";
+}
+
+var ADAPTER_VERSION$1 = 7; // used to manage migrations
+
+// The object stores created for each database
+// DOC_STORE stores the document meta data, its revision history and state
+var DOC_STORE$1 = quote('document-store');
+// BY_SEQ_STORE stores a particular version of a document, keyed by its
+// sequence id
+var BY_SEQ_STORE$1 = quote('by-sequence');
+// Where we store attachments
+var ATTACH_STORE$1 = quote('attach-store');
+var LOCAL_STORE$1 = quote('local-store');
+var META_STORE$1 = quote('metadata-store');
+// where we store many-to-many relations between attachment
+// digests and seqs
+var ATTACH_AND_SEQ_STORE$1 = quote('attach-seq-store');
+
+function createOpenDBFunction() {
+  if (typeof sqlitePlugin !== 'undefined') {
+    // The SQLite Plugin started deviating pretty heavily from the
+    // standard openDatabase() function, as they started adding more features.
+    // It's better to just use their "new" format and pass in a big ol'
+    // options object.
+    return sqlitePlugin.openDatabase.bind(sqlitePlugin);
+  }
+
+  if (typeof openDatabase !== 'undefined') {
+    return function openDB(opts) {
+      // Traditional WebSQL API
+      return openDatabase(opts.name, opts.version, opts.description, opts.size);
+    };
+  }
+}
+
+function valid() {
+  // SQLitePlugin leaks this global object, which we can use
+  // to detect if it's installed or not. The benefit is that it's
+  // declared immediately, before the 'deviceready' event has fired.
+  return typeof openDatabase !== 'undefined' ||
+    typeof SQLitePlugin !== 'undefined';
+}
+
+// escapeBlob and unescapeBlob are workarounds for a websql bug:
+// https://code.google.com/p/chromium/issues/detail?id=422690
+// https://bugs.webkit.org/show_bug.cgi?id=137637
+// The goal is to never actually insert the \u0000 character
+// in the database.
+function escapeBlob(str) {
+  return str
+    .replace(/\u0002/g, '\u0002\u0002')
+    .replace(/\u0001/g, '\u0001\u0002')
+    .replace(/\u0000/g, '\u0001\u0001');
+}
+
+function unescapeBlob(str) {
+  return str
+    .replace(/\u0001\u0001/g, '\u0000')
+    .replace(/\u0001\u0002/g, '\u0001')
+    .replace(/\u0002\u0002/g, '\u0002');
+}
+
+function stringifyDoc(doc) {
+  // don't bother storing the id/rev. it uses lots of space,
+  // in persistent map/reduce especially
+  delete doc._id;
+  delete doc._rev;
+  return JSON.stringify(doc);
+}
+
+function unstringifyDoc(doc, id, rev) {
+  doc = JSON.parse(doc);
+  doc._id = id;
+  doc._rev = rev;
+  return doc;
+}
+
+// question mark groups IN queries, e.g. 3 -> '(?,?,?)'
+function qMarks(num) {
+  var s = '(';
+  while (num--) {
+    s += '?';
+    if (num) {
+      s += ',';
+    }
+  }
+  return s + ')';
+}
+
+function select(selector, table, joiner, where, orderBy) {
+  return 'SELECT ' + selector + ' FROM ' +
+    (typeof table === 'string' ? table : table.join(' JOIN ')) +
+    (joiner ? (' ON ' + joiner) : '') +
+    (where ? (' WHERE ' +
+    (typeof where === 'string' ? where : where.join(' AND '))) : '') +
+    (orderBy ? (' ORDER BY ' + orderBy) : '');
+}
+
+function compactRevs$1(revs, docId, tx) {
+
+  if (!revs.length) {
+    return;
+  }
+
+  var numDone = 0;
+  var seqs = [];
+
+  function checkDone() {
+    if (++numDone === revs.length) { // done
+      deleteOrphans();
+    }
+  }
+
+  function deleteOrphans() {
+    // find orphaned attachment digests
+
+    if (!seqs.length) {
+      return;
+    }
+
+    var sql = 'SELECT DISTINCT digest AS digest FROM ' +
+      ATTACH_AND_SEQ_STORE$1 + ' WHERE seq IN ' + qMarks(seqs.length);
+
+    tx.executeSql(sql, seqs, function (tx, res) {
+
+      var digestsToCheck = [];
+      for (var i = 0; i < res.rows.length; i++) {
+        digestsToCheck.push(res.rows.item(i).digest);
+      }
+      if (!digestsToCheck.length) {
+        return;
+      }
+
+      var sql = 'DELETE FROM ' + ATTACH_AND_SEQ_STORE$1 +
+        ' WHERE seq IN (' +
+        seqs.map(function () { return '?'; }).join(',') +
+        ')';
+      tx.executeSql(sql, seqs, function (tx) {
+
+        var sql = 'SELECT digest FROM ' + ATTACH_AND_SEQ_STORE$1 +
+          ' WHERE digest IN (' +
+          digestsToCheck.map(function () { return '?'; }).join(',') +
+          ')';
+        tx.executeSql(sql, digestsToCheck, function (tx, res) {
+          var nonOrphanedDigests = new pouchdbCollections.Set();
+          for (var i = 0; i < res.rows.length; i++) {
+            nonOrphanedDigests.add(res.rows.item(i).digest);
+          }
+          digestsToCheck.forEach(function (digest) {
+            if (nonOrphanedDigests.has(digest)) {
+              return;
+            }
+            tx.executeSql(
+              'DELETE FROM ' + ATTACH_AND_SEQ_STORE$1 + ' WHERE digest=?',
+              [digest]);
+            tx.executeSql(
+              'DELETE FROM ' + ATTACH_STORE$1 + ' WHERE digest=?', [digest]);
+          });
+        });
+      });
+    });
+  }
+
+  // update by-seq and attach stores in parallel
+  revs.forEach(function (rev) {
+    var sql = 'SELECT seq FROM ' + BY_SEQ_STORE$1 +
+      ' WHERE doc_id=? AND rev=?';
+
+    tx.executeSql(sql, [docId, rev], function (tx, res) {
+      if (!res.rows.length) { // already deleted
+        return checkDone();
+      }
+      var seq = res.rows.item(0).seq;
+      seqs.push(seq);
+
+      tx.executeSql(
+        'DELETE FROM ' + BY_SEQ_STORE$1 + ' WHERE seq=?', [seq], checkDone);
+    });
+  });
+}
+
+function websqlError(callback) {
+  return function (event) {
+    console.error('WebSQL threw an error', event);
+    // event may actually be a SQLError object, so report is as such
+    var errorNameMatch = event && event.constructor.toString()
+        .match(/function ([^\(]+)/);
+    var errorName = (errorNameMatch && errorNameMatch[1]) || event.type;
+    var errorReason = event.target || event.message;
+    callback(createError(WSQ_ERROR, errorReason, errorName));
+  };
+}
+
+function getSize(opts) {
+  if ('size' in opts) {
+    // triggers immediate popup in iOS, fixes #2347
+    // e.g. 5000001 asks for 5 MB, 10000001 asks for 10 MB,
+    return opts.size * 1000000;
+  }
+  // In iOS, doesn't matter as long as it's <= 5000000.
+  // Except that if you request too much, our tests fail
+  // because of the native "do you accept?" popup.
+  // In Android <=4.3, this value is actually used as an
+  // honest-to-god ceiling for data, so we need to
+  // set it to a decently high number.
+  var isAndroid = typeof navigator !== 'undefined' &&
+    /Android/.test(navigator.userAgent);
+  return isAndroid ? 5000000 : 1; // in PhantomJS, if you use 0 it will crash
+}
+
+function openDBSafely(openDBFunction, opts) {
+  try {
+    return {
+      db: openDBFunction(opts)
+    };
+  } catch (err) {
+    return {
+      error: err
+    };
+  }
+}
+
+var cachedDatabases = new pouchdbCollections.Map();
+
+function openDB(opts) {
+  var cachedResult = cachedDatabases.get(opts.name);
+  if (!cachedResult) {
+    var openDBFun = createOpenDBFunction();
+    cachedResult = openDBSafely(openDBFun, opts);
+    cachedDatabases.set(opts.name, cachedResult);
+    if (cachedResult.db) {
+      cachedResult.db._sqlitePlugin = typeof sqlitePlugin !== 'undefined';
+    }
+  }
+  return cachedResult;
+}
+
+function websqlBulkDocs(dbOpts, req, opts, api, db, websqlChanges, callback) {
+  var newEdits = opts.new_edits;
+  var userDocs = req.docs;
+
+  // Parse the docs, give them a sequence number for the result
+  var docInfos = userDocs.map(function (doc) {
+    if (doc._id && isLocalId(doc._id)) {
+      return doc;
+    }
+    var newDoc = parseDoc(doc, newEdits);
+    return newDoc;
+  });
+
+  var docInfoErrors = docInfos.filter(function (docInfo) {
+    return docInfo.error;
+  });
+  if (docInfoErrors.length) {
+    return callback(docInfoErrors[0]);
+  }
+
+  var tx;
+  var results = new Array(docInfos.length);
+  var fetchedDocs = new pouchdbCollections.Map();
+
+  var preconditionErrored;
+  function complete() {
+    if (preconditionErrored) {
+      return callback(preconditionErrored);
+    }
+    websqlChanges.notify(api._name);
+    api._docCount = -1; // invalidate
+    callback(null, results);
+  }
+
+  function verifyAttachment(digest, callback) {
+    var sql = 'SELECT count(*) as cnt FROM ' + ATTACH_STORE$1 +
+      ' WHERE digest=?';
+    tx.executeSql(sql, [digest], function (tx, result) {
+      if (result.rows.item(0).cnt === 0) {
+        var err = createError(MISSING_STUB,
+          'unknown stub attachment with digest ' +
+          digest);
+        callback(err);
+      } else {
+        callback();
+      }
+    });
+  }
+
+  function verifyAttachments(finish) {
+    var digests = [];
+    docInfos.forEach(function (docInfo) {
+      if (docInfo.data && docInfo.data._attachments) {
+        Object.keys(docInfo.data._attachments).forEach(function (filename) {
+          var att = docInfo.data._attachments[filename];
+          if (att.stub) {
+            digests.push(att.digest);
+          }
+        });
+      }
+    });
+    if (!digests.length) {
+      return finish();
+    }
+    var numDone = 0;
+    var err;
+
+    function checkDone() {
+      if (++numDone === digests.length) {
+        finish(err);
+      }
+    }
+    digests.forEach(function (digest) {
+      verifyAttachment(digest, function (attErr) {
+        if (attErr && !err) {
+          err = attErr;
+        }
+        checkDone();
+      });
+    });
+  }
+
+  function writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
+                    isUpdate, delta, resultsIdx, callback) {
+
+    function finish() {
+      var data = docInfo.data;
+      var deletedInt = newRevIsDeleted ? 1 : 0;
+
+      var id = data._id;
+      var rev = data._rev;
+      var json = stringifyDoc(data);
+      var sql = 'INSERT INTO ' + BY_SEQ_STORE$1 +
+        ' (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);';
+      var sqlArgs = [id, rev, json, deletedInt];
+
+      // map seqs to attachment digests, which
+      // we will need later during compaction
+      function insertAttachmentMappings(seq, callback) {
+        var attsAdded = 0;
+        var attsToAdd = Object.keys(data._attachments || {});
+
+        if (!attsToAdd.length) {
+          return callback();
+        }
+        function checkDone() {
+          if (++attsAdded === attsToAdd.length) {
+            callback();
+          }
+          return false; // ack handling a constraint error
+        }
+        function add(att) {
+          var sql = 'INSERT INTO ' + ATTACH_AND_SEQ_STORE$1 +
+            ' (digest, seq) VALUES (?,?)';
+          var sqlArgs = [data._attachments[att].digest, seq];
+          tx.executeSql(sql, sqlArgs, checkDone, checkDone);
+          // second callback is for a constaint error, which we ignore
+          // because this docid/rev has already been associated with
+          // the digest (e.g. when new_edits == false)
+        }
+        for (var i = 0; i < attsToAdd.length; i++) {
+          add(attsToAdd[i]); // do in parallel
+        }
+      }
+
+      tx.executeSql(sql, sqlArgs, function (tx, result) {
+        var seq = result.insertId;
+        insertAttachmentMappings(seq, function () {
+          dataWritten(tx, seq);
+        });
+      }, function () {
+        // constraint error, recover by updating instead (see #1638)
+        var fetchSql = select('seq', BY_SEQ_STORE$1, null,
+          'doc_id=? AND rev=?');
+        tx.executeSql(fetchSql, [id, rev], function (tx, res) {
+          var seq = res.rows.item(0).seq;
+          var sql = 'UPDATE ' + BY_SEQ_STORE$1 +
+            ' SET json=?, deleted=? WHERE doc_id=? AND rev=?;';
+          var sqlArgs = [json, deletedInt, id, rev];
+          tx.executeSql(sql, sqlArgs, function (tx) {
+            insertAttachmentMappings(seq, function () {
+              dataWritten(tx, seq);
+            });
+          });
+        });
+        return false; // ack that we've handled the error
+      });
+    }
+
+    function collectResults(attachmentErr) {
+      if (!err) {
+        if (attachmentErr) {
+          err = attachmentErr;
+          callback(err);
+        } else if (recv === attachments.length) {
+          finish();
+        }
+      }
+    }
+
+    var err = null;
+    var recv = 0;
+
+    docInfo.data._id = docInfo.metadata.id;
+    docInfo.data._rev = docInfo.metadata.rev;
+    var attachments = Object.keys(docInfo.data._attachments || {});
+
+
+    if (newRevIsDeleted) {
+      docInfo.data._deleted = true;
+    }
+
+    function attachmentSaved(err) {
+      recv++;
+      collectResults(err);
+    }
+
+    attachments.forEach(function (key) {
+      var att = docInfo.data._attachments[key];
+      if (!att.stub) {
+        var data = att.data;
+        delete att.data;
+        att.revpos = parseInt(winningRev, 10);
+        var digest = att.digest;
+        saveAttachment(digest, data, attachmentSaved);
+      } else {
+        recv++;
+        collectResults();
+      }
+    });
+
+    if (!attachments.length) {
+      finish();
+    }
+
+    function dataWritten(tx, seq) {
+      var id = docInfo.metadata.id;
+      if (isUpdate && api.auto_compaction) {
+        compactRevs$1(compactTree(docInfo.metadata), id, tx);
+      } else if (docInfo.stemmedRevs.length) {
+        compactRevs$1(docInfo.stemmedRevs, id, tx);
+      }
+
+      docInfo.metadata.seq = seq;
+      delete docInfo.metadata.rev;
+
+      var sql = isUpdate ?
+      'UPDATE ' + DOC_STORE$1 +
+      ' SET json=?, max_seq=?, winningseq=' +
+      '(SELECT seq FROM ' + BY_SEQ_STORE$1 +
+      ' WHERE doc_id=' + DOC_STORE$1 + '.id AND rev=?) WHERE id=?'
+        : 'INSERT INTO ' + DOC_STORE$1 +
+      ' (id, winningseq, max_seq, json) VALUES (?,?,?,?);';
+      var metadataStr = safeJsonStringify(docInfo.metadata);
+      var params = isUpdate ?
+        [metadataStr, seq, winningRev, id] :
+        [id, seq, seq, metadataStr];
+      tx.executeSql(sql, params, function () {
+        results[resultsIdx] = {
+          ok: true,
+          id: docInfo.metadata.id,
+          rev: winningRev
+        };
+        fetchedDocs.set(id, docInfo.metadata);
+        callback();
+      });
+    }
+  }
+
+  function websqlProcessDocs() {
+    processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs, tx,
+                results, writeDoc, opts);
+  }
+
+  function fetchExistingDocs(callback) {
+    if (!docInfos.length) {
+      return callback();
+    }
+
+    var numFetched = 0;
+
+    function checkDone() {
+      if (++numFetched === docInfos.length) {
+        callback();
+      }
+    }
+
+    docInfos.forEach(function (docInfo) {
+      if (docInfo._id && isLocalId(docInfo._id)) {
+        return checkDone(); // skip local docs
+      }
+      var id = docInfo.metadata.id;
+      tx.executeSql('SELECT json FROM ' + DOC_STORE$1 +
+      ' WHERE id = ?', [id], function (tx, result) {
+        if (result.rows.length) {
+          var metadata = safeJsonParse(result.rows.item(0).json);
+          fetchedDocs.set(id, metadata);
+        }
+        checkDone();
+      });
+    });
+  }
+
+  function saveAttachment(digest, data, callback) {
+    var sql = 'SELECT digest FROM ' + ATTACH_STORE$1 + ' WHERE digest=?';
+    tx.executeSql(sql, [digest], function (tx, result) {
+      if (result.rows.length) { // attachment already exists
+        return callback();
+      }
+      // we could just insert before selecting and catch the error,
+      // but my hunch is that it's cheaper not to serialize the blob
+      // from JS to C if we don't have to (TODO: confirm this)
+      sql = 'INSERT INTO ' + ATTACH_STORE$1 +
+      ' (digest, body, escaped) VALUES (?,?,1)';
+      tx.executeSql(sql, [digest, escapeBlob(data)], function () {
+        callback();
+      }, function () {
+        // ignore constaint errors, means it already exists
+        callback();
+        return false; // ack we handled the error
+      });
+    });
+  }
+
+  preprocessAttachments$1(docInfos, 'binary', function (err) {
+    if (err) {
+      return callback(err);
+    }
+    db.transaction(function (txn) {
+      tx = txn;
+      verifyAttachments(function (err) {
+        if (err) {
+          preconditionErrored = err;
+        } else {
+          fetchExistingDocs(websqlProcessDocs);
+        }
+      });
+    }, websqlError(callback), complete);
+  });
+}
+
+var websqlChanges = new Changes$1();
+
+function fetchAttachmentsIfNecessary$1(doc, opts, api, txn, cb) {
+  var attachments = Object.keys(doc._attachments || {});
+  if (!attachments.length) {
+    return cb && cb();
+  }
+  var numDone = 0;
+
+  function checkDone() {
+    if (++numDone === attachments.length && cb) {
+      cb();
+    }
+  }
+
+  function fetchAttachment(doc, att) {
+    var attObj = doc._attachments[att];
+    var attOpts = {binary: opts.binary, ctx: txn};
+    api._getAttachment(attObj, attOpts, function (_, data) {
+      doc._attachments[att] = jsExtend.extend(
+        pick(attObj, ['digest', 'content_type']),
+        { data: data }
+      );
+      checkDone();
+    });
+  }
+
+  attachments.forEach(function (att) {
+    if (opts.attachments && opts.include_docs) {
+      fetchAttachment(doc, att);
+    } else {
+      doc._attachments[att].stub = true;
+      checkDone();
+    }
+  });
+}
+
+var POUCH_VERSION = 1;
+
+// these indexes cover the ground for most allDocs queries
+var BY_SEQ_STORE_DELETED_INDEX_SQL =
+  'CREATE INDEX IF NOT EXISTS \'by-seq-deleted-idx\' ON ' +
+  BY_SEQ_STORE$1 + ' (seq, deleted)';
+var BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL =
+  'CREATE UNIQUE INDEX IF NOT EXISTS \'by-seq-doc-id-rev\' ON ' +
+    BY_SEQ_STORE$1 + ' (doc_id, rev)';
+var DOC_STORE_WINNINGSEQ_INDEX_SQL =
+  'CREATE INDEX IF NOT EXISTS \'doc-winningseq-idx\' ON ' +
+  DOC_STORE$1 + ' (winningseq)';
+var ATTACH_AND_SEQ_STORE_SEQ_INDEX_SQL =
+  'CREATE INDEX IF NOT EXISTS \'attach-seq-seq-idx\' ON ' +
+    ATTACH_AND_SEQ_STORE$1 + ' (seq)';
+var ATTACH_AND_SEQ_STORE_ATTACH_INDEX_SQL =
+  'CREATE UNIQUE INDEX IF NOT EXISTS \'attach-seq-digest-idx\' ON ' +
+    ATTACH_AND_SEQ_STORE$1 + ' (digest, seq)';
+
+var DOC_STORE_AND_BY_SEQ_JOINER = BY_SEQ_STORE$1 +
+  '.seq = ' + DOC_STORE$1 + '.winningseq';
+
+var SELECT_DOCS = BY_SEQ_STORE$1 + '.seq AS seq, ' +
+  BY_SEQ_STORE$1 + '.deleted AS deleted, ' +
+  BY_SEQ_STORE$1 + '.json AS data, ' +
+  BY_SEQ_STORE$1 + '.rev AS rev, ' +
+  DOC_STORE$1 + '.json AS metadata';
+
+function WebSqlPouch(opts, callback) {
+  var api = this;
+  var instanceId = null;
+  var size = getSize(opts);
+  var idRequests = [];
+  var encoding;
+
+  api._docCount = -1; // cache sqlite count(*) for performance
+  api._name = opts.name;
+
+  // extend the options here, because sqlite plugin has a ton of options
+  // and they are constantly changing, so it's more prudent to allow anything
+  var websqlOpts = jsExtend.extend({}, opts, {size: size, version: POUCH_VERSION});
+  var openDBResult = openDB(websqlOpts);
+  if (openDBResult.error) {
+    return websqlError(callback)(openDBResult.error);
+  }
+  var db = openDBResult.db;
+  if (typeof db.readTransaction !== 'function') {
+    // doesn't exist in sqlite plugin
+    db.readTransaction = db.transaction;
+  }
+
+  function dbCreated() {
+    // note the db name in case the browser upgrades to idb
+    if (hasLocalStorage()) {
+      window.localStorage['_pouch__websqldb_' + api._name] = true;
+    }
+    callback(null, api);
+  }
+
+  // In this migration, we added the 'deleted' and 'local' columns to the
+  // by-seq and doc store tables.
+  // To preserve existing user data, we re-process all the existing JSON
+  // and add these values.
+  // Called migration2 because it corresponds to adapter version (db_version) #2
+  function runMigration2(tx, callback) {
+    // index used for the join in the allDocs query
+    tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
+
+    tx.executeSql('ALTER TABLE ' + BY_SEQ_STORE$1 +
+      ' ADD COLUMN deleted TINYINT(1) DEFAULT 0', [], function () {
+      tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
+      tx.executeSql('ALTER TABLE ' + DOC_STORE$1 +
+        ' ADD COLUMN local TINYINT(1) DEFAULT 0', [], function () {
+        tx.executeSql('CREATE INDEX IF NOT EXISTS \'doc-store-local-idx\' ON ' +
+          DOC_STORE$1 + ' (local, id)');
+
+        var sql = 'SELECT ' + DOC_STORE$1 + '.winningseq AS seq, ' + DOC_STORE$1 +
+          '.json AS metadata FROM ' + BY_SEQ_STORE$1 + ' JOIN ' + DOC_STORE$1 +
+          ' ON ' + BY_SEQ_STORE$1 + '.seq = ' + DOC_STORE$1 + '.winningseq';
+
+        tx.executeSql(sql, [], function (tx, result) {
+
+          var deleted = [];
+          var local = [];
+
+          for (var i = 0; i < result.rows.length; i++) {
+            var item = result.rows.item(i);
+            var seq = item.seq;
+            var metadata = JSON.parse(item.metadata);
+            if (isDeleted(metadata)) {
+              deleted.push(seq);
+            }
+            if (isLocalId(metadata.id)) {
+              local.push(metadata.id);
+            }
+          }
+          tx.executeSql('UPDATE ' + DOC_STORE$1 + 'SET local = 1 WHERE id IN ' +
+            qMarks(local.length), local, function () {
+            tx.executeSql('UPDATE ' + BY_SEQ_STORE$1 +
+              ' SET deleted = 1 WHERE seq IN ' +
+              qMarks(deleted.length), deleted, callback);
+          });
+        });
+      });
+    });
+  }
+
+  // in this migration, we make all the local docs unversioned
+  function runMigration3(tx, callback) {
+    var local = 'CREATE TABLE IF NOT EXISTS ' + LOCAL_STORE$1 +
+      ' (id UNIQUE, rev, json)';
+    tx.executeSql(local, [], function () {
+      var sql = 'SELECT ' + DOC_STORE$1 + '.id AS id, ' +
+        BY_SEQ_STORE$1 + '.json AS data ' +
+        'FROM ' + BY_SEQ_STORE$1 + ' JOIN ' +
+        DOC_STORE$1 + ' ON ' + BY_SEQ_STORE$1 + '.seq = ' +
+        DOC_STORE$1 + '.winningseq WHERE local = 1';
+      tx.executeSql(sql, [], function (tx, res) {
+        var rows = [];
+        for (var i = 0; i < res.rows.length; i++) {
+          rows.push(res.rows.item(i));
+        }
+        function doNext() {
+          if (!rows.length) {
+            return callback(tx);
+          }
+          var row = rows.shift();
+          var rev = JSON.parse(row.data)._rev;
+          tx.executeSql('INSERT INTO ' + LOCAL_STORE$1 +
+              ' (id, rev, json) VALUES (?,?,?)',
+              [row.id, rev, row.data], function (tx) {
+            tx.executeSql('DELETE FROM ' + DOC_STORE$1 + ' WHERE id=?',
+                [row.id], function (tx) {
+              tx.executeSql('DELETE FROM ' + BY_SEQ_STORE$1 + ' WHERE seq=?',
+                  [row.seq], function () {
+                doNext();
+              });
+            });
+          });
+        }
+        doNext();
+      });
+    });
+  }
+
+  // in this migration, we remove doc_id_rev and just use rev
+  function runMigration4(tx, callback) {
+
+    function updateRows(rows) {
+      function doNext() {
+        if (!rows.length) {
+          return callback(tx);
+        }
+        var row = rows.shift();
+        var doc_id_rev = parseHexString(row.hex, encoding);
+        var idx = doc_id_rev.lastIndexOf('::');
+        var doc_id = doc_id_rev.substring(0, idx);
+        var rev = doc_id_rev.substring(idx + 2);
+        var sql = 'UPDATE ' + BY_SEQ_STORE$1 +
+          ' SET doc_id=?, rev=? WHERE doc_id_rev=?';
+        tx.executeSql(sql, [doc_id, rev, doc_id_rev], function () {
+          doNext();
+        });
+      }
+      doNext();
+    }
+
+    var sql = 'ALTER TABLE ' + BY_SEQ_STORE$1 + ' ADD COLUMN doc_id';
+    tx.executeSql(sql, [], function (tx) {
+      var sql = 'ALTER TABLE ' + BY_SEQ_STORE$1 + ' ADD COLUMN rev';
+      tx.executeSql(sql, [], function (tx) {
+        tx.executeSql(BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL, [], function (tx) {
+          var sql = 'SELECT hex(doc_id_rev) as hex FROM ' + BY_SEQ_STORE$1;
+          tx.executeSql(sql, [], function (tx, res) {
+            var rows = [];
+            for (var i = 0; i < res.rows.length; i++) {
+              rows.push(res.rows.item(i));
+            }
+            updateRows(rows);
+          });
+        });
+      });
+    });
+  }
+
+  // in this migration, we add the attach_and_seq table
+  // for issue #2818
+  function runMigration5(tx, callback) {
+
+    function migrateAttsAndSeqs(tx) {
+      // need to actually populate the table. this is the expensive part,
+      // so as an optimization, check first that this database even
+      // contains attachments
+      var sql = 'SELECT COUNT(*) AS cnt FROM ' + ATTACH_STORE$1;
+      tx.executeSql(sql, [], function (tx, res) {
+        var count = res.rows.item(0).cnt;
+        if (!count) {
+          return callback(tx);
+        }
+
+        var offset = 0;
+        var pageSize = 10;
+        function nextPage() {
+          var sql = select(
+            SELECT_DOCS + ', ' + DOC_STORE$1 + '.id AS id',
+            [DOC_STORE$1, BY_SEQ_STORE$1],
+            DOC_STORE_AND_BY_SEQ_JOINER,
+            null,
+            DOC_STORE$1 + '.id '
+          );
+          sql += ' LIMIT ' + pageSize + ' OFFSET ' + offset;
+          offset += pageSize;
+          tx.executeSql(sql, [], function (tx, res) {
+            if (!res.rows.length) {
+              return callback(tx);
+            }
+            var digestSeqs = {};
+            function addDigestSeq(digest, seq) {
+              // uniq digest/seq pairs, just in case there are dups
+              var seqs = digestSeqs[digest] = (digestSeqs[digest] || []);
+              if (seqs.indexOf(seq) === -1) {
+                seqs.push(seq);
+              }
+            }
+            for (var i = 0; i < res.rows.length; i++) {
+              var row = res.rows.item(i);
+              var doc = unstringifyDoc(row.data, row.id, row.rev);
+              var atts = Object.keys(doc._attachments || {});
+              for (var j = 0; j < atts.length; j++) {
+                var att = doc._attachments[atts[j]];
+                addDigestSeq(att.digest, row.seq);
+              }
+            }
+            var digestSeqPairs = [];
+            Object.keys(digestSeqs).forEach(function (digest) {
+              var seqs = digestSeqs[digest];
+              seqs.forEach(function (seq) {
+                digestSeqPairs.push([digest, seq]);
+              });
+            });
+            if (!digestSeqPairs.length) {
+              return nextPage();
+            }
+            var numDone = 0;
+            digestSeqPairs.forEach(function (pair) {
+              var sql = 'INSERT INTO ' + ATTACH_AND_SEQ_STORE$1 +
+                ' (digest, seq) VALUES (?,?)';
+              tx.executeSql(sql, pair, function () {
+                if (++numDone === digestSeqPairs.length) {
+                  nextPage();
+                }
+              });
+            });
+          });
+        }
+        nextPage();
+      });
+    }
+
+    var attachAndRev = 'CREATE TABLE IF NOT EXISTS ' +
+      ATTACH_AND_SEQ_STORE$1 + ' (digest, seq INTEGER)';
+    tx.executeSql(attachAndRev, [], function (tx) {
+      tx.executeSql(
+        ATTACH_AND_SEQ_STORE_ATTACH_INDEX_SQL, [], function (tx) {
+          tx.executeSql(
+            ATTACH_AND_SEQ_STORE_SEQ_INDEX_SQL, [],
+            migrateAttsAndSeqs);
+        });
+    });
+  }
+
+  // in this migration, we use escapeBlob() and unescapeBlob()
+  // instead of reading out the binary as HEX, which is slow
+  function runMigration6(tx, callback) {
+    var sql = 'ALTER TABLE ' + ATTACH_STORE$1 +
+      ' ADD COLUMN escaped TINYINT(1) DEFAULT 0';
+    tx.executeSql(sql, [], callback);
+  }
+
+  // issue #3136, in this migration we need a "latest seq" as well
+  // as the "winning seq" in the doc store
+  function runMigration7(tx, callback) {
+    var sql = 'ALTER TABLE ' + DOC_STORE$1 +
+      ' ADD COLUMN max_seq INTEGER';
+    tx.executeSql(sql, [], function (tx) {
+      var sql = 'UPDATE ' + DOC_STORE$1 + ' SET max_seq=(SELECT MAX(seq) FROM ' +
+        BY_SEQ_STORE$1 + ' WHERE doc_id=id)';
+      tx.executeSql(sql, [], function (tx) {
+        // add unique index after filling, else we'll get a constraint
+        // error when we do the ALTER TABLE
+        var sql =
+          'CREATE UNIQUE INDEX IF NOT EXISTS \'doc-max-seq-idx\' ON ' +
+          DOC_STORE$1 + ' (max_seq)';
+        tx.executeSql(sql, [], callback);
+      });
+    });
+  }
+
+  function checkEncoding(tx, cb) {
+    // UTF-8 on chrome/android, UTF-16 on safari < 7.1
+    tx.executeSql('SELECT HEX("a") AS hex', [], function (tx, res) {
+        var hex = res.rows.item(0).hex;
+        encoding = hex.length === 2 ? 'UTF-8' : 'UTF-16';
+        cb();
+      }
+    );
+  }
+
+  function onGetInstanceId() {
+    while (idRequests.length > 0) {
+      var idCallback = idRequests.pop();
+      idCallback(null, instanceId);
+    }
+  }
+
+  function onGetVersion(tx, dbVersion) {
+    if (dbVersion === 0) {
+      // initial schema
+
+      var meta = 'CREATE TABLE IF NOT EXISTS ' + META_STORE$1 +
+        ' (dbid, db_version INTEGER)';
+      var attach = 'CREATE TABLE IF NOT EXISTS ' + ATTACH_STORE$1 +
+        ' (digest UNIQUE, escaped TINYINT(1), body BLOB)';
+      var attachAndRev = 'CREATE TABLE IF NOT EXISTS ' +
+        ATTACH_AND_SEQ_STORE$1 + ' (digest, seq INTEGER)';
+      // TODO: migrate winningseq to INTEGER
+      var doc = 'CREATE TABLE IF NOT EXISTS ' + DOC_STORE$1 +
+        ' (id unique, json, winningseq, max_seq INTEGER UNIQUE)';
+      var seq = 'CREATE TABLE IF NOT EXISTS ' + BY_SEQ_STORE$1 +
+        ' (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
+        'json, deleted TINYINT(1), doc_id, rev)';
+      var local = 'CREATE TABLE IF NOT EXISTS ' + LOCAL_STORE$1 +
+        ' (id UNIQUE, rev, json)';
+
+      // creates
+      tx.executeSql(attach);
+      tx.executeSql(local);
+      tx.executeSql(attachAndRev, [], function () {
+        tx.executeSql(ATTACH_AND_SEQ_STORE_SEQ_INDEX_SQL);
+        tx.executeSql(ATTACH_AND_SEQ_STORE_ATTACH_INDEX_SQL);
+      });
+      tx.executeSql(doc, [], function () {
+        tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
+        tx.executeSql(seq, [], function () {
+          tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
+          tx.executeSql(BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL);
+          tx.executeSql(meta, [], function () {
+            // mark the db version, and new dbid
+            var initSeq = 'INSERT INTO ' + META_STORE$1 +
+              ' (db_version, dbid) VALUES (?,?)';
+            instanceId = uuid();
+            var initSeqArgs = [ADAPTER_VERSION$1, instanceId];
+            tx.executeSql(initSeq, initSeqArgs, function () {
+              onGetInstanceId();
+            });
+          });
+        });
+      });
+    } else { // version > 0
+
+      var setupDone = function () {
+        var migrated = dbVersion < ADAPTER_VERSION$1;
+        if (migrated) {
+          // update the db version within this transaction
+          tx.executeSql('UPDATE ' + META_STORE$1 + ' SET db_version = ' +
+            ADAPTER_VERSION$1);
+        }
+        // notify db.id() callers
+        var sql = 'SELECT dbid FROM ' + META_STORE$1;
+        tx.executeSql(sql, [], function (tx, result) {
+          instanceId = result.rows.item(0).dbid;
+          onGetInstanceId();
+        });
+      };
+
+      // would love to use promises here, but then websql
+      // ends the transaction early
+      var tasks = [
+        runMigration2,
+        runMigration3,
+        runMigration4,
+        runMigration5,
+        runMigration6,
+        runMigration7,
+        setupDone
+      ];
+
+      // run each migration sequentially
+      var i = dbVersion;
+      var nextMigration = function (tx) {
+        tasks[i - 1](tx, nextMigration);
+        i++;
+      };
+      nextMigration(tx);
+    }
+  }
+
+  function setup() {
+    db.transaction(function (tx) {
+      // first check the encoding
+      checkEncoding(tx, function () {
+        // then get the version
+        fetchVersion(tx);
+      });
+    }, websqlError(callback), dbCreated);
+  }
+
+  function fetchVersion(tx) {
+    var sql = 'SELECT sql FROM sqlite_master WHERE tbl_name = ' + META_STORE$1;
+    tx.executeSql(sql, [], function (tx, result) {
+      if (!result.rows.length) {
+        // database hasn't even been created yet (version 0)
+        onGetVersion(tx, 0);
+      } else if (!/db_version/.test(result.rows.item(0).sql)) {
+        // table was created, but without the new db_version column,
+        // so add it.
+        tx.executeSql('ALTER TABLE ' + META_STORE$1 +
+          ' ADD COLUMN db_version INTEGER', [], function () {
+          // before version 2, this column didn't even exist
+          onGetVersion(tx, 1);
+        });
+      } else { // column exists, we can safely get it
+        tx.executeSql('SELECT db_version FROM ' + META_STORE$1,
+          [], function (tx, result) {
+          var dbVersion = result.rows.item(0).db_version;
+          onGetVersion(tx, dbVersion);
+        });
+      }
+    });
+  }
+
+  setup();
+
+  api.type = function () {
+    return 'websql';
+  };
+
+  api._id = toPromise(function (callback) {
+    callback(null, instanceId);
+  });
+
+  api._info = function (callback) {
+    db.readTransaction(function (tx) {
+      countDocs(tx, function (docCount) {
+        var sql = 'SELECT MAX(seq) AS seq FROM ' + BY_SEQ_STORE$1;
+        tx.executeSql(sql, [], function (tx, res) {
+          var updateSeq = res.rows.item(0).seq || 0;
+          callback(null, {
+            doc_count: docCount,
+            update_seq: updateSeq,
+            // for debugging
+            sqlite_plugin: db._sqlitePlugin,
+            websql_encoding: encoding
+          });
+        });
+      });
+    }, websqlError(callback));
+  };
+
+  api._bulkDocs = function (req, reqOpts, callback) {
+    websqlBulkDocs(opts, req, reqOpts, api, db, websqlChanges, callback);
+  };
+
+  api._get = function (id, opts, callback) {
+    var doc;
+    var metadata;
+    var err;
+    var tx = opts.ctx;
+    if (!tx) {
+      return db.readTransaction(function (txn) {
+        api._get(id, jsExtend.extend({ctx: txn}, opts), callback);
+      });
+    }
+
+    function finish() {
+      callback(err, {doc: doc, metadata: metadata, ctx: tx});
+    }
+
+    var sql;
+    var sqlArgs;
+    if (opts.rev) {
+      sql = select(
+        SELECT_DOCS,
+        [DOC_STORE$1, BY_SEQ_STORE$1],
+        DOC_STORE$1 + '.id=' + BY_SEQ_STORE$1 + '.doc_id',
+        [BY_SEQ_STORE$1 + '.doc_id=?', BY_SEQ_STORE$1 + '.rev=?']);
+      sqlArgs = [id, opts.rev];
+    } else {
+      sql = select(
+        SELECT_DOCS,
+        [DOC_STORE$1, BY_SEQ_STORE$1],
+        DOC_STORE_AND_BY_SEQ_JOINER,
+        DOC_STORE$1 + '.id=?');
+      sqlArgs = [id];
+    }
+    tx.executeSql(sql, sqlArgs, function (a, results) {
+      if (!results.rows.length) {
+        err = createError(MISSING_DOC, 'missing');
+        return finish();
+      }
+      var item = results.rows.item(0);
+      metadata = safeJsonParse(item.metadata);
+      if (item.deleted && !opts.rev) {
+        err = createError(MISSING_DOC, 'deleted');
+        return finish();
+      }
+      doc = unstringifyDoc(item.data, metadata.id, item.rev);
+      finish();
+    });
+  };
+
+  function countDocs(tx, callback) {
+
+    if (api._docCount !== -1) {
+      return callback(api._docCount);
+    }
+
+    // count the total rows
+    var sql = select(
+      'COUNT(' + DOC_STORE$1 + '.id) AS \'num\'',
+      [DOC_STORE$1, BY_SEQ_STORE$1],
+      DOC_STORE_AND_BY_SEQ_JOINER,
+      BY_SEQ_STORE$1 + '.deleted=0');
+
+    tx.executeSql(sql, [], function (tx, result) {
+      api._docCount = result.rows.item(0).num;
+      callback(api._docCount);
+    });
+  }
+
+  api._allDocs = function (opts, callback) {
+    var results = [];
+    var totalRows;
+
+    var start = 'startkey' in opts ? opts.startkey : false;
+    var end = 'endkey' in opts ? opts.endkey : false;
+    var key = 'key' in opts ? opts.key : false;
+    var descending = 'descending' in opts ? opts.descending : false;
+    var limit = 'limit' in opts ? opts.limit : -1;
+    var offset = 'skip' in opts ? opts.skip : 0;
+    var inclusiveEnd = opts.inclusive_end !== false;
+
+    var sqlArgs = [];
+    var criteria = [];
+
+    if (key !== false) {
+      criteria.push(DOC_STORE$1 + '.id = ?');
+      sqlArgs.push(key);
+    } else if (start !== false || end !== false) {
+      if (start !== false) {
+        criteria.push(DOC_STORE$1 + '.id ' + (descending ? '<=' : '>=') + ' ?');
+        sqlArgs.push(start);
+      }
+      if (end !== false) {
+        var comparator = descending ? '>' : '<';
+        if (inclusiveEnd) {
+          comparator += '=';
+        }
+        criteria.push(DOC_STORE$1 + '.id ' + comparator + ' ?');
+        sqlArgs.push(end);
+      }
+      if (key !== false) {
+        criteria.push(DOC_STORE$1 + '.id = ?');
+        sqlArgs.push(key);
+      }
+    }
+
+    if (opts.deleted !== 'ok') {
+      // report deleted if keys are specified
+      criteria.push(BY_SEQ_STORE$1 + '.deleted = 0');
+    }
+
+    db.readTransaction(function (tx) {
+
+      // first count up the total rows
+      countDocs(tx, function (count) {
+        totalRows = count;
+
+        if (limit === 0) {
+          return;
+        }
+
+        // then actually fetch the documents
+        var sql = select(
+          SELECT_DOCS,
+          [DOC_STORE$1, BY_SEQ_STORE$1],
+          DOC_STORE_AND_BY_SEQ_JOINER,
+          criteria,
+          DOC_STORE$1 + '.id ' + (descending ? 'DESC' : 'ASC')
+          );
+        sql += ' LIMIT ' + limit + ' OFFSET ' + offset;
+
+        tx.executeSql(sql, sqlArgs, function (tx, result) {
+          for (var i = 0, l = result.rows.length; i < l; i++) {
+            var item = result.rows.item(i);
+            var metadata = safeJsonParse(item.metadata);
+            var id = metadata.id;
+            var data = unstringifyDoc(item.data, id, item.rev);
+            var winningRev = data._rev;
+            var doc = {
+              id: id,
+              key: id,
+              value: {rev: winningRev}
+            };
+            if (opts.include_docs) {
+              doc.doc = data;
+              doc.doc._rev = winningRev;
+              if (opts.conflicts) {
+                doc.doc._conflicts = collectConflicts(metadata);
+              }
+              fetchAttachmentsIfNecessary$1(doc.doc, opts, api, tx);
+            }
+            if (item.deleted) {
+              if (opts.deleted === 'ok') {
+                doc.value.deleted = true;
+                doc.doc = null;
+              } else {
+                continue;
+              }
+            }
+            results.push(doc);
+          }
+        });
+      });
+    }, websqlError(callback), function () {
+      callback(null, {
+        total_rows: totalRows,
+        offset: opts.skip,
+        rows: results
+      });
+    });
+  };
+
+  api._changes = function (opts) {
+    opts = clone(opts);
+
+    if (opts.continuous) {
+      var id = api._name + ':' + uuid();
+      websqlChanges.addListener(api._name, id, api, opts);
+      websqlChanges.notify(api._name);
+      return {
+        cancel: function () {
+          websqlChanges.removeListener(api._name, id);
+        }
+      };
+    }
+
+    var descending = opts.descending;
+
+    // Ignore the `since` parameter when `descending` is true
+    opts.since = opts.since && !descending ? opts.since : 0;
+
+    var limit = 'limit' in opts ? opts.limit : -1;
+    if (limit === 0) {
+      limit = 1; // per CouchDB _changes spec
+    }
+
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+    var results = [];
+    var numResults = 0;
+
+    function fetchChanges() {
+
+      var selectStmt =
+        DOC_STORE$1 + '.json AS metadata, ' +
+        DOC_STORE$1 + '.max_seq AS maxSeq, ' +
+        BY_SEQ_STORE$1 + '.json AS winningDoc, ' +
+        BY_SEQ_STORE$1 + '.rev AS winningRev ';
+
+      var from = DOC_STORE$1 + ' JOIN ' + BY_SEQ_STORE$1;
+
+      var joiner = DOC_STORE$1 + '.id=' + BY_SEQ_STORE$1 + '.doc_id' +
+        ' AND ' + DOC_STORE$1 + '.winningseq=' + BY_SEQ_STORE$1 + '.seq';
+
+      var criteria = ['maxSeq > ?'];
+      var sqlArgs = [opts.since];
+
+      if (opts.doc_ids) {
+        criteria.push(DOC_STORE$1 + '.id IN ' + qMarks(opts.doc_ids.length));
+        sqlArgs = sqlArgs.concat(opts.doc_ids);
+      }
+
+      var orderBy = 'maxSeq ' + (descending ? 'DESC' : 'ASC');
+
+      var sql = select(selectStmt, from, joiner, criteria, orderBy);
+
+      var filter = filterChange(opts);
+      if (!opts.view && !opts.filter) {
+        // we can just limit in the query
+        sql += ' LIMIT ' + limit;
+      }
+
+      var lastSeq = opts.since || 0;
+      db.readTransaction(function (tx) {
+        tx.executeSql(sql, sqlArgs, function (tx, result) {
+          function reportChange(change) {
+            return function () {
+              opts.onChange(change);
+            };
+          }
+          for (var i = 0, l = result.rows.length; i < l; i++) {
+            var item = result.rows.item(i);
+            var metadata = safeJsonParse(item.metadata);
+            lastSeq = item.maxSeq;
+
+            var doc = unstringifyDoc(item.winningDoc, metadata.id,
+              item.winningRev);
+            var change = opts.processChange(doc, metadata, opts);
+            change.seq = item.maxSeq;
+
+            var filtered = filter(change);
+            if (typeof filtered === 'object') {
+              return opts.complete(filtered);
+            }
+
+            if (filtered) {
+              numResults++;
+              if (returnDocs) {
+                results.push(change);
+              }
+              // process the attachment immediately
+              // for the benefit of live listeners
+              if (opts.attachments && opts.include_docs) {
+                fetchAttachmentsIfNecessary$1(doc, opts, api, tx,
+                  reportChange(change));
+              } else {
+                reportChange(change)();
+              }
+            }
+            if (numResults === limit) {
+              break;
+            }
+          }
+        });
+      }, websqlError(opts.complete), function () {
+        if (!opts.continuous) {
+          opts.complete(null, {
+            results: results,
+            last_seq: lastSeq
+          });
+        }
+      });
+    }
+
+    fetchChanges();
+  };
+
+  api._close = function (callback) {
+    //WebSQL databases do not need to be closed
+    callback();
+  };
+
+  api._getAttachment = function (attachment, opts, callback) {
+    var res;
+    var tx = opts.ctx;
+    var digest = attachment.digest;
+    var type = attachment.content_type;
+    var sql = 'SELECT escaped, ' +
+      'CASE WHEN escaped = 1 THEN body ELSE HEX(body) END AS body FROM ' +
+      ATTACH_STORE$1 + ' WHERE digest=?';
+    tx.executeSql(sql, [digest], function (tx, result) {
+      // websql has a bug where \u0000 causes early truncation in strings
+      // and blobs. to work around this, we used to use the hex() function,
+      // but that's not performant. after migration 6, we remove \u0000
+      // and add it back in afterwards
+      var item = result.rows.item(0);
+      var data = item.escaped ? unescapeBlob(item.body) :
+        parseHexString(item.body, encoding);
+      if (opts.binary) {
+        res = binStringToBluffer(data, type);
+      } else {
+        res = btoa$1(data);
+      }
+      callback(null, res);
+    });
+  };
+
+  api._getRevisionTree = function (docId, callback) {
+    db.readTransaction(function (tx) {
+      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE$1 + ' WHERE id = ?';
+      tx.executeSql(sql, [docId], function (tx, result) {
+        if (!result.rows.length) {
+          callback(createError(MISSING_DOC));
+        } else {
+          var data = safeJsonParse(result.rows.item(0).metadata);
+          callback(null, data.rev_tree);
+        }
+      });
+    });
+  };
+
+  api._doCompaction = function (docId, revs, callback) {
+    if (!revs.length) {
+      return callback();
+    }
+    db.transaction(function (tx) {
+
+      // update doc store
+      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE$1 + ' WHERE id = ?';
+      tx.executeSql(sql, [docId], function (tx, result) {
+        var metadata = safeJsonParse(result.rows.item(0).metadata);
+        traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                           revHash, ctx, opts) {
+          var rev = pos + '-' + revHash;
+          if (revs.indexOf(rev) !== -1) {
+            opts.status = 'missing';
+          }
+        });
+
+        var sql = 'UPDATE ' + DOC_STORE$1 + ' SET json = ? WHERE id = ?';
+        tx.executeSql(sql, [safeJsonStringify(metadata), docId]);
+      });
+
+      compactRevs$1(revs, docId, tx);
+    }, websqlError(callback), function () {
+      callback();
+    });
+  };
+
+  api._getLocal = function (id, callback) {
+    db.readTransaction(function (tx) {
+      var sql = 'SELECT json, rev FROM ' + LOCAL_STORE$1 + ' WHERE id=?';
+      tx.executeSql(sql, [id], function (tx, res) {
+        if (res.rows.length) {
+          var item = res.rows.item(0);
+          var doc = unstringifyDoc(item.json, id, item.rev);
+          callback(null, doc);
+        } else {
+          callback(createError(MISSING_DOC));
+        }
+      });
+    });
+  };
+
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+    var newRev;
+    if (!oldRev) {
+      newRev = doc._rev = '0-1';
+    } else {
+      newRev = doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
+    }
+    var json = stringifyDoc(doc);
+
+    var ret;
+    function putLocal(tx) {
+      var sql;
+      var values;
+      if (oldRev) {
+        sql = 'UPDATE ' + LOCAL_STORE$1 + ' SET rev=?, json=? ' +
+          'WHERE id=? AND rev=?';
+        values = [newRev, json, id, oldRev];
+      } else {
+        sql = 'INSERT INTO ' + LOCAL_STORE$1 + ' (id, rev, json) VALUES (?,?,?)';
+        values = [id, newRev, json];
+      }
+      tx.executeSql(sql, values, function (tx, res) {
+        if (res.rowsAffected) {
+          ret = {ok: true, id: id, rev: newRev};
+          if (opts.ctx) { // return immediately
+            callback(null, ret);
+          }
+        } else {
+          callback(createError(REV_CONFLICT));
+        }
+      }, function () {
+        callback(createError(REV_CONFLICT));
+        return false; // ack that we handled the error
+      });
+    }
+
+    if (opts.ctx) {
+      putLocal(opts.ctx);
+    } else {
+      db.transaction(putLocal, websqlError(callback), function () {
+        if (ret) {
+          callback(null, ret);
+        }
+      });
+    }
+  };
+
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var ret;
+
+    function removeLocal(tx) {
+      var sql = 'DELETE FROM ' + LOCAL_STORE$1 + ' WHERE id=? AND rev=?';
+      var params = [doc._id, doc._rev];
+      tx.executeSql(sql, params, function (tx, res) {
+        if (!res.rowsAffected) {
+          return callback(createError(MISSING_DOC));
+        }
+        ret = {ok: true, id: doc._id, rev: '0-0'};
+        if (opts.ctx) { // return immediately
+          callback(null, ret);
+        }
+      });
+    }
+
+    if (opts.ctx) {
+      removeLocal(opts.ctx);
+    } else {
+      db.transaction(removeLocal, websqlError(callback), function () {
+        if (ret) {
+          callback(null, ret);
+        }
+      });
+    }
+  };
+
+  api._destroy = function (opts, callback) {
+    websqlChanges.removeAllListeners(api._name);
+    db.transaction(function (tx) {
+      var stores = [DOC_STORE$1, BY_SEQ_STORE$1, ATTACH_STORE$1, META_STORE$1,
+        LOCAL_STORE$1, ATTACH_AND_SEQ_STORE$1];
+      stores.forEach(function (store) {
+        tx.executeSql('DROP TABLE IF EXISTS ' + store, []);
+      });
+    }, websqlError(callback), function () {
+      if (hasLocalStorage()) {
+        delete window.localStorage['_pouch__websqldb_' + api._name];
+        delete window.localStorage[api._name];
+      }
+      callback(null, {'ok': true});
+    });
+  };
+}
+
+// in the browser, use a prefix. in Node, don't bother having one
+WebSqlPouch.use_prefix = !!(typeof process === 'undefined' || process.browser);
+
+WebSqlPouch.valid = valid;
+
+var adapters = {
+  idb: IdbPouch,
+  websql: WebSqlPouch
+};
+
+PouchDB.ajax = ajax;
+PouchDB.utils = utils;
+PouchDB.Errors = allErrors;
+PouchDB.replicate = replication.replicate;
+PouchDB.sync = sync;
+PouchDB.version = '5.3.2'; // will be automatically supplied by build.sh
+PouchDB.adapter('http', HttpPouch);
+PouchDB.adapter('https', HttpPouch);
+
+PouchDB.plugin(mapreduce);
+
+Object.keys(adapters).forEach(function (adapterName) {
+  PouchDB.adapter(adapterName, adapters[adapterName], true);
+});
+
+module.exports = PouchDB;
+}).call(this,_dereq_(13),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1,"10":10,"12":12,"13":13,"14":14,"15":15,"16":16,"2":2,"4":4,"6":6,"7":7,"8":8}]},{},[17])(17)
+});
\ No newline at end of file
diff --git a/dist/pouchdb.localstorage.js b/dist/pouchdb.localstorage.js
new file mode 100644
index 0000000..d9b12ea
--- /dev/null
+++ b/dist/pouchdb.localstorage.js
@@ -0,0 +1,17862 @@
+// PouchDB localStorage plugin 5.3.2
+// Based on localstorage-down: https://github.com/No9/localstorage-down
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var levelup = _interopDefault(_dereq_(46));
+var sublevel = _interopDefault(_dereq_(76));
+var through2 = _dereq_(94);
+var events = _dereq_(23);
+var inherits = _interopDefault(_dereq_(29));
+var pouchdbCollections = _dereq_(57);
+var getArguments = _interopDefault(_dereq_(5));
+var vuvuzela = _interopDefault(_dereq_(99));
+var lie = _interopDefault(_dereq_(50));
+var Md5 = _interopDefault(_dereq_(61));
+var Deque = _interopDefault(_dereq_(19));
+var jsExtend = _dereq_(32);
+var downAdapter = _interopDefault(_dereq_(51));
+
+function isBinaryObject(object) {
+  return object instanceof ArrayBuffer ||
+    (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+  if (typeof buff.slice === 'function') {
+    return buff.slice(0);
+  }
+  // IE10-11 slice() polyfill
+  var target = new ArrayBuffer(buff.byteLength);
+  var targetArray = new Uint8Array(target);
+  var sourceArray = new Uint8Array(buff);
+  targetArray.set(sourceArray);
+  return target;
+}
+
+function cloneBinaryObject(object) {
+  if (object instanceof ArrayBuffer) {
+    return cloneArrayBuffer(object);
+  }
+  var size = object.size;
+  var type = object.type;
+  // Blob
+  if (typeof object.slice === 'function') {
+    return object.slice(0, size, type);
+  }
+  // PhantomJS slice() replacement
+  return object.webkitSlice(0, size, type);
+}
+
+function clone(object) {
+  var newObject;
+  var i;
+  var len;
+
+  if (!object || typeof object !== 'object') {
+    return object;
+  }
+
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone(object[i]);
+    }
+    return newObject;
+  }
+
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
+
+  if (isBinaryObject(object)) {
+    return cloneBinaryObject(object);
+  }
+
+  newObject = {};
+  for (i in object) {
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
+      }
+    }
+  }
+  return newObject;
+}
+
+function isChromeApp() {
+  return (typeof chrome !== "undefined" &&
+    typeof chrome.storage !== "undefined" &&
+    typeof chrome.storage.local !== "undefined");
+}
+
+var hasLocal;
+
+if (isChromeApp()) {
+  hasLocal = false;
+} else {
+  try {
+    localStorage.setItem('_pouch_check_localstorage', 1);
+    hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+  } catch (e) {
+    hasLocal = false;
+  }
+}
+
+function hasLocalStorage() {
+  return hasLocal;
+}
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
+
+inherits(Changes, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (isChromeApp()) {
+    chrome.storage.onChanged.addListener(function (e) {
+      // make sure it's event addressed to us
+      if (e.db_name != null) {
+        //object only has oldValue, newValue members
+        self.emit(e.dbName.newValue);
+      }
+    });
+  } else if (hasLocalStorage()) {
+    if (typeof addEventListener !== 'undefined') {
+      addEventListener("storage", function (e) {
+        self.emit(e.key);
+      });
+    } else { // old IE
+      window.attachEvent("storage", function (e) {
+        self.emit(e.key);
+      });
+    }
+  }
+}
+
+function Changes() {
+  events.EventEmitter.call(this);
+  this._listeners = {};
+
+  attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
+  }
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
+    }
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
+    }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary'
+    ]);
+
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
+    }
+
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        setTimeout(function (){
+          eventFunction();
+        },0);
+      }
+      inprogress = false;
+    }).on('error', onError);
+  }
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
+
+Changes.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
+    return;
+  }
+  events.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+};
+
+
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (isChromeApp()) {
+    chrome.storage.local.set({dbName: dbName});
+  } else if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
+
+Changes.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
+
+// BEGIN Math.uuid.js
+
+/*!
+Math.uuid.js (v1.4)
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+*/
+
+/*
+ * Generate a random uuid.
+ *
+ * USAGE: Math.uuid(length, radix)
+ *   length - the desired number of characters
+ *   radix  - the number of allowable values for each character.
+ *
+ * EXAMPLES:
+ *   // No arguments  - returns RFC4122, version 4 ID
+ *   >>> Math.uuid()
+ *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ *   // One argument - returns ID of the specified length
+ *   >>> Math.uuid(15)     // 15 character ID (default base=62)
+ *   "VcydxgltxrVZSTV"
+ *
+ *   // Two arguments - returns ID of the specified length, and radix. 
+ *   // (Radix must be <= 62)
+ *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
+ *   "01001010"
+ *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
+ *   "47473046"
+ *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
+ *   "098F4D35"
+ */
+var chars = (
+  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
+  'abcdefghijklmnopqrstuvwxyz'
+).split('');
+function getValue(radix) {
+  return 0 | Math.random() * radix;
+}
+function uuid(len, radix) {
+  radix = radix || chars.length;
+  var out = '';
+  var i = -1;
+
+  if (len) {
+    // Compact form
+    while (++i < len) {
+      out += chars[getValue(radix)];
+    }
+    return out;
+  }
+    // rfc4122, version 4 form
+    // Fill in random data.  At i==19 set the high bits of clock sequence as
+    // per rfc4122, sec. 4.1.5
+  while (++i < 36) {
+    switch (i) {
+      case 8:
+      case 13:
+      case 18:
+      case 23:
+        out += '-';
+        break;
+      case 19:
+        out += chars[(getValue(16) & 0x3) | 0x8];
+        break;
+      default:
+        out += chars[getValue(16)];
+    }
+  }
+
+  return out;
+}
+
+inherits(PouchError, Error);
+
+function PouchError(opts) {
+  Error.call(this, opts.reason);
+  this.status = opts.status;
+  this.name = opts.error;
+  this.message = opts.reason;
+  this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
+
+var UNAUTHORIZED = new PouchError({
+  status: 401,
+  error: 'unauthorized',
+  reason: "Name or password is incorrect."
+});
+
+var MISSING_BULK_DOCS = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: "Missing JSON list of 'docs'"
+});
+
+var MISSING_DOC = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'missing'
+});
+
+var REV_CONFLICT = new PouchError({
+  status: 409,
+  error: 'conflict',
+  reason: 'Document update conflict'
+});
+
+var INVALID_ID = new PouchError({
+  status: 400,
+  error: 'invalid_id',
+  reason: '_id field must contain a string'
+});
+
+var MISSING_ID = new PouchError({
+  status: 412,
+  error: 'missing_id',
+  reason: '_id is required for puts'
+});
+
+var RESERVED_ID = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Only reserved document ids may start with underscore.'
+});
+
+var NOT_OPEN = new PouchError({
+  status: 412,
+  error: 'precondition_failed',
+  reason: 'Database not open'
+});
+
+var UNKNOWN_ERROR = new PouchError({
+  status: 500,
+  error: 'unknown_error',
+  reason: 'Database encountered an unknown error'
+});
+
+var BAD_ARG = new PouchError({
+  status: 500,
+  error: 'badarg',
+  reason: 'Some query argument is invalid'
+});
+
+var INVALID_REQUEST = new PouchError({
+  status: 400,
+  error: 'invalid_request',
+  reason: 'Request was invalid'
+});
+
+var QUERY_PARSE_ERROR = new PouchError({
+  status: 400,
+  error: 'query_parse_error',
+  reason: 'Some query parameter is invalid'
+});
+
+var DOC_VALIDATION = new PouchError({
+  status: 500,
+  error: 'doc_validation',
+  reason: 'Bad special document member'
+});
+
+var BAD_REQUEST = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Something wrong with the request'
+});
+
+var NOT_AN_OBJECT = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Document must be a JSON object'
+});
+
+var DB_MISSING = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'Database not found'
+});
+
+var IDB_ERROR = new PouchError({
+  status: 500,
+  error: 'indexed_db_went_bad',
+  reason: 'unknown'
+});
+
+var WSQ_ERROR = new PouchError({
+  status: 500,
+  error: 'web_sql_went_bad',
+  reason: 'unknown'
+});
+
+var LDB_ERROR = new PouchError({
+  status: 500,
+  error: 'levelDB_went_went_bad',
+  reason: 'unknown'
+});
+
+var FORBIDDEN = new PouchError({
+  status: 403,
+  error: 'forbidden',
+  reason: 'Forbidden by design doc validate_doc_update function'
+});
+
+var INVALID_REV = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Invalid rev format'
+});
+
+var FILE_EXISTS = new PouchError({
+  status: 412,
+  error: 'file_exists',
+  reason: 'The database could not be created, the file already exists.'
+});
+
+var MISSING_STUB = new PouchError({
+  status: 412,
+  error: 'missing_stub'
+});
+
+var INVALID_URL = new PouchError({
+  status: 413,
+  error: 'invalid_url',
+  reason: 'Provided URL is invalid'
+});
+
+var allErrors = {
+  UNAUTHORIZED: UNAUTHORIZED,
+  MISSING_BULK_DOCS: MISSING_BULK_DOCS,
+  MISSING_DOC: MISSING_DOC,
+  REV_CONFLICT: REV_CONFLICT,
+  INVALID_ID: INVALID_ID,
+  MISSING_ID: MISSING_ID,
+  RESERVED_ID: RESERVED_ID,
+  NOT_OPEN: NOT_OPEN,
+  UNKNOWN_ERROR: UNKNOWN_ERROR,
+  BAD_ARG: BAD_ARG,
+  INVALID_REQUEST: INVALID_REQUEST,
+  QUERY_PARSE_ERROR: QUERY_PARSE_ERROR,
+  DOC_VALIDATION: DOC_VALIDATION,
+  BAD_REQUEST: BAD_REQUEST,
+  NOT_AN_OBJECT: NOT_AN_OBJECT,
+  DB_MISSING: DB_MISSING,
+  WSQ_ERROR: WSQ_ERROR,
+  LDB_ERROR: LDB_ERROR,
+  FORBIDDEN: FORBIDDEN,
+  INVALID_REV: INVALID_REV,
+  FILE_EXISTS: FILE_EXISTS,
+  MISSING_STUB: MISSING_STUB,
+  IDB_ERROR: IDB_ERROR,
+  INVALID_URL: INVALID_URL
+};
+
+function createError(error, reason, name) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
+    }
+    /* jshint ignore:end */
+    if (name !== undefined) {
+      this.name = name;
+    }
+    if (reason !== undefined) {
+      this.reason = reason;
+    }
+  }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
+
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return createError(BAD_REQUEST, msg);
+  }
+}
+
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
+
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
+    }
+
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
+
+    if (filterReturn) {
+      return false;
+    }
+
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
+  };
+}
+
+function slowJsonParse(str) {
+  try {
+    return JSON.parse(str);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.parse(str);
+  }
+}
+
+function safeJsonParse(str) {
+  // try/catch is deoptimized in V8, leading to slower
+  // times than we'd like to have. Most documents are _not_
+  // huge, and do not require a slower code path just to parse them.
+  // We can be pretty sure that a document under 50000 characters
+  // will not be so deeply nested as to throw a stack overflow error
+  // (depends on the engine and available memory, though, so this is
+  // just a hunch). 50000 was chosen based on the average length
+  // of this string in our test suite, to try to find a number that covers
+  // most of our test cases (26 over this size, 26378 under it).
+  if (str.length < 50000) {
+    return JSON.parse(str);
+  }
+  return slowJsonParse(str);
+}
+
+function safeJsonStringify(json) {
+  try {
+    return JSON.stringify(json);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.stringify(json);
+  }
+}
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+  var winningId;
+  var winningPos;
+  var winningDeleted;
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var tree = node.ids;
+    var branches = tree[2];
+    var pos = node.pos;
+    if (branches.length) { // non-leaf
+      for (var i = 0, len = branches.length; i < len; i++) {
+        toVisit.push({pos: pos + 1, ids: branches[i]});
+      }
+      continue;
+    }
+    var deleted = !!tree[1].deleted;
+    var id = tree[0];
+    // sort by deleted, then pos, then id
+    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+        winningPos !== pos ? winningPos < pos : winningId < id)) {
+      winningId = id;
+      winningPos = pos;
+      winningDeleted = deleted;
+    }
+  }
+
+  return winningPos + '-' + winningId;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+  var toVisit = revs.slice();
+
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var branches = tree[2];
+    var newCtx =
+      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+    }
+  }
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+  var revs = [];
+  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                               revHash, ctx, opts) {
+    if (opts.status === 'available' && !isLeaf) {
+      revs.push(pos + '-' + revHash);
+      opts.status = 'missing';
+    }
+  });
+  return revs;
+}
+
+function sortByPos(a, b) {
+  return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+  var leaves = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+    if (isLeaf) {
+      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+    }
+  });
+  leaves.sort(sortByPos).reverse();
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    delete leaves[i].pos;
+  }
+  return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+  var win = winningRev(metadata);
+  var leaves = collectLeaves(metadata.rev_tree);
+  var conflicts = [];
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    var leaf = leaves[i];
+    if (leaf.rev !== win && !leaf.opts.deleted) {
+      conflicts.push(leaf.rev);
+    }
+  }
+  return conflicts;
+}
+
+function getTrees(node) {
+  return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+//  - metadata: the metadata object from the doc store
+//  - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+  if (!rev) {
+    rev = winningRev(metadata);
+  }
+  var id = rev.substring(rev.indexOf('-') + 1);
+  var toVisit = metadata.rev_tree.map(getTrees);
+
+  var tree;
+  while ((tree = toVisit.pop())) {
+    if (tree[0] === id) {
+      return !!tree[1].deleted;
+    }
+    toVisit = toVisit.concat(tree[2]);
+  }
+}
+
+function isLocalId(id) {
+  return (/^_local/).test(id);
+}
+
+function toObject(array) {
+  return array.reduce(function (obj, item) {
+    obj[item] = true;
+    return obj;
+  }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+  '_id',
+  '_rev',
+  '_attachments',
+  '_deleted',
+  '_revisions',
+  '_revs_info',
+  '_conflicts',
+  '_deleted_conflicts',
+  '_local_seq',
+  '_rev_tree',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats',
+  // Specific to Couchbase Sync Gateway
+  '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+  '_attachments',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats'
+]);
+
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = createError(MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = createError(INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = createError(RESERVED_ID);
+  }
+  if (err) {
+    throw err;
+  }
+}
+
+function parseRevisionInfo(rev) {
+  if (!/^\d+\-./.test(rev)) {
+    return createError(INVALID_REV);
+  }
+  var idx = rev.indexOf('-');
+  var left = rev.substring(0, idx);
+  var right = rev.substring(idx + 1);
+  return {
+    prefix: parseInt(left, 10),
+    id: right
+  };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+  var pos = revisions.start - revisions.ids.length + 1;
+
+  var revisionIds = revisions.ids;
+  var ids = [revisionIds[0], opts, []];
+
+  for (var i = 1, len = revisionIds.length; i < len; i++) {
+    ids = [revisionIds[i], {status: 'missing'}, [ids]];
+  }
+
+  return [{
+    pos: pos,
+    ids: ids
+  }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits) {
+
+  var nRevNum;
+  var newRevId;
+  var revInfo;
+  var opts = {status: 'available'};
+  if (doc._deleted) {
+    opts.deleted = true;
+  }
+
+  if (newEdits) {
+    if (!doc._id) {
+      doc._id = uuid();
+    }
+    newRevId = uuid(32, 16).toLowerCase();
+    if (doc._rev) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      doc._rev_tree = [{
+        pos: revInfo.prefix,
+        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+      }];
+      nRevNum = revInfo.prefix + 1;
+    } else {
+      doc._rev_tree = [{
+        pos: 1,
+        ids : [newRevId, opts, []]
+      }];
+      nRevNum = 1;
+    }
+  } else {
+    if (doc._revisions) {
+      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+      nRevNum = doc._revisions.start;
+      newRevId = doc._revisions.ids[0];
+    }
+    if (!doc._rev_tree) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      nRevNum = revInfo.prefix;
+      newRevId = revInfo.id;
+      doc._rev_tree = [{
+        pos: nRevNum,
+        ids: [newRevId, opts, []]
+      }];
+    }
+  }
+
+  invalidIdError(doc._id);
+
+  doc._rev = nRevNum + '-' + newRevId;
+
+  var result = {metadata : {}, data : {}};
+  for (var key in doc) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(doc, key)) {
+      var specialKey = key[0] === '_';
+      if (specialKey && !reservedWords[key]) {
+        var error = createError(DOC_VALIDATION, key);
+        error.message = DOC_VALIDATION.message + ': ' + key;
+        throw error;
+      } else if (specialKey && !dataWords[key]) {
+        result.metadata[key.slice(1)] = doc[key];
+      } else {
+        result.data[key] = doc[key];
+      }
+    }
+  }
+  return result;
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+  var paths = [];
+  var toVisit = revs.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
+
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, opts: opts});
+    if (isLeaf) {
+      paths.push({pos: (pos + 1 - history.length), ids: history});
+    }
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+    }
+  }
+  return paths.reverse();
+}
+
+function sortByPos$1(a, b) {
+  return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (comparator(arr[mid], item) < 0) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+  var idx = binarySearch(arr, item, comparator);
+  arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+  var root;
+  var leaf;
+  for (var i = numStemmed, len = path.length; i < len; i++) {
+    var node = path[i];
+    var currentLeaf = [node.id, node.opts, []];
+    if (leaf) {
+      leaf[2].push(currentLeaf);
+      leaf = currentLeaf;
+    } else {
+      root = leaf = currentLeaf;
+    }
+  }
+  return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+  return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+  var queue = [{tree1: in_tree1, tree2: in_tree2}];
+  var conflicts = false;
+  while (queue.length > 0) {
+    var item = queue.pop();
+    var tree1 = item.tree1;
+    var tree2 = item.tree2;
+
+    if (tree1[1].status || tree2[1].status) {
+      tree1[1].status =
+        (tree1[1].status ===  'available' ||
+        tree2[1].status === 'available') ? 'available' : 'missing';
+    }
+
+    for (var i = 0; i < tree2[2].length; i++) {
+      if (!tree1[2][0]) {
+        conflicts = 'new_leaf';
+        tree1[2][0] = tree2[2][i];
+        continue;
+      }
+
+      var merged = false;
+      for (var j = 0; j < tree1[2].length; j++) {
+        if (tree1[2][j][0] === tree2[2][i][0]) {
+          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+          merged = true;
+        }
+      }
+      if (!merged) {
+        conflicts = 'new_branch';
+        insertSorted(tree1[2], tree2[2][i], compareTree);
+      }
+    }
+  }
+  return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+  var restree = [];
+  var conflicts = false;
+  var merged = false;
+  var res;
+
+  if (!tree.length) {
+    return {tree: [path], conflicts: 'new_leaf'};
+  }
+
+  for (var i = 0, len = tree.length; i < len; i++) {
+    var branch = tree[i];
+    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+      // Paths start at the same position and have the same root, so they need
+      // merged
+      res = mergeTree(branch.ids, path.ids);
+      restree.push({pos: branch.pos, ids: res.tree});
+      conflicts = conflicts || res.conflicts;
+      merged = true;
+    } else if (dontExpand !== true) {
+      // The paths start at a different position, take the earliest path and
+      // traverse up until it as at the same point from root as the path we
+      // want to merge.  If the keys match we return the longer path with the
+      // other merged After stemming we dont want to expand the trees
+
+      var t1 = branch.pos < path.pos ? branch : path;
+      var t2 = branch.pos < path.pos ? path : branch;
+      var diff = t2.pos - t1.pos;
+
+      var candidateParents = [];
+
+      var trees = [];
+      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+      while (trees.length > 0) {
+        var item = trees.pop();
+        if (item.diff === 0) {
+          if (item.ids[0] === t2.ids[0]) {
+            candidateParents.push(item);
+          }
+          continue;
+        }
+        var elements = item.ids[2];
+        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+          trees.push({
+            ids: elements[j],
+            diff: item.diff - 1,
+            parent: item.ids,
+            parentIdx: j
+          });
+        }
+      }
+
+      var el = candidateParents[0];
+
+      if (!el) {
+        restree.push(branch);
+      } else {
+        res = mergeTree(el.ids, t2.ids);
+        el.parent[2][el.parentIdx] = res.tree;
+        restree.push({pos: t1.pos, ids: t1.ids});
+        conflicts = conflicts || res.conflicts;
+        merged = true;
+      }
+    } else {
+      restree.push(branch);
+    }
+  }
+
+  // We didnt find
+  if (!merged) {
+    restree.push(path);
+  }
+
+  restree.sort(sortByPos$1);
+
+  return {
+    tree: restree,
+    conflicts: conflicts || 'internal_node'
+  };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+  // First we break out the tree into a complete list of root to leaf paths
+  var paths = rootToLeaf(tree);
+  var maybeStem = {};
+
+  var result;
+  for (var i = 0, len = paths.length; i < len; i++) {
+    // Then for each path, we cut off the start of the path based on the
+    // `depth` to stem to, and generate a new set of flat trees
+    var path = paths[i];
+    var stemmed = path.ids;
+    var numStemmed = Math.max(0, stemmed.length - depth);
+    var stemmedNode = {
+      pos: path.pos + numStemmed,
+      ids: pathToTree(stemmed, numStemmed)
+    };
+
+    for (var s = 0; s < numStemmed; s++) {
+      var rev = (path.pos + s) + '-' + stemmed[s].id;
+      maybeStem[rev] = true;
+    }
+
+    // Then we remerge all those flat trees together, ensuring that we dont
+    // connect trees that would go beyond the depth limit
+    if (result) {
+      result = doMerge(result, stemmedNode, true).tree;
+    } else {
+      result = [stemmedNode];
+    }
+  }
+
+  traverseRevTree(result, function (isLeaf, pos, revHash) {
+    // some revisions may have been removed in a branch but not in another
+    delete maybeStem[pos + '-' + revHash];
+  });
+
+  return {
+    tree: result,
+    revs: Object.keys(maybeStem)
+  };
+}
+
+function merge(tree, path, depth) {
+  var newTree = doMerge(tree, path);
+  var stemmed = stem(newTree.tree, depth);
+  return {
+    tree: stemmed.tree,
+    stemmedRevs: stemmed.revs,
+    conflicts: newTree.conflicts
+  };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+  var toVisit = revs.slice();
+  var splitRev = rev.split('-');
+  var targetPos = parseInt(splitRev[0], 10);
+  var targetId = splitRev[1];
+
+  var node;
+  while ((node = toVisit.pop())) {
+    if (node.pos === targetPos && node.ids[0] === targetId) {
+      return true;
+    }
+    var branches = node.ids[2];
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: node.pos + 1, ids: branches[i]});
+    }
+  }
+  return false;
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+                   i, cb, writeDoc, newEdits) {
+
+  if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
+    results[i] = docInfo;
+    return cb();
+  }
+
+  // sometimes this is pre-calculated. historically not always
+  var previousWinningRev = prev.winningRev || winningRev(prev);
+  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+    isDeleted(prev, previousWinningRev);
+  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+    isDeleted(docInfo.metadata);
+  var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+  if (previouslyDeleted && !deleted && newEdits && isRoot) {
+    var newDoc = docInfo.data;
+    newDoc._rev = previousWinningRev;
+    newDoc._id = docInfo.metadata.id;
+    docInfo = parseDoc(newDoc, newEdits);
+  }
+
+  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+  var inConflict = newEdits && (((previouslyDeleted && deleted) ||
+    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+  if (inConflict) {
+    var err = createError(REV_CONFLICT);
+    results[i] = err;
+    return cb();
+  }
+
+  var newRev = docInfo.metadata.rev;
+  docInfo.metadata.rev_tree = merged.tree;
+  docInfo.stemmedRevs = merged.stemmedRevs || [];
+  /* istanbul ignore else */
+  if (prev.rev_map) {
+    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+  }
+
+  // recalculate
+  var winningRev$$ = winningRev(docInfo.metadata);
+  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$);
+
+  // calculate the total number of documents that were added/removed,
+  // from the perspective of total_rows/doc_count
+  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+  var newRevIsDeleted;
+  if (newRev === winningRev$$) {
+    // if the new rev is the same as the winning rev, we can reuse that value
+    newRevIsDeleted = winningRevIsDeleted;
+  } else {
+    // if they're not the same, then we need to recalculate
+    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+  }
+
+  writeDoc(docInfo, winningRev$$, winningRevIsDeleted, newRevIsDeleted,
+    true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+                     writeDoc, opts, overallCallback) {
+
+  // Default to 1000 locally
+  revLimit = revLimit || 1000;
+
+  function insertDoc(docInfo, resultsIdx, callback) {
+    // Cant insert new deleted documents
+    var winningRev$$ = winningRev(docInfo.metadata);
+    var deleted = isDeleted(docInfo.metadata, winningRev$$);
+    if ('was_delete' in opts && deleted) {
+      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+      return callback();
+    }
+
+    // 4712 - detect whether a new document was inserted with a _rev
+    var inConflict = newEdits && rootIsMissing(docInfo);
+
+    if (inConflict) {
+      var err = createError(REV_CONFLICT);
+      results[resultsIdx] = err;
+      return callback();
+    }
+
+    var delta = deleted ? 0 : 1;
+
+    writeDoc(docInfo, winningRev$$, deleted, deleted, false,
+      delta, resultsIdx, callback);
+  }
+
+  var newEdits = opts.new_edits;
+  var idsToDocs = new pouchdbCollections.Map();
+
+  var docsDone = 0;
+  var docsToDo = docInfos.length;
+
+  function checkAllDocsDone() {
+    if (++docsDone === docsToDo && overallCallback) {
+      overallCallback();
+    }
+  }
+
+  docInfos.forEach(function (currentDoc, resultsIdx) {
+
+    if (currentDoc._id && isLocalId(currentDoc._id)) {
+      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+      api[fun](currentDoc, {ctx: tx}, function (err, res) {
+        results[resultsIdx] = err || res;
+        checkAllDocsDone();
+      });
+      return;
+    }
+
+    var id = currentDoc.metadata.id;
+    if (idsToDocs.has(id)) {
+      docsToDo--; // duplicate
+      idsToDocs.get(id).push([currentDoc, resultsIdx]);
+    } else {
+      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+    }
+  });
+
+  // in the case of new_edits, the user can provide multiple docs
+  // with the same id. these need to be processed sequentially
+  idsToDocs.forEach(function (docs, id) {
+    var numDone = 0;
+
+    function docWritten() {
+      if (++numDone < docs.length) {
+        nextDoc();
+      } else {
+        checkAllDocsDone();
+      }
+    }
+    function nextDoc() {
+      var value = docs[numDone];
+      var currentDoc = value[0];
+      var resultsIdx = value[1];
+
+      if (fetchedDocs.has(id)) {
+        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+          resultsIdx, docWritten, writeDoc, newEdits);
+      } else {
+        // Ensure stemming applies to new writes as well
+        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+        currentDoc.metadata.rev_tree = merged.tree;
+        currentDoc.stemmedRevs = merged.stemmedRevs || [];
+        insertDoc(currentDoc, resultsIdx, docWritten);
+      }
+    }
+    nextDoc();
+  });
+}
+
+/* istanbul ignore next */
+var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+
+function once(fun) {
+  var called = false;
+  return getArguments(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
+    }
+  });
+}
+
+function toPromise(func) {
+  //create the function we will be returning
+  return getArguments(function (args) {
+    // Clone arguments
+    args = clone(args);
+    var self = this;
+    var tempCB =
+      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    // if the last argument is a function, assume its a callback
+    var usedCB;
+    if (tempCB) {
+      // if it was a callback, create a new callback which calls it,
+      // but do so async so we don't trap any errors
+      usedCB = function (err, resp) {
+        process.nextTick(function () {
+          tempCB(err, resp);
+        });
+      };
+    }
+    var promise = new PouchPromise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
+      }
+    });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
+    }
+    return promise;
+  });
+}
+
+var thisAtob = function (str) {
+  return atob(str);
+};
+
+var thisBtoa = function (str) {
+  return btoa(str);
+};
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+  return thisBtoa(raw);
+}
+
+function appendBuffer(buffer, data, start, end) {
+  if (start > 0 || end < data.byteLength) {
+    // only create a subarray if we really need to
+    data = new Uint8Array(data, start,
+      Math.min(end, data.byteLength) - start);
+  }
+  buffer.append(data);
+}
+
+function appendString(buffer, data, start, end) {
+  if (start > 0 || end < data.length) {
+    // only create a substring if we really need to
+    data = data.substring(start, end);
+  }
+  buffer.appendBinary(data);
+}
+
+var md5 = toPromise(function (data, callback) {
+  var inputIsString = typeof data === 'string';
+  var len = inputIsString ? data.length : data.byteLength;
+  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+  var chunks = Math.ceil(len / chunkSize);
+  var currentChunk = 0;
+  var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+  var append = inputIsString ? appendString : appendBuffer;
+
+  function loadNextChunk() {
+    var start = currentChunk * chunkSize;
+    var end = start + chunkSize;
+    currentChunk++;
+    if (currentChunk < chunks) {
+      append(buffer, data, start, end);
+      setImmediateShim(loadNextChunk);
+    } else {
+      append(buffer, data, start, end);
+      var raw = buffer.end(true);
+      var base64 = rawToBase64(raw);
+      callback(null, base64);
+      buffer.destroy();
+    }
+  }
+  loadNextChunk();
+});
+
+// in the browser, LevelAlt doesn't need the
+// pre-2.2.0 LevelDB-specific migrations
+var toSublevel = function (name, db, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var localAndMetaStores = function (db, stores, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var migrate = {
+  toSublevel: toSublevel,
+  localAndMetaStores: localAndMetaStores
+};
+
+// shim for Function.prototype.name,
+// for browsers that don't support it like IE
+
+/* istanbul ignore next */
+function f() {}
+
+var hasName = f.name;
+var res;
+
+// We dont run coverage in IE
+/* istanbul ignore else */
+if (hasName) {
+  res = function (fun) {
+    return fun.name;
+  };
+} else {
+  res = function (fun) {
+    return fun.toString().match(/^\s*function\s*(\S*)\s*\(/)[1];
+  };
+}
+
+var functionName = res;
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+  parts = parts || [];
+  properties = properties || {};
+  try {
+    return new Blob(parts, properties);
+  } catch (e) {
+    if (e.name !== "TypeError") {
+      throw e;
+    }
+    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+                  WebKitBlobBuilder;
+    var builder = new Builder();
+    for (var i = 0; i < parts.length; i += 1) {
+      builder.append(parts[i]);
+    }
+    return builder.getBlob(properties.type);
+  }
+}
+
+function readAsBlobOrBuffer(storedObject, type) {
+  // In the browser, we've stored a binary string. This now comes back as a
+  // browserified Node-style Buffer, but we want a Blob instead.
+  return createBlob([storedObject.toArrayBuffer()], {type: type});
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
+  }
+  return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  if (typeof FileReader === 'undefined') {
+    // fix for Firefox in a web worker
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+    return callback(arrayBufferToBinaryString(
+      new FileReaderSync().readAsArrayBuffer(blob)));
+  }
+
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
+    }
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
+  }
+}
+
+// In the browser, we store a binary string
+function prepareAttachmentForStorage(attData, cb) {
+  readAsBinaryString(attData, cb);
+}
+
+function createEmptyBlobOrBuffer(type) {
+  return createBlob([''], {type: type});
+}
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
+  }
+  return buf;
+}
+
+function binStringToBluffer(binString, type) {
+  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+function getCacheFor(transaction, store) {
+  var prefix = store.prefix()[0];
+  var cache = transaction._cache;
+  var subCache = cache.get(prefix);
+  if (!subCache) {
+    subCache = new pouchdbCollections.Map();
+    cache.set(prefix, subCache);
+  }
+  return subCache;
+}
+
+function LevelTransaction() {
+  this._batch = [];
+  this._cache = new pouchdbCollections.Map();
+}
+
+LevelTransaction.prototype.get = function (store, key, callback) {
+  var cache = getCacheFor(this, store);
+  var exists = cache.get(key);
+  if (exists) {
+    return process.nextTick(function () {
+      callback(null, exists);
+    });
+  } else if (exists === null) { // deleted marker
+    /* istanbul ignore next */
+    return process.nextTick(function () {
+      callback({name: 'NotFoundError'});
+    });
+  }
+  store.get(key, function (err, res) {
+    if (err) {
+      /* istanbul ignore else */
+      if (err.name === 'NotFoundError') {
+        cache.set(key, null);
+      }
+      return callback(err);
+    }
+    cache.set(key, res);
+    callback(null, res);
+  });
+};
+
+LevelTransaction.prototype.batch = function (batch) {
+  for (var i = 0, len = batch.length; i < len; i++) {
+    var operation = batch[i];
+
+    var cache = getCacheFor(this, operation.prefix);
+
+    if (operation.type === 'put') {
+      cache.set(operation.key, operation.value);
+    } else {
+      cache.set(operation.key, null);
+    }
+  }
+  this._batch = this._batch.concat(batch);
+};
+
+LevelTransaction.prototype.execute = function (db, callback) {
+
+  var keys = new pouchdbCollections.Set();
+  var uniqBatches = [];
+
+  // remove duplicates; last one wins
+  for (var i = this._batch.length - 1; i >= 0; i--) {
+    var operation = this._batch[i];
+    var lookupKey = operation.prefix.prefix()[0] + '\xff' + operation.key;
+    if (keys.has(lookupKey)) {
+      continue;
+    }
+    keys.add(lookupKey);
+    uniqBatches.push(operation);
+  }
+
+  db.batch(uniqBatches, callback);
+};
+
+var DOC_STORE = 'document-store';
+var BY_SEQ_STORE = 'by-sequence';
+var ATTACHMENT_STORE = 'attach-store';
+var BINARY_STORE = 'attach-binary-store';
+var LOCAL_STORE = 'local-store';
+var META_STORE = 'meta-store';
+
+// leveldb barks if we try to open a db multiple times
+// so we cache opened connections here for initstore()
+var dbStores = new pouchdbCollections.Map();
+
+// store the value of update_seq in the by-sequence store the key name will
+// never conflict, since the keys in the by-sequence store are integers
+var UPDATE_SEQ_KEY = '_local_last_update_seq';
+var DOC_COUNT_KEY = '_local_doc_count';
+var UUID_KEY = '_local_uuid';
+
+var MD5_PREFIX = 'md5-';
+
+var safeJsonEncoding = {
+  encode: safeJsonStringify,
+  decode: safeJsonParse,
+  buffer: false,
+  type: 'cheap-json'
+};
+
+var levelChanges = new Changes();
+
+// require leveldown. provide verbose output on error as it is the default
+// nodejs adapter, which we do not provide for the user
+/* istanbul ignore next */
+var requireLeveldown = function () {
+  try {
+    return _dereq_(7);
+  } catch (err) {
+    /* eslint no-ex-assign: 0*/
+    err = err || 'leveldown import error';
+    if (err.code === 'MODULE_NOT_FOUND') {
+      // handle leveldown not installed case
+      return new Error([
+        'the \'leveldown\' package is not available. install it, or,',
+        'specify another storage backend using the \'db\' option'
+      ].join(' '));
+    } else if (err.message && err.message.match('Module version mismatch')) {
+      // handle common user enviornment error
+      return new Error([
+        err.message,
+        'This generally implies that leveldown was built with a different',
+        'version of node than that which is running now.  You may try',
+        'fully removing and reinstalling PouchDB or leveldown to resolve.'
+      ].join(' '));
+    }
+    // handle general internal nodejs require error
+    return new Error(err.toString() + ': unable to import leveldown');
+  }
+};
+
+// winningRev and deleted are performance-killers, but
+// in newer versions of PouchDB, they are cached on the metadata
+function getWinningRev(metadata) {
+  return 'winningRev' in metadata ?
+    metadata.winningRev : winningRev(metadata);
+}
+
+function getIsDeleted(metadata, winningRev) {
+  return 'deleted' in metadata ?
+    metadata.deleted : isDeleted(metadata, winningRev);
+}
+
+function fetchAttachment(att, stores, opts) {
+  var type = att.content_type;
+  return new PouchPromise(function (resolve, reject) {
+    stores.binaryStore.get(att.digest, function (err, buffer) {
+      var data;
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return reject(err);
+        } else {
+          // empty
+          if (!opts.binary) {
+            data = '';
+          } else {
+            data = binStringToBluffer('', type);
+          }
+        }
+      } else { // non-empty
+        if (opts.binary) {
+          data = readAsBlobOrBuffer(buffer, type);
+        } else {
+          data = buffer.toString('base64');
+        }
+      }
+      delete att.stub;
+      delete att.length;
+      att.data = data;
+      resolve();
+    });
+  });
+}
+
+function fetchAttachments(results, stores, opts) {
+  var atts = [];
+  results.forEach(function (row) {
+    if (!(row.doc && row.doc._attachments)) {
+      return;
+    }
+    var attNames = Object.keys(row.doc._attachments);
+    attNames.forEach(function (attName) {
+      var att = row.doc._attachments[attName];
+      if (!('data' in att)) {
+        atts.push(att);
+      }
+    });
+  });
+
+  return PouchPromise.all(atts.map(function (att) {
+    return fetchAttachment(att, stores, opts);
+  }));
+}
+
+function LevelPouch(opts, callback) {
+  opts = clone(opts);
+  var api = this;
+  var instanceId;
+  var stores = {};
+  var revLimit = opts.revs_limit;
+  var db;
+  var name = opts.name;
+  if (typeof opts.createIfMissing === 'undefined') {
+    opts.createIfMissing = true;
+  }
+
+  var leveldown = opts.db || requireLeveldown();
+  /* istanbul ignore if */
+  if (leveldown instanceof Error) {
+    return callback(leveldown);
+  }
+
+  if (typeof leveldown.destroy !== 'function') {
+    /* istanbul ignore next */
+    leveldown.destroy = function (name, cb) { cb(); };
+  }
+  var dbStore;
+  var leveldownName = functionName(leveldown);
+  if (dbStores.has(leveldownName)) {
+    dbStore = dbStores.get(leveldownName);
+  } else {
+    dbStore = new pouchdbCollections.Map();
+    dbStores.set(leveldownName, dbStore);
+  }
+  if (dbStore.has(name)) {
+    db = dbStore.get(name);
+    afterDBCreated();
+  } else {
+    dbStore.set(name, sublevel(levelup(name, opts, function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        dbStore["delete"](name);
+        return callback(err);
+      }
+      db = dbStore.get(name);
+      db._docCount  = -1;
+      db._queue = new Deque();
+      if (opts.db || opts.noMigrate) {
+        afterDBCreated();
+      } else {
+        migrate.toSublevel(name, db, afterDBCreated);
+      }
+    })));
+  }
+
+  function afterDBCreated() {
+    stores.docStore = db.sublevel(DOC_STORE, {valueEncoding: safeJsonEncoding});
+    stores.bySeqStore = db.sublevel(BY_SEQ_STORE, {valueEncoding: 'json'});
+    stores.attachmentStore =
+      db.sublevel(ATTACHMENT_STORE, {valueEncoding: 'json'});
+    stores.binaryStore = db.sublevel(BINARY_STORE, {valueEncoding: 'binary'});
+    stores.localStore = db.sublevel(LOCAL_STORE, {valueEncoding: 'json'});
+    stores.metaStore = db.sublevel(META_STORE, {valueEncoding: 'json'});
+    migrate.localAndMetaStores(db, stores, function () {
+      stores.metaStore.get(UPDATE_SEQ_KEY, function (err, value) {
+        if (typeof db._updateSeq === 'undefined') {
+          db._updateSeq = value || 0;
+        }
+        stores.metaStore.get(DOC_COUNT_KEY, function (err, value) {
+          db._docCount = !err ? value : 0;
+          stores.metaStore.get(UUID_KEY, function (err, value) {
+            instanceId = !err ? value : uuid();
+            stores.metaStore.put(UUID_KEY, instanceId, function () {
+              process.nextTick(function () {
+                callback(null, api);
+              });
+            });
+          });
+        });
+      });
+    });
+  }
+
+  function countDocs(callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(new Error('database is closed'));
+    }
+    return callback(null, db._docCount); // use cached value
+  }
+
+  api.type = function () {
+    return 'leveldb';
+  };
+
+  api._id = function (callback) {
+    callback(null, instanceId);
+  };
+
+  api._info = function (callback) {
+    var res = {
+      doc_count: db._docCount,
+      update_seq: db._updateSeq,
+      backend_adapter: functionName(leveldown)
+    };
+    return process.nextTick(function () {
+      callback(null, res);
+    });
+  };
+
+  function tryCode(fun, args) {
+    try {
+      fun.apply(null, args);
+    } catch (err) {
+      args[args.length - 1](err);
+    }
+  }
+
+  function executeNext() {
+    var firstTask = db._queue.peekFront();
+
+    if (firstTask.type === 'read') {
+      runReadOperation(firstTask);
+    } else { // write, only do one at a time
+      runWriteOperation(firstTask);
+    }
+  }
+
+  function runReadOperation(firstTask) {
+    // do multiple reads at once simultaneously, because it's safe
+
+    var readTasks = [firstTask];
+    var i = 1;
+    var nextTask = db._queue.get(i);
+    while (typeof nextTask !== 'undefined' && nextTask.type === 'read') {
+      readTasks.push(nextTask);
+      i++;
+      nextTask = db._queue.get(i);
+    }
+
+    var numDone = 0;
+
+    readTasks.forEach(function (readTask) {
+      var args = readTask.args;
+      var callback = args[args.length - 1];
+      args[args.length - 1] = getArguments(function (cbArgs) {
+        callback.apply(null, cbArgs);
+        if (++numDone === readTasks.length) {
+          process.nextTick(function () {
+            // all read tasks have finished
+            readTasks.forEach(function () {
+              db._queue.shift();
+            });
+            if (db._queue.length) {
+              executeNext();
+            }
+          });
+        }
+      });
+      tryCode(readTask.fun, args);
+    });
+  }
+
+  function runWriteOperation(firstTask) {
+    var args = firstTask.args;
+    var callback = args[args.length - 1];
+    args[args.length - 1] = getArguments(function (cbArgs) {
+      callback.apply(null, cbArgs);
+      process.nextTick(function () {
+        db._queue.shift();
+        if (db._queue.length) {
+          executeNext();
+        }
+      });
+    });
+    tryCode(firstTask.fun, args);
+  }
+
+  // all read/write operations to the database are done in a queue,
+  // similar to how websql/idb works. this avoids problems such
+  // as e.g. compaction needing to have a lock on the database while
+  // it updates stuff. in the future we can revisit this.
+  function writeLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'write'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  // same as the writelock, but multiple can run at once
+  function readLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'read'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  function formatSeq(n) {
+    return ('0000000000000000' + n).slice(-16);
+  }
+
+  function parseSeq(s) {
+    return parseInt(s, 10);
+  }
+
+  api._get = readLock(function (id, opts, callback) {
+    opts = clone(opts);
+
+    stores.docStore.get(id, function (err, metadata) {
+
+      if (err || !metadata) {
+        return callback(createError(MISSING_DOC, 'missing'));
+      }
+
+      var rev = getWinningRev(metadata);
+      var deleted = getIsDeleted(metadata, rev);
+      if (deleted && !opts.rev) {
+        return callback(createError(MISSING_DOC, "deleted"));
+      }
+
+      rev = opts.rev ? opts.rev : rev;
+
+      var seq = metadata.rev_map[rev];
+
+      stores.bySeqStore.get(formatSeq(seq), function (err, doc) {
+        if (!doc) {
+          return callback(createError(MISSING_DOC));
+        }
+        /* istanbul ignore if */
+        if ('_id' in doc && doc._id !== metadata.id) {
+          // this failing implies something very wrong
+          return callback(new Error('wrong doc returned'));
+        }
+        doc._id = metadata.id;
+        if ('_rev' in doc) {
+          /* istanbul ignore if */
+          if (doc._rev !== rev) {
+            // this failing implies something very wrong
+            return callback(new Error('wrong doc returned'));
+          }
+        } else {
+          // we didn't always store this
+          doc._rev = rev;
+        }
+        return callback(null, {doc: doc, metadata: metadata});
+      });
+    });
+  });
+
+  // not technically part of the spec, but if putAttachment has its own
+  // method...
+  api._getAttachment = function (attachment, opts, callback) {
+    var digest = attachment.digest;
+    var type = attachment.content_type;
+
+    stores.binaryStore.get(digest, function (err, attach) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        }
+        // Empty attachment
+        return callback(null, opts.binary ? createEmptyBlobOrBuffer(type) : '');
+      }
+
+      if (opts.binary) {
+        callback(null, readAsBlobOrBuffer(attach, type));
+      } else {
+        callback(null, attach.toString('base64'));
+      }
+    });
+  };
+
+  api._bulkDocs = writeLock(function (req, opts, callback) {
+    var newEdits = opts.new_edits;
+    var results = new Array(req.docs.length);
+    var fetchedDocs = new pouchdbCollections.Map();
+    var stemmedRevs = new pouchdbCollections.Map();
+
+    var txn = new LevelTransaction();
+    var docCountDelta = 0;
+    var newUpdateSeq = db._updateSeq;
+
+    // parse the docs and give each a sequence number
+    var userDocs = req.docs;
+    var docInfos = userDocs.map(function (doc) {
+      if (doc._id && isLocalId(doc._id)) {
+        return doc;
+      }
+      var newDoc = parseDoc(doc, newEdits);
+
+      if (newDoc.metadata && !newDoc.metadata.rev_map) {
+        newDoc.metadata.rev_map = {};
+      }
+
+      return newDoc;
+    });
+    var infoErrors = docInfos.filter(function (doc) {
+      return doc.error;
+    });
+
+    if (infoErrors.length) {
+      return callback(infoErrors[0]);
+    }
+
+    // verify any stub attachments as a precondition test
+
+    function verifyAttachment(digest, callback) {
+      txn.get(stores.attachmentStore, digest, function (levelErr) {
+        if (levelErr) {
+          var err = createError(MISSING_STUB,
+                                'unknown stub attachment with digest ' +
+                                digest);
+          callback(err);
+        } else {
+          callback();
+        }
+      });
+    }
+
+    function verifyAttachments(finish) {
+      var digests = [];
+      userDocs.forEach(function (doc) {
+        if (doc && doc._attachments) {
+          Object.keys(doc._attachments).forEach(function (filename) {
+            var att = doc._attachments[filename];
+            if (att.stub) {
+              digests.push(att.digest);
+            }
+          });
+        }
+      });
+      if (!digests.length) {
+        return finish();
+      }
+      var numDone = 0;
+      var err;
+
+      digests.forEach(function (digest) {
+        verifyAttachment(digest, function (attErr) {
+          if (attErr && !err) {
+            err = attErr;
+          }
+
+          if (++numDone === digests.length) {
+            finish(err);
+          }
+        });
+      });
+    }
+
+    function fetchExistingDocs(finish) {
+      var numDone = 0;
+      var overallErr;
+      function checkDone() {
+        if (++numDone === userDocs.length) {
+          return finish(overallErr);
+        }
+      }
+
+      userDocs.forEach(function (doc) {
+        if (doc._id && isLocalId(doc._id)) {
+          // skip local docs
+          return checkDone();
+        }
+        txn.get(stores.docStore, doc._id, function (err, info) {
+          if (err) {
+            /* istanbul ignore if */
+            if (err.name !== 'NotFoundError') {
+              overallErr = err;
+            }
+          } else {
+            fetchedDocs.set(doc._id, info);
+          }
+          checkDone();
+        });
+      });
+    }
+
+    function compact(revsMap, callback) {
+      var promise = PouchPromise.resolve();
+      revsMap.forEach(function (revs, docId) {
+        // TODO: parallelize, for now need to be sequential to
+        // pass orphaned attachment tests
+        promise = promise.then(function () {
+          return new PouchPromise(function (resolve, reject) {
+            api._doCompactionNoLock(docId, revs, {ctx: txn}, function (err) {
+              /* istanbul ignore if */
+              if (err) {
+                return reject(err);
+              }
+              resolve();
+            });
+          });
+        });
+      });
+
+      promise.then(function () {
+        callback();
+      }, callback);
+    }
+
+    function autoCompact(callback) {
+      var revsMap = new pouchdbCollections.Map();
+      fetchedDocs.forEach(function (metadata, docId) {
+        revsMap.set(docId, compactTree(metadata));
+      });
+      compact(revsMap, callback);
+    }
+
+    function finish() {
+      if (api.auto_compaction) {
+        return autoCompact(complete);
+      } else {
+        compact(stemmedRevs, complete);
+      }
+    }
+
+    function writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
+                      isUpdate, delta, resultsIdx, callback2) {
+      docCountDelta += delta;
+
+      var err = null;
+      var recv = 0;
+
+      docInfo.metadata.winningRev = winningRev;
+      docInfo.metadata.deleted = winningRevIsDeleted;
+
+      docInfo.data._id = docInfo.metadata.id;
+      docInfo.data._rev = docInfo.metadata.rev;
+
+      if (newRevIsDeleted) {
+        docInfo.data._deleted = true;
+      }
+
+      if (docInfo.stemmedRevs.length) {
+        stemmedRevs.set(docInfo.metadata.id, docInfo.stemmedRevs);
+      }
+
+      var attachments = docInfo.data._attachments ?
+        Object.keys(docInfo.data._attachments) :
+        [];
+
+      function attachmentSaved(attachmentErr) {
+        recv++;
+        if (!err) {
+          /* istanbul ignore if */
+          if (attachmentErr) {
+            err = attachmentErr;
+            callback2(err);
+          } else if (recv === attachments.length) {
+            finish();
+          }
+        }
+      }
+
+      function onMD5Load(doc, key, data, attachmentSaved) {
+        return function (result) {
+          saveAttachment(doc, MD5_PREFIX + result, key, data, attachmentSaved);
+        };
+      }
+
+      function doMD5(doc, key, attachmentSaved) {
+        return function (data) {
+          md5(data).then(
+            onMD5Load(doc, key, data, attachmentSaved)
+          );
+        };
+      }
+
+      for (var i = 0; i < attachments.length; i++) {
+        var key = attachments[i];
+        var att = docInfo.data._attachments[key];
+
+        if (att.stub) {
+          // still need to update the refs mapping
+          var id = docInfo.data._id;
+          var rev = docInfo.data._rev;
+          saveAttachmentRefs(id, rev, att.digest, attachmentSaved);
+          continue;
+        }
+        var data;
+        if (typeof att.data === 'string') {
+          // input is assumed to be a base64 string
+          try {
+            data = thisAtob(att.data);
+          } catch (e) {
+            callback(createError(BAD_ARG,
+                     'Attachment is not a valid base64 string'));
+            return;
+          }
+          doMD5(docInfo, key, attachmentSaved)(data);
+        } else {
+          prepareAttachmentForStorage(att.data,
+            doMD5(docInfo, key, attachmentSaved));
+        }
+      }
+
+      function finish() {
+        var seq = docInfo.metadata.rev_map[docInfo.metadata.rev];
+        /* istanbul ignore if */
+        if (seq) {
+          // check that there aren't any existing revisions with the same
+          // revision id, else we shouldn't do anything
+          return callback2(null, docInfo.revsStemmed);
+        }
+        seq = ++newUpdateSeq;
+        docInfo.metadata.rev_map[docInfo.metadata.rev] =
+          docInfo.metadata.seq = seq;
+        var seqKey = formatSeq(seq);
+        var batch = [{
+          key: seqKey,
+          value: docInfo.data,
+          prefix: stores.bySeqStore,
+          type: 'put'
+        }, {
+          key: docInfo.metadata.id,
+          value: docInfo.metadata,
+          prefix: stores.docStore,
+          type: 'put'
+        }];
+        txn.batch(batch);
+        results[resultsIdx] = {
+          ok: true,
+          id: docInfo.metadata.id,
+          rev: winningRev
+        };
+        fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+        callback2(null, docInfo.revsStemmed);
+      }
+
+      if (!attachments.length) {
+        finish();
+      }
+    }
+
+    // attachments are queued per-digest, otherwise the refs could be
+    // overwritten by concurrent writes in the same bulkDocs session
+    var attachmentQueues = {};
+
+    function saveAttachmentRefs(id, rev, digest, callback) {
+
+      function fetchAtt() {
+        return new PouchPromise(function (resolve, reject) {
+          txn.get(stores.attachmentStore, digest, function (err, oldAtt) {
+            /* istanbul ignore if */
+            if (err && err.name !== 'NotFoundError') {
+              return reject(err);
+            }
+            resolve(oldAtt);
+          });
+        });
+      }
+
+      function saveAtt(oldAtt) {
+        var ref = [id, rev].join('@');
+        var newAtt = {};
+
+        if (oldAtt) {
+          if (oldAtt.refs) {
+            // only update references if this attachment already has them
+            // since we cannot migrate old style attachments here without
+            // doing a full db scan for references
+            newAtt.refs = oldAtt.refs;
+            newAtt.refs[ref] = true;
+          }
+        } else {
+          newAtt.refs = {};
+          newAtt.refs[ref] = true;
+        }
+
+        return new PouchPromise(function (resolve) {
+          txn.batch([{
+            type: 'put',
+            prefix: stores.attachmentStore,
+            key: digest,
+            value: newAtt
+          }]);
+          resolve(!oldAtt);
+        });
+      }
+
+      // put attachments in a per-digest queue, to avoid two docs with the same
+      // attachment overwriting each other
+      var queue = attachmentQueues[digest] || PouchPromise.resolve();
+      attachmentQueues[digest] = queue.then(function () {
+        return fetchAtt().then(saveAtt).then(function (isNewAttachment) {
+          callback(null, isNewAttachment);
+        }, callback);
+      });
+    }
+
+    function saveAttachment(docInfo, digest, key, data, callback) {
+      var att = docInfo.data._attachments[key];
+      delete att.data;
+      att.digest = digest;
+      att.length = data.length;
+      var id = docInfo.metadata.id;
+      var rev = docInfo.metadata.rev;
+      att.revpos = parseInt(rev, 10);
+
+      saveAttachmentRefs(id, rev, digest, function (err, isNewAttachment) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        // do not try to store empty attachments
+        if (data.length === 0) {
+          return callback(err);
+        }
+        if (!isNewAttachment) {
+          // small optimization - don't bother writing it again
+          return callback(err);
+        }
+        txn.batch([{
+          type: 'put',
+          prefix: stores.binaryStore,
+          key: digest,
+          value: new Buffer(data, 'binary')
+        }]);
+        callback();
+      });
+    }
+
+    function complete(err) {
+      /* istanbul ignore if */
+      if (err) {
+        return process.nextTick(function () {
+          callback(err);
+        });
+      }
+      txn.batch([
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: UPDATE_SEQ_KEY,
+          value: newUpdateSeq
+        },
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: DOC_COUNT_KEY,
+          value: db._docCount + docCountDelta
+        }
+      ]);
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        db._docCount += docCountDelta;
+        db._updateSeq = newUpdateSeq;
+        levelChanges.notify(name);
+        process.nextTick(function () {
+          callback(null, results);
+        });
+      });
+    }
+
+    if (!docInfos.length) {
+      return callback(null, []);
+    }
+
+    verifyAttachments(function (err) {
+      if (err) {
+        return callback(err);
+      }
+      fetchExistingDocs(function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        processDocs(revLimit, docInfos, api, fetchedDocs, txn, results,
+                    writeDoc, opts, finish);
+      });
+    });
+  });
+  api._allDocs = readLock(function (opts, callback) {
+    opts = clone(opts);
+    countDocs(function (err, docCount) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var readstreamOpts = {};
+      var skip = opts.skip || 0;
+      if (opts.startkey) {
+        readstreamOpts.gte = opts.startkey;
+      }
+      if (opts.endkey) {
+        readstreamOpts.lte = opts.endkey;
+      }
+      if (opts.key) {
+        readstreamOpts.gte = readstreamOpts.lte = opts.key;
+      }
+      if (opts.descending) {
+        readstreamOpts.reverse = true;
+        // switch start and ends
+        var tmp = readstreamOpts.lte;
+        readstreamOpts.lte = readstreamOpts.gte;
+        readstreamOpts.gte = tmp;
+      }
+      var limit;
+      if (typeof opts.limit === 'number') {
+        limit = opts.limit;
+      }
+      if (limit === 0 ||
+          ('start' in readstreamOpts && 'end' in readstreamOpts &&
+          readstreamOpts.start > readstreamOpts.end)) {
+        // should return 0 results when start is greater than end.
+        // normally level would "fix" this for us by reversing the order,
+        // so short-circuit instead
+        return callback(null, {
+          total_rows: docCount,
+          offset: opts.skip,
+          rows: []
+        });
+      }
+      var results = [];
+      var docstream = stores.docStore.readStream(readstreamOpts);
+
+      var throughStream = through2.obj(function (entry, _, next) {
+        var metadata = entry.value;
+        // winningRev and deleted are performance-killers, but
+        // in newer versions of PouchDB, they are cached on the metadata
+        var winningRev = getWinningRev(metadata);
+        var deleted = getIsDeleted(metadata, winningRev);
+        if (!deleted) {
+          if (skip-- > 0) {
+            next();
+            return;
+          } else if (typeof limit === 'number' && limit-- <= 0) {
+            docstream.unpipe();
+            docstream.destroy();
+            next();
+            return;
+          }
+        } else if (opts.deleted !== 'ok') {
+          next();
+          return;
+        }
+        function allDocsInner(data) {
+          var doc = {
+            id: metadata.id,
+            key: metadata.id,
+            value: {
+              rev: winningRev
+            }
+          };
+          if (opts.include_docs) {
+            doc.doc = data;
+            doc.doc._rev = doc.value.rev;
+            if (opts.conflicts) {
+              doc.doc._conflicts = collectConflicts(metadata);
+            }
+            for (var att in doc.doc._attachments) {
+              if (doc.doc._attachments.hasOwnProperty(att)) {
+                doc.doc._attachments[att].stub = true;
+              }
+            }
+          }
+          if (opts.inclusive_end === false && metadata.id === opts.endkey) {
+            return next();
+          } else if (deleted) {
+            if (opts.deleted === 'ok') {
+              doc.value.deleted = true;
+              doc.doc = null;
+            } else {
+              /* istanbul ignore next */
+              return next();
+            }
+          }
+          results.push(doc);
+          next();
+        }
+        if (opts.include_docs) {
+          var seq = metadata.rev_map[winningRev];
+          stores.bySeqStore.get(formatSeq(seq), function (err, data) {
+            allDocsInner(data);
+          });
+        }
+        else {
+          allDocsInner();
+        }
+      }, function (next) {
+        PouchPromise.resolve().then(function () {
+          if (opts.include_docs && opts.attachments) {
+            return fetchAttachments(results, stores, opts);
+          }
+        }).then(function () {
+          callback(null, {
+            total_rows: docCount,
+            offset: opts.skip,
+            rows: results
+          });
+        }, callback);
+        next();
+      }).on('unpipe', function () {
+        throughStream.end();
+      });
+
+      docstream.on('error', callback);
+
+      docstream.pipe(throughStream);
+    });
+  });
+
+  api._changes = function (opts) {
+    opts = clone(opts);
+
+    if (opts.continuous) {
+      var id = name + ':' + uuid();
+      levelChanges.addListener(name, id, api, opts);
+      levelChanges.notify(name);
+      return {
+        cancel: function () {
+          levelChanges.removeListener(name, id);
+        }
+      };
+    }
+
+    var descending = opts.descending;
+    var results = [];
+    var lastSeq = opts.since || 0;
+    var called = 0;
+    var streamOpts = {
+      reverse: descending
+    };
+    var limit;
+    if ('limit' in opts && opts.limit > 0) {
+      limit = opts.limit;
+    }
+    if (!streamOpts.reverse) {
+      streamOpts.start = formatSeq(opts.since || 0);
+    }
+
+    var docIds = opts.doc_ids && new pouchdbCollections.Set(opts.doc_ids);
+    var filter = filterChange(opts);
+    var docIdsToMetadata = new pouchdbCollections.Map();
+
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+
+    function complete() {
+      opts.done = true;
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+      changeStream.unpipe(throughStream);
+      changeStream.destroy();
+      if (!opts.continuous && !opts.cancelled) {
+        if (opts.include_docs && opts.attachments) {
+          fetchAttachments(results, stores, opts).then(function () {
+            opts.complete(null, {results: results, last_seq: lastSeq});
+          });
+        } else {
+          opts.complete(null, {results: results, last_seq: lastSeq});
+        }
+      }
+    }
+    var changeStream = stores.bySeqStore.readStream(streamOpts);
+    var throughStream = through2.obj(function (data, _, next) {
+      if (limit && called >= limit) {
+        complete();
+        return next();
+      }
+      if (opts.cancelled || opts.done) {
+        return next();
+      }
+
+      var seq = parseSeq(data.key);
+      var doc = data.value;
+
+      if (seq === opts.since && !descending) {
+        // couchdb ignores `since` if descending=true
+        return next();
+      }
+
+      if (docIds && !docIds.has(doc._id)) {
+        return next();
+      }
+
+      var metadata;
+
+      function onGetMetadata(metadata) {
+        var winningRev = getWinningRev(metadata);
+
+        function onGetWinningDoc(winningDoc) {
+
+          var change = opts.processChange(winningDoc, metadata, opts);
+          change.seq = metadata.seq;
+
+          var filtered = filter(change);
+          if (typeof filtered === 'object') {
+            return opts.complete(filtered);
+          }
+
+          if (filtered) {
+            called++;
+
+            if (opts.attachments && opts.include_docs) {
+              // fetch attachment immediately for the benefit
+              // of live listeners
+              fetchAttachments([change], stores, opts).then(function () {
+                opts.onChange(change);
+              });
+            } else {
+              opts.onChange(change);
+            }
+
+            if (returnDocs) {
+              results.push(change);
+            }
+          }
+          next();
+        }
+
+        if (metadata.seq !== seq) {
+          // some other seq is later
+          return next();
+        }
+
+        lastSeq = seq;
+
+        if (winningRev === doc._rev) {
+          return onGetWinningDoc(doc);
+        }
+
+        // fetch the winner
+
+        var winningSeq = metadata.rev_map[winningRev];
+
+        stores.bySeqStore.get(formatSeq(winningSeq), function (err, doc) {
+          onGetWinningDoc(doc);
+        });
+      }
+
+      metadata = docIdsToMetadata.get(doc._id);
+      if (metadata) { // cached
+        return onGetMetadata(metadata);
+      }
+      // metadata not cached, have to go fetch it
+      stores.docStore.get(doc._id, function (err, metadata) {
+        /* istanbul ignore if */
+        if (opts.cancelled || opts.done || db.isClosed() ||
+          isLocalId(metadata.id)) {
+          return next();
+        }
+        docIdsToMetadata.set(doc._id, metadata);
+        onGetMetadata(metadata);
+      });
+    }, function (next) {
+      if (opts.cancelled) {
+        return next();
+      }
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+
+      next();
+    }).on('unpipe', function () {
+      throughStream.end();
+      complete();
+    });
+    changeStream.pipe(throughStream);
+    return {
+      cancel: function () {
+        opts.cancelled = true;
+        complete();
+      }
+    };
+  };
+
+  api._close = function (callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(createError(NOT_OPEN));
+    }
+    db.close(function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        callback(err);
+      } else {
+        dbStore["delete"](name);
+        callback();
+      }
+    });
+  };
+
+  api._getRevisionTree = function (docId, callback) {
+    stores.docStore.get(docId, function (err, metadata) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, metadata.rev_tree);
+      }
+    });
+  };
+
+  api._doCompaction = writeLock(function (docId, revs, opts, callback) {
+    api._doCompactionNoLock(docId, revs, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._doCompactionNoLock = function (docId, revs, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+
+    if (!revs.length) {
+      return callback();
+    }
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.docStore, docId, function (err, metadata) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var seqs = revs.map(function (rev) {
+        var seq = metadata.rev_map[rev];
+        delete metadata.rev_map[rev];
+        return seq;
+      });
+      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                         revHash, ctx, opts) {
+        var rev = pos + '-' + revHash;
+        if (revs.indexOf(rev) !== -1) {
+          opts.status = 'missing';
+        }
+      });
+
+      var batch = [];
+      batch.push({
+        key: metadata.id,
+        value: metadata,
+        type: 'put',
+        prefix: stores.docStore
+      });
+
+      var digestMap = {};
+      var numDone = 0;
+      var overallErr;
+      function checkDone(err) {
+        /* istanbul ignore if */
+        if (err) {
+          overallErr = err;
+        }
+        if (++numDone === revs.length) { // done
+          /* istanbul ignore if */
+          if (overallErr) {
+            return callback(overallErr);
+          }
+          deleteOrphanedAttachments();
+        }
+      }
+
+      function finish(err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        txn.batch(batch);
+        if (opts.ctx) {
+          // don't execute immediately
+          return callback();
+        }
+        txn.execute(db, callback);
+      }
+
+      function deleteOrphanedAttachments() {
+        var possiblyOrphanedAttachments = Object.keys(digestMap);
+        if (!possiblyOrphanedAttachments.length) {
+          return finish();
+        }
+        var numDone = 0;
+        var overallErr;
+        function checkDone(err) {
+          /* istanbul ignore if */
+          if (err) {
+            overallErr = err;
+          }
+          if (++numDone === possiblyOrphanedAttachments.length) {
+            finish(overallErr);
+          }
+        }
+        var refsToDelete = new pouchdbCollections.Map();
+        revs.forEach(function (rev) {
+          refsToDelete.set(docId + '@' + rev, true);
+        });
+        possiblyOrphanedAttachments.forEach(function (digest) {
+          txn.get(stores.attachmentStore, digest, function (err, attData) {
+            /* istanbul ignore if */
+            if (err) {
+              if (err.name === 'NotFoundError') {
+                return checkDone();
+              } else {
+                return checkDone(err);
+              }
+            }
+            var refs = Object.keys(attData.refs || {}).filter(function (ref) {
+              return !refsToDelete.has(ref);
+            });
+            var newRefs = {};
+            refs.forEach(function (ref) {
+              newRefs[ref] = true;
+            });
+            if (refs.length) { // not orphaned
+              batch.push({
+                key: digest,
+                type: 'put',
+                value: {refs: newRefs},
+                prefix: stores.attachmentStore
+              });
+            } else { // orphaned, can safely delete
+              batch = batch.concat([{
+                key: digest,
+                type: 'del',
+                prefix: stores.attachmentStore
+              }, {
+                key: digest,
+                type: 'del',
+                prefix: stores.binaryStore
+              }]);
+            }
+            checkDone();
+          });
+        });
+      }
+
+      seqs.forEach(function (seq) {
+        batch.push({
+          key: formatSeq(seq),
+          type: 'del',
+          prefix: stores.bySeqStore
+        });
+        txn.get(stores.bySeqStore, formatSeq(seq), function (err, doc) {
+          /* istanbul ignore if */
+          if (err) {
+            if (err.name === 'NotFoundError') {
+              return checkDone();
+            } else {
+              return checkDone(err);
+            }
+          }
+          var atts = Object.keys(doc._attachments || {});
+          atts.forEach(function (attName) {
+            var digest = doc._attachments[attName].digest;
+            digestMap[digest] = true;
+          });
+          checkDone();
+        });
+      });
+    });
+  };
+
+  api._getLocal = function (id, callback) {
+    stores.localStore.get(id, function (err, doc) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, doc);
+      }
+    });
+  };
+
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._putLocalNoLock(doc, opts, callback);
+    } else {
+      api._putLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._putLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._putLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._putLocalNoLock = function (doc, opts, callback) {
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.localStore, id, function (err, resp) {
+      if (err && oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      if (resp && resp._rev !== oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      doc._rev =
+          oldRev ? '0-' + (parseInt(oldRev.split('-')[1], 10) + 1) : '0-1';
+      var batch = [
+        {
+          type: 'put',
+          prefix: stores.localStore,
+          key: id,
+          value: doc
+        }
+      ];
+
+      txn.batch(batch);
+      var ret = {ok: true, id: doc._id, rev: doc._rev};
+
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._removeLocalNoLock(doc, opts, callback);
+    } else {
+      api._removeLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._removeLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._removeLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._removeLocalNoLock = function (doc, opts, callback) {
+    var txn = opts.ctx || new LevelTransaction();
+    txn.get(stores.localStore, doc._id, function (err, resp) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        } else {
+          return callback(createError(MISSING_DOC));
+        }
+      }
+      if (resp._rev !== doc._rev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      txn.batch([{
+        prefix: stores.localStore,
+        type: 'del',
+        key: doc._id
+      }]);
+      var ret = {ok: true, id: doc._id, rev: '0-0'};
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  // close and delete open leveldb stores
+  api._destroy = function (opts, callback) {
+    var dbStore;
+    var leveldownName = functionName(leveldown);
+    /* istanbul ignore else */
+    if (dbStores.has(leveldownName)) {
+      dbStore = dbStores.get(leveldownName);
+    } else {
+      return callDestroy(name, callback);
+    }
+
+    /* istanbul ignore else */
+    if (dbStore.has(name)) {
+      levelChanges.removeAllListeners(name);
+
+      dbStore.get(name).close(function () {
+        dbStore["delete"](name);
+        callDestroy(name, callback);
+      });
+    } else {
+      callDestroy(name, callback);
+    }
+  };
+  function callDestroy(name, cb) {
+    /* istanbul ignore else */
+    if (typeof leveldown.destroy === 'function') {
+      leveldown.destroy(name, cb);
+    } else {
+      process.nextTick(cb);
+    }
+  }
+}
+
+LevelPouch.valid = function () {
+  // this gets overriden by the *down-based browser adapters
+  return true;
+};
+
+LevelPouch.use_prefix = false;
+
+function altFactory(adapterConfig, downAdapter) {
+
+  function LevelPouchAlt(opts, callback) {
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    LevelPouch.call(this, _opts, callback);
+  }
+
+  // overrides for normal LevelDB behavior on Node
+  LevelPouchAlt.valid = function () {
+    return adapterConfig.valid();
+  };
+  LevelPouchAlt.use_prefix = adapterConfig.use_prefix;
+
+  LevelPouchAlt.destroy = toPromise(function (name, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    return LevelPouch.destroy(name, _opts, callback);
+  });
+  return LevelPouchAlt;
+}
+
+function pluginBase(adapterConfig, downAdapter) {
+  var adapterName = adapterConfig.name;
+  var adapter = altFactory(adapterConfig, downAdapter);
+  // use global PouchDB if it's there (e.g. window.PouchDB)
+  var PDB = (typeof PouchDB !== 'undefined') ? PouchDB : _dereq_("pouchdb");
+  if (!PDB) {
+    console.error(adapterConfig.name + ' adapter plugin error: ' +
+      'Cannot find global "PouchDB" object! ' +
+      'Did you remember to include pouchdb.js?');
+  } else {
+    PDB.adapter(adapterName, adapter, true);
+  }
+}
+
+var adapterConfig = {
+  name: 'localstorage',
+  valid: function () {
+    return typeof localStorage !== 'undefined';
+  },
+  use_prefix: true
+};
+
+pluginBase(adapterConfig, downAdapter);
+}).call(this,_dereq_(59),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(8).Buffer)
+},{"19":19,"23":23,"29":29,"32":32,"46":46,"5":5,"50":50,"51":51,"57":57,"59":59,"61":61,"7":7,"76":76,"8":8,"94":94,"99":99,"pouchdb":"pouchdb"}],2:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKeyValue(key, 'key', this._db._isBuffer)
+  if (err) throw err
+  err = this._db._checkKeyValue(value, 'value', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+  if (!this._db._isBuffer(value)) value = String(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKeyValue(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+}).call(this,_dereq_(59))
+},{"59":59}],3:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractIterator (db) {
+  this.db = db
+  this._ended = false
+  this._nexting = false
+}
+
+AbstractIterator.prototype.next = function (callback) {
+  var self = this
+
+  if (typeof callback != 'function')
+    throw new Error('next() requires a callback argument')
+
+  if (self._ended)
+    return callback(new Error('cannot call next() after end()'))
+  if (self._nexting)
+    return callback(new Error('cannot call next() before previous next() has completed'))
+
+  self._nexting = true
+  if (typeof self._next == 'function') {
+    return self._next(function () {
+      self._nexting = false
+      callback.apply(null, arguments)
+    })
+  }
+
+  process.nextTick(function () {
+    self._nexting = false
+    callback()
+  })
+}
+
+AbstractIterator.prototype.end = function (callback) {
+  if (typeof callback != 'function')
+    throw new Error('end() requires a callback argument')
+
+  if (this._ended)
+    return callback(new Error('end() already called on iterator'))
+
+  this._ended = true
+
+  if (typeof this._end == 'function')
+    return this._end(callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractIterator
+
+}).call(this,_dereq_(59))
+},{"59":59}],4:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(100)
+  , AbstractIterator     = _dereq_(3)
+  , AbstractChainedBatch = _dereq_(2)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._open == 'function')
+    return this._open(options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function')
+    return this._close(callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (err = this._checkKeyValue(value, 'value', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  // coerce value to string in node, don't touch it in browser
+  // (indexeddb can store any JS type)
+  if (!this._isBuffer(value) && !process.browser)
+    value = String(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKeyValue(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKeyValue(e.type, 'type', this._isBuffer))
+      return callback(err)
+
+    if (err = this._checkKeyValue(e.key, 'key', this._isBuffer))
+      return callback(err)
+
+    if (e.type == 'put') {
+      if (err = this._checkKeyValue(e.value, 'value', this._isBuffer))
+        return callback(err)
+    }
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  if (!this._isBuffer(start))
+    start = String(start)
+
+  if (!this._isBuffer(end))
+    end = String(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+
+  // fix `start` so it takes into account gt, gte, lt, lte as appropriate
+  if (options.reverse && options.lt)
+    options.start = options.lt
+  if (options.reverse && options.lte)
+    options.start = options.lte
+  if (!options.reverse && options.gt)
+    options.start = options.gt
+  if (!options.reverse && options.gte)
+    options.start = options.gte
+
+  if ((options.reverse && options.lt && !options.lte)
+    || (!options.reverse && options.gt && !options.gte))
+    options.exclusiveStart = true // start should *not* include matching key
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._checkKeyValue = function (obj, type) {
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj)) {
+    if (obj.length === 0)
+      return new Error(type + ' cannot be an empty Buffer')
+  } else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports.AbstractLevelDOWN    = AbstractLevelDOWN
+module.exports.AbstractIterator     = AbstractIterator
+module.exports.AbstractChainedBatch = AbstractChainedBatch
+
+}).call(this,{"isBuffer":_dereq_(30)},_dereq_(59))
+},{"100":100,"2":2,"3":3,"30":30,"59":59}],5:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+  return function () {
+    var len = arguments.length;
+    if (len) {
+      var args = [];
+      var i = -1;
+      while (++i < len) {
+        args[i] = arguments[i];
+      }
+      return fun.call(this, args);
+    } else {
+      return fun.call(this, []);
+    }
+  };
+}
+},{}],6:[function(_dereq_,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+	'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+	var PLUS   = '+'.charCodeAt(0)
+	var SLASH  = '/'.charCodeAt(0)
+	var NUMBER = '0'.charCodeAt(0)
+	var LOWER  = 'a'.charCodeAt(0)
+	var UPPER  = 'A'.charCodeAt(0)
+	var PLUS_URL_SAFE = '-'.charCodeAt(0)
+	var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+	function decode (elt) {
+		var code = elt.charCodeAt(0)
+		if (code === PLUS ||
+		    code === PLUS_URL_SAFE)
+			return 62 // '+'
+		if (code === SLASH ||
+		    code === SLASH_URL_SAFE)
+			return 63 // '/'
+		if (code < NUMBER)
+			return -1 //no match
+		if (code < NUMBER + 10)
+			return code - NUMBER + 26 + 26
+		if (code < UPPER + 26)
+			return code - UPPER
+		if (code < LOWER + 26)
+			return code - LOWER + 26
+	}
+
+	function b64ToByteArray (b64) {
+		var i, j, l, tmp, placeHolders, arr
+
+		if (b64.length % 4 > 0) {
+			throw new Error('Invalid string. Length must be a multiple of 4')
+		}
+
+		// the number of equal signs (place holders)
+		// if there are two placeholders, than the two characters before it
+		// represent one byte
+		// if there is only one, then the three characters before it represent 2 bytes
+		// this is just a cheap hack to not do indexOf twice
+		var len = b64.length
+		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+		// base64 is 4/3 + up to two characters of the original data
+		arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+		// if there are placeholders, only get up to the last complete 4 chars
+		l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+		var L = 0
+
+		function push (v) {
+			arr[L++] = v
+		}
+
+		for (i = 0, j = 0; i < l; i += 4, j += 3) {
+			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+			push((tmp & 0xFF0000) >> 16)
+			push((tmp & 0xFF00) >> 8)
+			push(tmp & 0xFF)
+		}
+
+		if (placeHolders === 2) {
+			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+			push(tmp & 0xFF)
+		} else if (placeHolders === 1) {
+			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+			push((tmp >> 8) & 0xFF)
+			push(tmp & 0xFF)
+		}
+
+		return arr
+	}
+
+	function uint8ToBase64 (uint8) {
+		var i,
+			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+			output = "",
+			temp, length
+
+		function encode (num) {
+			return lookup.charAt(num)
+		}
+
+		function tripletToBase64 (num) {
+			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+		}
+
+		// go through the array every three bytes, we'll deal with trailing stuff later
+		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+			output += tripletToBase64(temp)
+		}
+
+		// pad the end with zeros, but make sure to not forget the extra bytes
+		switch (extraBytes) {
+			case 1:
+				temp = uint8[uint8.length - 1]
+				output += encode(temp >> 2)
+				output += encode((temp << 4) & 0x3F)
+				output += '=='
+				break
+			case 2:
+				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+				output += encode(temp >> 10)
+				output += encode((temp >> 4) & 0x3F)
+				output += encode((temp << 2) & 0x3F)
+				output += '='
+				break
+		}
+
+		return output
+	}
+
+	exports.toByteArray = b64ToByteArray
+	exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],7:[function(_dereq_,module,exports){
+
+},{}],8:[function(_dereq_,module,exports){
+(function (global){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+/* eslint-disable no-proto */
+
+'use strict'
+
+var base64 = _dereq_(6)
+var ieee754 = _dereq_(27)
+var isArray = _dereq_(31)
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ *     on objects.
+ *
+ *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *     incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
+  ? global.TYPED_ARRAY_SUPPORT
+  : typedArraySupport()
+
+function typedArraySupport () {
+  function Bar () {}
+  try {
+    var arr = new Uint8Array(1)
+    arr.foo = function () { return 42 }
+    arr.constructor = Bar
+    return arr.foo() === 42 && // typed array instances can be augmented
+        arr.constructor === Bar && // constructor can be set
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+}
+
+function kMaxLength () {
+  return Buffer.TYPED_ARRAY_SUPPORT
+    ? 0x7fffffff
+    : 0x3fffffff
+}
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (arg) {
+  if (!(this instanceof Buffer)) {
+    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+    if (arguments.length > 1) return new Buffer(arg, arguments[1])
+    return new Buffer(arg)
+  }
+
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    this.length = 0
+    this.parent = undefined
+  }
+
+  // Common case.
+  if (typeof arg === 'number') {
+    return fromNumber(this, arg)
+  }
+
+  // Slightly less common case.
+  if (typeof arg === 'string') {
+    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+  }
+
+  // Unusual.
+  return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < length; i++) {
+      that[i] = 0
+    }
+  }
+  return that
+}
+
+function fromString (that, string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+  // Assumption: byteLength() return value is always < kMaxLength.
+  var length = byteLength(string, encoding) | 0
+  that = allocate(that, length)
+
+  that.write(string, encoding)
+  return that
+}
+
+function fromObject (that, object) {
+  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+  if (isArray(object)) return fromArray(that, object)
+
+  if (object == null) {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (typeof ArrayBuffer !== 'undefined') {
+    if (object.buffer instanceof ArrayBuffer) {
+      return fromTypedArray(that, object)
+    }
+    if (object instanceof ArrayBuffer) {
+      return fromArrayBuffer(that, object)
+    }
+  }
+
+  if (object.length) return fromArrayLike(that, object)
+
+  return fromJsonObject(that, object)
+}
+
+function fromBuffer (that, buffer) {
+  var length = checked(buffer.length) | 0
+  that = allocate(that, length)
+  buffer.copy(that, 0, 0, length)
+  return that
+}
+
+function fromArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  // Truncating the elements is probably not what people expect from typed
+  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+  // of the old Buffer constructor.
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function fromArrayBuffer (that, array) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    array.byteLength
+    that = Buffer._augment(new Uint8Array(array))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that = fromTypedArray(that, new Uint8Array(array))
+  }
+  return that
+}
+
+function fromArrayLike (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject (that, object) {
+  var array
+  var length = 0
+
+  if (object.type === 'Buffer' && isArray(object.data)) {
+    array = object.data
+    length = checked(array.length) | 0
+  }
+  that = allocate(that, length)
+
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+if (Buffer.TYPED_ARRAY_SUPPORT) {
+  Buffer.prototype.__proto__ = Uint8Array.prototype
+  Buffer.__proto__ = Uint8Array
+} else {
+  // pre-set for values that may exist in the future
+  Buffer.prototype.length = undefined
+  Buffer.prototype.parent = undefined
+}
+
+function allocate (that, length) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    that = Buffer._augment(new Uint8Array(length))
+    that.__proto__ = Buffer.prototype
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that.length = length
+    that._isBuffer = true
+  }
+
+  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+  if (fromPool) that.parent = rootParent
+
+  return that
+}
+
+function checked (length) {
+  // Note: cannot use `length < kMaxLength` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= kMaxLength()) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  var i = 0
+  var len = Math.min(x, y)
+  while (i < len) {
+    if (a[i] !== b[i]) break
+
+    ++i
+  }
+
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; i++) {
+      length += list[i].length
+    }
+  }
+
+  var buf = new Buffer(length)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+function byteLength (string, encoding) {
+  if (typeof string !== 'string') string = '' + string
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'binary':
+      // Deprecated
+      case 'raw':
+      case 'raws':
+        return len
+      case 'utf8':
+      case 'utf-8':
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start | 0
+  end = end === undefined || end === Infinity ? this.length : end | 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length | 0
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` is deprecated
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` is deprecated
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset | 0
+    if (isFinite(length)) {
+      length = length | 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  // legacy write(string, encoding, offset, length) - remove in v0.13
+  } else {
+    var swap = encoding
+    encoding = offset
+    offset = length | 0
+    length = swap
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'binary':
+        return binaryWrite(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; i--) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    // ascending copy from start
+    for (i = 0; i < len; i++) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), targetStart)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function fill (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function _augment (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array set method before overwriting
+  arr._set = arr.set
+
+  // deprecated
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.indexOf = BP.indexOf
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"27":27,"31":31,"6":6}],9:[function(_dereq_,module,exports){
+(function (Buffer){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+  if (Array.isArray) {
+    return Array.isArray(arg);
+  }
+  return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+}).call(this,{"isBuffer":_dereq_(30)})
+},{"30":30}],10:[function(_dereq_,module,exports){
+var Buffer = _dereq_(8).Buffer
+
+var CHARS = '.PYFGCRLAOEUIDHTNSQJKXBMWVZ_pyfgcrlaoeuidhtnsqjkxbmwvz1234567890'
+  .split('').sort().join('')
+
+module.exports = function (chars, exports) {
+  chars = chars || CHARS
+  exports = exports || {}
+  if(chars.length !== 64) throw new Error('a base 64 encoding requires 64 chars')
+
+  var codeToIndex = new Buffer(128)
+  codeToIndex.fill()
+
+  for(var i = 0; i < 64; i++) {
+    var code = chars.charCodeAt(i)
+    codeToIndex[code] = i
+  }
+
+  exports.encode = function (data) {
+      var s = '', l = data.length, hang = 0
+      for(var i = 0; i < l; i++) {
+        var v = data[i]
+
+        switch (i % 3) {
+          case 0:
+            s += chars[v >> 2]
+            hang = (v & 3) << 4
+          break;
+          case 1:
+            s += chars[hang | v >> 4]
+            hang = (v & 0xf) << 2
+          break;
+          case 2:
+            s += chars[hang | v >> 6]
+            s += chars[v & 0x3f]
+            hang = 0
+          break;
+        }
+
+      }
+      if(l%3) s += chars[hang]
+      return s
+    }
+  exports.decode = function (str) {
+      var l = str.length, j = 0
+      var b = new Buffer(~~((l/4)*3)), hang = 0
+
+      for(var i = 0; i < l; i++) {
+        var v = codeToIndex[str.charCodeAt(i)]
+
+        switch (i % 4) {
+          case 0:
+            hang = v << 2;
+          break;
+          case 1:
+            b[j++] = hang | v >> 4
+            hang = (v << 4) & 0xff
+          break;
+          case 2:
+            b[j++] = hang | v >> 2
+            hang = (v << 6) & 0xff
+          break;
+          case 3:
+            b[j++] = hang | v
+          break;
+        }
+
+      }
+      return b
+    }
+  return exports
+}
+
+module.exports(CHARS, module.exports)
+
+
+},{"8":8}],11:[function(_dereq_,module,exports){
+var util = _dereq_(98)
+  , AbstractIterator = _dereq_(16).AbstractIterator
+
+
+function DeferredIterator (options) {
+  AbstractIterator.call(this, options)
+
+  this._options = options
+  this._iterator = null
+  this._operations = []
+}
+
+util.inherits(DeferredIterator, AbstractIterator)
+
+DeferredIterator.prototype.setDb = function (db) {
+  var it = this._iterator = db.iterator(this._options)
+  this._operations.forEach(function (op) {
+    it[op.method].apply(it, op.args)
+  })
+}
+
+DeferredIterator.prototype._operation = function (method, args) {
+  if (this._iterator)
+    return this._iterator[method].apply(this._iterator, args)
+  this._operations.push({ method: method, args: args })
+}
+
+'next end'.split(' ').forEach(function (m) {
+  DeferredIterator.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+module.exports = DeferredIterator;
+
+},{"16":16,"98":98}],12:[function(_dereq_,module,exports){
+(function (Buffer,process){
+var util              = _dereq_(98)
+  , AbstractLevelDOWN = _dereq_(16).AbstractLevelDOWN
+  , DeferredIterator  = _dereq_(11)
+
+function DeferredLevelDOWN (location) {
+  AbstractLevelDOWN.call(this, typeof location == 'string' ? location : '') // optional location, who cares?
+  this._db         = undefined
+  this._operations = []
+  this._iterators  = []
+}
+
+util.inherits(DeferredLevelDOWN, AbstractLevelDOWN)
+
+// called by LevelUP when we have a real DB to take its place
+DeferredLevelDOWN.prototype.setDb = function (db) {
+  this._db = db
+  this._operations.forEach(function (op) {
+    db[op.method].apply(db, op.args)
+  })
+  this._iterators.forEach(function (it) {
+    it.setDb(db)
+  })
+}
+
+DeferredLevelDOWN.prototype._open = function (options, callback) {
+  return process.nextTick(callback)
+}
+
+// queue a new deferred operation
+DeferredLevelDOWN.prototype._operation = function (method, args) {
+  if (this._db)
+    return this._db[method].apply(this._db, args)
+  this._operations.push({ method: method, args: args })
+}
+
+// deferrables
+'put get del batch approximateSize'.split(' ').forEach(function (m) {
+  DeferredLevelDOWN.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+DeferredLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+DeferredLevelDOWN.prototype._iterator = function (options) {
+  if (this._db)
+    return this._db.iterator.apply(this._db, arguments)
+  var it = new DeferredIterator(options)
+  this._iterators.push(it)
+  return it
+}
+
+module.exports                  = DeferredLevelDOWN
+module.exports.DeferredIterator = DeferredIterator
+
+}).call(this,{"isBuffer":_dereq_(30)},_dereq_(59))
+},{"11":11,"16":16,"30":30,"59":59,"98":98}],13:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err)
+    throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+  if (!this._db._isBuffer(value)) value = String(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+}).call(this,_dereq_(59))
+},{"59":59}],14:[function(_dereq_,module,exports){
+arguments[4][3][0].apply(exports,arguments)
+},{"3":3,"59":59}],15:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(18)
+  , AbstractIterator     = _dereq_(14)
+  , AbstractChainedBatch = _dereq_(13)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+  this.status = 'new'
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.createIfMissing = options.createIfMissing != false
+  options.errorIfExists = !!options.errorIfExists
+
+  if (typeof this._open == 'function') {
+    this.status = 'opening'
+    this._open(options, function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'open'
+      callback()
+    })
+  } else {
+    this.status = 'open'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function') {
+    this.status = 'closing'
+    this._close(function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'closed'
+      callback()
+    })
+  } else {
+    this.status = 'closed'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.asBuffer = options.asBuffer != false
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  // coerce value to string in node, don't touch it in browser
+  // (indexeddb can store any JS type)
+  if (value != null && !this._isBuffer(value) && !process.browser)
+    value = String(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof array == 'function')
+    callback = array
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (!options || typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKey(e.type, 'type', this._isBuffer))
+      return callback(err)
+
+    if (err = this._checkKey(e.key, 'key', this._isBuffer))
+      return callback(err)
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  if (!this._isBuffer(start))
+    start = String(start)
+
+  if (!this._isBuffer(end))
+    end = String(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+  options.keys = options.keys != false
+  options.values = options.values != false
+  options.limit = 'limit' in options ? options.limit : -1
+  options.keyAsBuffer = options.keyAsBuffer != false
+  options.valueAsBuffer = options.valueAsBuffer != false
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._checkKey = function (obj, type) {
+
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj)) {
+    if (obj.length === 0)
+      return new Error(type + ' cannot be an empty Buffer')
+  } else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports = AbstractLevelDOWN
+
+}).call(this,{"isBuffer":_dereq_(30)},_dereq_(59))
+},{"13":13,"14":14,"18":18,"30":30,"59":59}],16:[function(_dereq_,module,exports){
+exports.AbstractLevelDOWN    = _dereq_(15)
+exports.AbstractIterator     = _dereq_(14)
+exports.AbstractChainedBatch = _dereq_(13)
+exports.isLevelDOWN          = _dereq_(17)
+
+},{"13":13,"14":14,"15":15,"17":17}],17:[function(_dereq_,module,exports){
+var AbstractLevelDOWN = _dereq_(15)
+
+function isLevelDOWN (db) {
+  if (!db || typeof db !== 'object')
+    return false
+  return Object.keys(AbstractLevelDOWN.prototype).filter(function (name) {
+    // TODO remove approximateSize check when method is gone
+    return name[0] != '_' && name != 'approximateSize'
+  }).every(function (name) {
+    return typeof db[name] == 'function'
+  })
+}
+
+module.exports = isLevelDOWN
+
+},{"15":15}],18:[function(_dereq_,module,exports){
+module.exports = extend
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function extend() {
+    var target = {}
+
+    for (var i = 0; i < arguments.length; i++) {
+        var source = arguments[i]
+
+        for (var key in source) {
+            if (hasOwnProperty.call(source, key)) {
+                target[key] = source[key]
+            }
+        }
+    }
+
+    return target
+}
+
+},{}],19:[function(_dereq_,module,exports){
+/**
+ * Copyright (c) 2013 Petka Antonov
+ * 
+ * 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:</p>
+ * 
+ * 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.
+ */
+"use strict";
+function Deque(capacity) {
+    this._capacity = getCapacity(capacity);
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+    if (isArray(capacity)) {
+        var len = capacity.length;
+        for (var i = 0; i < len; ++i) {
+            this[i] = capacity[i];
+        }
+        this._length = len;
+    }
+}
+
+Deque.prototype.toArray = function Deque$toArray() {
+    var len = this._length;
+    var ret = new Array(len);
+    var front = this._front;
+    var capacity = this._capacity;
+    for (var j = 0; j < len; ++j) {
+        ret[j] = this[(front + j) & (capacity - 1)];
+    }
+    return ret;
+};
+
+Deque.prototype.push = function Deque$push(item) {
+    var argsLength = arguments.length;
+    var length = this._length;
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = 0; i < argsLength; ++i) {
+                this._checkCapacity(length + 1);
+                var j = (this._front + length) & (this._capacity - 1);
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+            }
+            return length;
+        }
+        else {
+            var j = this._front;
+            for (var i = 0; i < argsLength; ++i) {
+                this[(j + length) & (capacity - 1)] = arguments[i];
+                j++;
+            }
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var i = (this._front + length) & (this._capacity - 1);
+    this[i] = item;
+    this._length = length + 1;
+    return length + 1;
+};
+
+Deque.prototype.pop = function Deque$pop() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var i = (this._front + length - 1) & (this._capacity - 1);
+    var ret = this[i];
+    this[i] = void 0;
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.shift = function Deque$shift() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var front = this._front;
+    var ret = this[front];
+    this[front] = void 0;
+    this._front = (front + 1) & (this._capacity - 1);
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.unshift = function Deque$unshift(item) {
+    var length = this._length;
+    var argsLength = arguments.length;
+
+
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = argsLength - 1; i >= 0; i--) {
+                this._checkCapacity(length + 1);
+                var capacity = this._capacity;
+                var j = (((( this._front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+                this._front = j;
+            }
+            return length;
+        }
+        else {
+            var front = this._front;
+            for (var i = argsLength - 1; i >= 0; i--) {
+                var j = (((( front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                front = j;
+            }
+            this._front = front;
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var capacity = this._capacity;
+    var i = (((( this._front - 1 ) &
+        ( capacity - 1) ) ^ capacity ) - capacity );
+    this[i] = item;
+    this._length = length + 1;
+    this._front = i;
+    return length + 1;
+};
+
+Deque.prototype.peekBack = function Deque$peekBack() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var index = (this._front + length - 1) & (this._capacity - 1);
+    return this[index];
+};
+
+Deque.prototype.peekFront = function Deque$peekFront() {
+    if (this._length === 0) {
+        return void 0;
+    }
+    return this[this._front];
+};
+
+Deque.prototype.get = function Deque$get(index) {
+    var i = index;
+    if ((i !== (i | 0))) {
+        return void 0;
+    }
+    var len = this._length;
+    if (i < 0) {
+        i = i + len;
+    }
+    if (i < 0 || i >= len) {
+        return void 0;
+    }
+    return this[(this._front + i) & (this._capacity - 1)];
+};
+
+Deque.prototype.isEmpty = function Deque$isEmpty() {
+    return this._length === 0;
+};
+
+Deque.prototype.clear = function Deque$clear() {
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+};
+
+Deque.prototype.toString = function Deque$toString() {
+    return this.toArray().toString();
+};
+
+Deque.prototype.valueOf = Deque.prototype.toString;
+Deque.prototype.removeFront = Deque.prototype.shift;
+Deque.prototype.removeBack = Deque.prototype.pop;
+Deque.prototype.insertFront = Deque.prototype.unshift;
+Deque.prototype.insertBack = Deque.prototype.push;
+Deque.prototype.enqueue = Deque.prototype.push;
+Deque.prototype.dequeue = Deque.prototype.shift;
+Deque.prototype.toJSON = Deque.prototype.toArray;
+
+Object.defineProperty(Deque.prototype, "length", {
+    get: function() {
+        return this._length;
+    },
+    set: function() {
+        throw new RangeError("");
+    }
+});
+
+Deque.prototype._makeCapacity = function Deque$_makeCapacity() {
+    var len = this._capacity;
+    for (var i = 0; i < len; ++i) {
+        this[i] = void 0;
+    }
+};
+
+Deque.prototype._checkCapacity = function Deque$_checkCapacity(size) {
+    if (this._capacity < size) {
+        this._resizeTo(getCapacity(this._capacity * 1.5 + 16));
+    }
+};
+
+Deque.prototype._resizeTo = function Deque$_resizeTo(capacity) {
+    var oldFront = this._front;
+    var oldCapacity = this._capacity;
+    var oldDeque = new Array(oldCapacity);
+    var length = this._length;
+
+    arrayCopy(this, 0, oldDeque, 0, oldCapacity);
+    this._capacity = capacity;
+    this._makeCapacity();
+    this._front = 0;
+    if (oldFront + length <= oldCapacity) {
+        arrayCopy(oldDeque, oldFront, this, 0, length);
+    } else {        var lengthBeforeWrapping =
+            length - ((oldFront + length) & (oldCapacity - 1));
+
+        arrayCopy(oldDeque, oldFront, this, 0, lengthBeforeWrapping);
+        arrayCopy(oldDeque, 0, this, lengthBeforeWrapping,
+            length - lengthBeforeWrapping);
+    }
+};
+
+
+var isArray = Array.isArray;
+
+function arrayCopy(src, srcIndex, dst, dstIndex, len) {
+    for (var j = 0; j < len; ++j) {
+        dst[j + dstIndex] = src[j + srcIndex];
+    }
+}
+
+function pow2AtLeast(n) {
+    n = n >>> 0;
+    n = n - 1;
+    n = n | (n >> 1);
+    n = n | (n >> 2);
+    n = n | (n >> 4);
+    n = n | (n >> 8);
+    n = n | (n >> 16);
+    return n + 1;
+}
+
+function getCapacity(capacity) {
+    if (typeof capacity !== "number") {
+        if (isArray(capacity)) {
+            capacity = capacity.length;
+        }
+        else {
+            return 16;
+        }
+    }
+    return pow2AtLeast(
+        Math.min(
+            Math.max(16, capacity), 1073741824)
+    );
+}
+
+module.exports = Deque;
+
+},{}],20:[function(_dereq_,module,exports){
+var prr = _dereq_(22)
+
+function init (type, message, cause) {
+  prr(this, {
+      type    : type
+    , name    : type
+      // can be passed just a 'cause'
+    , cause   : typeof message != 'string' ? message : cause
+    , message : !!message && typeof message != 'string' ? message.message : message
+
+  }, 'ewr')
+}
+
+// generic prototype, not intended to be actually used - helpful for `instanceof`
+function CustomError (message, cause) {
+  Error.call(this)
+  if (Error.captureStackTrace)
+    Error.captureStackTrace(this, arguments.callee)
+  init.call(this, 'CustomError', message, cause)
+}
+
+CustomError.prototype = new Error()
+
+function createError (errno, type, proto) {
+  var err = function (message, cause) {
+    init.call(this, type, message, cause)
+    //TODO: the specificity here is stupid, errno should be available everywhere
+    if (type == 'FilesystemError') {
+      this.code    = this.cause.code
+      this.path    = this.cause.path
+      this.errno   = this.cause.errno
+      this.message =
+        (errno.errno[this.cause.errno]
+          ? errno.errno[this.cause.errno].description
+          : this.cause.message)
+        + (this.cause.path ? ' [' + this.cause.path + ']' : '')
+    }
+    Error.call(this)
+    if (Error.captureStackTrace)
+      Error.captureStackTrace(this, arguments.callee)
+  }
+  err.prototype = !!proto ? new proto() : new CustomError()
+  return err
+}
+
+module.exports = function (errno) {
+  var ce = function (type, proto) {
+    return createError(errno, type, proto)
+  }
+  return {
+      CustomError     : CustomError
+    , FilesystemError : ce('FilesystemError')
+    , createError     : ce
+  }
+}
+
+},{"22":22}],21:[function(_dereq_,module,exports){
+var all = module.exports.all = [
+  {
+    errno: -2,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: -1,
+    code: 'UNKNOWN',
+    description: 'unknown error'
+  },
+  {
+    errno: 0,
+    code: 'OK',
+    description: 'success'
+  },
+  {
+    errno: 1,
+    code: 'EOF',
+    description: 'end of file'
+  },
+  {
+    errno: 2,
+    code: 'EADDRINFO',
+    description: 'getaddrinfo error'
+  },
+  {
+    errno: 3,
+    code: 'EACCES',
+    description: 'permission denied'
+  },
+  {
+    errno: 4,
+    code: 'EAGAIN',
+    description: 'resource temporarily unavailable'
+  },
+  {
+    errno: 5,
+    code: 'EADDRINUSE',
+    description: 'address already in use'
+  },
+  {
+    errno: 6,
+    code: 'EADDRNOTAVAIL',
+    description: 'address not available'
+  },
+  {
+    errno: 7,
+    code: 'EAFNOSUPPORT',
+    description: 'address family not supported'
+  },
+  {
+    errno: 8,
+    code: 'EALREADY',
+    description: 'connection already in progress'
+  },
+  {
+    errno: 9,
+    code: 'EBADF',
+    description: 'bad file descriptor'
+  },
+  {
+    errno: 10,
+    code: 'EBUSY',
+    description: 'resource busy or locked'
+  },
+  {
+    errno: 11,
+    code: 'ECONNABORTED',
+    description: 'software caused connection abort'
+  },
+  {
+    errno: 12,
+    code: 'ECONNREFUSED',
+    description: 'connection refused'
+  },
+  {
+    errno: 13,
+    code: 'ECONNRESET',
+    description: 'connection reset by peer'
+  },
+  {
+    errno: 14,
+    code: 'EDESTADDRREQ',
+    description: 'destination address required'
+  },
+  {
+    errno: 15,
+    code: 'EFAULT',
+    description: 'bad address in system call argument'
+  },
+  {
+    errno: 16,
+    code: 'EHOSTUNREACH',
+    description: 'host is unreachable'
+  },
+  {
+    errno: 17,
+    code: 'EINTR',
+    description: 'interrupted system call'
+  },
+  {
+    errno: 18,
+    code: 'EINVAL',
+    description: 'invalid argument'
+  },
+  {
+    errno: 19,
+    code: 'EISCONN',
+    description: 'socket is already connected'
+  },
+  {
+    errno: 20,
+    code: 'EMFILE',
+    description: 'too many open files'
+  },
+  {
+    errno: 21,
+    code: 'EMSGSIZE',
+    description: 'message too long'
+  },
+  {
+    errno: 22,
+    code: 'ENETDOWN',
+    description: 'network is down'
+  },
+  {
+    errno: 23,
+    code: 'ENETUNREACH',
+    description: 'network is unreachable'
+  },
+  {
+    errno: 24,
+    code: 'ENFILE',
+    description: 'file table overflow'
+  },
+  {
+    errno: 25,
+    code: 'ENOBUFS',
+    description: 'no buffer space available'
+  },
+  {
+    errno: 26,
+    code: 'ENOMEM',
+    description: 'not enough memory'
+  },
+  {
+    errno: 27,
+    code: 'ENOTDIR',
+    description: 'not a directory'
+  },
+  {
+    errno: 28,
+    code: 'EISDIR',
+    description: 'illegal operation on a directory'
+  },
+  {
+    errno: 29,
+    code: 'ENONET',
+    description: 'machine is not on the network'
+  },
+  {
+    errno: 31,
+    code: 'ENOTCONN',
+    description: 'socket is not connected'
+  },
+  {
+    errno: 32,
+    code: 'ENOTSOCK',
+    description: 'socket operation on non-socket'
+  },
+  {
+    errno: 33,
+    code: 'ENOTSUP',
+    description: 'operation not supported on socket'
+  },
+  {
+    errno: 34,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: 35,
+    code: 'ENOSYS',
+    description: 'function not implemented'
+  },
+  {
+    errno: 36,
+    code: 'EPIPE',
+    description: 'broken pipe'
+  },
+  {
+    errno: 37,
+    code: 'EPROTO',
+    description: 'protocol error'
+  },
+  {
+    errno: 38,
+    code: 'EPROTONOSUPPORT',
+    description: 'protocol not supported'
+  },
+  {
+    errno: 39,
+    code: 'EPROTOTYPE',
+    description: 'protocol wrong type for socket'
+  },
+  {
+    errno: 40,
+    code: 'ETIMEDOUT',
+    description: 'connection timed out'
+  },
+  {
+    errno: 41,
+    code: 'ECHARSET',
+    description: 'invalid Unicode character'
+  },
+  {
+    errno: 42,
+    code: 'EAIFAMNOSUPPORT',
+    description: 'address family for hostname not supported'
+  },
+  {
+    errno: 44,
+    code: 'EAISERVICE',
+    description: 'servname not supported for ai_socktype'
+  },
+  {
+    errno: 45,
+    code: 'EAISOCKTYPE',
+    description: 'ai_socktype not supported'
+  },
+  {
+    errno: 46,
+    code: 'ESHUTDOWN',
+    description: 'cannot send after transport endpoint shutdown'
+  },
+  {
+    errno: 47,
+    code: 'EEXIST',
+    description: 'file already exists'
+  },
+  {
+    errno: 48,
+    code: 'ESRCH',
+    description: 'no such process'
+  },
+  {
+    errno: 49,
+    code: 'ENAMETOOLONG',
+    description: 'name too long'
+  },
+  {
+    errno: 50,
+    code: 'EPERM',
+    description: 'operation not permitted'
+  },
+  {
+    errno: 51,
+    code: 'ELOOP',
+    description: 'too many symbolic links encountered'
+  },
+  {
+    errno: 52,
+    code: 'EXDEV',
+    description: 'cross-device link not permitted'
+  },
+  {
+    errno: 53,
+    code: 'ENOTEMPTY',
+    description: 'directory not empty'
+  },
+  {
+    errno: 54,
+    code: 'ENOSPC',
+    description: 'no space left on device'
+  },
+  {
+    errno: 55,
+    code: 'EIO',
+    description: 'i/o error'
+  },
+  {
+    errno: 56,
+    code: 'EROFS',
+    description: 'read-only file system'
+  },
+  {
+    errno: 57,
+    code: 'ENODEV',
+    description: 'no such device'
+  },
+  {
+    errno: 58,
+    code: 'ESPIPE',
+    description: 'invalid seek'
+  },
+  {
+    errno: 59,
+    code: 'ECANCELED',
+    description: 'operation canceled'
+  }
+]
+
+module.exports.errno = {}
+module.exports.code = {}
+
+all.forEach(function (error) {
+  module.exports.errno[error.errno] = error
+  module.exports.code[error.code] = error
+})
+
+module.exports.custom = _dereq_(20)(module.exports)
+module.exports.create = module.exports.custom.createError
+
+},{"20":20}],22:[function(_dereq_,module,exports){
+/*!
+  * prr
+  * (c) 2013 Rod Vagg <rod@vagg.org>
+  * https://github.com/rvagg/prr
+  * License: MIT
+  */
+
+(function (name, context, definition) {
+  if (typeof module != 'undefined' && module.exports)
+    module.exports = definition()
+  else
+    context[name] = definition()
+})('prr', this, function() {
+
+  var setProperty = typeof Object.defineProperty == 'function'
+      ? function (obj, key, options) {
+          Object.defineProperty(obj, key, options)
+          return obj
+        }
+      : function (obj, key, options) { // < es5
+          obj[key] = options.value
+          return obj
+        }
+
+    , makeOptions = function (value, options) {
+        var oo = typeof options == 'object'
+          , os = !oo && typeof options == 'string'
+          , op = function (p) {
+              return oo
+                ? !!options[p]
+                : os
+                  ? options.indexOf(p[0]) > -1
+                  : false
+            }
+
+        return {
+            enumerable   : op('enumerable')
+          , configurable : op('configurable')
+          , writable     : op('writable')
+          , value        : value
+        }
+      }
+
+    , prr = function (obj, key, value, options) {
+        var k
+
+        options = makeOptions(value, options)
+
+        if (typeof key == 'object') {
+          for (k in key) {
+            if (Object.hasOwnProperty.call(key, k)) {
+              options.value = key[k]
+              setProperty(obj, k, options)
+            }
+          }
+          return obj
+        }
+
+        return setProperty(obj, key, options)
+      }
+
+  return prr
+})
+},{}],23:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      }
+      throw TypeError('Uncaught, unspecified "error" event.');
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],24:[function(_dereq_,module,exports){
+/**
+ * # hasLocalStorage()
+ *
+ * returns `true` or `false` depending on whether localStorage is supported or not.
+ * Beware that some browsers like Safari do not support localStorage in private mode.
+ *
+ * inspired by this cappuccino commit
+ * https://github.com/cappuccino/cappuccino/commit/063b05d9643c35b303568a28809e4eb3224f71ec
+ *
+ * @returns {Boolean}
+ */
+function hasLocalStorage() {
+  try {
+
+    // we've to put this in here. I've seen Firefox throwing `Security error: 1000`
+    // when cookies have been disabled
+    if (typeof localStorage === 'undefined') {
+      return false;
+    }
+
+    // Just because localStorage exists does not mean it works. In particular it might be disabled
+    // as it is when Safari's private browsing mode is active.
+    localStorage.setItem('Storage-Test', '1');
+
+    // that should not happen ...
+    if (localStorage.getItem('Storage-Test') !== '1') {
+      return false;
+    }
+
+    // okay, let's clean up if we got here.
+    localStorage.removeItem('Storage-Test');
+  } catch (_error) {
+
+    // in case of an error, like Safari's Private Mode, return false
+    return false;
+  }
+
+  // we're good.
+  return true;
+}
+
+
+if (typeof exports === 'object') {
+  module.exports = hasLocalStorage;
+}
+
+},{}],25:[function(_dereq_,module,exports){
+(function (global){
+var exports = module.exports = {};
+var localStorageMemory = _dereq_(56);
+exports.hasLocalStorage = _dereq_(24);
+
+/**
+ * returns localStorage-compatible API, either backed by window.localStorage
+ * or memory if it's not available or not persistent.
+ *
+ * It also adds an object API (`.getObject(key)`,
+ * `.setObject(key, properties)`) and a `isPresistent` property
+ *
+ * @returns {Object}
+ */
+exports.create = function () {
+  var api;
+
+  if (!exports.hasLocalStorage()) {
+    api = localStorageMemory;
+    api.isPersistent = false;
+  } else {
+    api = global.localStorage;
+    api = {
+      get length() { return global.localStorage.length; },
+      getItem: global.localStorage.getItem.bind(global.localStorage),
+      setItem: global.localStorage.setItem.bind(global.localStorage),
+      removeItem: global.localStorage.removeItem.bind(global.localStorage),
+      key: global.localStorage.key.bind(global.localStorage),
+      clear: global.localStorage.clear.bind(global.localStorage),
+    };
+
+    api.isPersistent = true;
+  }
+
+  api.getObject = exports.getObject.bind(null, api);
+  api.setObject = exports.setObject.bind(null, api);
+
+  return api;
+};
+
+/**
+ * sets key to passed Object.
+ *
+ * @returns undefined
+ */
+exports.setObject = function (store, key, object) {
+  if (typeof object !== 'object') {
+    return store.setItem(key, object);
+  }
+
+  return store.setItem(key, JSON.stringify(object));
+};
+
+/**
+ * returns Object for key, or null
+ *
+ * @returns {Object|null}
+ */
+exports.getObject = function (store, key) {
+  var item = store.getItem(key);
+
+  if (!item) {
+    return null;
+  }
+
+  try {
+    return JSON.parse(item);
+  } catch (e) {
+    return item;
+  }
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"24":24,"56":56}],26:[function(_dereq_,module,exports){
+var api = _dereq_(25);
+module.exports = api.create();
+
+},{"25":25}],27:[function(_dereq_,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],28:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
+
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
+
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
+  }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],29:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
+
+},{}],30:[function(_dereq_,module,exports){
+/**
+ * Determine if an object is Buffer
+ *
+ * Author:   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * License:  MIT
+ *
+ * `npm install is-buffer`
+ */
+
+module.exports = function (obj) {
+  return !!(obj != null &&
+    (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
+      (obj.constructor &&
+      typeof obj.constructor.isBuffer === 'function' &&
+      obj.constructor.isBuffer(obj))
+    ))
+}
+
+},{}],31:[function(_dereq_,module,exports){
+var toString = {}.toString;
+
+module.exports = Array.isArray || function (arr) {
+  return toString.call(arr) == '[object Array]';
+};
+
+},{}],32:[function(_dereq_,module,exports){
+(function(factory) {
+  if(typeof exports === 'object') {
+    factory(exports);
+  } else {
+    factory(this);
+  }
+}).call(this, function(root) { 
+
+  var slice   = Array.prototype.slice,
+      each    = Array.prototype.forEach;
+
+  var extend = function(obj) {
+    if(typeof obj !== 'object') throw obj + ' is not an object' ;
+
+    var sources = slice.call(arguments, 1); 
+
+    each.call(sources, function(source) {
+      if(source) {
+        for(var prop in source) {
+          if(typeof source[prop] === 'object' && obj[prop]) {
+            extend.call(obj, obj[prop], source[prop]);
+          } else {
+            obj[prop] = source[prop];
+          }
+        } 
+      }
+    });
+
+    return obj;
+  }
+
+  root.extend = extend;
+});
+
+},{}],33:[function(_dereq_,module,exports){
+var encodings = _dereq_(34);
+
+module.exports = Codec;
+
+function Codec(opts){
+  this.opts = opts || {};
+  this.encodings = encodings;
+}
+
+Codec.prototype._encoding = function(encoding){
+  if (typeof encoding == 'string') encoding = encodings[encoding];
+  if (!encoding) encoding = encodings.id;
+  return encoding;
+};
+
+Codec.prototype._keyEncoding = function(opts, batchOpts){
+  return this._encoding(batchOpts && batchOpts.keyEncoding
+    || opts && opts.keyEncoding
+    || this.opts.keyEncoding);
+};
+
+Codec.prototype._valueEncoding = function(opts, batchOpts){
+  return this._encoding(
+    batchOpts && (batchOpts.valueEncoding || batchOpts.encoding)
+    || opts && (opts.valueEncoding || opts.encoding)
+    || (this.opts.valueEncoding || this.opts.encoding));
+};
+
+Codec.prototype.encodeKey = function(key, opts, batchOpts){
+  return this._keyEncoding(opts, batchOpts).encode(key);
+};
+
+Codec.prototype.encodeValue = function(value, opts, batchOpts){
+  return this._valueEncoding(opts, batchOpts).encode(value);
+};
+
+Codec.prototype.decodeKey = function(key, opts){
+  return this._keyEncoding(opts).decode(key);
+};
+
+Codec.prototype.decodeValue = function(value, opts){
+  return this._valueEncoding(opts).decode(value);
+};
+
+Codec.prototype.encodeBatch = function(ops, opts){
+  var self = this;
+
+  return ops.map(function(_op){
+    var op = {
+      type: _op.type,
+      key: self.encodeKey(_op.key, opts, _op)
+    };
+    if (self.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary';
+    if (_op.prefix) op.prefix = _op.prefix;
+    if ('value' in _op) {
+      op.value = self.encodeValue(_op.value, opts, _op);
+      if (self.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary';
+    }
+    return op;
+  });
+};
+
+var ltgtKeys = ['lt', 'gt', 'lte', 'gte', 'start', 'end'];
+
+Codec.prototype.encodeLtgt = function(ltgt){
+  var self = this;
+  var ret = {};
+  Object.keys(ltgt).forEach(function(key){
+    ret[key] = ltgtKeys.indexOf(key) > -1
+      ? self.encodeKey(ltgt[key], ltgt)
+      : ltgt[key]
+  });
+  return ret;
+};
+
+Codec.prototype.createStreamDecoder = function(opts){
+  var self = this;
+
+  if (opts.keys && opts.values) {
+    return function(key, value){
+      return {
+        key: self.decodeKey(key, opts),
+        value: self.decodeValue(value, opts)
+      };
+    };
+  } else if (opts.keys) {
+    return function(key) {
+      return self.decodeKey(key, opts);
+    }; 
+  } else if (opts.values) {
+    return function(_, value){
+      return self.decodeValue(value, opts);
+    }
+  } else {
+    return function(){};
+  }
+};
+
+Codec.prototype.keyAsBuffer = function(opts){
+  return this._keyEncoding(opts).buffer;
+};
+
+Codec.prototype.valueAsBuffer = function(opts){
+  return this._valueEncoding(opts).buffer;
+};
+
+
+},{"34":34}],34:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.utf8 = exports['utf-8'] = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : String(data);
+  },
+  decode: identity,
+  buffer: false,
+  type: 'utf8'
+};
+
+exports.json = {
+  encode: JSON.stringify,
+  decode: JSON.parse,
+  buffer: false,
+  type: 'json'
+};
+
+exports.binary = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : new Buffer(data);      
+  },
+  decode: identity,
+  buffer: true,
+  type: 'binary'
+};
+
+exports.id = {
+  encode: function(data){
+    return data;
+  },
+  decode: function(data){
+    return data;
+  },
+  buffer: false,
+  type: 'id'
+};
+
+var bufferEncodings = [
+  'hex',
+  'ascii',
+  'base64',
+  'ucs2',
+  'ucs-2',
+  'utf16le',
+  'utf-16le'
+];
+
+bufferEncodings.forEach(function(type){
+  exports[type] = {
+    encode: function(data){
+      return isBinary(data)
+        ? data
+        : new Buffer(data, type);
+    },
+    decode: function(buffer){
+      return buffer.toString(type);
+    },
+    buffer: true,
+    type: type
+  };
+});
+
+function identity(value){
+  return value;
+}
+
+function isBinary(data){
+  return data === undefined
+    || data === null
+    || Buffer.isBuffer(data);
+}
+
+
+}).call(this,_dereq_(8).Buffer)
+},{"8":8}],35:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(21).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+    LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"21":21}],36:[function(_dereq_,module,exports){
+var inherits = _dereq_(29);
+var Readable = _dereq_(43).Readable;
+var extend = _dereq_(44);
+var EncodingError = _dereq_(35).EncodingError;
+
+module.exports = ReadStream;
+inherits(ReadStream, Readable);
+
+function ReadStream(iterator, options){
+  if (!(this instanceof ReadStream)) return new ReadStream(iterator, options);
+  Readable.call(this, extend(options, {
+    objectMode: true
+  }));
+  this._iterator = iterator;
+  this._destroyed = false;
+  this._decoder = null;
+  if (options && options.decoder) this._decoder = options.decoder;
+  this.on('end', this._cleanup.bind(this));
+}
+
+ReadStream.prototype._read = function(){
+  var self = this;
+  if (this._destroyed) return;
+
+  this._iterator.next(function(err, key, value){
+    if (self._destroyed) return;
+    if (err) return self.emit('error', err);
+    if (key === undefined && value === undefined) {
+      self.push(null);
+    } else {
+      if (!self._decoder) return self.push({ key: key, value: value });
+
+      try {
+        var value = self._decoder(key, value);
+      } catch (err) {
+        self.emit('error', new EncodingError(err));
+        self.push(null);
+        return;
+      }
+      self.push(value);
+    }
+  });
+};
+
+ReadStream.prototype.destroy =
+ReadStream.prototype._cleanup = function(){
+  var self = this;
+  if (this._destroyed) return;
+  this._destroyed = true;
+
+  this._iterator.end(function(err){
+    if (err) return self.emit('error', err);
+    self.emit('close');
+  });
+};
+
+
+},{"29":29,"35":35,"43":43,"44":44}],37:[function(_dereq_,module,exports){
+module.exports = Array.isArray || function (arr) {
+  return Object.prototype.toString.call(arr) == '[object Array]';
+};
+
+},{}],38:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) keys.push(key);
+  return keys;
+}
+/*</replacement>*/
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var Readable = _dereq_(40);
+var Writable = _dereq_(42);
+
+util.inherits(Duplex, Readable);
+
+forEach(objectKeys(Writable.prototype), function(method) {
+  if (!Duplex.prototype[method])
+    Duplex.prototype[method] = Writable.prototype[method];
+});
+
+function Duplex(options) {
+  if (!(this instanceof Duplex))
+    return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false)
+    this.readable = false;
+
+  if (options && options.writable === false)
+    this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false)
+    this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended)
+    return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  process.nextTick(this.end.bind(this));
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+}).call(this,_dereq_(59))
+},{"29":29,"40":40,"42":42,"59":59,"9":9}],39:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(41);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough))
+    return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function(chunk, encoding, cb) {
+  cb(null, chunk);
+};
+
+},{"29":29,"41":41,"9":9}],40:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(37);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(62);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var StringDecoder;
+
+
+/*<replacement>*/
+var debug = _dereq_(7);
+if (debug && debug.debuglog) {
+  debug = debug.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  var Duplex = _dereq_(38);
+
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(73).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  var Duplex = _dereq_(38);
+
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (util.isString(chunk) && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (util.isNullOrUndefined(chunk)) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      if (!addToFront)
+        state.reading = false;
+
+      // if we want the data now, just emit it.
+      if (state.flowing && state.length === 0 && !state.sync) {
+        stream.emit('data', chunk);
+        stream.read(0);
+      } else {
+        // update the buffer info.
+        state.length += state.objectMode ? 1 : chunk.length;
+        if (addToFront)
+          state.buffer.unshift(chunk);
+        else
+          state.buffer.push(chunk);
+
+        if (state.needReadable)
+          emitReadable(stream);
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(73).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (isNaN(n) || util.isNull(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (!util.isNumber(n) || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended)
+      endReadable(this);
+    else
+      emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0)
+      endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (util.isNull(ret)) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0)
+    endReadable(this);
+
+  if (!util.isNull(ret))
+    this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync)
+      process.nextTick(function() {
+        emitReadable_(stream);
+      });
+    else
+      emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain &&
+        (!dest._writableState || dest._writableState.needDrain))
+      ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      debug('false write response, pause',
+            src._readableState.awaitDrain);
+      src._readableState.awaitDrain++;
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain)
+      state.awaitDrain--;
+    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        var self = this;
+        process.nextTick(function() {
+          debug('readable nexttick read 0');
+          self.read(0);
+        });
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    if (!state.reading) {
+      debug('resume read 0');
+      this.read(0);
+    }
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    process.nextTick(function() {
+      resume_(stream, state);
+    });
+  }
+}
+
+function resume_(stream, state) {
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading)
+    stream.read(0);
+}
+
+Readable.prototype.pause = function() {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    debug('wrapped data');
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+    if (!chunk || !state.objectMode && !chunk.length)
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(59))
+},{"23":23,"29":29,"37":37,"38":38,"59":59,"62":62,"7":7,"73":73,"8":8,"9":9}],41:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(38);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (!util.isNullOrUndefined(data))
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('prefinish', function() {
+    if (util.isFunction(this._flush))
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"29":29,"38":38,"9":9}],42:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var Stream = _dereq_(62);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  var Duplex = _dereq_(38);
+
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(38);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (!util.isFunction(cb))
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function() {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function() {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing &&
+        !state.corked &&
+        !state.finished &&
+        !state.bufferProcessing &&
+        state.buffer.length)
+      clearBuffer(this, state);
+  }
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      util.isString(chunk)) {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing || state.corked)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev)
+    stream._writev(chunk, state.onwrite);
+  else
+    stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      state.pendingcb--;
+      cb(er);
+    });
+  else {
+    state.pendingcb--;
+    cb(er);
+  }
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished &&
+        !state.corked &&
+        !state.bufferProcessing &&
+        state.buffer.length) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  if (stream._writev && state.buffer.length > 1) {
+    // Fast case, write everything using _writev()
+    var cbs = [];
+    for (var c = 0; c < state.buffer.length; c++)
+      cbs.push(state.buffer[c].callback);
+
+    // count the one we are adding, as well.
+    // TODO(isaacs) clean this up
+    state.pendingcb++;
+    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
+      for (var i = 0; i < cbs.length; i++) {
+        state.pendingcb--;
+        cbs[i](err);
+      }
+    });
+
+    // Clear buffer
+    state.buffer = [];
+  } else {
+    // Slow case, write chunks one-by-one
+    for (var c = 0; c < state.buffer.length; c++) {
+      var entry = state.buffer[c];
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        c++;
+        break;
+      }
+    }
+
+    if (c < state.buffer.length)
+      state.buffer = state.buffer.slice(c);
+    else
+      state.buffer.length = 0;
+  }
+
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (util.isFunction(chunk)) {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (!util.isNullOrUndefined(chunk))
+    this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else
+      prefinish(stream, state);
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(59))
+},{"29":29,"38":38,"59":59,"62":62,"8":8,"9":9}],43:[function(_dereq_,module,exports){
+(function (process){
+exports = module.exports = _dereq_(40);
+exports.Stream = _dereq_(62);
+exports.Readable = exports;
+exports.Writable = _dereq_(42);
+exports.Duplex = _dereq_(38);
+exports.Transform = _dereq_(41);
+exports.PassThrough = _dereq_(39);
+if (!process.browser && process.env.READABLE_STREAM === 'disable') {
+  module.exports = _dereq_(62);
+}
+
+}).call(this,_dereq_(59))
+},{"38":38,"39":39,"40":40,"41":41,"42":42,"59":59,"62":62}],44:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],45:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var util          = _dereq_(47)
+  , WriteError    = _dereq_(35).WriteError
+
+  , getOptions    = util.getOptions
+  , dispatchError = util.dispatchError
+
+function Batch (levelup, codec) {
+  this._levelup = levelup
+  this._codec = codec
+  this.batch = levelup.db.batch()
+  this.ops = []
+  this.length = 0
+}
+
+Batch.prototype.put = function (key_, value_, options) {
+  options = getOptions(options)
+
+  var key   = this._codec.encodeKey(key_, options)
+    , value = this._codec.encodeValue(value_, options)
+
+  try {
+    this.batch.put(key, value)
+  } catch (e) {
+    throw new WriteError(e)
+  }
+  this.ops.push({ type : 'put', key : key, value : value })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.del = function (key_, options) {
+  options = getOptions(options)
+
+  var key = this._codec.encodeKey(key_, options)
+
+  try {
+    this.batch.del(key)
+  } catch (err) {
+    throw new WriteError(err)
+  }
+  this.ops.push({ type : 'del', key : key })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.clear = function () {
+  try {
+    this.batch.clear()
+  } catch (err) {
+    throw new WriteError(err)
+  }
+
+  this.ops = []
+  this.length = 0
+  return this
+}
+
+Batch.prototype.write = function (callback) {
+  var levelup = this._levelup
+    , ops     = this.ops
+
+  try {
+    this.batch.write(function (err) {
+      if (err)
+        return dispatchError(levelup, new WriteError(err), callback)
+      levelup.emit('batch', ops)
+      if (callback)
+        callback()
+    })
+  } catch (err) {
+    throw new WriteError(err)
+  }
+}
+
+module.exports = Batch
+
+},{"35":35,"47":47}],46:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var EventEmitter        = _dereq_(23).EventEmitter
+  , inherits            = _dereq_(98).inherits
+  , deprecate           = _dereq_(98).deprecate
+  , extend              = _dereq_(48)
+  , prr                 = _dereq_(60)
+  , DeferredLevelDOWN   = _dereq_(12)
+  , IteratorStream      = _dereq_(36)
+
+  , errors              = _dereq_(35)
+  , WriteError          = errors.WriteError
+  , ReadError           = errors.ReadError
+  , NotFoundError       = errors.NotFoundError
+  , OpenError           = errors.OpenError
+  , EncodingError       = errors.EncodingError
+  , InitializationError = errors.InitializationError
+
+  , util                = _dereq_(47)
+  , Batch               = _dereq_(45)
+  , Codec               = _dereq_(33)
+
+  , getOptions          = util.getOptions
+  , defaultOptions      = util.defaultOptions
+  , getLevelDOWN        = util.getLevelDOWN
+  , dispatchError       = util.dispatchError
+  , isDefined           = util.isDefined
+
+function getCallback (options, callback) {
+  return typeof options == 'function' ? options : callback
+}
+
+// Possible LevelUP#_status values:
+//  - 'new'     - newly created, not opened or closed
+//  - 'opening' - waiting for the database to be opened, post open()
+//  - 'open'    - successfully opened the database, available for use
+//  - 'closing' - waiting for the database to be closed, post close()
+//  - 'closed'  - database has been successfully closed, should not be
+//                 used except for another open() operation
+
+function LevelUP (location, options, callback) {
+  if (!(this instanceof LevelUP))
+    return new LevelUP(location, options, callback)
+
+  var error
+
+  EventEmitter.call(this)
+  this.setMaxListeners(Infinity)
+
+  if (typeof location == 'function') {
+    options = typeof options == 'object' ? options : {}
+    options.db = location
+    location = null
+  } else if (typeof location == 'object' && typeof location.db == 'function') {
+    options = location
+    location = null
+  }
+
+
+  if (typeof options == 'function') {
+    callback = options
+    options  = {}
+  }
+
+  if ((!options || typeof options.db != 'function') && typeof location != 'string') {
+    error = new InitializationError(
+        'Must provide a location for the database')
+    if (callback) {
+      return process.nextTick(function () {
+        callback(error)
+      })
+    }
+    throw error
+  }
+
+  options      = getOptions(options)
+  this.options = extend(defaultOptions, options)
+  this._codec = new Codec(this.options)
+  this._status = 'new'
+  // set this.location as enumerable but not configurable or writable
+  prr(this, 'location', location, 'e')
+
+  this.open(callback)
+}
+
+inherits(LevelUP, EventEmitter)
+
+LevelUP.prototype.open = function (callback) {
+  var self = this
+    , dbFactory
+    , db
+
+  if (this.isOpen()) {
+    if (callback)
+      process.nextTick(function () { callback(null, self) })
+    return this
+  }
+
+  if (this._isOpening()) {
+    return callback && this.once(
+        'open'
+      , function () { callback(null, self) }
+    )
+  }
+
+  this.emit('opening')
+
+  this._status = 'opening'
+  this.db      = new DeferredLevelDOWN(this.location)
+  dbFactory    = this.options.db || getLevelDOWN()
+  db           = dbFactory(this.location)
+
+  db.open(this.options, function (err) {
+    if (err) {
+      return dispatchError(self, new OpenError(err), callback)
+    } else {
+      self.db.setDb(db)
+      self.db = db
+      self._status = 'open'
+      if (callback)
+        callback(null, self)
+      self.emit('open')
+      self.emit('ready')
+    }
+  })
+}
+
+LevelUP.prototype.close = function (callback) {
+  var self = this
+
+  if (this.isOpen()) {
+    this._status = 'closing'
+    this.db.close(function () {
+      self._status = 'closed'
+      self.emit('closed')
+      if (callback)
+        callback.apply(null, arguments)
+    })
+    this.emit('closing')
+    this.db = new DeferredLevelDOWN(this.location)
+  } else if (this._status == 'closed' && callback) {
+    return process.nextTick(callback)
+  } else if (this._status == 'closing' && callback) {
+    this.once('closed', callback)
+  } else if (this._isOpening()) {
+    this.once('open', function () {
+      self.close(callback)
+    })
+  }
+}
+
+LevelUP.prototype.isOpen = function () {
+  return this._status == 'open'
+}
+
+LevelUP.prototype._isOpening = function () {
+  return this._status == 'opening'
+}
+
+LevelUP.prototype.isClosed = function () {
+  return (/^clos/).test(this._status)
+}
+
+function maybeError(db, options, callback) {
+  if (!db._isOpening() && !db.isOpen()) {
+    dispatchError(
+        db
+      , new ReadError('Database is not open')
+      , callback
+    )
+    return true
+  }
+}
+
+function writeError (db, message, callback) {
+  dispatchError(
+      db
+     , new WriteError(message)
+     , callback
+  )
+}
+
+function readError (db, message, callback) {
+  dispatchError(
+      db
+     , new ReadError(message)
+     , callback
+  )
+}
+
+
+LevelUP.prototype.get = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  if (key_ === null || key_ === undefined || 'function' !== typeof callback)
+    return readError(this
+      , 'get() requires key and callback arguments', callback)
+
+  options = util.getOptions(options)
+  key = this._codec.encodeKey(key_, options)
+
+  options.asBuffer = this._codec.valueAsBuffer(options)
+
+  this.db.get(key, options, function (err, value) {
+    if (err) {
+      if ((/notfound/i).test(err) || err.notFound) {
+        err = new NotFoundError(
+            'Key not found in database [' + key_ + ']', err)
+      } else {
+        err = new ReadError(err)
+      }
+      return dispatchError(self, err, callback)
+    }
+    if (callback) {
+      try {
+        value = self._codec.decodeValue(value, options)
+      } catch (e) {
+        return callback(new EncodingError(e))
+      }
+      callback(null, value)
+    }
+  })
+}
+
+LevelUP.prototype.put = function (key_, value_, options, callback) {
+  var self = this
+    , key
+    , value
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'put() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+  value   = this._codec.encodeValue(value_, options)
+
+  this.db.put(key, value, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('put', key_, value_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.del = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'del() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+
+  this.db.del(key, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('del', key_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.batch = function (arr_, options, callback) {
+  var self = this
+    , keyEnc
+    , valueEnc
+    , arr
+
+  if (!arguments.length)
+    return new Batch(this, this._codec)
+
+  callback = getCallback(options, callback)
+
+  if (!Array.isArray(arr_))
+    return writeError(this, 'batch() requires an array argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options  = getOptions(options)
+  arr      = self._codec.encodeBatch(arr_, options)
+  arr      = arr.map(function (op) {
+    if (!op.type && op.key !== undefined && op.value !== undefined)
+      op.type = 'put'
+    return op
+  })
+
+  this.db.batch(arr, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('batch', arr_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.approximateSize = deprecate(function (start_, end_, options, callback) {   
+  var self = this    
+    , start    
+    , end    
+   
+  callback = getCallback(options, callback)    
+   
+  options = getOptions(options)    
+   
+  if (start_ === null || start_ === undefined    
+        || end_ === null || end_ === undefined || 'function' !== typeof callback)    
+    return readError(this, 'approximateSize() requires start, end and callback arguments', callback)   
+   
+  start = this._codec.encodeKey(start_, options)   
+  end   = this._codec.encodeKey(end_, options)   
+   
+  this.db.approximateSize(start, end, function (err, size) {   
+    if (err) {   
+      return dispatchError(self, new OpenError(err), callback)   
+    } else if (callback) {   
+      callback(null, size)   
+    }    
+  })   
+}, 'db.approximateSize() is deprecated. Use db.db.approximateSize() instead')
+
+LevelUP.prototype.readStream =
+LevelUP.prototype.createReadStream = function (options) {
+  options = extend( {keys: true, values: true}, this.options, options)
+
+  options.keyEncoding   = options.keyEncoding
+  options.valueEncoding = options.valueEncoding
+
+  options = this._codec.encodeLtgt(options);
+  options.keyAsBuffer   = this._codec.keyAsBuffer(options)
+  options.valueAsBuffer = this._codec.valueAsBuffer(options)
+
+  if ('number' !== typeof options.limit)
+    options.limit = -1
+
+  return new IteratorStream(this.db.iterator(options), extend(options, {
+    decoder: this._codec.createStreamDecoder(options)
+  }))
+}
+
+LevelUP.prototype.keyStream =
+LevelUP.prototype.createKeyStream = function (options) {
+  return this.createReadStream(extend(options, { keys: true, values: false }))
+}
+
+LevelUP.prototype.valueStream =
+LevelUP.prototype.createValueStream = function (options) {
+  return this.createReadStream(extend(options, { keys: false, values: true }))
+}
+
+LevelUP.prototype.toString = function () {
+  return 'LevelUP'
+}
+
+function utilStatic (name) {
+  return function (location, callback) {
+    getLevelDOWN()[name](location, callback || function () {})
+  }
+}
+
+module.exports         = LevelUP
+module.exports.errors  = _dereq_(35)
+module.exports.destroy = deprecate(
+    utilStatic('destroy')
+  , 'levelup.destroy() is deprecated. Use leveldown.destroy() instead'
+)
+module.exports.repair  = deprecate(
+    utilStatic('repair')
+  , 'levelup.repair() is deprecated. Use leveldown.repair() instead'
+)
+
+
+}).call(this,_dereq_(59))
+},{"12":12,"23":23,"33":33,"35":35,"36":36,"45":45,"47":47,"48":48,"59":59,"60":60,"98":98}],47:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var extend         = _dereq_(48)
+  , LevelUPError   = _dereq_(35).LevelUPError
+  , format         = _dereq_(98).format
+  , defaultOptions = {
+        createIfMissing : true
+      , errorIfExists   : false
+      , keyEncoding     : 'utf8'
+      , valueEncoding   : 'utf8'
+      , compression     : true
+    }
+
+  , leveldown
+
+function getOptions (options) {
+  if (typeof options == 'string')
+    options = { valueEncoding: options }
+  if (typeof options != 'object')
+    options = {}
+  return options
+}
+
+function getLevelDOWN () {
+  if (leveldown)
+    return leveldown
+
+  var requiredVersion  = _dereq_(49).devDependencies.leveldown
+    , leveldownVersion
+
+  try {
+    leveldownVersion = _dereq_(7).version
+  } catch (e) {
+    throw requireError(e)
+  }
+
+  if (!_dereq_(7).satisfies(leveldownVersion, requiredVersion)) {
+    throw new LevelUPError(
+        'Installed version of LevelDOWN ('
+      + leveldownVersion
+      + ') does not match required version ('
+      + requiredVersion
+      + ')'
+    )
+  }
+
+  try {
+    return leveldown = _dereq_(7)
+  } catch (e) {
+    throw requireError(e)
+  }
+}
+
+function requireError (e) {
+  var template = 'Failed to require LevelDOWN (%s). Try `npm install leveldown` if it\'s missing'
+  return new LevelUPError(format(template, e.message))
+}
+
+function dispatchError (db, error, callback) {
+  typeof callback == 'function' ? callback(error) : db.emit('error', error)
+}
+
+function isDefined (v) {
+  return typeof v !== 'undefined'
+}
+
+module.exports = {
+    defaultOptions  : defaultOptions
+  , getOptions      : getOptions
+  , getLevelDOWN    : getLevelDOWN
+  , dispatchError   : dispatchError
+  , isDefined       : isDefined
+}
+
+},{"35":35,"48":48,"49":49,"7":7,"98":98}],48:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],49:[function(_dereq_,module,exports){
+module.exports={
+  "_args": [
+    [
+      "levelup@1.3.1",
+      "/Users/nolan/workspace/pouchdb"
+    ]
+  ],
+  "_from": "levelup@1.3.1",
+  "_id": "levelup@1.3.1",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/levelup",
+  "_nodeVersion": "4.2.2",
+  "_npmUser": {
+    "email": "ralphtheninja@riseup.net",
+    "name": "ralphtheninja"
+  },
+  "_npmVersion": "3.5.0",
+  "_phantomChildren": {},
+  "_requested": {
+    "name": "levelup",
+    "raw": "levelup@1.3.1",
+    "rawSpec": "1.3.1",
+    "scope": null,
+    "spec": "1.3.1",
+    "type": "version"
+  },
+  "_requiredBy": [
+    "/",
+    "/pouchdb"
+  ],
+  "_resolved": "http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",
+  "_shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+  "_shrinkwrap": null,
+  "_spec": "levelup@1.3.1",
+  "_where": "/Users/nolan/workspace/pouchdb",
+  "browser": {
+    "leveldown": false,
+    "leveldown/package": false,
+    "semver": false
+  },
+  "bugs": {
+    "url": "https://github.com/level/levelup/issues"
+  },
+  "contributors": [
+    {
+      "email": "r@va.gg",
+      "name": "Rod Vagg",
+      "url": "https://github.com/rvagg"
+    },
+    {
+      "email": "john@chesl.es",
+      "name": "John Chesley",
+      "url": "https://github.com/chesles/"
+    },
+    {
+      "email": "raynos2@gmail.com",
+      "name": "Jake Verbaten",
+      "url": "https://github.com/raynos"
+    },
+    {
+      "email": "dominic.tarr@gmail.com",
+      "name": "Dominic Tarr",
+      "url": "https://github.com/dominictarr"
+    },
+    {
+      "email": "max@maxogden.com",
+      "name": "Max Ogden",
+      "url": "https://github.com/maxogden"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "Lars-Magnus Skog",
+      "url": "https://github.com/ralphtheninja"
+    },
+    {
+      "email": "david.bjorklund@gmail.com",
+      "name": "David Björklund",
+      "url": "https://github.com/kesla"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "Julian Gruber",
+      "url": "https://github.com/juliangruber"
+    },
+    {
+      "email": "paolo@async.ly",
+      "name": "Paolo Fragomeni",
+      "url": "https://github.com/hij1nx"
+    },
+    {
+      "email": "anton.whalley@nearform.com",
+      "name": "Anton Whalley",
+      "url": "https://github.com/No9"
+    },
+    {
+      "email": "matteo.collina@gmail.com",
+      "name": "Matteo Collina",
+      "url": "https://github.com/mcollina"
+    },
+    {
+      "email": "pedro.teixeira@gmail.com",
+      "name": "Pedro Teixeira",
+      "url": "https://github.com/pgte"
+    },
+    {
+      "email": "mail@substack.net",
+      "name": "James Halliday",
+      "url": "https://github.com/substack"
+    },
+    {
+      "email": "jcrugzz@gmail.com",
+      "name": "Jarrett Cruger",
+      "url": "https://github.com/jcrugzz"
+    }
+  ],
+  "dependencies": {
+    "deferred-leveldown": "~1.2.1",
+    "level-codec": "~6.1.0",
+    "level-errors": "~1.0.3",
+    "level-iterator-stream": "~1.3.0",
+    "prr": "~1.0.1",
+    "semver": "~5.1.0",
+    "xtend": "~4.0.0"
+  },
+  "description": "Fast & simple storage - a Node.js-style LevelDB wrapper",
+  "devDependencies": {
+    "async": "~1.5.0",
+    "bustermove": "~1.0.0",
+    "delayed": "~1.0.1",
+    "faucet": "~0.0.1",
+    "leveldown": "^1.1.0",
+    "memdown": "~1.1.0",
+    "msgpack-js": "~0.3.0",
+    "referee": "~1.2.0",
+    "rimraf": "~2.4.3",
+    "slow-stream": "0.0.4",
+    "tap": "~2.3.1",
+    "tape": "~4.2.1"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+    "tarball": "https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"
+  },
+  "gitHead": "40bd66872974140c79a74d9411b992ddffa926a4",
+  "homepage": "https://github.com/level/levelup",
+  "keywords": [
+    "leveldb",
+    "stream",
+    "database",
+    "db",
+    "store",
+    "storage",
+    "json"
+  ],
+  "license": "MIT",
+  "main": "lib/levelup.js",
+  "maintainers": [
+    {
+      "email": "rod@vagg.org",
+      "name": "rvagg"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "ralphtheninja"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "juliangruber"
+    }
+  ],
+  "name": "levelup",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/level/levelup.git"
+  },
+  "scripts": {
+    "test": "tape test/*-test.js | faucet"
+  },
+  "version": "1.3.1"
+}
+
+},{}],50:[function(_dereq_,module,exports){
+'use strict';
+var immediate = _dereq_(28);
+
+/* istanbul ignore next */
+function INTERNAL() {}
+
+var handlers = {};
+
+var REJECTED = ['REJECTED'];
+var FULFILLED = ['FULFILLED'];
+var PENDING = ['PENDING'];
+
+module.exports = exports = Promise;
+
+function Promise(resolver) {
+  if (typeof resolver !== 'function') {
+    throw new TypeError('resolver must be a function');
+  }
+  this.state = PENDING;
+  this.queue = [];
+  this.outcome = void 0;
+  if (resolver !== INTERNAL) {
+    safelyResolveThenable(this, resolver);
+  }
+}
+
+Promise.prototype["catch"] = function (onRejected) {
+  return this.then(null, onRejected);
+};
+Promise.prototype.then = function (onFulfilled, onRejected) {
+  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
+    typeof onRejected !== 'function' && this.state === REJECTED) {
+    return this;
+  }
+  var promise = new this.constructor(INTERNAL);
+  if (this.state !== PENDING) {
+    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
+    unwrap(promise, resolver, this.outcome);
+  } else {
+    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
+  }
+
+  return promise;
+};
+function QueueItem(promise, onFulfilled, onRejected) {
+  this.promise = promise;
+  if (typeof onFulfilled === 'function') {
+    this.onFulfilled = onFulfilled;
+    this.callFulfilled = this.otherCallFulfilled;
+  }
+  if (typeof onRejected === 'function') {
+    this.onRejected = onRejected;
+    this.callRejected = this.otherCallRejected;
+  }
+}
+QueueItem.prototype.callFulfilled = function (value) {
+  handlers.resolve(this.promise, value);
+};
+QueueItem.prototype.otherCallFulfilled = function (value) {
+  unwrap(this.promise, this.onFulfilled, value);
+};
+QueueItem.prototype.callRejected = function (value) {
+  handlers.reject(this.promise, value);
+};
+QueueItem.prototype.otherCallRejected = function (value) {
+  unwrap(this.promise, this.onRejected, value);
+};
+
+function unwrap(promise, func, value) {
+  immediate(function () {
+    var returnValue;
+    try {
+      returnValue = func(value);
+    } catch (e) {
+      return handlers.reject(promise, e);
+    }
+    if (returnValue === promise) {
+      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
+    } else {
+      handlers.resolve(promise, returnValue);
+    }
+  });
+}
+
+handlers.resolve = function (self, value) {
+  var result = tryCatch(getThen, value);
+  if (result.status === 'error') {
+    return handlers.reject(self, result.value);
+  }
+  var thenable = result.value;
+
+  if (thenable) {
+    safelyResolveThenable(self, thenable);
+  } else {
+    self.state = FULFILLED;
+    self.outcome = value;
+    var i = -1;
+    var len = self.queue.length;
+    while (++i < len) {
+      self.queue[i].callFulfilled(value);
+    }
+  }
+  return self;
+};
+handlers.reject = function (self, error) {
+  self.state = REJECTED;
+  self.outcome = error;
+  var i = -1;
+  var len = self.queue.length;
+  while (++i < len) {
+    self.queue[i].callRejected(error);
+  }
+  return self;
+};
+
+function getThen(obj) {
+  // Make sure we only access the accessor once as required by the spec
+  var then = obj && obj.then;
+  if (obj && typeof obj === 'object' && typeof then === 'function') {
+    return function appyThen() {
+      then.apply(obj, arguments);
+    };
+  }
+}
+
+function safelyResolveThenable(self, thenable) {
+  // Either fulfill, reject or reject with error
+  var called = false;
+  function onError(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.reject(self, value);
+  }
+
+  function onSuccess(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.resolve(self, value);
+  }
+
+  function tryToUnwrap() {
+    thenable(onSuccess, onError);
+  }
+
+  var result = tryCatch(tryToUnwrap);
+  if (result.status === 'error') {
+    onError(result.value);
+  }
+}
+
+function tryCatch(func, value) {
+  var out = {};
+  try {
+    out.value = func(value);
+    out.status = 'success';
+  } catch (e) {
+    out.status = 'error';
+    out.value = e;
+  }
+  return out;
+}
+
+exports.resolve = resolve;
+function resolve(value) {
+  if (value instanceof this) {
+    return value;
+  }
+  return handlers.resolve(new this(INTERNAL), value);
+}
+
+exports.reject = reject;
+function reject(reason) {
+  var promise = new this(INTERNAL);
+  return handlers.reject(promise, reason);
+}
+
+exports.all = all;
+function all(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var values = new Array(len);
+  var resolved = 0;
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    allResolver(iterable[i], i);
+  }
+  return promise;
+  function allResolver(value, i) {
+    self.resolve(value).then(resolveFromAll, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+    function resolveFromAll(outValue) {
+      values[i] = outValue;
+      if (++resolved === len && !called) {
+        called = true;
+        handlers.resolve(promise, values);
+      }
+    }
+  }
+}
+
+exports.race = race;
+function race(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    resolver(iterable[i]);
+  }
+  return promise;
+  function resolver(value) {
+    self.resolve(value).then(function (response) {
+      if (!called) {
+        called = true;
+        handlers.resolve(promise, response);
+      }
+    }, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+  }
+}
+
+},{"28":28}],51:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+'use strict';
+
+var inherits = _dereq_(29);
+var AbstractLevelDOWN = _dereq_(4).AbstractLevelDOWN;
+var AbstractIterator = _dereq_(4).AbstractIterator;
+
+var LocalStorage = _dereq_(53).LocalStorage;
+var LocalStorageCore = _dereq_(52);
+var utils = _dereq_(55);
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+function LDIterator(db, options) {
+
+  AbstractIterator.call(this, db);
+
+  this._reverse = !!options.reverse;
+  this._endkey     = options.end;
+  this._startkey   = options.start;
+  this._gt      = options.gt;
+  this._gte     = options.gte;
+  this._lt      = options.lt;
+  this._lte     = options.lte;
+  this._exclusiveStart = options.exclusiveStart;
+  this._limit = options.limit;
+  this._count = 0;
+
+  this.onInitCompleteListeners = [];
+}
+
+inherits(LDIterator, AbstractIterator);
+
+LDIterator.prototype._init = function (callback) {
+  nextTick(function () {
+    callback();
+  });
+};
+
+LDIterator.prototype._next = function (callback) {
+  var self = this;
+
+  function onInitComplete() {
+    if (self._pos === self._keys.length || self._pos < 0) { // done reading
+      return callback();
+    }
+
+    var key = self._keys[self._pos];
+
+    if (!!self._endkey && (self._reverse ? key < self._endkey : key > self._endkey)) {
+      return callback();
+    }
+
+    if (!!self._limit && self._limit > 0 && self._count++ >= self._limit) {
+      return callback();
+    }
+
+    if ((self._lt  && key >= self._lt) ||
+      (self._lte && key > self._lte) ||
+      (self._gt  && key <= self._gt) ||
+      (self._gte && key < self._gte)) {
+      return callback();
+    }
+
+    self._pos += self._reverse ? -1 : 1;
+    self.db.container.getItem(key, function (err, value) {
+      if (err) {
+        if (err.message === 'NotFound') {
+          return nextTick(function () {
+            self._next(callback);
+          });
+        }
+        return callback(err);
+      }
+      callback(null, key, value);
+    });
+  }
+  if (!self.initStarted) {
+    process.nextTick(function () {
+      self.initStarted = true;
+      self._init(function (err) {
+        if (err) {
+          return callback(err);
+        }
+        self.db.container.keys(function (err, keys) {
+          if (err) {
+            return callback(err);
+          }
+          self._keys = keys;
+          if (self._startkey) {
+            var index = utils.sortedIndexOf(self._keys, self._startkey);
+            var startkey = (index >= self._keys.length || index < 0) ?
+              undefined : self._keys[index];
+            self._pos = index;
+            if (self._reverse) {
+              if (self._exclusiveStart || startkey !== self._startkey) {
+                self._pos--;
+              }
+            } else if (self._exclusiveStart && startkey === self._startkey) {
+              self._pos++;
+            }
+          } else {
+            self._pos = self._reverse ? self._keys.length - 1 : 0;
+          }
+          onInitComplete();
+
+          self.initCompleted = true;
+          var i = -1;
+          while (++i < self.onInitCompleteListeners.length) {
+            nextTick(self.onInitCompleteListeners[i]);
+          }
+        });
+      });
+    });
+  } else if (!self.initCompleted) {
+    self.onInitCompleteListeners.push(onInitComplete);
+  } else {
+    process.nextTick(onInitComplete);
+  }
+};
+
+function LD(location) {
+  if (!(this instanceof LD)) {
+    return new LD(location);
+  }
+  AbstractLevelDOWN.call(this, location);
+  this.container = new LocalStorage(location);
+}
+
+inherits(LD, AbstractLevelDOWN);
+
+LD.prototype._open = function (options, callback) {
+  this.container.init(callback);
+};
+
+LD.prototype._put = function (key, value, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  err = checkKeyValue(value, 'value');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  if (typeof value === 'object' && !Buffer.isBuffer(value) && value.buffer === undefined) {
+    var obj = {};
+    obj.storetype = "json";
+    obj.data = value;
+    value = JSON.stringify(obj);
+  }
+
+  this.container.setItem(key, value, callback);
+};
+
+LD.prototype._get = function (key, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+
+  if (!Buffer.isBuffer(key)) {
+    key = String(key);
+  }
+  this.container.getItem(key, function (err, value) {
+
+    if (err) {
+      return callback(err);
+    }
+
+    if (options.asBuffer !== false && !Buffer.isBuffer(value)) {
+      value = new Buffer(value);
+    }
+
+
+    if (options.asBuffer === false) {
+      if (value.indexOf("{\"storetype\":\"json\",\"data\"") > -1) {
+        var res = JSON.parse(value);
+        value = res.data;
+      }
+    }
+    callback(null, value);
+  });
+};
+
+LD.prototype._del = function (key, options, callback) {
+
+  var err = checkKeyValue(key, 'key');
+
+  if (err) {
+    return nextTick(function () {
+      callback(err);
+    });
+  }
+  if (!Buffer.isBuffer(key)) {
+    key = String(key);
+  }
+
+  this.container.removeItem(key, callback);
+};
+
+LD.prototype._batch = function (array, options, callback) {
+  var self = this;
+  nextTick(function () {
+    var err;
+    var key;
+    var value;
+
+    var numDone = 0;
+    var overallErr;
+    function checkDone() {
+      if (++numDone === array.length) {
+        callback(overallErr);
+      }
+    }
+
+    if (Array.isArray(array) && array.length) {
+      for (var i = 0; i < array.length; i++) {
+        var task = array[i];
+        if (task) {
+          key = Buffer.isBuffer(task.key) ? task.key : String(task.key);
+          err = checkKeyValue(key, 'key');
+          if (err) {
+            overallErr = err;
+            checkDone();
+          } else if (task.type === 'del') {
+            self._del(task.key, options, checkDone);
+          } else if (task.type === 'put') {
+            value = Buffer.isBuffer(task.value) ? task.value : String(task.value);
+            err = checkKeyValue(value, 'value');
+            if (err) {
+              overallErr = err;
+              checkDone();
+            } else {
+              self._put(key, value, options, checkDone);
+            }
+          }
+        } else {
+          checkDone();
+        }
+      }
+    } else {
+      callback();
+    }
+  });
+};
+
+LD.prototype._iterator = function (options) {
+  return new LDIterator(this, options);
+};
+
+LD.destroy = function (name, callback) {
+  LocalStorageCore.destroy(name, callback);
+};
+
+function checkKeyValue(obj, type) {
+  if (obj === null || obj === undefined) {
+    return new Error(type + ' cannot be `null` or `undefined`');
+  }
+  if (obj === null || obj === undefined) {
+    return new Error(type + ' cannot be `null` or `undefined`');
+  }
+
+  if (type === 'key') {
+
+    if (obj instanceof Boolean) {
+      return new Error(type + ' cannot be `null` or `undefined`');
+    }
+    if (obj === '') {
+      return new Error(type + ' cannot be empty');
+    }
+  }
+  if (obj.toString().indexOf("[object ArrayBuffer]") === 0) {
+    if (obj.byteLength === 0 || obj.byteLength === undefined) {
+      return new Error(type + ' cannot be an empty Buffer');
+    }
+  }
+
+  if (Buffer.isBuffer(obj)) {
+    if (obj.length === 0) {
+      return new Error(type + ' cannot be an empty Buffer');
+    }
+  } else if (String(obj) === '') {
+    return new Error(type + ' cannot be an empty String');
+  }
+}
+
+module.exports = LD;
+
+}).call(this,_dereq_(59),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(8).Buffer)
+},{"29":29,"4":4,"52":52,"53":53,"55":55,"59":59,"8":8}],52:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+//
+// Class that should contain everything necessary to interact
+// with localStorage as a generic key-value store.
+// The idea is that authors who want to create an AbstractKeyValueDOWN
+// module (e.g. on lawnchair, S3, whatever) will only have to
+// reimplement this file.
+//
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+// We use humble-localstorage as a wrapper for localStorage because
+// it falls back to an in-memory implementation in environments without
+// localStorage, like Node or Safari private browsing.
+var storage = _dereq_(26);
+
+function callbackify(callback, fun) {
+  var val;
+  var err;
+  try {
+    val = fun();
+  } catch (e) {
+    err = e;
+  }
+  nextTick(function () {
+    callback(err, val);
+  });
+}
+
+function createPrefix(dbname) {
+  return dbname.replace(/!/g, '!!') + '!'; // escape bangs in dbname;
+}
+
+function LocalStorageCore(dbname) {
+  this._prefix = createPrefix(dbname);
+}
+
+LocalStorageCore.prototype.getKeys = function (callback) {
+  var self = this;
+  callbackify(callback, function () {
+    var keys = [];
+    var prefixLen = self._prefix.length;
+    var i = -1;
+    var len = storage.length;
+    while (++i < len) {
+      var fullKey = storage.key(i);
+      if (fullKey.substring(0, prefixLen) === self._prefix) {
+        keys.push(fullKey.substring(prefixLen));
+      }
+    }
+    keys.sort();
+    return keys;
+  });
+};
+
+LocalStorageCore.prototype.put = function (key, value, callback) {
+  var self = this;
+  callbackify(callback, function () {
+    storage.setItem(self._prefix + key, value);
+  });
+};
+
+LocalStorageCore.prototype.get = function (key, callback) {
+  var self = this;
+  callbackify(callback, function () {
+    return storage.getItem(self._prefix + key);
+  });
+};
+
+LocalStorageCore.prototype.remove = function (key, callback) {
+  var self = this;
+  callbackify(callback, function () {
+    storage.removeItem(self._prefix + key);
+  });
+};
+
+LocalStorageCore.destroy = function (dbname, callback) {
+  var prefix = createPrefix(dbname);
+  callbackify(callback, function () {
+    var keysToDelete = [];
+    var i = -1;
+    var len = storage.length;
+    while (++i < len) {
+      var key = storage.key(i);
+      if (key.substring(0, prefix.length) === prefix) {
+        keysToDelete.push(key);
+      }
+    }
+    keysToDelete.forEach(function (key) {
+      storage.removeItem(key);
+    });
+  });
+};
+
+module.exports = LocalStorageCore;
+}).call(this,_dereq_(59),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"26":26,"59":59}],53:[function(_dereq_,module,exports){
+(function (Buffer){
+'use strict';
+
+// ArrayBuffer/Uint8Array are old formats that date back to before we
+// had a proper browserified buffer type. they may be removed later
+var arrayBuffPrefix = 'ArrayBuffer:';
+var arrayBuffRegex = new RegExp('^' + arrayBuffPrefix);
+var uintPrefix = 'Uint8Array:';
+var uintRegex = new RegExp('^' + uintPrefix);
+
+// this is the new encoding format used going forward
+var bufferPrefix = 'Buff:';
+var bufferRegex = new RegExp('^' + bufferPrefix);
+
+var utils = _dereq_(55);
+var LocalStorageCore = _dereq_(52);
+var TaskQueue = _dereq_(54);
+var d64 = _dereq_(10);
+
+function LocalStorage(dbname) {
+  this._store = new LocalStorageCore(dbname);
+  this._queue = new TaskQueue();
+}
+
+LocalStorage.prototype.sequentialize = function (callback, fun) {
+  this._queue.add(fun, callback);
+};
+
+LocalStorage.prototype.init = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    self._store.getKeys(function (err, keys) {
+      if (err) {
+        return callback(err);
+      }
+      self._keys = keys;
+      return callback();
+    });
+  });
+};
+
+LocalStorage.prototype.keys = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    callback(null, self._keys.slice());
+  });
+};
+
+//setItem: Saves and item at the key provided.
+LocalStorage.prototype.setItem = function (key, value, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    if (Buffer.isBuffer(value)) {
+      value = bufferPrefix + d64.encode(value);
+    }
+
+    var idx = utils.sortedIndexOf(self._keys, key);
+    if (self._keys[idx] !== key) {
+      self._keys.splice(idx, 0, key);
+    }
+    self._store.put(key, value, callback);
+  });
+};
+
+//getItem: Returns the item identified by it's key.
+LocalStorage.prototype.getItem = function (key, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    self._store.get(key, function (err, retval) {
+      if (err) {
+        return callback(err);
+      }
+      if (typeof retval === 'undefined' || retval === null) {
+        // 'NotFound' error, consistent with LevelDOWN API
+        return callback(new Error('NotFound'));
+      }
+      if (typeof retval !== 'undefined') {
+        if (bufferRegex.test(retval)) {
+          retval = d64.decode(retval.substring(bufferPrefix.length));
+        } else if (arrayBuffRegex.test(retval)) {
+          // this type is kept for backwards
+          // compatibility with older databases, but may be removed
+          // after a major version bump
+          retval = retval.substring(arrayBuffPrefix.length);
+          retval = new ArrayBuffer(atob(retval).split('').map(function (c) {
+            return c.charCodeAt(0);
+          }));
+        } else if (uintRegex.test(retval)) {
+          // ditto
+          retval = retval.substring(uintPrefix.length);
+          retval = new Uint8Array(atob(retval).split('').map(function (c) {
+            return c.charCodeAt(0);
+          }));
+        }
+      }
+      callback(null, retval);
+    });
+  });
+};
+
+//removeItem: Removes the item identified by it's key.
+LocalStorage.prototype.removeItem = function (key, callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    var idx = utils.sortedIndexOf(self._keys, key);
+    if (self._keys[idx] === key) {
+      self._keys.splice(idx, 1);
+      self._store.remove(key, function (err) {
+        if (err) {
+          return callback(err);
+        }
+        callback();
+      });
+    } else {
+      callback();
+    }
+  });
+};
+
+LocalStorage.prototype.length = function (callback) {
+  var self = this;
+  self.sequentialize(callback, function (callback) {
+    callback(null, self._keys.length);
+  });
+};
+
+exports.LocalStorage = LocalStorage;
+
+}).call(this,{"isBuffer":_dereq_(30)})
+},{"10":10,"30":30,"52":52,"54":54,"55":55}],54:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+var argsarray = _dereq_(5);
+var Queue = _dereq_(95);
+
+// see http://stackoverflow.com/a/15349865/680742
+var nextTick = global.setImmediate || process.nextTick;
+
+function TaskQueue() {
+  this.queue = new Queue();
+  this.running = false;
+}
+
+TaskQueue.prototype.add = function (fun, callback) {
+  this.queue.push({fun: fun, callback: callback});
+  this.processNext();
+};
+
+TaskQueue.prototype.processNext = function () {
+  var self = this;
+  if (self.running || !self.queue.length) {
+    return;
+  }
+  self.running = true;
+
+  var task = self.queue.shift();
+  nextTick(function () {
+    task.fun(argsarray(function (args) {
+      task.callback.apply(null, args);
+      self.running = false;
+      self.processNext();
+    }));
+  });
+};
+
+module.exports = TaskQueue;
+
+}).call(this,_dereq_(59),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"5":5,"59":59,"95":95}],55:[function(_dereq_,module,exports){
+'use strict';
+// taken from rvagg/memdown commit 2078b40
+exports.sortedIndexOf = function(arr, item) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (arr[mid] < item) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+};
+
+},{}],56:[function(_dereq_,module,exports){
+(function(root) {
+  var localStorageMemory = {};
+  var cache = {};
+
+  /**
+   * number of stored items.
+   */
+  localStorageMemory.length = 0;
+
+  /**
+   * returns item for passed key, or null
+   *
+   * @para {String} key
+   *       name of item to be returned
+   * @returns {String|null}
+   */
+  localStorageMemory.getItem = function(key) {
+    return cache[key] || null;
+  };
+
+  /**
+   * sets item for key to passed value, as String
+   *
+   * @para {String} key
+   *       name of item to be set
+   * @para {String} value
+   *       value, will always be turned into a String
+   * @returns {undefined}
+   */
+  localStorageMemory.setItem = function(key, value) {
+    if (typeof value === 'undefined') {
+      localStorageMemory.removeItem(key);
+    } else {
+      if (!(cache.hasOwnProperty(key))) {
+        localStorageMemory.length++;
+      }
+
+      cache[key] = '' + value;
+    }
+  };
+
+  /**
+   * removes item for passed key
+   *
+   * @para {String} key
+   *       name of item to be removed
+   * @returns {undefined}
+   */
+  localStorageMemory.removeItem = function(key) {
+    if (cache.hasOwnProperty(key)) {
+      delete cache[key];
+      localStorageMemory.length--;
+    }
+  };
+
+  /**
+   * returns name of key at passed index
+   *
+   * @para {Number} index
+   *       Position for key to be returned (starts at 0)
+   * @returns {String|null}
+   */
+  localStorageMemory.key = function(index) {
+    return Object.keys(cache)[index] || null;
+  };
+
+  /**
+   * removes all stored items and sets length to 0
+   *
+   * @returns {undefined}
+   */
+  localStorageMemory.clear = function() {
+    cache = {};
+    localStorageMemory.length = 0;
+  };
+
+  if (typeof exports === 'object') {
+    module.exports = localStorageMemory;
+  } else {
+    root.localStorageMemory = localStorageMemory;
+  }
+})(this);
+
+},{}],57:[function(_dereq_,module,exports){
+'use strict';
+exports.Map = LazyMap; // TODO: use ES6 map
+exports.Set = LazySet; // TODO: use ES6 set
+// based on https://github.com/montagejs/collections
+function LazyMap() {
+  this.store = {};
+}
+LazyMap.prototype.mangle = function (key) {
+  if (typeof key !== "string") {
+    throw new TypeError("key must be a string but Got " + key);
+  }
+  return '$' + key;
+};
+LazyMap.prototype.unmangle = function (key) {
+  return key.substring(1);
+};
+LazyMap.prototype.get = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    return this.store[mangled];
+  }
+  return void 0;
+};
+LazyMap.prototype.set = function (key, value) {
+  var mangled = this.mangle(key);
+  this.store[mangled] = value;
+  return true;
+};
+LazyMap.prototype.has = function (key) {
+  var mangled = this.mangle(key);
+  return mangled in this.store;
+};
+LazyMap.prototype.delete = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    delete this.store[mangled];
+    return true;
+  }
+  return false;
+};
+LazyMap.prototype.forEach = function (cb) {
+  var keys = Object.keys(this.store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this.store[key];
+    key = this.unmangle(key);
+    cb(value, key);
+  }
+};
+
+function LazySet(array) {
+  this.store = new LazyMap();
+
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
+    }
+  }
+}
+LazySet.prototype.add = function (key) {
+  return this.store.set(key, true);
+};
+LazySet.prototype.has = function (key) {
+  return this.store.has(key);
+};
+LazySet.prototype.delete = function (key) {
+  return this.store.delete(key);
+};
+
+},{}],58:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+if (!process.version ||
+    process.version.indexOf('v0.') === 0 ||
+    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+  module.exports = nextTick;
+} else {
+  module.exports = process.nextTick;
+}
+
+function nextTick(fn) {
+  var args = new Array(arguments.length - 1);
+  var i = 0;
+  while (i < args.length) {
+    args[i++] = arguments[i];
+  }
+  process.nextTick(function afterTick() {
+    fn.apply(null, args);
+  });
+}
+
+}).call(this,_dereq_(59))
+},{"59":59}],59:[function(_dereq_,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = setTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    clearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],60:[function(_dereq_,module,exports){
+arguments[4][22][0].apply(exports,arguments)
+},{"22":22}],61:[function(_dereq_,module,exports){
+(function (factory) {
+    if (typeof exports === 'object') {
+        // Node/CommonJS
+        module.exports = factory();
+    } else if (typeof define === 'function' && define.amd) {
+        // AMD
+        define(factory);
+    } else {
+        // Browser globals (with support for web workers)
+        var glob;
+
+        try {
+            glob = window;
+        } catch (e) {
+            glob = self;
+        }
+
+        glob.SparkMD5 = factory();
+    }
+}(function (undefined) {
+
+    'use strict';
+
+    /*
+     * Fastest md5 implementation around (JKM md5).
+     * Credits: Joseph Myers
+     *
+     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+     * @see http://jsperf.com/md5-shootout/7
+     */
+
+    /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+    var add32 = function (a, b) {
+        return (a + b) & 0xFFFFFFFF;
+    },
+        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+    function cmn(q, a, b, x, s, t) {
+        a = add32(add32(a, q), add32(x, t));
+        return add32((a << s) | (a >>> (32 - s)), b);
+    }
+
+    function ff(a, b, c, d, x, s, t) {
+        return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+    }
+
+    function gg(a, b, c, d, x, s, t) {
+        return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+    }
+
+    function hh(a, b, c, d, x, s, t) {
+        return cmn(b ^ c ^ d, a, b, x, s, t);
+    }
+
+    function ii(a, b, c, d, x, s, t) {
+        return cmn(c ^ (b | (~d)), a, b, x, s, t);
+    }
+
+    function md5cycle(x, k) {
+        var a = x[0],
+            b = x[1],
+            c = x[2],
+            d = x[3];
+
+        a = ff(a, b, c, d, k[0], 7, -680876936);
+        d = ff(d, a, b, c, k[1], 12, -389564586);
+        c = ff(c, d, a, b, k[2], 17, 606105819);
+        b = ff(b, c, d, a, k[3], 22, -1044525330);
+        a = ff(a, b, c, d, k[4], 7, -176418897);
+        d = ff(d, a, b, c, k[5], 12, 1200080426);
+        c = ff(c, d, a, b, k[6], 17, -1473231341);
+        b = ff(b, c, d, a, k[7], 22, -45705983);
+        a = ff(a, b, c, d, k[8], 7, 1770035416);
+        d = ff(d, a, b, c, k[9], 12, -1958414417);
+        c = ff(c, d, a, b, k[10], 17, -42063);
+        b = ff(b, c, d, a, k[11], 22, -1990404162);
+        a = ff(a, b, c, d, k[12], 7, 1804603682);
+        d = ff(d, a, b, c, k[13], 12, -40341101);
+        c = ff(c, d, a, b, k[14], 17, -1502002290);
+        b = ff(b, c, d, a, k[15], 22, 1236535329);
+
+        a = gg(a, b, c, d, k[1], 5, -165796510);
+        d = gg(d, a, b, c, k[6], 9, -1069501632);
+        c = gg(c, d, a, b, k[11], 14, 643717713);
+        b = gg(b, c, d, a, k[0], 20, -373897302);
+        a = gg(a, b, c, d, k[5], 5, -701558691);
+        d = gg(d, a, b, c, k[10], 9, 38016083);
+        c = gg(c, d, a, b, k[15], 14, -660478335);
+        b = gg(b, c, d, a, k[4], 20, -405537848);
+        a = gg(a, b, c, d, k[9], 5, 568446438);
+        d = gg(d, a, b, c, k[14], 9, -1019803690);
+        c = gg(c, d, a, b, k[3], 14, -187363961);
+        b = gg(b, c, d, a, k[8], 20, 1163531501);
+        a = gg(a, b, c, d, k[13], 5, -1444681467);
+        d = gg(d, a, b, c, k[2], 9, -51403784);
+        c = gg(c, d, a, b, k[7], 14, 1735328473);
+        b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+        a = hh(a, b, c, d, k[5], 4, -378558);
+        d = hh(d, a, b, c, k[8], 11, -2022574463);
+        c = hh(c, d, a, b, k[11], 16, 1839030562);
+        b = hh(b, c, d, a, k[14], 23, -35309556);
+        a = hh(a, b, c, d, k[1], 4, -1530992060);
+        d = hh(d, a, b, c, k[4], 11, 1272893353);
+        c = hh(c, d, a, b, k[7], 16, -155497632);
+        b = hh(b, c, d, a, k[10], 23, -1094730640);
+        a = hh(a, b, c, d, k[13], 4, 681279174);
+        d = hh(d, a, b, c, k[0], 11, -358537222);
+        c = hh(c, d, a, b, k[3], 16, -722521979);
+        b = hh(b, c, d, a, k[6], 23, 76029189);
+        a = hh(a, b, c, d, k[9], 4, -640364487);
+        d = hh(d, a, b, c, k[12], 11, -421815835);
+        c = hh(c, d, a, b, k[15], 16, 530742520);
+        b = hh(b, c, d, a, k[2], 23, -995338651);
+
+        a = ii(a, b, c, d, k[0], 6, -198630844);
+        d = ii(d, a, b, c, k[7], 10, 1126891415);
+        c = ii(c, d, a, b, k[14], 15, -1416354905);
+        b = ii(b, c, d, a, k[5], 21, -57434055);
+        a = ii(a, b, c, d, k[12], 6, 1700485571);
+        d = ii(d, a, b, c, k[3], 10, -1894986606);
+        c = ii(c, d, a, b, k[10], 15, -1051523);
+        b = ii(b, c, d, a, k[1], 21, -2054922799);
+        a = ii(a, b, c, d, k[8], 6, 1873313359);
+        d = ii(d, a, b, c, k[15], 10, -30611744);
+        c = ii(c, d, a, b, k[6], 15, -1560198380);
+        b = ii(b, c, d, a, k[13], 21, 1309151649);
+        a = ii(a, b, c, d, k[4], 6, -145523070);
+        d = ii(d, a, b, c, k[11], 10, -1120210379);
+        c = ii(c, d, a, b, k[2], 15, 718787259);
+        b = ii(b, c, d, a, k[9], 21, -343485551);
+
+        x[0] = add32(a, x[0]);
+        x[1] = add32(b, x[1]);
+        x[2] = add32(c, x[2]);
+        x[3] = add32(d, x[3]);
+    }
+
+    function md5blk(s) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+        }
+        return md5blks;
+    }
+
+    function md5blk_array(a) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+        }
+        return md5blks;
+    }
+
+    function md51(s) {
+        var n = s.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk(s.substring(i - 64, i)));
+        }
+        s = s.substring(i - 64);
+        length = s.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+        }
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+        return state;
+    }
+
+    function md51_array(a) {
+        var n = a.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+        }
+
+        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+        // containing the last element of the parent array if the sub array specified starts
+        // beyond the length of the parent array - weird.
+        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+        length = a.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= a[i] << ((i % 4) << 3);
+        }
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+
+        return state;
+    }
+
+    function rhex(n) {
+        var s = '',
+            j;
+        for (j = 0; j < 4; j += 1) {
+            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+        }
+        return s;
+    }
+
+    function hex(x) {
+        var i;
+        for (i = 0; i < x.length; i += 1) {
+            x[i] = rhex(x[i]);
+        }
+        return x.join('');
+    }
+
+    // In some cases the fast add32 function cannot be used..
+    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+        add32 = function (x, y) {
+            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+            return (msw << 16) | (lsw & 0xFFFF);
+        };
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * ArrayBuffer slice polyfill.
+     *
+     * @see https://github.com/ttaubert/node-arraybuffer-slice
+     */
+
+    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+        (function () {
+            function clamp(val, length) {
+                val = (val | 0) || 0;
+
+                if (val < 0) {
+                    return Math.max(val + length, 0);
+                }
+
+                return Math.min(val, length);
+            }
+
+            ArrayBuffer.prototype.slice = function (from, to) {
+                var length = this.byteLength,
+                    begin = clamp(from, length),
+                    end = length,
+                    num,
+                    target,
+                    targetArray,
+                    sourceArray;
+
+                if (to !== undefined) {
+                    end = clamp(to, length);
+                }
+
+                if (begin > end) {
+                    return new ArrayBuffer(0);
+                }
+
+                num = end - begin;
+                target = new ArrayBuffer(num);
+                targetArray = new Uint8Array(target);
+
+                sourceArray = new Uint8Array(this, begin, num);
+                targetArray.set(sourceArray);
+
+                return target;
+            };
+        })();
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * Helpers.
+     */
+
+    function toUtf8(str) {
+        if (/[\u0080-\uFFFF]/.test(str)) {
+            str = unescape(encodeURIComponent(str));
+        }
+
+        return str;
+    }
+
+    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+        var length = str.length,
+           buff = new ArrayBuffer(length),
+           arr = new Uint8Array(buff),
+           i;
+
+        for (i = 0; i < length; i += 1) {
+            arr[i] = str.charCodeAt(i);
+        }
+
+        return returnUInt8Array ? arr : buff;
+    }
+
+    function arrayBuffer2Utf8Str(buff) {
+        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    }
+
+    function concatenateArrayBuffers(first, second, returnUInt8Array) {
+        var result = new Uint8Array(first.byteLength + second.byteLength);
+
+        result.set(new Uint8Array(first));
+        result.set(new Uint8Array(second), first.byteLength);
+
+        return returnUInt8Array ? result : result.buffer;
+    }
+
+    function hexToBinaryString(hex) {
+        var bytes = [],
+            length = hex.length,
+            x;
+
+        for (x = 0; x < length - 1; x += 2) {
+            bytes.push(parseInt(hex.substr(x, 2), 16));
+        }
+
+        return String.fromCharCode.apply(String, bytes);
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation.
+     *
+     * Use this class to perform an incremental md5, otherwise use the
+     * static methods instead.
+     */
+
+    function SparkMD5() {
+        // call reset to init the instance
+        this.reset();
+    }
+
+    /**
+     * Appends a string.
+     * A conversion will be applied if an utf8 string is detected.
+     *
+     * @param {String} str The string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.append = function (str) {
+        // Converts the string to utf8 bytes if necessary
+        // Then append as binary
+        this.appendBinary(toUtf8(str));
+
+        return this;
+    };
+
+    /**
+     * Appends a binary string.
+     *
+     * @param {String} contents The binary string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.appendBinary = function (contents) {
+        this._buff += contents;
+        this._length += contents.length;
+
+        var length = this._buff.length,
+            i;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+        }
+
+        this._buff = this._buff.substring(i - 64);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            i,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.reset = function () {
+        this._buff = '';
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.prototype.getState = function () {
+        return {
+            buff: this._buff,
+            length: this._length,
+            hash: this._hash
+        };
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.setState = function (state) {
+        this._buff = state.buff;
+        this._length = state.length;
+        this._hash = state.hash;
+
+        return this;
+    };
+
+    /**
+     * Releases memory used by the incremental buffer and other additional
+     * resources. If you plan to use the instance again, use reset instead.
+     */
+    SparkMD5.prototype.destroy = function () {
+        delete this._hash;
+        delete this._buff;
+        delete this._length;
+    };
+
+    /**
+     * Finish the final calculation based on the tail.
+     *
+     * @param {Array}  tail   The tail (will be modified)
+     * @param {Number} length The length of the remaining buffer
+     */
+    SparkMD5.prototype._finish = function (tail, length) {
+        var i = length,
+            tmp,
+            lo,
+            hi;
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(this._hash, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Do the final computation based on the tail and length
+        // Beware that the final length may not fit in 32 bits so we take care of that
+        tmp = this._length * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+        md5cycle(this._hash, tail);
+    };
+
+    /**
+     * Performs the md5 hash on a string.
+     * A conversion will be applied if utf8 string is detected.
+     *
+     * @param {String}  str The string
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hash = function (str, raw) {
+        // Converts the string to utf8 bytes if necessary
+        // Then compute it using the binary function
+        return SparkMD5.hashBinary(toUtf8(str), raw);
+    };
+
+    /**
+     * Performs the md5 hash on a binary string.
+     *
+     * @param {String}  content The binary string
+     * @param {Boolean} raw     True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hashBinary = function (content, raw) {
+        var hash = md51(content),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation for array buffers.
+     *
+     * Use this class to perform an incremental md5 ONLY for array buffers.
+     */
+    SparkMD5.ArrayBuffer = function () {
+        // call reset to init the instance
+        this.reset();
+    };
+
+    /**
+     * Appends an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array to be appended
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+            length = buff.length,
+            i;
+
+        this._length += arr.byteLength;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+        }
+
+        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            i,
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.reset = function () {
+        this._buff = new Uint8Array(0);
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.ArrayBuffer.prototype.getState = function () {
+        var state = SparkMD5.prototype.getState.call(this);
+
+        // Convert buffer to a string
+        state.buff = arrayBuffer2Utf8Str(state.buff);
+
+        return state;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+        // Convert string to buffer
+        state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+        return SparkMD5.prototype.setState.call(this, state);
+    };
+
+    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+    /**
+     * Performs the md5 hash on an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array buffer
+     * @param {Boolean}     raw True to get the raw string, false to get the hex one
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+        var hash = md51_array(new Uint8Array(arr)),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    return SparkMD5;
+}));
+
+},{}],62:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Stream;
+
+var EE = _dereq_(23).EventEmitter;
+var inherits = _dereq_(29);
+
+inherits(Stream, EE);
+Stream.Readable = _dereq_(70);
+Stream.Writable = _dereq_(72);
+Stream.Duplex = _dereq_(63);
+Stream.Transform = _dereq_(71);
+Stream.PassThrough = _dereq_(69);
+
+// Backwards-compat with node 0.4.x
+Stream.Stream = Stream;
+
+
+
+// old-style streams.  Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+  EE.call(this);
+}
+
+Stream.prototype.pipe = function(dest, options) {
+  var source = this;
+
+  function ondata(chunk) {
+    if (dest.writable) {
+      if (false === dest.write(chunk) && source.pause) {
+        source.pause();
+      }
+    }
+  }
+
+  source.on('data', ondata);
+
+  function ondrain() {
+    if (source.readable && source.resume) {
+      source.resume();
+    }
+  }
+
+  dest.on('drain', ondrain);
+
+  // If the 'end' option is not supplied, dest.end() will be called when
+  // source gets the 'end' or 'close' events.  Only dest.end() once.
+  if (!dest._isStdio && (!options || options.end !== false)) {
+    source.on('end', onend);
+    source.on('close', onclose);
+  }
+
+  var didOnEnd = false;
+  function onend() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    dest.end();
+  }
+
+
+  function onclose() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    if (typeof dest.destroy === 'function') dest.destroy();
+  }
+
+  // don't leave dangling pipes when there are errors.
+  function onerror(er) {
+    cleanup();
+    if (EE.listenerCount(this, 'error') === 0) {
+      throw er; // Unhandled stream error in pipe.
+    }
+  }
+
+  source.on('error', onerror);
+  dest.on('error', onerror);
+
+  // remove all the event listeners that were added.
+  function cleanup() {
+    source.removeListener('data', ondata);
+    dest.removeListener('drain', ondrain);
+
+    source.removeListener('end', onend);
+    source.removeListener('close', onclose);
+
+    source.removeListener('error', onerror);
+    dest.removeListener('error', onerror);
+
+    source.removeListener('end', cleanup);
+    source.removeListener('close', cleanup);
+
+    dest.removeListener('close', cleanup);
+  }
+
+  source.on('end', cleanup);
+  source.on('close', cleanup);
+
+  dest.on('close', cleanup);
+
+  dest.emit('pipe', source);
+
+  // Allow for unix-like usage: A.pipe(B).pipe(C)
+  return dest;
+};
+
+},{"23":23,"29":29,"63":63,"69":69,"70":70,"71":71,"72":72}],63:[function(_dereq_,module,exports){
+module.exports = _dereq_(64)
+
+},{"64":64}],64:[function(_dereq_,module,exports){
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+'use strict';
+
+/*<replacement>*/
+
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) {
+    keys.push(key);
+  }return keys;
+};
+/*</replacement>*/
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var processNextTick = _dereq_(58);
+/*</replacement>*/
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var Readable = _dereq_(66);
+var Writable = _dereq_(68);
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+  var method = keys[v];
+  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+  if (!(this instanceof Duplex)) return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false) this.readable = false;
+
+  if (options && options.writable === false) this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended) return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+  self.end();
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+},{"29":29,"58":58,"66":66,"68":68,"9":9}],65:[function(_dereq_,module,exports){
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+'use strict';
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(67);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+  cb(null, chunk);
+};
+},{"29":29,"67":67,"9":9}],66:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+module.exports = Readable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(58);
+/*</replacement>*/
+
+/*<replacement>*/
+var isArray = _dereq_(31);
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23);
+
+/*<replacement>*/
+var EElistenerCount = function (emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+/*<replacement>*/
+var debugUtil = _dereq_(7);
+var debug = undefined;
+if (debugUtil && debugUtil.debuglog) {
+  debug = debugUtil.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+var Duplex;
+function ReadableState(options, stream) {
+  Duplex = Duplex || _dereq_(64);
+
+  options = options || {};
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+  this.resumeScheduled = false;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder) StringDecoder = _dereq_(73).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+var Duplex;
+function Readable(options) {
+  Duplex = Duplex || _dereq_(64);
+
+  if (!(this instanceof Readable)) return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  if (options && typeof options.read === 'function') this._read = options.read;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function (chunk, encoding) {
+  var state = this._readableState;
+
+  if (!state.objectMode && typeof chunk === 'string') {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function (chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+Readable.prototype.isPaused = function () {
+  return this._readableState.flowing === false;
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null) {
+    state.reading = false;
+    onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      var skipAdd;
+      if (state.decoder && !addToFront && !encoding) {
+        chunk = state.decoder.write(chunk);
+        skipAdd = !state.objectMode && chunk.length === 0;
+      }
+
+      if (!addToFront) state.reading = false;
+
+      // Don't add to the buffer if we've decoded to an empty string chunk and
+      // we're not in object mode
+      if (!skipAdd) {
+        // if we want the data now, just emit it.
+        if (state.flowing && state.length === 0 && !state.sync) {
+          stream.emit('data', chunk);
+          stream.read(0);
+        } else {
+          // update the buffer info.
+          state.length += state.objectMode ? 1 : chunk.length;
+          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
+
+          if (state.needReadable) emitReadable(stream);
+        }
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function (enc) {
+  if (!StringDecoder) StringDecoder = _dereq_(73).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 8MB
+var MAX_HWM = 0x800000;
+function computeNewHighWaterMark(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    n |= n >>> 1;
+    n |= n >>> 2;
+    n |= n >>> 4;
+    n |= n >>> 8;
+    n |= n >>> 16;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended) return 0;
+
+  if (state.objectMode) return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
+  }
+
+  if (n <= 0) return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else {
+      return state.length;
+    }
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function (n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0) endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0) state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0) ret = fromList(n, state);else ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended) state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
+
+  if (ret !== null) this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+function onEofChunk(stream, state) {
+  if (state.ended) return;
+  if (state.decoder) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    processNextTick(maybeReadMore_, stream, state);
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;else len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function (n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function (dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  var cleanedUp = false;
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    cleanedUp = true;
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      // If the user unpiped during `dest.write()`, it is possible
+      // to get stuck in a permanently paused state if that write
+      // also returned false.
+      if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
+        debug('false write response, pause', src._readableState.awaitDrain);
+        src._readableState.awaitDrain++;
+      }
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function () {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain) state.awaitDrain--;
+    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+Readable.prototype.unpipe = function (dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0) return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes) return this;
+
+    if (!dest) dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest) dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var _i = 0; _i < len; _i++) {
+      dests[_i].emit('unpipe', this);
+    }return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1) return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1) state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function (ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && !this._readableState.endEmitted) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        processNextTick(nReadingNextTick, this);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+function nReadingNextTick(self) {
+  debug('readable nexttick read 0');
+  self.read(0);
+}
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function () {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    processNextTick(resume_, stream, state);
+  }
+}
+
+function resume_(stream, state) {
+  if (!state.reading) {
+    debug('resume read 0');
+    stream.read(0);
+  }
+
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading) stream.read(0);
+}
+
+Readable.prototype.pause = function () {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function (stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function () {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length) self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function (chunk) {
+    debug('wrapped data');
+    if (state.decoder) chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (this[i] === undefined && typeof stream[i] === 'function') {
+      this[i] = function (method) {
+        return function () {
+          return stream[method].apply(stream, arguments);
+        };
+      }(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function (ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function (n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0) return null;
+
+  if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode) ret = '';else ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0) throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    processNextTick(endReadableNT, state, stream);
+  }
+}
+
+function endReadableNT(state, stream) {
+  // Check that we didn't get one last unshift.
+  if (!state.endEmitted && state.length === 0) {
+    state.endEmitted = true;
+    stream.readable = false;
+    stream.emit('end');
+  }
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf(xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+}).call(this,_dereq_(59))
+},{"23":23,"29":29,"31":31,"58":58,"59":59,"64":64,"7":7,"73":73,"8":8,"9":9}],67:[function(_dereq_,module,exports){
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+'use strict';
+
+module.exports = Transform;
+
+var Duplex = _dereq_(64);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+function TransformState(stream) {
+  this.afterTransform = function (er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+  this.writeencoding = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined) stream.push(data);
+
+  cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+function Transform(options) {
+  if (!(this instanceof Transform)) return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  if (options) {
+    if (typeof options.transform === 'function') this._transform = options.transform;
+
+    if (typeof options.flush === 'function') this._flush = options.flush;
+  }
+
+  this.once('prefinish', function () {
+    if (typeof this._flush === 'function') this._flush(function (er) {
+      done(stream, er);
+    });else done(stream);
+  });
+}
+
+Transform.prototype.push = function (chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function (chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function (chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function (n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+function done(stream, er) {
+  if (er) return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length) throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming) throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+},{"29":29,"64":64,"9":9}],68:[function(_dereq_,module,exports){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(58);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !true ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(96)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(64);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(64);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+},{"23":23,"29":29,"58":58,"64":64,"8":8,"9":9,"96":96}],69:[function(_dereq_,module,exports){
+module.exports = _dereq_(65)
+
+},{"65":65}],70:[function(_dereq_,module,exports){
+var Stream = (function (){
+  try {
+    return _dereq_('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
+  } catch(_){}
+}());
+exports = module.exports = _dereq_(66);
+exports.Stream = Stream || exports;
+exports.Readable = exports;
+exports.Writable = _dereq_(68);
+exports.Duplex = _dereq_(64);
+exports.Transform = _dereq_(67);
+exports.PassThrough = _dereq_(65);
+
+// inline-process-browser and unreachable-branch-transform make sure this is
+// removed in browserify builds
+if (!true) {
+  module.exports = _dereq_(62);
+}
+
+},{"62":62,"64":64,"65":65,"66":66,"67":67,"68":68}],71:[function(_dereq_,module,exports){
+module.exports = _dereq_(67)
+
+},{"67":67}],72:[function(_dereq_,module,exports){
+module.exports = _dereq_(68)
+
+},{"68":68}],73:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Buffer = _dereq_(8).Buffer;
+
+var isBufferEncoding = Buffer.isEncoding
+  || function(encoding) {
+       switch (encoding && encoding.toLowerCase()) {
+         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
+         default: return false;
+       }
+     }
+
+
+function assertEncoding(encoding) {
+  if (encoding && !isBufferEncoding(encoding)) {
+    throw new Error('Unknown encoding: ' + encoding);
+  }
+}
+
+// StringDecoder provides an interface for efficiently splitting a series of
+// buffers into a series of JS strings without breaking apart multi-byte
+// characters. CESU-8 is handled as part of the UTF-8 encoding.
+//
+// @TODO Handling all encodings inside a single object makes it very difficult
+// to reason about this code, so it should be split up in the future.
+// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
+// points as used by CESU-8.
+var StringDecoder = exports.StringDecoder = function(encoding) {
+  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+  assertEncoding(encoding);
+  switch (this.encoding) {
+    case 'utf8':
+      // CESU-8 represents each of Surrogate Pair by 3-bytes
+      this.surrogateSize = 3;
+      break;
+    case 'ucs2':
+    case 'utf16le':
+      // UTF-16 represents each of Surrogate Pair by 2-bytes
+      this.surrogateSize = 2;
+      this.detectIncompleteChar = utf16DetectIncompleteChar;
+      break;
+    case 'base64':
+      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+      this.surrogateSize = 3;
+      this.detectIncompleteChar = base64DetectIncompleteChar;
+      break;
+    default:
+      this.write = passThroughWrite;
+      return;
+  }
+
+  // Enough space to store all bytes of a single character. UTF-8 needs 4
+  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
+  this.charBuffer = new Buffer(6);
+  // Number of bytes received for the current incomplete multi-byte character.
+  this.charReceived = 0;
+  // Number of bytes expected for the current incomplete multi-byte character.
+  this.charLength = 0;
+};
+
+
+// write decodes the given buffer and returns it as JS string that is
+// guaranteed to not contain any partial multi-byte characters. Any partial
+// character found at the end of the buffer is buffered up, and will be
+// returned when calling write again with the remaining bytes.
+//
+// Note: Converting a Buffer containing an orphan surrogate to a String
+// currently works, but converting a String to a Buffer (via `new Buffer`, or
+// Buffer#write) will replace incomplete surrogates with the unicode
+// replacement character. See https://codereview.chromium.org/121173009/ .
+StringDecoder.prototype.write = function(buffer) {
+  var charStr = '';
+  // if our last write ended with an incomplete multibyte character
+  while (this.charLength) {
+    // determine how many remaining bytes this buffer has to offer for this char
+    var available = (buffer.length >= this.charLength - this.charReceived) ?
+        this.charLength - this.charReceived :
+        buffer.length;
+
+    // add the new bytes to the char buffer
+    buffer.copy(this.charBuffer, this.charReceived, 0, available);
+    this.charReceived += available;
+
+    if (this.charReceived < this.charLength) {
+      // still not enough chars in this buffer? wait for more ...
+      return '';
+    }
+
+    // remove bytes belonging to the current character from the buffer
+    buffer = buffer.slice(available, buffer.length);
+
+    // get the character that was split
+    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
+
+    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+    var charCode = charStr.charCodeAt(charStr.length - 1);
+    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      this.charLength += this.surrogateSize;
+      charStr = '';
+      continue;
+    }
+    this.charReceived = this.charLength = 0;
+
+    // if there are no more bytes in this buffer, just emit our char
+    if (buffer.length === 0) {
+      return charStr;
+    }
+    break;
+  }
+
+  // determine and set charLength / charReceived
+  this.detectIncompleteChar(buffer);
+
+  var end = buffer.length;
+  if (this.charLength) {
+    // buffer the incomplete character bytes we got
+    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
+    end -= this.charReceived;
+  }
+
+  charStr += buffer.toString(this.encoding, 0, end);
+
+  var end = charStr.length - 1;
+  var charCode = charStr.charCodeAt(end);
+  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+  if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+    var size = this.surrogateSize;
+    this.charLength += size;
+    this.charReceived += size;
+    this.charBuffer.copy(this.charBuffer, size, 0, size);
+    buffer.copy(this.charBuffer, 0, 0, size);
+    return charStr.substring(0, end);
+  }
+
+  // or just emit the charStr
+  return charStr;
+};
+
+// detectIncompleteChar determines if there is an incomplete UTF-8 character at
+// the end of the given buffer. If so, it sets this.charLength to the byte
+// length that character, and sets this.charReceived to the number of bytes
+// that are available for this character.
+StringDecoder.prototype.detectIncompleteChar = function(buffer) {
+  // determine how many bytes we have to check at the end of this buffer
+  var i = (buffer.length >= 3) ? 3 : buffer.length;
+
+  // Figure out if one of the last i bytes of our buffer announces an
+  // incomplete char.
+  for (; i > 0; i--) {
+    var c = buffer[buffer.length - i];
+
+    // See http://en.wikipedia.org/wiki/UTF-8#Description
+
+    // 110XXXXX
+    if (i == 1 && c >> 5 == 0x06) {
+      this.charLength = 2;
+      break;
+    }
+
+    // 1110XXXX
+    if (i <= 2 && c >> 4 == 0x0E) {
+      this.charLength = 3;
+      break;
+    }
+
+    // 11110XXX
+    if (i <= 3 && c >> 3 == 0x1E) {
+      this.charLength = 4;
+      break;
+    }
+  }
+  this.charReceived = i;
+};
+
+StringDecoder.prototype.end = function(buffer) {
+  var res = '';
+  if (buffer && buffer.length)
+    res = this.write(buffer);
+
+  if (this.charReceived) {
+    var cr = this.charReceived;
+    var buf = this.charBuffer;
+    var enc = this.encoding;
+    res += buf.slice(0, cr).toString(enc);
+  }
+
+  return res;
+};
+
+function passThroughWrite(buffer) {
+  return buffer.toString(this.encoding);
+}
+
+function utf16DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 2;
+  this.charLength = this.charReceived ? 2 : 0;
+}
+
+function base64DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 3;
+  this.charLength = this.charReceived ? 3 : 0;
+}
+
+},{"8":8}],74:[function(_dereq_,module,exports){
+module.exports = {
+  encode: function (decodedKey) {
+    return '\xff' + decodedKey[0] + '\xff' + decodedKey[1]
+  },
+  decode: function (encodedKeyAsBuffer) {
+    var str = encodedKeyAsBuffer.toString()
+    var idx = str.indexOf('\xff', 1)
+    return [str.substring(1, idx), str.substring(idx + 1)]
+  },
+  lowerBound: '\x00',
+  upperBound: '\xff'
+}
+
+
+},{}],75:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(21).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+  LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"21":21}],76:[function(_dereq_,module,exports){
+var nut   = _dereq_(77)
+var shell = _dereq_(79) //the shell surrounds the nut
+var Codec = _dereq_(33)
+var codec = new Codec();
+
+var ReadStream = _dereq_(78)
+
+var precodec = _dereq_(74)
+
+module.exports = function (db) {
+  return shell ( nut ( db, precodec, codec ), [], ReadStream, db.options)
+}
+
+
+},{"33":33,"74":74,"77":77,"78":78,"79":79}],77:[function(_dereq_,module,exports){
+var ltgt = _dereq_(81)
+
+function isFunction (f) {
+  return 'function' === typeof f
+}
+
+function getPrefix (db) {
+  if(db == null) return db
+  if(isFunction(db.prefix)) return db.prefix()
+  return db
+}
+
+function clone (_obj) {
+  var obj = {}
+  for(var k in _obj)
+    obj[k] = _obj[k]
+  return obj
+}
+
+module.exports = function (db, precodec, codec, compare) {
+  var waiting = [], ready = false
+
+  function encodePrefix(prefix, key, opts1, opts2) {
+    return precodec.encode([ prefix, codec.encodeKey(key, opts1, opts2 ) ])
+  }
+
+  function decodePrefix(data) {
+    return precodec.decode(data)
+  }
+
+  function addEncodings(op, prefix) {
+    if(prefix && prefix.options) {
+      op.keyEncoding =
+        op.keyEncoding || prefix.options.keyEncoding
+      op.valueEncoding =
+        op.valueEncoding || prefix.options.valueEncoding
+    }
+    return op
+  }
+
+  function start () {
+    ready = true
+    while(waiting.length)
+      waiting.shift()()
+  }
+
+  if(isFunction(db.isOpen)) {
+    if(db.isOpen())
+      ready = true
+    else
+      db.open(start)
+  } else {
+    db.open(start)
+  }
+
+  return {
+    apply: function (ops, opts, cb) {
+      for(var i = 0; i < ops.length; i++) {
+        var op = ops[i]
+        addEncodings(op, op.prefix)
+        op.prefix = getPrefix(op.prefix)
+      }
+
+      opts = opts || {}
+
+      if('object' !== typeof opts) throw new Error('opts must be object, was:'+ opts) 
+
+      if('function' === typeof opts) cb = opts, opts = {}
+
+      if(ops.length)
+        (db.db || db).batch(
+          ops.map(function (op) {
+            return {
+              key: encodePrefix(op.prefix, op.key, opts, op),
+              value:
+                  op.type !== 'del'
+                ? codec.encodeValue(
+                    op.value,
+                    opts,
+                    op
+                  )
+                : undefined,
+              type:
+                op.type || (op.value === undefined ? 'del' : 'put')
+            }
+          }),
+          opts,
+          function (err) {
+              if(err) return cb(err)
+            cb()
+          }
+        )
+      else
+        cb()
+    },
+    get: function (key, prefix, opts, cb) {
+      opts.asBuffer = codec.valueAsBuffer(opts)
+      return (db.db || db).get(
+        encodePrefix(prefix, key, opts),
+        opts,
+        function (err, value) {
+          if(err) cb(err)
+          else    cb(null, codec.decodeValue(value, opts))
+        }
+      )
+    },
+    createDecoder: function (opts) {
+      return function (key, value) {
+        return {
+          key: codec.decodeKey(precodec.decode(key)[1], opts),
+          value: codec.decodeValue(value, opts)
+        }
+      }
+    },
+    isOpen: function isOpen() {
+      if (db.db && isFunction(db.db.isOpen))
+        return db.db.isOpen()
+
+      return db.isOpen()
+    },
+    isClosed: function isClosed() {
+      if (db.db && isFunction(db.db.isClosed))
+        return db.db.isClosed()
+
+      return db.isClosed()
+    },
+    close: function close (cb) {
+      return db.close(cb)
+    },
+    iterator: function (_opts, cb) {
+      var opts = clone(_opts || {})
+      var prefix = _opts.prefix || []
+
+      function encodeKey(key) {
+        return encodePrefix(prefix, key, opts, {})
+      }
+
+      ltgt.toLtgt(_opts, opts, encodeKey, precodec.lowerBound, precodec.upperBound)
+
+      // if these legacy values are in the options, remove them
+
+      opts.prefix = null
+
+      //************************************************
+      //hard coded defaults, for now...
+      //TODO: pull defaults and encoding out of levelup.
+      opts.keyAsBuffer = opts.valueAsBuffer = false
+      //************************************************
+
+
+      //this is vital, otherwise limit: undefined will
+      //create an empty stream.
+      if ('number' !== typeof opts.limit)
+        opts.limit = -1
+
+      opts.keyAsBuffer = precodec.buffer
+      opts.valueAsBuffer = codec.valueAsBuffer(opts)
+
+      function wrapIterator (iterator) {
+        return {
+          next: function (cb) {
+            return iterator.next(cb)
+          },
+          end: function (cb) {
+            iterator.end(cb)
+          }
+        }
+      }
+
+      if(ready)
+        return wrapIterator((db.db || db).iterator(opts))
+      else
+        waiting.push(function () {
+          cb(null, wrapIterator((db.db || db).iterator(opts)))
+        })
+
+    }
+  }
+
+}
+
+},{"81":81}],78:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+// NOTE: we are fixed to readable-stream@1.0.x for now
+// for pure Streams2 across Node versions
+var Readable      = _dereq_(87).Readable
+  , inherits      = _dereq_(29)
+  , EncodingError = _dereq_(75).EncodingError;
+
+function ReadStream (options, makeData) {
+  if (!(this instanceof ReadStream))
+    return new ReadStream(options, makeData)
+
+  Readable.call(this, { objectMode: true, highWaterMark: options.highWaterMark })
+
+  // purely to keep `db` around until we're done so it's not GCed if the user doesn't keep a ref
+
+  this._waiting = false
+  this._options = options
+  this._makeData = makeData
+}
+
+inherits(ReadStream, Readable)
+
+ReadStream.prototype.setIterator = function (it) {
+  var self = this
+  this._iterator = it
+  if(this._destroyed) return it.end(function () {})
+  if(this._waiting) {
+    this._waiting = false
+    return this._read()
+  }
+  return this
+}
+
+ReadStream.prototype._read = function read () {
+  var self = this
+  if (self._destroyed)
+    return
+  if(!self._iterator)
+    return this._waiting = true
+
+  self._iterator.next(function(err, key, value) {
+    if (err || (key === undefined && value === undefined)) {
+      if (!err && !self._destroyed)
+        self.push(null)
+      return self._cleanup(err)
+    }
+
+
+    try {
+      value = self._makeData(key, value)
+    } catch (e) {
+      return self._cleanup(new EncodingError(e))
+    }
+    if (!self._destroyed)
+      self.push(value)
+  })
+}
+
+ReadStream.prototype._cleanup = function (err) {
+  if (this._destroyed)
+    return
+
+  this._destroyed = true
+
+  var self = this
+  if (err)
+    self.emit('error', err)
+
+  if (self._iterator) {
+    self._iterator.end(function () {
+      self._iterator = null
+      self.emit('close')
+    })
+  } else {
+    self.emit('close')
+  }
+}
+
+ReadStream.prototype.destroy = function () {
+  this._cleanup()
+}
+
+ReadStream.prototype.toString = function () {
+  return 'LevelUP.ReadStream'
+}
+
+
+module.exports = ReadStream
+
+
+},{"29":29,"75":75,"87":87}],79:[function(_dereq_,module,exports){
+(function (process){
+var EventEmitter = _dereq_(23).EventEmitter
+
+var errors = _dereq_(75)
+
+var version = "6.5.4"
+
+var sublevel = module.exports = function (nut, prefix, createStream, options) {
+  var emitter = new EventEmitter()
+  emitter.sublevels = {}
+  emitter.options = options
+
+  emitter.version = version
+
+  emitter.methods = {}
+  prefix = prefix || []
+
+  function errback (err) { if (err) emitter.emit('error', err) }
+
+  function mergeOpts(opts) {
+    var o = {}
+    if(options)
+      for(var k in options)
+        if(options[k] != undefined)o[k] = options[k]
+    if(opts)
+      for(var k in opts)
+        if(opts[k] != undefined) o[k] = opts[k]
+    return o
+  }
+
+  emitter.put = function (key, value, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key, value: value,
+      prefix: prefix.slice(), type: 'put'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('put', key, value); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.prefix = function () {
+    return prefix.slice()
+  }
+
+  emitter.del = function (key, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key,
+      prefix: prefix.slice(), type: 'del'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('del', key); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.batch = function (ops, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    ops = ops.map(function (op) {
+      return {
+        key:           op.key,
+        value:         op.value,
+        prefix:        op.prefix || prefix,
+        keyEncoding:   op.keyEncoding,    // *
+        valueEncoding: op.valueEncoding,  // * (TODO: encodings on sublevel)
+        type:          op.type
+      }
+    })
+
+    nut.apply(ops, mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('batch', ops); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.get = function (key, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    nut.get(key, prefix, mergeOpts(opts), function (err, value) {
+      if(err) cb(new errors.NotFoundError('Key not found in database', err))
+      else cb(null, value)
+    })
+  }
+
+  emitter.clone = function(opts) {
+    return sublevel(nut, prefix, createStream, mergeOpts(opts))
+  }
+
+  emitter.sublevel = function (name, opts) {
+    return emitter.sublevels[name] =
+      emitter.sublevels[name] || sublevel(nut, prefix.concat(name), createStream, mergeOpts(opts))
+  }
+
+  emitter.readStream = emitter.createReadStream = function (opts) {
+    opts = mergeOpts(opts)
+    opts.prefix = prefix
+    var stream
+    var it = nut.iterator(opts, function (err, it) {
+      stream.setIterator(it)
+    })
+
+    stream = createStream(opts, nut.createDecoder(opts))
+    if(it) stream.setIterator(it)
+
+    return stream
+  }
+
+  emitter.valueStream =
+  emitter.createValueStream = function (opts) {
+    opts = opts || {}
+    opts.values = true
+    opts.keys = false
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.keyStream =
+  emitter.createKeyStream = function (opts) {
+    opts = opts || {}
+    opts.values = false
+    opts.keys = true
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.close = function (cb) {
+    //TODO: deregister all hooks
+    cb = cb || function () {}
+    if (!prefix.length) nut.close(cb)
+    else process.nextTick(cb)
+  }
+
+  emitter.isOpen = nut.isOpen
+  emitter.isClosed = nut.isClosed
+
+  return emitter
+}
+
+}).call(this,_dereq_(59))
+},{"23":23,"59":59,"75":75}],80:[function(_dereq_,module,exports){
+arguments[4][37][0].apply(exports,arguments)
+},{"37":37}],81:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.compare = function (a, b) {
+
+  if(Buffer.isBuffer(a)) {
+    var l = Math.min(a.length, b.length)
+    for(var i = 0; i < l; i++) {
+      var cmp = a[i] - b[i]
+      if(cmp) return cmp
+    }
+    return a.length - b.length
+  }
+
+  return a < b ? -1 : a > b ? 1 : 0
+}
+
+function has(obj, key) {
+  return Object.hasOwnProperty.call(obj, key)
+}
+
+// to be compatible with the current abstract-leveldown tests
+// nullish or empty strings.
+// I could use !!val but I want to permit numbers and booleans,
+// if possible.
+
+function isDef (val) {
+  return val !== undefined && val !== ''
+}
+
+function has (range, name) {
+  return Object.hasOwnProperty.call(range, name)
+}
+
+function hasKey(range, name) {
+  return Object.hasOwnProperty.call(range, name) && name
+}
+
+var lowerBoundKey = exports.lowerBoundKey = function (range) {
+    return (
+       hasKey(range, 'gt')
+    || hasKey(range, 'gte')
+    || hasKey(range, 'min')
+    || (range.reverse ? hasKey(range, 'end') : hasKey(range, 'start'))
+    || undefined
+    )
+}
+
+var lowerBound = exports.lowerBound = function (range) {
+  var k = lowerBoundKey(range)
+  return k && range[k]
+}
+
+exports.lowerBoundInclusive = function (range) {
+  return has(range, 'gt') ? false : true
+}
+
+exports.upperBoundInclusive =
+  function (range) {
+    return has(range, 'lt') || !range.minEx ? false : true
+  }
+
+var lowerBoundExclusive = exports.lowerBoundExclusive =
+  function (range) {
+    return has(range, 'gt') || range.minEx ? true : false
+  }
+
+var upperBoundExclusive = exports.upperBoundExclusive =
+  function (range) {
+    return has(range, 'lt') ? true : false
+  }
+
+var upperBoundKey = exports.upperBoundKey = function (range) {
+    return (
+       hasKey(range, 'lt')
+    || hasKey(range, 'lte')
+    || hasKey(range, 'max')
+    || (range.reverse ? hasKey(range, 'start') : hasKey(range, 'end'))
+    || undefined
+    )
+}
+
+var upperBound = exports.upperBound = function (range) {
+  var k = upperBoundKey(range)
+  return k && range[k]
+}
+
+function id (e) { return e }
+
+exports.toLtgt = function (range, _range, map, lower, upper) {
+  _range = _range || {}
+  map = map || id
+  var defaults = arguments.length > 3
+  var lb = exports.lowerBoundKey(range)
+  var ub = exports.upperBoundKey(range)
+  if(lb) {
+    if(lb === 'gt') _range.gt = map(range.gt, false)
+    else            _range.gte = map(range[lb], false)
+  }
+  else if(defaults)
+    _range.gte = map(lower, false)
+
+  if(ub) {
+    if(ub === 'lt') _range.lt = map(range.lt, true)
+    else            _range.lte = map(range[ub], true)
+  }
+  else if(defaults)
+    _range.lte = map(upper, true)
+
+  if(range.reverse != null)
+    _range.reverse = !!range.reverse
+
+  //if range was used mutably
+  //(in level-sublevel it's part of an options object
+  //that has more properties on it.)
+  if(has(_range, 'max'))   delete _range.max
+  if(has(_range, 'min'))   delete _range.min
+  if(has(_range, 'start')) delete _range.start
+  if(has(_range, 'end'))   delete _range.end
+
+  return _range
+}
+
+exports.contains = function (range, key, compare) {
+  compare = compare || exports.compare
+
+  var lb = lowerBound(range)
+  if(isDef(lb)) {
+    var cmp = compare(key, lb)
+    if(cmp < 0 || (cmp === 0 && lowerBoundExclusive(range)))
+      return false
+  }
+
+  var ub = upperBound(range)
+  if(isDef(ub)) {
+    var cmp = compare(key, ub)
+    if(cmp > 0 || (cmp === 0) && upperBoundExclusive(range))
+      return false
+  }
+
+  return true
+}
+
+exports.filter = function (range, compare) {
+  return function (key) {
+    return exports.contains(range, key, compare)
+  }
+}
+
+}).call(this,{"isBuffer":_dereq_(30)})
+},{"30":30}],82:[function(_dereq_,module,exports){
+arguments[4][38][0].apply(exports,arguments)
+},{"29":29,"38":38,"59":59,"84":84,"86":86,"9":9}],83:[function(_dereq_,module,exports){
+arguments[4][39][0].apply(exports,arguments)
+},{"29":29,"39":39,"85":85,"9":9}],84:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(80);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(23).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(62);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = false;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // In streams that never have any data, and do push(null) right away,
+  // the consumer can miss the 'end' event if they do some I/O before
+  // consuming the stream.  So, we don't emit('end') until some reading
+  // happens.
+  this.calledRead = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(73).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (typeof chunk === 'string' && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null || chunk === undefined) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      // update the buffer info.
+      state.length += state.objectMode ? 1 : chunk.length;
+      if (addToFront) {
+        state.buffer.unshift(chunk);
+      } else {
+        state.reading = false;
+        state.buffer.push(chunk);
+      }
+
+      if (state.needReadable)
+        emitReadable(stream);
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(73).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  var state = this._readableState;
+  state.calledRead = true;
+  var nOrig = n;
+  var ret;
+
+  if (typeof n !== 'number' || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    ret = null;
+
+    // In cases where the decoder did not receive enough data
+    // to produce a full chunk, then immediately received an
+    // EOF, state.buffer will contain [<Buffer >, <Buffer 00 ...>].
+    // howMuchToRead will see this and coerce the amount to
+    // read to zero (because it's looking at the length of the
+    // first <Buffer > in state.buffer), and we'll end up here.
+    //
+    // This can only happen via state.decoder -- no other venue
+    // exists for pushing a zero-length chunk into state.buffer
+    // and triggering this behavior. In this case, we return our
+    // remaining data and end the stream, if appropriate.
+    if (state.length > 0 && state.decoder) {
+      ret = fromList(n, state);
+      state.length -= ret.length;
+    }
+
+    if (state.length === 0)
+      endReadable(this);
+
+    return ret;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length - n <= state.highWaterMark)
+    doRead = true;
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading)
+    doRead = false;
+
+  if (doRead) {
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read called its callback synchronously, then `reading`
+  // will be false, and we need to re-evaluate how much data we
+  // can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we happened to read() exactly the remaining amount in the
+  // buffer, and the EOF has been seen at this point, then make sure
+  // that we emit 'end' on the very next tick.
+  if (state.ended && !state.endEmitted && state.length === 0)
+    endReadable(this);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // if we've ended and we have some data left, then emit
+  // 'readable' now to make sure it gets picked up.
+  if (state.length > 0)
+    emitReadable(stream);
+  else
+    endReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (state.emittedReadable)
+    return;
+
+  state.emittedReadable = true;
+  if (state.sync)
+    process.nextTick(function() {
+      emitReadable_(stream);
+    });
+  else
+    emitReadable_(stream);
+}
+
+function emitReadable_(stream) {
+  stream.emit('readable');
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    if (readable !== src) return;
+    cleanup();
+  }
+
+  function onend() {
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (!dest._writableState || dest._writableState.needDrain)
+      ondrain();
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    // the handler that waits for readable events after all
+    // the data gets sucked out in flow.
+    // This would be easier to follow with a .once() handler
+    // in flow(), but that is too slow.
+    this.on('readable', pipeOnReadable);
+
+    state.flowing = true;
+    process.nextTick(function() {
+      flow(src);
+    });
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var dest = this;
+    var state = src._readableState;
+    state.awaitDrain--;
+    if (state.awaitDrain === 0)
+      flow(src);
+  };
+}
+
+function flow(src) {
+  var state = src._readableState;
+  var chunk;
+  state.awaitDrain = 0;
+
+  function write(dest, i, list) {
+    var written = dest.write(chunk);
+    if (false === written) {
+      state.awaitDrain++;
+    }
+  }
+
+  while (state.pipesCount && null !== (chunk = src.read())) {
+
+    if (state.pipesCount === 1)
+      write(state.pipes, 0, null);
+    else
+      forEach(state.pipes, write);
+
+    src.emit('data', chunk);
+
+    // if anyone needs a drain, then we have to wait for that.
+    if (state.awaitDrain > 0)
+      return;
+  }
+
+  // if every destination was unpiped, either before entering this
+  // function, or in the while loop, then stop flowing.
+  //
+  // NB: This is a pretty rare edge case.
+  if (state.pipesCount === 0) {
+    state.flowing = false;
+
+    // if there were data event listeners added, then switch to old mode.
+    if (EE.listenerCount(src, 'data') > 0)
+      emitDataEvents(src);
+    return;
+  }
+
+  // at this point, no one needed a drain, so we just ran out of data
+  // on the next readable event, start it over again.
+  state.ranOut = true;
+}
+
+function pipeOnReadable() {
+  if (this._readableState.ranOut) {
+    this._readableState.ranOut = false;
+    flow(this);
+  }
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  if (ev === 'data' && !this._readableState.flowing)
+    emitDataEvents(this);
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        this.read(0);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  emitDataEvents(this);
+  this.read(0);
+  this.emit('resume');
+};
+
+Readable.prototype.pause = function() {
+  emitDataEvents(this, true);
+  this.emit('pause');
+};
+
+function emitDataEvents(stream, startPaused) {
+  var state = stream._readableState;
+
+  if (state.flowing) {
+    // https://github.com/isaacs/readable-stream/issues/16
+    throw new Error('Cannot switch to old mode now.');
+  }
+
+  var paused = startPaused || false;
+  var readable = false;
+
+  // convert to an old-style stream.
+  stream.readable = true;
+  stream.pipe = Stream.prototype.pipe;
+  stream.on = stream.addListener = Stream.prototype.on;
+
+  stream.on('readable', function() {
+    readable = true;
+
+    var c;
+    while (!paused && (null !== (c = stream.read())))
+      stream.emit('data', c);
+
+    if (c === null) {
+      readable = false;
+      stream._readableState.needReadable = true;
+    }
+  });
+
+  stream.pause = function() {
+    paused = true;
+    this.emit('pause');
+  };
+
+  stream.resume = function() {
+    paused = false;
+    if (readable)
+      process.nextTick(function() {
+        stream.emit('readable');
+      });
+    else
+      this.read(0);
+    this.emit('resume');
+  };
+
+  // now make it start, just in case it hadn't already.
+  stream.emit('readable');
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    //if (state.objectMode && util.isNullOrUndefined(chunk))
+    if (state.objectMode && (chunk === null || chunk === undefined))
+      return;
+    else if (!state.objectMode && (!chunk || !chunk.length))
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (typeof stream[i] === 'function' &&
+        typeof this[i] === 'undefined') {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted && state.calledRead) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(59))
+},{"23":23,"29":29,"59":59,"62":62,"73":73,"8":8,"80":80,"9":9}],85:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(82);
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined)
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  var ts = this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('finish', function() {
+    if ('function' === typeof this._flush)
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var rs = stream._readableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"29":29,"82":82,"9":9}],86:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+var Stream = _dereq_(62);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(82);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function')
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb))
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+
+  return ret;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      cb(er);
+    });
+  else
+    cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished && !state.bufferProcessing && state.buffer.length)
+      clearBuffer(stream, state);
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  cb();
+  if (finished)
+    finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  for (var c = 0; c < state.buffer.length; c++) {
+    var entry = state.buffer[c];
+    var chunk = entry.chunk;
+    var encoding = entry.encoding;
+    var cb = entry.callback;
+    var len = state.objectMode ? 1 : chunk.length;
+
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+    // if we didn't call the onwrite immediately, then
+    // it means that we need to wait until it does.
+    // also, that means that the chunk and cb are currently
+    // being processed, so move the buffer counter past them.
+    if (state.writing) {
+      c++;
+      break;
+    }
+  }
+
+  state.bufferProcessing = false;
+  if (c < state.buffer.length)
+    state.buffer = state.buffer.slice(c);
+  else
+    state.buffer.length = 0;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (typeof chunk !== 'undefined' && chunk !== null)
+    this.write(chunk, encoding);
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    state.finished = true;
+    stream.emit('finish');
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(59))
+},{"29":29,"59":59,"62":62,"8":8,"82":82,"9":9}],87:[function(_dereq_,module,exports){
+var Stream = _dereq_(62); // hack to fix a circular dependency issue when used with browserify
+exports = module.exports = _dereq_(84);
+exports.Stream = Stream;
+exports.Readable = exports;
+exports.Writable = _dereq_(86);
+exports.Duplex = _dereq_(82);
+exports.Transform = _dereq_(85);
+exports.PassThrough = _dereq_(83);
+
+},{"62":62,"82":82,"83":83,"84":84,"85":85,"86":86}],88:[function(_dereq_,module,exports){
+arguments[4][64][0].apply(exports,arguments)
+},{"29":29,"58":58,"64":64,"89":89,"9":9,"91":91}],89:[function(_dereq_,module,exports){
+arguments[4][66][0].apply(exports,arguments)
+},{"23":23,"29":29,"31":31,"58":58,"59":59,"66":66,"7":7,"73":73,"8":8,"88":88,"9":9}],90:[function(_dereq_,module,exports){
+arguments[4][67][0].apply(exports,arguments)
+},{"29":29,"67":67,"88":88,"9":9}],91:[function(_dereq_,module,exports){
+(function (process){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(58);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(8).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(9);
+util.inherits = _dereq_(29);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(96)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(23).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(8).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(88);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(88);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+}).call(this,_dereq_(59))
+},{"23":23,"29":29,"58":58,"59":59,"8":8,"88":88,"9":9,"96":96}],92:[function(_dereq_,module,exports){
+arguments[4][71][0].apply(exports,arguments)
+},{"71":71,"90":90}],93:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],94:[function(_dereq_,module,exports){
+(function (process){
+var Transform = _dereq_(92)
+  , inherits  = _dereq_(98).inherits
+  , xtend     = _dereq_(93)
+
+function DestroyableTransform(opts) {
+  Transform.call(this, opts)
+  this._destroyed = false
+}
+
+inherits(DestroyableTransform, Transform)
+
+DestroyableTransform.prototype.destroy = function(err) {
+  if (this._destroyed) return
+  this._destroyed = true
+  
+  var self = this
+  process.nextTick(function() {
+    if (err)
+      self.emit('error', err)
+    self.emit('close')
+  })
+}
+
+// a noop _transform function
+function noop (chunk, enc, callback) {
+  callback(null, chunk)
+}
+
+
+// create a new export function, used by both the main export and
+// the .ctor export, contains common logic for dealing with arguments
+function through2 (construct) {
+  return function (options, transform, flush) {
+    if (typeof options == 'function') {
+      flush     = transform
+      transform = options
+      options   = {}
+    }
+
+    if (typeof transform != 'function')
+      transform = noop
+
+    if (typeof flush != 'function')
+      flush = null
+
+    return construct(options, transform, flush)
+  }
+}
+
+
+// main export, just make me a transform stream!
+module.exports = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(options)
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+
+// make me a reusable prototype that I can `new`, or implicitly `new`
+// with a constructor call
+module.exports.ctor = through2(function (options, transform, flush) {
+  function Through2 (override) {
+    if (!(this instanceof Through2))
+      return new Through2(override)
+
+    this.options = xtend(options, override)
+
+    DestroyableTransform.call(this, this.options)
+  }
+
+  inherits(Through2, DestroyableTransform)
+
+  Through2.prototype._transform = transform
+
+  if (flush)
+    Through2.prototype._flush = flush
+
+  return Through2
+})
+
+
+module.exports.obj = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options))
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+}).call(this,_dereq_(59))
+},{"59":59,"92":92,"93":93,"98":98}],95:[function(_dereq_,module,exports){
+'use strict';
+
+// Simple FIFO queue implementation to avoid having to do shift()
+// on an array, which is slow.
+
+function Queue() {
+  this.length = 0;
+}
+
+Queue.prototype.push = function (item) {
+  var node = {item: item};
+  if (this.last) {
+    this.last = this.last.next = node;
+  } else {
+    this.last = this.first = node;
+  }
+  this.length++;
+};
+
+Queue.prototype.shift = function () {
+  var node = this.first;
+  if (node) {
+    this.first = node.next;
+    if (!(--this.length)) {
+      this.last = undefined;
+    }
+    return node.item;
+  }
+};
+
+Queue.prototype.slice = function (start, end) {
+  start = typeof start === 'undefined' ? 0 : start;
+  end = typeof end === 'undefined' ? Infinity : end;
+
+  var output = [];
+
+  var i = 0;
+  for (var node = this.first; node; node = node.next) {
+    if (--end < 0) {
+      break;
+    } else if (++i > start) {
+      output.push(node.item);
+    }
+  }
+  return output;
+}
+
+module.exports = Queue;
+
+},{}],96:[function(_dereq_,module,exports){
+(function (global){
+
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used.
+ * Returns a modified function which warns once by default.
+ *
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ *
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ *
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ *
+ * @param {Function} fn - the function to deprecate
+ * @param {String} msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+  if (config('noDeprecation')) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (config('throwDeprecation')) {
+        throw new Error(msg);
+      } else if (config('traceDeprecation')) {
+        console.trace(msg);
+      } else {
+        console.warn(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ *
+ * @param {String} name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
+  try {
+    if (!global.localStorage) return false;
+  } catch (_) {
+    return false;
+  }
+  var val = global.localStorage[name];
+  if (null == val) return false;
+  return String(val).toLowerCase() === 'true';
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],97:[function(_dereq_,module,exports){
+module.exports = function isBuffer(arg) {
+  return arg && typeof arg === 'object'
+    && typeof arg.copy === 'function'
+    && typeof arg.fill === 'function'
+    && typeof arg.readUInt8 === 'function';
+}
+},{}],98:[function(_dereq_,module,exports){
+(function (process,global){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+  if (!isString(f)) {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j':
+        try {
+          return JSON.stringify(args[i++]);
+        } catch (_) {
+          return '[Circular]';
+        }
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (isNull(x) || !isObject(x)) {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+  // Allow for deprecating things in the process of starting up.
+  if (isUndefined(global.process)) {
+    return function() {
+      return exports.deprecate(fn, msg).apply(this, arguments);
+    };
+  }
+
+  if (process.noDeprecation === true) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (process.throwDeprecation) {
+        throw new Error(msg);
+      } else if (process.traceDeprecation) {
+        console.trace(msg);
+      } else {
+        console.error(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+  if (isUndefined(debugEnviron))
+    debugEnviron = process.env.NODE_DEBUG || '';
+  set = set.toUpperCase();
+  if (!debugs[set]) {
+    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+      var pid = process.pid;
+      debugs[set] = function() {
+        var msg = exports.format.apply(exports, arguments);
+        console.error('%s %d: %s', set, pid, msg);
+      };
+    } else {
+      debugs[set] = function() {};
+    }
+  }
+  return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+  // default options
+  var ctx = {
+    seen: [],
+    stylize: stylizeNoColor
+  };
+  // legacy...
+  if (arguments.length >= 3) ctx.depth = arguments[2];
+  if (arguments.length >= 4) ctx.colors = arguments[3];
+  if (isBoolean(opts)) {
+    // legacy...
+    ctx.showHidden = opts;
+  } else if (opts) {
+    // got an "options" object
+    exports._extend(ctx, opts);
+  }
+  // set default options
+  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+  if (isUndefined(ctx.depth)) ctx.depth = 2;
+  if (isUndefined(ctx.colors)) ctx.colors = false;
+  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+  if (ctx.colors) ctx.stylize = stylizeWithColor;
+  return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+  'bold' : [1, 22],
+  'italic' : [3, 23],
+  'underline' : [4, 24],
+  'inverse' : [7, 27],
+  'white' : [37, 39],
+  'grey' : [90, 39],
+  'black' : [30, 39],
+  'blue' : [34, 39],
+  'cyan' : [36, 39],
+  'green' : [32, 39],
+  'magenta' : [35, 39],
+  'red' : [31, 39],
+  'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+  'special': 'cyan',
+  'number': 'yellow',
+  'boolean': 'yellow',
+  'undefined': 'grey',
+  'null': 'bold',
+  'string': 'green',
+  'date': 'magenta',
+  // "name": intentionally not styling
+  'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+  var style = inspect.styles[styleType];
+
+  if (style) {
+    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+           '\u001b[' + inspect.colors[style][1] + 'm';
+  } else {
+    return str;
+  }
+}
+
+
+function stylizeNoColor(str, styleType) {
+  return str;
+}
+
+
+function arrayToHash(array) {
+  var hash = {};
+
+  array.forEach(function(val, idx) {
+    hash[val] = true;
+  });
+
+  return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+  // Provide a hook for user-specified inspect functions.
+  // Check that value is an object with an inspect function on it
+  if (ctx.customInspect &&
+      value &&
+      isFunction(value.inspect) &&
+      // Filter out the util module, it's inspect function is special
+      value.inspect !== exports.inspect &&
+      // Also filter out any prototype objects using the circular check.
+      !(value.constructor && value.constructor.prototype === value)) {
+    var ret = value.inspect(recurseTimes, ctx);
+    if (!isString(ret)) {
+      ret = formatValue(ctx, ret, recurseTimes);
+    }
+    return ret;
+  }
+
+  // Primitive types cannot have properties
+  var primitive = formatPrimitive(ctx, value);
+  if (primitive) {
+    return primitive;
+  }
+
+  // Look up the keys of the object.
+  var keys = Object.keys(value);
+  var visibleKeys = arrayToHash(keys);
+
+  if (ctx.showHidden) {
+    keys = Object.getOwnPropertyNames(value);
+  }
+
+  // IE doesn't make error fields non-enumerable
+  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+  if (isError(value)
+      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+    return formatError(value);
+  }
+
+  // Some type of object without properties can be shortcutted.
+  if (keys.length === 0) {
+    if (isFunction(value)) {
+      var name = value.name ? ': ' + value.name : '';
+      return ctx.stylize('[Function' + name + ']', 'special');
+    }
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    }
+    if (isDate(value)) {
+      return ctx.stylize(Date.prototype.toString.call(value), 'date');
+    }
+    if (isError(value)) {
+      return formatError(value);
+    }
+  }
+
+  var base = '', array = false, braces = ['{', '}'];
+
+  // Make Array say that they are Array
+  if (isArray(value)) {
+    array = true;
+    braces = ['[', ']'];
+  }
+
+  // Make functions say that they are functions
+  if (isFunction(value)) {
+    var n = value.name ? ': ' + value.name : '';
+    base = ' [Function' + n + ']';
+  }
+
+  // Make RegExps say that they are RegExps
+  if (isRegExp(value)) {
+    base = ' ' + RegExp.prototype.toString.call(value);
+  }
+
+  // Make dates with properties first say the date
+  if (isDate(value)) {
+    base = ' ' + Date.prototype.toUTCString.call(value);
+  }
+
+  // Make error with message first say the error
+  if (isError(value)) {
+    base = ' ' + formatError(value);
+  }
+
+  if (keys.length === 0 && (!array || value.length == 0)) {
+    return braces[0] + base + braces[1];
+  }
+
+  if (recurseTimes < 0) {
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    } else {
+      return ctx.stylize('[Object]', 'special');
+    }
+  }
+
+  ctx.seen.push(value);
+
+  var output;
+  if (array) {
+    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+  } else {
+    output = keys.map(function(key) {
+      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+    });
+  }
+
+  ctx.seen.pop();
+
+  return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+  if (isUndefined(value))
+    return ctx.stylize('undefined', 'undefined');
+  if (isString(value)) {
+    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+                                             .replace(/'/g, "\\'")
+                                             .replace(/\\"/g, '"') + '\'';
+    return ctx.stylize(simple, 'string');
+  }
+  if (isNumber(value))
+    return ctx.stylize('' + value, 'number');
+  if (isBoolean(value))
+    return ctx.stylize('' + value, 'boolean');
+  // For some reason typeof null is "object", so special case here.
+  if (isNull(value))
+    return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+  return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+  var output = [];
+  for (var i = 0, l = value.length; i < l; ++i) {
+    if (hasOwnProperty(value, String(i))) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          String(i), true));
+    } else {
+      output.push('');
+    }
+  }
+  keys.forEach(function(key) {
+    if (!key.match(/^\d+$/)) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          key, true));
+    }
+  });
+  return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+  var name, str, desc;
+  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+  if (desc.get) {
+    if (desc.set) {
+      str = ctx.stylize('[Getter/Setter]', 'special');
+    } else {
+      str = ctx.stylize('[Getter]', 'special');
+    }
+  } else {
+    if (desc.set) {
+      str = ctx.stylize('[Setter]', 'special');
+    }
+  }
+  if (!hasOwnProperty(visibleKeys, key)) {
+    name = '[' + key + ']';
+  }
+  if (!str) {
+    if (ctx.seen.indexOf(desc.value) < 0) {
+      if (isNull(recurseTimes)) {
+        str = formatValue(ctx, desc.value, null);
+      } else {
+        str = formatValue(ctx, desc.value, recurseTimes - 1);
+      }
+      if (str.indexOf('\n') > -1) {
+        if (array) {
+          str = str.split('\n').map(function(line) {
+            return '  ' + line;
+          }).join('\n').substr(2);
+        } else {
+          str = '\n' + str.split('\n').map(function(line) {
+            return '   ' + line;
+          }).join('\n');
+        }
+      }
+    } else {
+      str = ctx.stylize('[Circular]', 'special');
+    }
+  }
+  if (isUndefined(name)) {
+    if (array && key.match(/^\d+$/)) {
+      return str;
+    }
+    name = JSON.stringify('' + key);
+    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+      name = name.substr(1, name.length - 2);
+      name = ctx.stylize(name, 'name');
+    } else {
+      name = name.replace(/'/g, "\\'")
+                 .replace(/\\"/g, '"')
+                 .replace(/(^"|"$)/g, "'");
+      name = ctx.stylize(name, 'string');
+    }
+  }
+
+  return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+  var numLinesEst = 0;
+  var length = output.reduce(function(prev, cur) {
+    numLinesEst++;
+    if (cur.indexOf('\n') >= 0) numLinesEst++;
+    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+  }, 0);
+
+  if (length > 60) {
+    return braces[0] +
+           (base === '' ? '' : base + '\n ') +
+           ' ' +
+           output.join(',\n  ') +
+           ' ' +
+           braces[1];
+  }
+
+  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+  return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return isObject(e) &&
+      (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = _dereq_(97);
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+  return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+              'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+  var d = new Date();
+  var time = [pad(d.getHours()),
+              pad(d.getMinutes()),
+              pad(d.getSeconds())].join(':');
+  return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ *     prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = _dereq_(29);
+
+exports._extend = function(origin, add) {
+  // Don't do anything if add isn't an object
+  if (!add || !isObject(add)) return origin;
+
+  var keys = Object.keys(add);
+  var i = keys.length;
+  while (i--) {
+    origin[keys[i]] = add[keys[i]];
+  }
+  return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+}).call(this,_dereq_(59),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"29":29,"59":59,"97":97}],99:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+  var queue = [];
+  queue.push({obj: input});
+
+  var res = '';
+  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+  while ((next = queue.pop())) {
+    obj = next.obj;
+    prefix = next.prefix || '';
+    val = next.val || '';
+    res += prefix;
+    if (val) {
+      res += val;
+    } else if (typeof obj !== 'object') {
+      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+    } else if (obj === null) {
+      res += 'null';
+    } else if (Array.isArray(obj)) {
+      queue.push({val: ']'});
+      for (i = obj.length - 1; i >= 0; i--) {
+        arrayPrefix = i === 0 ? '' : ',';
+        queue.push({obj: obj[i], prefix: arrayPrefix});
+      }
+      queue.push({val: '['});
+    } else { // object
+      keys = [];
+      for (k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          keys.push(k);
+        }
+      }
+      queue.push({val: '}'});
+      for (i = keys.length - 1; i >= 0; i--) {
+        key = keys[i];
+        value = obj[key];
+        objPrefix = (i > 0 ? ',' : '');
+        objPrefix += JSON.stringify(key) + ':';
+        queue.push({obj: value, prefix: objPrefix});
+      }
+      queue.push({val: '{'});
+    }
+  }
+  return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+  var lastMetaElement = metaStack[metaStack.length - 1];
+  if (obj === lastMetaElement.element) {
+    // popping a meta-element, e.g. an object whose value is another object
+    metaStack.pop();
+    lastMetaElement = metaStack[metaStack.length - 1];
+  }
+  var element = lastMetaElement.element;
+  var lastElementIndex = lastMetaElement.index;
+  if (Array.isArray(element)) {
+    element.push(obj);
+  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+    var key = stack.pop();
+    element[key] = obj;
+  } else {
+    stack.push(obj); // obj with key only
+  }
+}
+
+exports.parse = function (str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
+  var collationIndex,parsedNum,numChar;
+  var parsedString,lastCh,numConsecutiveSlashes,ch;
+  var arrayElement, objElement;
+  while (true) {
+    collationIndex = str[i++];
+    if (collationIndex === '}' ||
+        collationIndex === ']' ||
+        typeof collationIndex === 'undefined') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack.pop(), stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case ' ':
+      case '\t':
+      case '\n':
+      case ':':
+      case ',':
+        break;
+      case 'n':
+        i += 3; // 'ull'
+        pop(null, stack, metaStack);
+        break;
+      case 't':
+        i += 3; // 'rue'
+        pop(true, stack, metaStack);
+        break;
+      case 'f':
+        i += 4; // 'alse'
+        pop(false, stack, metaStack);
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '-':
+        parsedNum = '';
+        i--;
+        while (true) {
+          numChar = str[i++];
+          if (/[\d\.\-e\+]/.test(numChar)) {
+            parsedNum += numChar;
+          } else {
+            i--;
+            break;
+          }
+        }
+        pop(parseFloat(parsedNum), stack, metaStack);
+        break;
+      case '"':
+        parsedString = '';
+        lastCh = void 0;
+        numConsecutiveSlashes = 0;
+        while (true) {
+          ch = str[i++];
+          if (ch !== '"' || (lastCh === '\\' &&
+              numConsecutiveSlashes % 2 === 1)) {
+            parsedString += ch;
+            lastCh = ch;
+            if (lastCh === '\\') {
+              numConsecutiveSlashes++;
+            } else {
+              numConsecutiveSlashes = 0;
+            }
+          } else {
+            break;
+          }
+        }
+        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+        break;
+      case '[':
+        arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '{':
+        objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      default:
+        throw new Error(
+          'unexpectedly reached end of input: ' + collationIndex);
+    }
+  }
+};
+
+},{}],100:[function(_dereq_,module,exports){
+module.exports = extend
+
+function extend() {
+    var target = {}
+
+    for (var i = 0; i < arguments.length; i++) {
+        var source = arguments[i]
+
+        for (var key in source) {
+            if (source.hasOwnProperty(key)) {
+                target[key] = source[key]
+            }
+        }
+    }
+
+    return target
+}
+
+},{}]},{},[1]);
diff --git a/dist/pouchdb.localstorage.min.js b/dist/pouchdb.localstorage.min.js
new file mode 100644
index 0000000..f2bbe83
--- /dev/null
+++ b/dist/pouchdb.localstorage.min.js
@@ -0,0 +1,14 @@
+// PouchDB localStorage plugin 5.3.2
+// Based on localstorage-down: https://github.com/No9/localstorage-down
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+!function e(t,n,r){function i(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return i(n?n:e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<r.length;a++)i(r[a]);return i}({1:[function(e,t,n){(function(t,n,r){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e["default"]:e}function o(e){return e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}function a(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}function s(e){if(e instanceof ArrayBuffer)return a(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}function u(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;r>n;n++)t[n]=u(e[n]);return t}if(e instanceof Date)return e.toISOString();if(o(e))return s(e);t={};for(n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var i=u(e[n]);"undefined"!=typeof i&&(t[n]=i)}return t}function c(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function f(){return me}function l(e,t){for(var n={},r=0,i=t.length;i>r;r++){var o=t[r];o in e&&(n[o]=e[o])}return n}function h(e){c()?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):f()&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}function d(){Se.EventEmitter.call(this),this._listeners={},h(this)}function p(e){return 0|Math.random()*e}function g(e,t){t=t||Ce.length;var n="",r=-1;if(e){for(;++r<e;)n+=Ce[p(t)];return n}for(;++r<36;)switch(r){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=Ce[3&p(16)|8];break;default:n+=Ce[p(16)]}return n}function v(e){Error.call(this,e.reason),this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}function y(e,t,n){function r(t){for(var r in e)"function"!=typeof e[r]&&(this[r]=e[r]);void 0!==n&&(this.name=n),void 0!==t&&(this.reason=t)}return r.prototype=v.prototype,new r(t)}function b(e,t,n){try{return!e(t,n)}catch(r){var i="Filter function threw: "+r.toString();return y(Ke,i)}}function _(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){r.doc||(r.doc={});var i=n&&b(e.filter,r.doc,t);if("object"==typeof i)return i;if(i)return!1;if(e.include_docs){if(!e.attachments)for(var o in r.doc._attachments)r.doc._attachments.hasOwnProperty(o)&&(r.doc._attachments[o].stub=!0)}else delete r.doc;return!0}}function m(e){try{return JSON.parse(e)}catch(t){return Ae.parse(e)}}function w(e){return e.length<5e4?JSON.parse(e):m(e)}function E(e){try{return JSON.stringify(e)}catch(t){return Ae.stringify(e)}}function k(e){for(var t,n,r,i,o=e.rev_tree.slice();i=o.pop();){var a=i.ids,s=a[2],u=i.pos;if(s.length)for(var c=0,f=s.length;f>c;c++)o.push({pos:u+1,ids:s[c]});else{var l=!!a[1].deleted,h=a[0];t&&!(r!==l?r:n!==u?u>n:h>t)||(t=h,n=u,r=l)}}return n+"-"+t}function S(e,t){for(var n,r=e.slice();n=r.pop();)for(var i=n.pos,o=n.ids,a=o[2],s=t(0===a.length,i,o[0],n.ctx,o[1]),u=0,c=a.length;c>u;u++)r.push({pos:i+1,ids:a[u],ctx:s})}function x(e){var t=[];return S(e.rev_tree,function(e,n,r,i,o){"available"!==o.status||e||(t.push(n+"-"+r),o.status="missing")}),t}function B(e,t){return e.pos-t.pos}function R(e){var t=[];S(e,function(e,n,r,i,o){e&&t.push({rev:n+"-"+r,pos:n,opts:o})}),t.sort(B).reverse();for(var n=0,r=t.length;r>n;n++)delete t[n].pos;return t}function A(e){for(var t=k(e),n=R(e.rev_tree),r=[],i=0,o=n.length;o>i;i++){var a=n[i];a.rev===t||a.opts.deleted||r.push(a.rev)}return r}function O(e){return e.ids}function L(e,t){t||(t=k(e));for(var n,r=t.substring(t.indexOf("-")+1),i=e.rev_tree.map(O);n=i.pop();){if(n[0]===r)return!!n[1].deleted;i=i.concat(n[2])}}function j(e){return/^_local/.test(e)}function M(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function T(e){var t;if(e?"string"!=typeof e?t=y(Pe):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=y(We)):t=y(Ue),t)throw t}function I(e){if(!/^\d+\-./.test(e))return y(Ve);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function C(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,i=[r[0],t,[]],o=1,a=r.length;a>o;o++)i=[r[o],{status:"missing"},[i]];return[{pos:n,ids:i}]}function D(e,t){var n,r,i,o={status:"available"};if(e._deleted&&(o.deleted=!0),t)if(e._id||(e._id=g()),r=g(32,16).toLowerCase(),e._rev){if(i=I(e._rev),i.error)return i;e._rev_tree=[{pos:i.prefix,ids:[i.id,{status:"missing"},[[r,o,[]]]]}],n=i.prefix+1}else e._rev_tree=[{pos:1,ids:[r,o,[]]}],n=1;else if(e._revisions&&(e._rev_tree=C(e._revisions,o),n=e._revisions.start,r=e._revisions.ids[0]),!e._rev_tree){if(i=I(e._rev),i.error)return i;n=i.prefix,r=i.id,e._rev_tree=[{pos:n,ids:[r,o,[]]}]}T(e._id),e._rev=n+"-"+r;var a={metadata:{},data:{}};for(var s in e)if(Object.prototype.hasOwnProperty.call(e,s)){var u="_"===s[0];if(u&&!He[s]){var c=y(Ye,s);throw c.message=Ye.message+": "+s,c}u&&!Ge[s]?a.metadata[s.slice(1)]=e[s]:a.data[s]=e[s]}return a}function q(e){for(var t,n=[],r=e.slice();t=r.pop();){var i=t.pos,o=t.ids,a=o[0],s=o[1],u=o[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:a,opts:s}),c&&n.push({pos:i+1-f.length,ids:f});for(var l=0,h=u.length;h>l;l++)r.push({pos:i+1,ids:u[l],history:f})}return n.reverse()}function N(e,t){return e.pos-t.pos}function P(e,t,n){for(var r,i=0,o=e.length;o>i;)r=i+o>>>1,n(e[r],t)<0?i=r+1:o=r;return i}function U(e,t,n){var r=P(e,t,n);e.splice(r,0,t)}function W(e,t){for(var n,r,i=t,o=e.length;o>i;i++){var a=e[i],s=[a.id,a.opts,[]];r?(r[2].push(s),r=s):n=r=s}return n}function F(e,t){return e[0]<t[0]?-1:1}function z(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var i=n.pop(),o=i.tree1,a=i.tree2;(o[1].status||a[1].status)&&(o[1].status="available"===o[1].status||"available"===a[1].status?"available":"missing");for(var s=0;s<a[2].length;s++)if(o[2][0]){for(var u=!1,c=0;c<o[2].length;c++)o[2][c][0]===a[2][s][0]&&(n.push({tree1:o[2][c],tree2:a[2][s]}),u=!0);u||(r="new_branch",U(o[2],a[2][s],F))}else r="new_leaf",o[2][0]=a[2][s]}return{conflicts:r,tree:e}}function Y(e,t,n){var r,i=[],o=!1,a=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var s=0,u=e.length;u>s;s++){var c=e[s];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=z(c.ids,t.ids),i.push({pos:c.pos,ids:r.tree}),o=o||r.conflicts,a=!0;else if(n!==!0){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,h=l.pos-f.pos,d=[],p=[];for(p.push({ids:f.ids,diff:h,parent:null,parentIdx:null});p.length>0;){var g=p.pop();if(0!==g.diff)for(var v=g.ids[2],y=0,b=v.length;b>y;y++)p.push({ids:v[y],diff:g.diff-1,parent:g.ids,parentIdx:y});else g.ids[0]===l.ids[0]&&d.push(g)}var _=d[0];_?(r=z(_.ids,l.ids),_.parent[2][_.parentIdx]=r.tree,i.push({pos:f.pos,ids:f.ids}),o=o||r.conflicts,a=!0):i.push(c)}else i.push(c)}return a||i.push(t),i.sort(N),{tree:i,conflicts:o||"internal_node"}}function K(e,t){for(var n,r=q(e),i={},o=0,a=r.length;a>o;o++){for(var s=r[o],u=s.ids,c=Math.max(0,u.length-t),f={pos:s.pos+c,ids:W(u,c)},l=0;c>l;l++){var h=s.pos+l+"-"+u[l].id;i[h]=!0}n=n?Y(n,f,!0).tree:[f]}return S(n,function(e,t,n){delete i[t+"-"+n]}),{tree:n,revs:Object.keys(i)}}function V(e,t,n){var r=Y(e,t),i=K(r.tree,n);return{tree:i.tree,stemmedRevs:i.revs,conflicts:r.conflicts}}function J(e,t){for(var n,r=e.slice(),i=t.split("-"),o=parseInt(i[0],10),a=i[1];n=r.pop();){if(n.pos===o&&n.ids[0]===a)return!0;for(var s=n.ids[2],u=0,c=s.length;c>u;u++)r.push({pos:n.pos+1,ids:s[u]})}return!1}function H(e,t,n,r,i,o,a,s){if(J(t.rev_tree,n.metadata.rev))return r[i]=n,o();var u=t.winningRev||k(t),c="deleted"in t?t.deleted:L(t,u),f="deleted"in n.metadata?n.metadata.deleted:L(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&s&&l){var h=n.data;h._rev=u,h._id=n.metadata.id,n=D(h,s)}var d=V(t.rev_tree,n.metadata.rev_tree[0],e),p=s&&(c&&f||!c&&"new_leaf"!==d.conflicts||c&&!f&&"new_branch"===d.conflicts);if(p){var g=y(Ne);return r[i]=g,o()}var v=n.metadata.rev;n.metadata.rev_tree=d.tree,n.stemmedRevs=d.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var b,_=k(n.metadata),m=L(n.metadata,_),w=c===m?0:m>c?-1:1;b=v===_?m:L(n.metadata,v),a(n,_,m,b,!0,w,i,o)}function G(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}function $(e,t,n,r,i,o,a,s,u){function c(e,t,n){var r=k(e.metadata),i=L(e.metadata,r);if("was_delete"in s&&i)return o[t]=y(qe,"deleted"),n();var u=l&&G(e);if(u){var c=y(Ne);return o[t]=c,n()}var f=i?0:1;a(e,r,i,i,!1,f,t,n)}function f(){++d===p&&u&&u()}e=e||1e3;var l=s.new_edits,h=new Be.Map,d=0,p=t.length;t.forEach(function(e,t){if(e._id&&j(e._id)){var r=e._deleted?"_removeLocal":"_putLocal";return void n[r](e,{ctx:i},function(e,n){o[t]=e||n,f()})}var a=e.metadata.id;h.has(a)?(p--,h.get(a).push([e,t])):h.set(a,[[e,t]])}),h.forEach(function(t,n){function i(){++u<t.length?s():f()}function s(){var s=t[u],f=s[0],h=s[1];if(r.has(n))H(e,r.get(n),f,o,h,i,a,l);else{var d=V([],f.metadata.rev_tree[0],e);f.metadata.rev_tree=d.tree,f.stemmedRevs=d.stemmedRevs||[],c(f,h,i)}}var u=0;s()})}function X(e){var t=!1;return Re(function(n){if(t)throw new Error("once called more than once");t=!0,e.apply(this,n)})}function Z(e){return Re(function(n){n=u(n);var r,i=this,o="function"==typeof n[n.length-1]?n.pop():!1;o&&(r=function(e,n){t.nextTick(function(){o(e,n)})});var a=new $e(function(t,r){var o;try{var a=X(function(e,n){e?r(e):t(n)});n.push(a),o=e.apply(i,n),o&&"function"==typeof o.then&&t(o)}catch(s){r(s)}});return r&&a.then(function(e){r(null,e)},r),a})}function Q(e){return Ze(e)}function ee(e,t,n,r){(n>0||r<t.byteLength)&&(t=new Uint8Array(t,n,Math.min(r,t.byteLength)-n)),e.append(t)}function te(e,t,n,r){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t)}function ne(){}function re(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(n){if("TypeError"!==n.name)throw n;for(var r="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,i=new r,o=0;o<e.length;o+=1)i.append(e[o]);return i.getBlob(t.type)}}function ie(e,t){return re([e.toArrayBuffer()],{type:t})}function oe(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,i=0;r>i;i++)t+=String.fromCharCode(n[i]);return t}function ae(e,t){if("undefined"==typeof FileReader)return t(oe((new FileReaderSync).readAsArrayBuffer(e)));var n=new FileReader,r="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";return r?t(n):void t(oe(n))},r?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}function se(e,t){ae(e,t)}function ue(e){return re([""],{type:e})}function ce(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),i=0;t>i;i++)r[i]=e.charCodeAt(i);return n}function fe(e,t){return re([ce(e)],{type:t})}function le(e,t){var n=t.prefix()[0],r=e._cache,i=r.get(n);return i||(i=new Be.Map,r.set(n,i)),i}function he(){this._batch=[],this._cache=new Be.Map}function de(e){return"winningRev"in e?e.winningRev:k(e)}function pe(e,t){return"deleted"in e?e.deleted:L(e,t)}function ge(e,t,n){var r=e.content_type;return new $e(function(i,o){t.binaryStore.get(e.digest,function(t,a){var s;if(t){if("NotFoundError"!==t.name)return o(t);s=n.binary?fe("",r):""}else s=n.binary?ie(a,r):a.toString("base64");delete e.stub,delete e.length,e.data=s,i()})})}function ve(e,t,n){var r=[];return e.forEach(function(e){if(e.doc&&e.doc._attachments){var t=Object.keys(e.doc._attachments);t.forEach(function(t){var n=e.doc._attachments[t];"data"in n||r.push(n)})}}),$e.all(r.map(function(e){return ge(e,t,n)}))}function ye(e,n){function i(){E.docStore=m.sublevel(st,{valueEncoding:bt}),E.bySeqStore=m.sublevel(ut,{valueEncoding:"json"}),E.attachmentStore=m.sublevel(ct,{valueEncoding:"json"}),E.binaryStore=m.sublevel(ft,{valueEncoding:"binary"}),E.localStore=m.sublevel(lt,{valueEncoding:"json"}),E.metaStore=m.sublevel(ht,{valueEncoding:"json"}),it.localAndMetaStores(m,E,function(){E.metaStore.get(pt,function(e,r){"undefined"==typeof m._updateSeq&&(m._updateSeq=r||0),E.metaStore.get(gt,function(e,r){m._docCount=e?0:r,E.metaStore.get(vt,function(e,r){b=e?g():r,E.metaStore.put(vt,b,function(){t.nextTick(function(){n(null,w)})})})})})})}function o(e){return m.isClosed()?e(new Error("database is closed")):e(null,m._docCount)}function a(e,t){try{e.apply(null,t)}catch(n){t[t.length-1](n)}}function s(){var e=m._queue.peekFront();"read"===e.type?c(e):f(e)}function c(e){for(var n=[e],r=1,i=m._queue.get(r);"undefined"!=typeof i&&"read"===i.type;)n.push(i),r++,i=m._queue.get(r);var o=0;n.forEach(function(e){var r=e.args,i=r[r.length-1];r[r.length-1]=Re(function(e){i.apply(null,e),++o===n.length&&t.nextTick(function(){n.forEach(function(){m._queue.shift()}),m._queue.length&&s()})}),a(e.fun,r)})}function f(e){var n=e.args,r=n[n.length-1];n[n.length-1]=Re(function(e){r.apply(null,e),t.nextTick(function(){m._queue.shift(),m._queue.length&&s()})}),a(e.fun,n)}function l(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"write"}),1===m._queue.length&&t.nextTick(s)})}function h(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"read"}),1===m._queue.length&&t.nextTick(s)})}function d(e){return("0000000000000000"+e).slice(-16)}function p(e){return parseInt(e,10)}function v(e,n){"function"==typeof R.destroy?R.destroy(e,n):t.nextTick(n)}e=u(e);var b,m,w=this,E={},k=e.revs_limit,B=e.name;"undefined"==typeof e.createIfMissing&&(e.createIfMissing=!0);var R=e.db||mt();if(R instanceof Error)return n(R);"function"!=typeof R.destroy&&(R.destroy=function(e,t){t()});var O,L=at(R);dt.has(L)?O=dt.get(L):(O=new Be.Map,dt.set(L,O)),O.has(B)?(m=O.get(B),i()):O.set(B,Ee(we(B,e,function(t){return t?(O["delete"](B),n(t)):(m=O.get(B),m._docCount=-1,m._queue=new je,void(e.db||e.noMigrate?i():it.toSublevel(B,m,i)))}))),w.type=function(){return"leveldb"},w._id=function(e){e(null,b)},w._info=function(e){var n={doc_count:m._docCount,update_seq:m._updateSeq,backend_adapter:at(R)};return t.nextTick(function(){e(null,n)})},w._get=h(function(e,t,n){t=u(t),E.docStore.get(e,function(e,r){if(e||!r)return n(y(qe,"missing"));var i=de(r),o=pe(r,i);if(o&&!t.rev)return n(y(qe,"deleted"));i=t.rev?t.rev:i;var a=r.rev_map[i];E.bySeqStore.get(d(a),function(e,t){if(!t)return n(y(qe));if("_id"in t&&t._id!==r.id)return n(new Error("wrong doc returned"));if(t._id=r.id,"_rev"in t){if(t._rev!==i)return n(new Error("wrong doc returned"))}else t._rev=i;return n(null,{doc:t,metadata:r})})})}),w._getAttachment=function(e,t,n){var r=e.digest,i=e.content_type;E.binaryStore.get(r,function(e,r){return e?"NotFoundError"!==e.name?n(e):n(null,t.binary?ue(i):""):void(t.binary?n(null,ie(r,i)):n(null,r.toString("base64")))})},w._bulkDocs=l(function(e,n,i){function o(e,t){R.get(E.attachmentStore,e,function(n){if(n){var r=y(Je,"unknown stub attachment with digest "+e);t(r)}else t()})}function a(e){var t=[];if(L.forEach(function(e){e&&e._attachments&&Object.keys(e._attachments).forEach(function(n){var r=e._attachments[n];r.stub&&t.push(r.digest)})}),!t.length)return e();var n,r=0;t.forEach(function(i){o(i,function(i){i&&!n&&(n=i),++r===t.length&&e(n)})})}function s(e){function t(){return++r===L.length?e(n):void 0}var n,r=0;L.forEach(function(e){return e._id&&j(e._id)?t():void R.get(E.docStore,e._id,function(r,i){r?"NotFoundError"!==r.name&&(n=r):_.set(e._id,i),t()})})}function u(e,t){var n=$e.resolve();e.forEach(function(e,t){n=n.then(function(){return new $e(function(n,r){w._doCompactionNoLock(t,e,{ctx:R},function(e){return e?r(e):void n()})})})}),n.then(function(){t()},t)}function c(e){var t=new Be.Map;_.forEach(function(e,n){t.set(n,x(e))}),u(t,e)}function f(){return w.auto_compaction?c(g):void u(S,g)}function l(e,t,n,r,o,a,s,u){function c(e){m++,v||(e?(v=e,u(v)):m===w.length&&g())}function f(e,t,n,r){return function(i){p(e,yt+i,t,n,r)}}function l(e,t,n){return function(r){tt(r).then(f(e,t,r,n))}}function g(){var n=e.metadata.rev_map[e.metadata.rev];if(n)return u(null,e.revsStemmed);n=++O,e.metadata.rev_map[e.metadata.rev]=e.metadata.seq=n;var r=d(n),i=[{key:r,value:e.data,prefix:E.bySeqStore,type:"put"},{key:e.metadata.id,value:e.metadata,prefix:E.docStore,type:"put"}];R.batch(i),b[s]={ok:!0,id:e.metadata.id,rev:t},_.set(e.metadata.id,e.metadata),u(null,e.revsStemmed)}A+=a;var v=null,m=0;e.metadata.winningRev=t,e.metadata.deleted=n,e.data._id=e.metadata.id,e.data._rev=e.metadata.rev,r&&(e.data._deleted=!0),e.stemmedRevs.length&&S.set(e.metadata.id,e.stemmedRevs);for(var w=e.data._attachments?Object.keys(e.data._attachments):[],k=0;k<w.length;k++){var x=w[k],B=e.data._attachments[x];if(B.stub){var L=e.data._id,j=e.data._rev;h(L,j,B.digest,c)}else{var M;if("string"==typeof B.data){try{M=Xe(B.data)}catch(T){return void i(y(ze,"Attachment is not a valid base64 string"))}l(e,x,c)(M)}else se(B.data,l(e,x,c))}}w.length||g()}function h(e,t,n,r){function i(){return new $e(function(e,t){R.get(E.attachmentStore,n,function(n,r){return n&&"NotFoundError"!==n.name?t(n):void e(r)})})}function o(r){var i=[e,t].join("@"),o={};return r?r.refs&&(o.refs=r.refs,o.refs[i]=!0):(o.refs={},o.refs[i]=!0),new $e(function(e){R.batch([{type:"put",prefix:E.attachmentStore,key:n,value:o}]),e(!r)})}var a=I[n]||$e.resolve();I[n]=a.then(function(){return i().then(o).then(function(e){r(null,e)},r)})}function p(e,t,n,i,o){var a=e.data._attachments[n];delete a.data,a.digest=t,a.length=i.length;var s=e.metadata.id,u=e.metadata.rev;a.revpos=parseInt(u,10),h(s,u,t,function(e,n){return e?o(e):0===i.length?o(e):n?(R.batch([{type:"put",prefix:E.binaryStore,key:t,value:new r(i,"binary")}]),void o()):o(e)})}function g(e){return e?t.nextTick(function(){i(e)}):(R.batch([{prefix:E.metaStore,type:"put",key:pt,value:O},{prefix:E.metaStore,type:"put",key:gt,value:m._docCount+A}]),void R.execute(m,function(e){return e?i(e):(m._docCount+=A,m._updateSeq=O,_t.notify(B),void t.nextTick(function(){i(null,b)}))}))}var v=n.new_edits,b=new Array(e.docs.length),_=new Be.Map,S=new Be.Map,R=new he,A=0,O=m._updateSeq,L=e.docs,M=L.map(function(e){if(e._id&&j(e._id))return e;var t=D(e,v);return t.metadata&&!t.metadata.rev_map&&(t.metadata.rev_map={}),t}),T=M.filter(function(e){return e.error});if(T.length)return i(T[0]);var I={};return M.length?void a(function(e){return e?i(e):void s(function(e){return e?i(e):void $(k,M,w,_,R,b,l,n,f)})}):i(null,[])}),w._allDocs=h(function(e,t){e=u(e),o(function(n,r){if(n)return t(n);var i={},o=e.skip||0;if(e.startkey&&(i.gte=e.startkey),e.endkey&&(i.lte=e.endkey),e.key&&(i.gte=i.lte=e.key),e.descending){i.reverse=!0;var a=i.lte;i.lte=i.gte,i.gte=a}var s;if("number"==typeof e.limit&&(s=e.limit),0===s||"start"in i&&"end"in i&&i.start>i.end)return t(null,{total_rows:r,offset:e.skip,rows:[]});var u=[],c=E.docStore.readStream(i),f=ke.obj(function(t,n,r){function i(t){var n={id:a.id,key:a.id,value:{rev:f}};if(e.include_docs){n.doc=t,n.doc._rev=n.value.rev,e.conflicts&&(n.doc._conflicts=A(a));for(var i in n.doc._attachments)n.doc._attachments.hasOwnProperty(i)&&(n.doc._attachments[i].stub=!0)}if(e.inclusive_end===!1&&a.id===e.endkey)return r();if(l){if("ok"!==e.deleted)return r();n.value.deleted=!0,n.doc=null}u.push(n),r()}var a=t.value,f=de(a),l=pe(a,f);if(l){if("ok"!==e.deleted)return void r()}else{if(o-- >0)return void r();if("number"==typeof s&&s--<=0)return c.unpipe(),c.destroy(),void r()}if(e.include_docs){var h=a.rev_map[f];E.bySeqStore.get(d(h),function(e,t){i(t)})}else i()},function(n){$e.resolve().then(function(){return e.include_docs&&e.attachments?ve(u,E,e):void 0}).then(function(){t(null,{total_rows:r,offset:e.skip,rows:u})},t),n()}).on("unpipe",function(){f.end()});c.on("error",t),c.pipe(f)})}),w._changes=function(e){function t(){e.done=!0,f&&e.limit&&e.limit<o.length&&(o.length=e.limit),y.unpipe(b),y.destroy(),e.continuous||e.cancelled||(e.include_docs&&e.attachments?ve(o,E,e).then(function(){e.complete(null,{results:o,last_seq:a})}):e.complete(null,{results:o,last_seq:a}))}if(e=u(e),e.continuous){var n=B+":"+g();return _t.addListener(B,n,w,e),_t.notify(B),{cancel:function(){_t.removeListener(B,n)}}}var r,i=e.descending,o=[],a=e.since||0,s=0,c={reverse:i};"limit"in e&&e.limit>0&&(r=e.limit),c.reverse||(c.start=d(e.since||0));var f,l=e.doc_ids&&new Be.Set(e.doc_ids),h=_(e),v=new Be.Map;f="return_docs"in e?e.return_docs:"returnDocs"in e?e.returnDocs:!0;var y=E.bySeqStore.readStream(c),b=ke.obj(function(n,u,c){function g(t){function n(n){var r=e.processChange(n,t,e);r.seq=t.seq;var i=h(r);return"object"==typeof i?e.complete(i):(i&&(s++,e.attachments&&e.include_docs?ve([r],E,e).then(function(){e.onChange(r)}):e.onChange(r),f&&o.push(r)),void c())}var r=de(t);if(t.seq!==y)return c();if(a=y,r===b._rev)return n(b);var i=t.rev_map[r];E.bySeqStore.get(d(i),function(e,t){n(t)})}if(r&&s>=r)return t(),c();if(e.cancelled||e.done)return c();var y=p(n.key),b=n.value;if(y===e.since&&!i)return c();if(l&&!l.has(b._id))return c();var _;return(_=v.get(b._id))?g(_):void E.docStore.get(b._id,function(t,n){return e.cancelled||e.done||m.isClosed()||j(n.id)?c():(v.set(b._id,n),void g(n))})},function(t){return e.cancelled?t():(f&&e.limit&&e.limit<o.length&&(o.length=e.limit),void t())}).on("unpipe",function(){b.end(),t()});return y.pipe(b),{cancel:function(){e.cancelled=!0,t()}}},w._close=function(e){return m.isClosed()?e(y(Fe)):void m.close(function(t){t?e(t):(O["delete"](B),e())})},w._getRevisionTree=function(e,t){E.docStore.get(e,function(e,n){e?t(y(qe)):t(null,n.rev_tree)})},w._doCompaction=l(function(e,t,n,r){w._doCompactionNoLock(e,t,n,r)}),w._doCompactionNoLock=function(e,t,n,r){if("function"==typeof n&&(r=n,n={}),!t.length)return r();var i=n.ctx||new he;i.get(E.docStore,e,function(o,a){function s(e){if(e&&(h=e),++g===t.length){if(h)return r(h);c()}}function u(e){return e?r(e):(i.batch(l),n.ctx?r():void i.execute(m,r))}function c(){function n(e){e&&(o=e),++a===r.length&&u(o)}var r=Object.keys(p);if(!r.length)return u();var o,a=0,s=new Be.Map;t.forEach(function(t){s.set(e+"@"+t,!0)}),r.forEach(function(e){i.get(E.attachmentStore,e,function(t,r){if(t)return"NotFoundError"===t.name?n():n(t);var i=Object.keys(r.refs||{}).filter(function(e){return!s.has(e)}),o={};i.forEach(function(e){o[e]=!0}),i.length?l.push({key:e,type:"put",value:{refs:o},prefix:E.attachmentStore}):l=l.concat([{key:e,type:"del",prefix:E.attachmentStore},{key:e,type:"del",prefix:E.binaryStore}]),n()})})}if(o)return r(o);var f=t.map(function(e){var t=a.rev_map[e];return delete a.rev_map[e],t});S(a.rev_tree,function(e,n,r,i,o){var a=n+"-"+r;-1!==t.indexOf(a)&&(o.status="missing")});var l=[];l.push({key:a.id,value:a,type:"put",prefix:E.docStore});var h,p={},g=0;f.forEach(function(e){l.push({key:d(e),type:"del",prefix:E.bySeqStore}),i.get(E.bySeqStore,d(e),function(e,t){if(e)return"NotFoundError"===e.name?s():s(e);var n=Object.keys(t._attachments||{});n.forEach(function(e){var n=t._attachments[e].digest;p[n]=!0}),s()})})})},w._getLocal=function(e,t){E.localStore.get(e,function(e,n){e?t(y(qe)):t(null,n)})},w._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._putLocalNoLock(e,t,n):w._putLocalWithLock(e,t,n)},w._putLocalWithLock=l(function(e,t,n){w._putLocalNoLock(e,t,n)}),w._putLocalNoLock=function(e,t,n){delete e._revisions;var r=e._rev,i=e._id,o=t.ctx||new he;o.get(E.localStore,i,function(a,s){if(a&&r)return n(y(Ne));if(s&&s._rev!==r)return n(y(Ne));e._rev=r?"0-"+(parseInt(r.split("-")[1],10)+1):"0-1";var u=[{type:"put",prefix:E.localStore,key:i,value:e}];o.batch(u);var c={ok:!0,id:e._id,rev:e._rev};return t.ctx?n(null,c):void o.execute(m,function(e){return e?n(e):void n(null,c)})})},w._removeLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._removeLocalNoLock(e,t,n):w._removeLocalWithLock(e,t,n)},w._removeLocalWithLock=l(function(e,t,n){w._removeLocalNoLock(e,t,n)}),w._removeLocalNoLock=function(e,t,n){var r=t.ctx||new he;r.get(E.localStore,e._id,function(i,o){if(i)return n("NotFoundError"!==i.name?i:y(qe));if(o._rev!==e._rev)return n(y(Ne));r.batch([{prefix:E.localStore,type:"del",key:e._id}]);var a={ok:!0,id:e._id,rev:"0-0"};return t.ctx?n(null,a):void r.execute(m,function(e){return e?n(e):void n(null,a)})})},w._destroy=function(e,t){var n,r=at(R);return dt.has(r)?(n=dt.get(r),void(n.has(B)?(_t.removeAllListeners(B),n.get(B).close(function(){n["delete"](B),v(B,t)})):v(B,t))):v(B,t)}}function be(e,t){function n(e,n){var r=Me.extend({db:t},e);ye.call(this,r,n)}return n.valid=function(){return e.valid()},n.use_prefix=e.use_prefix,n.destroy=Z(function(e,n,r){"function"==typeof n&&(r=n,n={});var i=Me.extend({db:t},n);return ye.destroy(e,i,r)}),n}function _e(t,n){var r=t.name,i=be(t,n),o="undefined"!=typeof PouchDB?PouchDB:e("pouchdb");o?o.adapter(r,i,!0):console.error(t.name+' adapter plugin error: Cannot find global "PouchDB" object! Did you remember to include pouchdb.js?')}var me,we=i(e(46)),Ee=i(e(76)),ke=e(94),Se=e(23),xe=i(e(29)),Be=e(57),Re=i(e(5)),Ae=i(e(99)),Oe=i(e(50)),Le=i(e(61)),je=i(e(19)),Me=e(32),Te=i(e(51));if(c())me=!1;else try{localStorage.setItem("_pouch_check_localstorage",1),me=!!localStorage.getItem("_pouch_check_localstorage")}catch(Ie){me=!1}xe(d,Se.EventEmitter),d.prototype.addListener=function(e,t,n,r){function i(){function e(){a=!1}if(o._listeners[t]){if(a)return void(a="waiting");a=!0;var s=l(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary"]);n.changes(s).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===a&&setTimeout(function(){i()},0),a=!1}).on("error",e)}}if(!this._listeners[t]){var o=this,a=!1;this._listeners[t]=i,this.on(e,i)}},d.prototype.removeListener=function(e,t){t in this._listeners&&Se.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t])},d.prototype.notifyLocalWindows=function(e){c()?chrome.storage.local.set({dbName:e}):f()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},d.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var Ce="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");xe(v,Error),v.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};var De,qe=(new v({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),new v({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),new v({status:404,error:"not_found",reason:"missing"})),Ne=new v({status:409,error:"conflict",reason:"Document update conflict"}),Pe=new v({status:400,error:"invalid_id",reason:"_id field must contain a string"}),Ue=new v({status:412,error:"missing_id",reason:"_id is required for puts"}),We=new v({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),Fe=new v({status:412,error:"precondition_failed",reason:"Database not open"}),ze=(new v({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),new v({status:500,error:"badarg",reason:"Some query argument is invalid"})),Ye=(new v({status:400,error:"invalid_request",reason:"Request was invalid"}),new v({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),new v({status:500,error:"doc_validation",reason:"Bad special document member"})),Ke=new v({status:400,error:"bad_request",reason:"Something wrong with the request"}),Ve=(new v({status:400,error:"bad_request",reason:"Document must be a JSON object"}),new v({status:404,error:"not_found",reason:"Database not found"}),new v({status:500,error:"indexed_db_went_bad",reason:"unknown"}),new v({status:500,error:"web_sql_went_bad",reason:"unknown"}),new v({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),new v({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),new v({status:400,error:"bad_request",reason:"Invalid rev format"})),Je=(new v({status:412,error:"file_exists",reason:"The database could not be created, the file already exists."}),new v({status:412,error:"missing_stub"})),He=(new v({status:413,error:"invalid_url",reason:"Provided URL is invalid"}),M(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"])),Ge=M(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]),$e="function"==typeof Promise?Promise:Oe,Xe=function(e){return atob(e)},Ze=function(e){return btoa(e)},Qe=n.setImmediate||n.setTimeout,et=32768,tt=Z(function(e,t){function n(){var r=s*o,i=r+o;if(s++,a>s)c(u,e,r,i),Qe(n);else{c(u,e,r,i);var f=u.end(!0),l=Q(f);t(null,l),u.destroy()}}var r="string"==typeof e,i=r?e.length:e.byteLength,o=Math.min(et,i),a=Math.ceil(i/o),s=0,u=r?new Le:new Le.ArrayBuffer,c=r?te:ee;n()}),nt=function(e,n,r){t.nextTick(function(){r()})},rt=function(e,n,r){t.nextTick(function(){r()})},it={toSublevel:nt,localAndMetaStores:rt},ot=ne.name;De=ot?function(e){return e.name}:function(e){return e.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]};var at=De;he.prototype.get=function(e,n,r){var i=le(this,e),o=i.get(n);return o?t.nextTick(function(){r(null,o)}):null===o?t.nextTick(function(){r({name:"NotFoundError"})}):void e.get(n,function(e,t){return e?("NotFoundError"===e.name&&i.set(n,null),r(e)):(i.set(n,t),void r(null,t))})},he.prototype.batch=function(e){for(var t=0,n=e.length;n>t;t++){var r=e[t],i=le(this,r.prefix);"put"===r.type?i.set(r.key,r.value):i.set(r.key,null)}this._batch=this._batch.concat(e)},he.prototype.execute=function(e,t){for(var n=new Be.Set,r=[],i=this._batch.length-1;i>=0;i--){var o=this._batch[i],a=o.prefix.prefix()[0]+"ÿ"+o.key;n.has(a)||(n.add(a),r.push(o))}e.batch(r,t)};var st="document-store",ut="by-sequence",ct="attach-store",ft="attach-binary-store",lt="local-store",ht="meta-store",dt=new Be.Map,pt="_local_last_update_seq",gt="_local_doc_count",vt="_local_uuid",yt="md5-",bt={encode:E,decode:w,buffer:!1,type:"cheap-json"},_t=new d,mt=function(){try{return e(7)}catch(t){return t=t||"leveldown import error","MODULE_NOT_FOUND"===t.code?new Error(["the 'leveldown' package is not available. install it, or,","specify another storage backend using the 'db' option"].join(" ")):t.message&&t.message.match("Module version mismatch")?new Error([t.message,"This generally implies that leveldown was built with a different","version of node than that which is running now.  You may try","fully removing and reinstalling PouchDB or leveldown to resolve."].join(" ")):new Error(t.toString()+": unable to import leveldown")}};ye.valid=function(){return!0},ye.use_prefix=!1;var wt={name:"localstorage",valid:function(){return"undefined"!=typeof localStorage},use_prefix:!0};_e(wt,Te)}).call(this,e(59),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(8).Buffer)},{19:19,23:23,29:29,32:32,46:46,5:5,50:50,51:51,57:57,59:59,61:61,7:7,76:76,8:8,94:94,99:99,pouchdb:"pouchdb"}],2:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(n)throw n;if(n=this._db._checkKeyValue(t,"value",this._db._isBuffer))throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKeyValue(e,"key",this._db._isBuffer);
+if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(59))},{59:59}],3:[function(e,t,n){(function(e){function n(e){this.db=e,this._ended=!1,this._nexting=!1}n.prototype.next=function(t){var n=this;if("function"!=typeof t)throw new Error("next() requires a callback argument");return n._ended?t(new Error("cannot call next() after end()")):n._nexting?t(new Error("cannot call next() before previous next() has completed")):(n._nexting=!0,"function"==typeof n._next?n._next(function(){n._nexting=!1,t.apply(null,arguments)}):void e.nextTick(function(){n._nexting=!1,t()}))},n.prototype.end=function(t){if("function"!=typeof t)throw new Error("end() requires a callback argument");return this._ended?t(new Error("end() already called on iterator")):(this._ended=!0,"function"==typeof this._end?this._end(t):void e.nextTick(t))},t.exports=n}).call(this,e(59))},{59:59}],4:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e}var o=e(100),a=e(3),s=e(2);i.prototype.open=function(e,t){if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");return"object"!=typeof e&&(e={}),"function"==typeof this._open?this._open(e,t):void r.nextTick(t)},i.prototype.close=function(e){if("function"!=typeof e)throw new Error("close() requires a callback argument");return"function"==typeof this._close?this._close(e):void r.nextTick(e)},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKeyValue(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?i(o):(o=this._checkKeyValue(t,"value",this._isBuffer))?i(o):(this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||r.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKeyValue(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));"object"!=typeof t&&(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKeyValue(i.type,"type",this._isBuffer))return n(o);if(o=this._checkKeyValue(i.key,"key",this._isBuffer))return n(o);if("put"==i.type&&(o=this._checkKeyValue(i.value,"value",this._isBuffer)))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||(t=String(t)),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.reverse&&e.lt&&(e.start=e.lt),e.reverse&&e.lte&&(e.start=e.lte),!e.reverse&&e.gt&&(e.start=e.gt),!e.reverse&&e.gte&&(e.start=e.gte),(e.reverse&&e.lt&&!e.lte||!e.reverse&&e.gt&&!e.gte)&&(e.exclusiveStart=!0),e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._checkKeyValue=function(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(this._isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")},t.exports.AbstractLevelDOWN=i,t.exports.AbstractIterator=a,t.exports.AbstractChainedBatch=s}).call(this,{isBuffer:e(30)},e(59))},{100:100,2:2,3:3,30:30,59:59}],5:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],6:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===a||t===l?62:t===s||t===h?63:u>t?-1:u+10>t?t-u+26+26:f+26>t?t-f:c+26>t?t-c+26:void 0}function n(e){function n(e){c[l++]=e}var r,i,a,s,u,c;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var f=e.length;u="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0,c=new o(3*e.length/4-u),a=u>0?e.length-4:e.length;var l=0;for(r=0,i=0;a>r;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===u?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===u&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(s>>8&255),n(255&s)),c}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,o,a,s=e.length%3,u="";for(i=0,a=e.length-s;a>i;i+=3)o=(e[i]<<16)+(e[i+1]<<8)+e[i+2],u+=n(o);switch(s){case 1:o=e[e.length-1],u+=t(o>>2),u+=t(o<<4&63),u+="==";break;case 2:o=(e[e.length-2]<<8)+e[e.length-1],u+=t(o>>10),u+=t(o>>4&63),u+=t(o<<2&63),u+="="}return u}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="+".charCodeAt(0),s="/".charCodeAt(0),u="0".charCodeAt(0),c="a".charCodeAt(0),f="A".charCodeAt(0),l="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],7:[function(e,t,n){},{}],8:[function(e,t,n){(function(t){"use strict";function r(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(e){return this instanceof o?(o.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof e?a(this,e):"string"==typeof e?s(this,e,arguments.length>1?arguments[1]:"utf8"):u(this,e)):arguments.length>1?new o(e,arguments[1]):new o(e)}function a(e,t){if(e=g(e,0>t?0:0|v(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)e[n]=0;return e}function s(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|b(t,n);return e=g(e,r),e.write(t,n),e}function u(e,t){if(o.isBuffer(t))return c(e,t);if($(t))return f(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return l(e,t);if(t instanceof ArrayBuffer)return h(e,t)}return t.length?d(e,t):p(e,t)}function c(e,t){var n=0|v(t.length);return e=g(e,n),t.copy(e,0,0,n),e}function f(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function l(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function h(e,t){return o.TYPED_ARRAY_SUPPORT?(t.byteLength,e=o._augment(new Uint8Array(t))):e=l(e,new Uint8Array(t)),e}function d(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function p(e,t){var n,r=0;"Buffer"===t.type&&$(t.data)&&(n=t.data,r=0|v(n.length)),e=g(e,r);for(var i=0;r>i;i+=1)e[i]=255&n[i];return e}function g(e,t){o.TYPED_ARRAY_SUPPORT?(e=o._augment(new Uint8Array(t)),e.__proto__=o.prototype):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=o.poolSize>>>1;return n&&(e.parent=X),e}function v(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function y(e,t){if(!(this instanceof y))return new y(e,t);var n=new o(e,t);return delete n.parent,n}function b(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return z(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return V(e).length;default:if(r)return z(e).length;t=(""+t).toLowerCase(),r=!0}}function _(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(e){case"hex":return j(this,t,n);case"utf8":case"utf-8":return R(this,t,n);case"ascii":return O(this,t,n);case"binary":return L(this,t,n);case"base64":return B(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function m(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;r>a;a++){var s=parseInt(t.substr(2*a,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+a]=s}return a}function w(e,t,n,r){return J(z(t,e.length-n),e,n,r)}function E(e,t,n,r){return J(Y(t),e,n,r)}function k(e,t,n,r){return E(e,t,n,r)}function S(e,t,n,r){return J(V(t),e,n,r)}function x(e,t,n,r){return J(K(t,e.length-n),e,n,r)}function B(e,t,n){return 0===t&&n===e.length?H.fromByteArray(e):H.fromByteArray(e.slice(t,n))}function R(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;n>i;){var o=e[i],a=null,s=o>239?4:o>223?3:o>191?2:1;if(n>=i+s){var u,c,f,l;switch(s){case 1:128>o&&(a=o);break;case 2:u=e[i+1],128===(192&u)&&(l=(31&o)<<6|63&u,l>127&&(a=l));break;case 3:u=e[i+1],c=e[i+2],128===(192&u)&&128===(192&c)&&(l=(15&o)<<12|(63&u)<<6|63&c,l>2047&&(55296>l||l>57343)&&(a=l));break;case 4:u=e[i+1],c=e[i+2],f=e[i+3],128===(192&u)&&128===(192&c)&&128===(192&f)&&(l=(15&o)<<18|(63&u)<<12|(63&c)<<6|63&f,l>65535&&1114112>l&&(a=l))}}null===a?(a=65533,s=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),i+=s}return A(r)}function A(e){var t=e.length;if(Z>=t)return String.fromCharCode.apply(String,e);for(var n="",r=0;t>r;)n+=String.fromCharCode.apply(String,e.slice(r,r+=Z));return n}function O(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(127&e[i]);return r}function L(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(e[i]);return r}function j(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var i="",o=t;n>o;o++)i+=F(e[o]);return i}function M(e,t,n){for(var r=e.slice(t,n),i="",o=0;o<r.length;o+=2)i+=String.fromCharCode(r[o]+256*r[o+1]);return i}function T(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function I(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>i||a>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function C(e,t,n,r){0>t&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);o>i;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function D(e,t,n,r){0>t&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);o>i;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function q(e,t,n,r,i,o){if(t>i||o>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(0>n)throw new RangeError("index out of range")}function N(e,t,n,r,i){return i||q(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),G.write(e,t,n,r,23,4),n+4}function P(e,t,n,r,i){return i||q(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),G.write(e,t,n,r,52,8),n+8}function U(e){if(e=W(e).replace(ee,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function W(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function F(e){return 16>e?"0"+e.toString(16):e.toString(16)}function z(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],a=0;r>a;a++){if(n=e.charCodeAt(a),n>55295&&57344>n){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(56320>n){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,128>n){if((t-=1)<0)break;o.push(n)}else if(2048>n){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function Y(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function K(e,t){for(var n,r,i,o=[],a=0;a<e.length&&!((t-=2)<0);a++)n=e.charCodeAt(a),r=n>>8,i=n%256,o.push(i),o.push(r);return o}function V(e){return H.toByteArray(U(e))}function J(e,t,n,r){for(var i=0;r>i&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var H=e(6),G=e(27),$=e(31);n.Buffer=o,n.SlowBuffer=y,n.INSPECT_MAX_BYTES=50,o.poolSize=8192;var X={};o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),o.TYPED_ARRAY_SUPPORT?(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array):(o.prototype.length=void 0,o.prototype.parent=void 0),o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);a>i&&e[i]===t[i];)++i;return i!==a&&(n=e[i],r=t[i]),r>n?-1:n>r?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!$(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new o(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new o(t),i=0;for(n=0;n<e.length;n++){var a=e[n];a.copy(r,i),i+=a.length}return r},o.byteLength=b,o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?R(this,0,e):_.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:o.compare(this,e)},o.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[-1===r?0:i-r]){if(-1===r&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(o.isBuffer(e))return n(this,e,t);if("number"==typeof e)return o.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},o.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},o.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return E(this,e,t,n);case"binary":return k(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Z=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=o._augment(this.subarray(e,t));else{var i=t-e;r=new o(i,void 0);for(var a=0;i>a;a++)r[a]=this[a+e]}return r.length&&(r.parent=this.parent||this),r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||T(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||T(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||T(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||T(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||T(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(e,t){return t||T(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},o.prototype.readInt16LE=function(e,t){t||T(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||T(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||T(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||T(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||I(this,e,t,n,Math.pow(2,8*n),0);var i=1,o=0;for(this[t]=255&e;++o<n&&(i*=256);)this[t+o]=e/i&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||I(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):C(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):C(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):D(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);I(this,e,t,n,i-1,-i)}var o=0,a=1,s=0>e?1:0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);I(this,e,t,n,i-1,-i)}var o=n-1,a=1,s=0>e?1:0;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):C(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):C(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):D(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||I(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return P(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return P(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&n>r&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&t>n&&r>t)for(i=a-1;i>=0;i--)e[i+t]=this[i+n];else if(1e3>a||!o.TYPED_ARRAY_SUPPORT)for(i=0;a>i;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),t>n)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new RangeError("start out of bounds");if(0>n||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;n>r;r++)this[r]=e;else{var i=z(e.toString()),o=i.length;for(r=t;n>r;r++)this[r]=i[r%o]}return this}},o.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(o.TYPED_ARRAY_SUPPORT)return new o(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;n>t;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var Q=o.prototype;o._augment=function(e){return e.constructor=o,e._isBuffer=!0,e._set=e.set,e.get=Q.get,e.set=Q.set,e.write=Q.write,e.toString=Q.toString,e.toLocaleString=Q.toString,e.toJSON=Q.toJSON,e.equals=Q.equals,e.compare=Q.compare,e.indexOf=Q.indexOf,e.copy=Q.copy,e.slice=Q.slice,e.readUIntLE=Q.readUIntLE,e.readUIntBE=Q.readUIntBE,e.readUInt8=Q.readUInt8,e.readUInt16LE=Q.readUInt16LE,e.readUInt16BE=Q.readUInt16BE,e.readUInt32LE=Q.readUInt32LE,e.readUInt32BE=Q.readUInt32BE,e.readIntLE=Q.readIntLE,e.readIntBE=Q.readIntBE,e.readInt8=Q.readInt8,e.readInt16LE=Q.readInt16LE,e.readInt16BE=Q.readInt16BE,e.readInt32LE=Q.readInt32LE,e.readInt32BE=Q.readInt32BE,e.readFloatLE=Q.readFloatLE,e.readFloatBE=Q.readFloatBE,e.readDoubleLE=Q.readDoubleLE,e.readDoubleBE=Q.readDoubleBE,e.writeUInt8=Q.writeUInt8,e.writeUIntLE=Q.writeUIntLE,e.writeUIntBE=Q.writeUIntBE,e.writeUInt16LE=Q.writeUInt16LE,e.writeUInt16BE=Q.writeUInt16BE,e.writeUInt32LE=Q.writeUInt32LE,e.writeUInt32BE=Q.writeUInt32BE,e.writeIntLE=Q.writeIntLE,e.writeIntBE=Q.writeIntBE,e.writeInt8=Q.writeInt8,e.writeInt16LE=Q.writeInt16LE,e.writeInt16BE=Q.writeInt16BE,e.writeInt32LE=Q.writeInt32LE,e.writeInt32BE=Q.writeInt32BE,e.writeFloatLE=Q.writeFloatLE,e.writeFloatBE=Q.writeFloatBE,e.writeDoubleLE=Q.writeDoubleLE,e.writeDoubleBE=Q.writeDoubleBE,e.fill=Q.fill,e.inspect=Q.inspect,e.toArrayBuffer=Q.toArrayBuffer,e};var ee=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{27:27,31:31,6:6}],9:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===v(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function o(e){return null==e}function a(e){return"number"==typeof e}function s(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function c(e){return void 0===e}function f(e){return"[object RegExp]"===v(e)}function l(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===v(e)}function d(e){return"[object Error]"===v(e)||e instanceof Error}function p(e){return"function"==typeof e}function g(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function v(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=o,n.isNumber=a,n.isString=s,n.isSymbol=u,n.isUndefined=c,n.isRegExp=f,n.isObject=l,n.isDate=h,n.isError=d,n.isFunction=p,n.isPrimitive=g,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e(30)})},{30:30}],10:[function(e,t,n){var r=e(8).Buffer,i=".PYFGCRLAOEUIDHTNSQJKXBMWVZ_pyfgcrlaoeuidhtnsqjkxbmwvz1234567890".split("").sort().join("");t.exports=function(e,t){if(e=e||i,t=t||{},64!==e.length)throw new Error("a base 64 encoding requires 64 chars");var n=new r(128);n.fill();for(var o=0;64>o;o++){var a=e.charCodeAt(o);n[a]=o}return t.encode=function(t){for(var n="",r=t.length,i=0,o=0;r>o;o++){var a=t[o];switch(o%3){case 0:n+=e[a>>2],i=(3&a)<<4;break;case 1:n+=e[i|a>>4],i=(15&a)<<2;break;case 2:n+=e[i|a>>6],n+=e[63&a],i=0}}return r%3&&(n+=e[i]),n},t.decode=function(e){for(var t=e.length,i=0,o=new r(~~(t/4*3)),a=0,s=0;t>s;s++){var u=n[e.charCodeAt(s)];switch(s%4){case 0:a=u<<2;break;case 1:o[i++]=a|u>>4,a=u<<4&255;break;case 2:o[i++]=a|u>>2,a=u<<6&255;break;case 3:o[i++]=a|u}}return o},t},t.exports(i,t.exports)},{8:8}],11:[function(e,t,n){function r(e){o.call(this,e),this._options=e,this._iterator=null,this._operations=[]}var i=e(98),o=e(16).AbstractIterator;i.inherits(r,o),r.prototype.setDb=function(e){var t=this._iterator=e.iterator(this._options);this._operations.forEach(function(e){t[e.method].apply(t,e.args)})},r.prototype._operation=function(e,t){return this._iterator?this._iterator[e].apply(this._iterator,t):void this._operations.push({method:e,args:t})},"next end".split(" ").forEach(function(e){r.prototype["_"+e]=function(){this._operation(e,arguments)}}),t.exports=r},{16:16,98:98}],12:[function(e,t,n){(function(n,r){function i(e){a.call(this,"string"==typeof e?e:""),this._db=void 0,this._operations=[],this._iterators=[]}var o=e(98),a=e(16).AbstractLevelDOWN,s=e(11);o.inherits(i,a),i.prototype.setDb=function(e){this._db=e,this._operations.forEach(function(t){e[t.method].apply(e,t.args)}),this._iterators.forEach(function(t){t.setDb(e)})},i.prototype._open=function(e,t){return r.nextTick(t)},i.prototype._operation=function(e,t){return this._db?this._db[e].apply(this._db,t):void this._operations.push({method:e,args:t})},"put get del batch approximateSize".split(" ").forEach(function(e){i.prototype["_"+e]=function(){this._operation(e,arguments)}}),i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._iterator=function(e){if(this._db)return this._db.iterator.apply(this._db,arguments);var t=new s(e);return this._iterators.push(t),t},t.exports=i,t.exports.DeferredIterator=s}).call(this,{isBuffer:e(30)},e(59))},{11:11,16:16,30:30,59:59,98:98}],13:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKey(e,"key",this._db._isBuffer);if(n)throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKey(e,"key",this._db._isBuffer);if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(59))},{59:59}],14:[function(e,t,n){arguments[4][3][0].apply(n,arguments)},{3:3,59:59}],15:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e,this.status="new"}var o=e(18),a=e(14),s=e(13);i.prototype.open=function(e,t){var n=this,i=this.status;if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");"object"!=typeof e&&(e={}),e.createIfMissing=0!=e.createIfMissing,e.errorIfExists=!!e.errorIfExists,"function"==typeof this._open?(this.status="opening",this._open(e,function(e){return e?(n.status=i,t(e)):(n.status="open",void t())})):(this.status="open",r.nextTick(t))},i.prototype.close=function(e){var t=this,n=this.status;if("function"!=typeof e)throw new Error("close() requires a callback argument");"function"==typeof this._close?(this.status="closing",this._close(function(r){return r?(t.status=n,e(r)):(t.status="closed",void e())})):(this.status="closed",r.nextTick(e))},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),
+"object"!=typeof t&&(t={}),t.asBuffer=0!=t.asBuffer,"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKey(e,"key",this._isBuffer))?i(o):(this._isBuffer(e)||(e=String(e)),null==t||this._isBuffer(t)||r.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"==typeof e&&(n=e),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));t&&"object"==typeof t||(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKey(i.type,"type",this._isBuffer))return n(o);if(o=this._checkKey(i.key,"key",this._isBuffer))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||(t=String(t)),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.keys=0!=e.keys,e.values=0!=e.values,e.limit="limit"in e?e.limit:-1,e.keyAsBuffer=0!=e.keyAsBuffer,e.valueAsBuffer=0!=e.valueAsBuffer,e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._checkKey=function(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(this._isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")},t.exports=i}).call(this,{isBuffer:e(30)},e(59))},{13:13,14:14,18:18,30:30,59:59}],16:[function(e,t,n){n.AbstractLevelDOWN=e(15),n.AbstractIterator=e(14),n.AbstractChainedBatch=e(13),n.isLevelDOWN=e(17)},{13:13,14:14,15:15,17:17}],17:[function(e,t,n){function r(e){return e&&"object"==typeof e?Object.keys(i.prototype).filter(function(e){return"_"!=e[0]&&"approximateSize"!=e}).every(function(t){return"function"==typeof e[t]}):!1}var i=e(15);t.exports=r},{15:15}],18:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}],19:[function(e,t,n){"use strict";function r(e){if(this._capacity=a(e),this._length=0,this._front=0,this._makeCapacity(),s(e)){for(var t=e.length,n=0;t>n;++n)this[n]=e[n];this._length=t}}function i(e,t,n,r,i){for(var o=0;i>o;++o)n[o+r]=e[o+t]}function o(e){return e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,e+1}function a(e){if("number"!=typeof e){if(!s(e))return 16;e=e.length}return o(Math.min(Math.max(16,e),1073741824))}r.prototype.toArray=function(){for(var e=this._length,t=new Array(e),n=this._front,r=this._capacity,i=0;e>i;++i)t[i]=this[n+i&r-1];return t},r.prototype.push=function(e){var t=arguments.length,n=this._length;if(t>1){var r=this._capacity;if(n+t>r){for(var i=0;t>i;++i){this._checkCapacity(n+1);var o=this._front+n&this._capacity-1;this[o]=arguments[i],n++,this._length=n}return n}for(var o=this._front,i=0;t>i;++i)this[o+n&r-1]=arguments[i],o++;return this._length=n+t,n+t}if(0===t)return n;this._checkCapacity(n+1);var i=this._front+n&this._capacity-1;return this[i]=e,this._length=n+1,n+1},r.prototype.pop=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1,n=this[t];return this[t]=void 0,this._length=e-1,n}},r.prototype.shift=function(){var e=this._length;if(0!==e){var t=this._front,n=this[t];return this[t]=void 0,this._front=t+1&this._capacity-1,this._length=e-1,n}},r.prototype.unshift=function(e){var t=this._length,n=arguments.length;if(n>1){var r=this._capacity;if(t+n>r){for(var i=n-1;i>=0;i--){this._checkCapacity(t+1);var r=this._capacity,o=(this._front-1&r-1^r)-r;this[o]=arguments[i],t++,this._length=t,this._front=o}return t}for(var a=this._front,i=n-1;i>=0;i--){var o=(a-1&r-1^r)-r;this[o]=arguments[i],a=o}return this._front=a,this._length=t+n,t+n}if(0===n)return t;this._checkCapacity(t+1);var r=this._capacity,i=(this._front-1&r-1^r)-r;return this[i]=e,this._length=t+1,this._front=i,t+1},r.prototype.peekBack=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1;return this[t]}},r.prototype.peekFront=function(){return 0!==this._length?this[this._front]:void 0},r.prototype.get=function(e){var t=e;if(t===(0|t)){var n=this._length;if(0>t&&(t+=n),!(0>t||t>=n))return this[this._front+t&this._capacity-1]}},r.prototype.isEmpty=function(){return 0===this._length},r.prototype.clear=function(){this._length=0,this._front=0,this._makeCapacity()},r.prototype.toString=function(){return this.toArray().toString()},r.prototype.valueOf=r.prototype.toString,r.prototype.removeFront=r.prototype.shift,r.prototype.removeBack=r.prototype.pop,r.prototype.insertFront=r.prototype.unshift,r.prototype.insertBack=r.prototype.push,r.prototype.enqueue=r.prototype.push,r.prototype.dequeue=r.prototype.shift,r.prototype.toJSON=r.prototype.toArray,Object.defineProperty(r.prototype,"length",{get:function(){return this._length},set:function(){throw new RangeError("")}}),r.prototype._makeCapacity=function(){for(var e=this._capacity,t=0;e>t;++t)this[t]=void 0},r.prototype._checkCapacity=function(e){this._capacity<e&&this._resizeTo(a(1.5*this._capacity+16))},r.prototype._resizeTo=function(e){var t=this._front,n=this._capacity,r=new Array(n),o=this._length;if(i(this,0,r,0,n),this._capacity=e,this._makeCapacity(),this._front=0,n>=t+o)i(r,t,this,0,o);else{var a=o-(t+o&n-1);i(r,t,this,0,a),i(r,0,this,a,o-a)}};var s=Array.isArray;t.exports=r},{}],20:[function(e,t,n){function r(e,t,n){a(this,{type:e,name:e,cause:"string"!=typeof t?t:n,message:t&&"string"!=typeof t?t.message:t},"ewr")}function i(e,t){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee),r.call(this,"CustomError",e,t)}function o(e,t,n){var o=function(n,i){r.call(this,t,n,i),"FilesystemError"==t&&(this.code=this.cause.code,this.path=this.cause.path,this.errno=this.cause.errno,this.message=(e.errno[this.cause.errno]?e.errno[this.cause.errno].description:this.cause.message)+(this.cause.path?" ["+this.cause.path+"]":"")),Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee)};return o.prototype=n?new n:new i,o}var a=e(22);i.prototype=new Error,t.exports=function(e){var t=function(t,n){return o(e,t,n)};return{CustomError:i,FilesystemError:t("FilesystemError"),createError:t}}},{22:22}],21:[function(e,t,n){var r=t.exports.all=[{errno:-2,code:"ENOENT",description:"no such file or directory"},{errno:-1,code:"UNKNOWN",description:"unknown error"},{errno:0,code:"OK",description:"success"},{errno:1,code:"EOF",description:"end of file"},{errno:2,code:"EADDRINFO",description:"getaddrinfo error"},{errno:3,code:"EACCES",description:"permission denied"},{errno:4,code:"EAGAIN",description:"resource temporarily unavailable"},{errno:5,code:"EADDRINUSE",description:"address already in use"},{errno:6,code:"EADDRNOTAVAIL",description:"address not available"},{errno:7,code:"EAFNOSUPPORT",description:"address family not supported"},{errno:8,code:"EALREADY",description:"connection already in progress"},{errno:9,code:"EBADF",description:"bad file descriptor"},{errno:10,code:"EBUSY",description:"resource busy or locked"},{errno:11,code:"ECONNABORTED",description:"software caused connection abort"},{errno:12,code:"ECONNREFUSED",description:"connection refused"},{errno:13,code:"ECONNRESET",description:"connection reset by peer"},{errno:14,code:"EDESTADDRREQ",description:"destination address required"},{errno:15,code:"EFAULT",description:"bad address in system call argument"},{errno:16,code:"EHOSTUNREACH",description:"host is unreachable"},{errno:17,code:"EINTR",description:"interrupted system call"},{errno:18,code:"EINVAL",description:"invalid argument"},{errno:19,code:"EISCONN",description:"socket is already connected"},{errno:20,code:"EMFILE",description:"too many open files"},{errno:21,code:"EMSGSIZE",description:"message too long"},{errno:22,code:"ENETDOWN",description:"network is down"},{errno:23,code:"ENETUNREACH",description:"network is unreachable"},{errno:24,code:"ENFILE",description:"file table overflow"},{errno:25,code:"ENOBUFS",description:"no buffer space available"},{errno:26,code:"ENOMEM",description:"not enough memory"},{errno:27,code:"ENOTDIR",description:"not a directory"},{errno:28,code:"EISDIR",description:"illegal operation on a directory"},{errno:29,code:"ENONET",description:"machine is not on the network"},{errno:31,code:"ENOTCONN",description:"socket is not connected"},{errno:32,code:"ENOTSOCK",description:"socket operation on non-socket"},{errno:33,code:"ENOTSUP",description:"operation not supported on socket"},{errno:34,code:"ENOENT",description:"no such file or directory"},{errno:35,code:"ENOSYS",description:"function not implemented"},{errno:36,code:"EPIPE",description:"broken pipe"},{errno:37,code:"EPROTO",description:"protocol error"},{errno:38,code:"EPROTONOSUPPORT",description:"protocol not supported"},{errno:39,code:"EPROTOTYPE",description:"protocol wrong type for socket"},{errno:40,code:"ETIMEDOUT",description:"connection timed out"},{errno:41,code:"ECHARSET",description:"invalid Unicode character"},{errno:42,code:"EAIFAMNOSUPPORT",description:"address family for hostname not supported"},{errno:44,code:"EAISERVICE",description:"servname not supported for ai_socktype"},{errno:45,code:"EAISOCKTYPE",description:"ai_socktype not supported"},{errno:46,code:"ESHUTDOWN",description:"cannot send after transport endpoint shutdown"},{errno:47,code:"EEXIST",description:"file already exists"},{errno:48,code:"ESRCH",description:"no such process"},{errno:49,code:"ENAMETOOLONG",description:"name too long"},{errno:50,code:"EPERM",description:"operation not permitted"},{errno:51,code:"ELOOP",description:"too many symbolic links encountered"},{errno:52,code:"EXDEV",description:"cross-device link not permitted"},{errno:53,code:"ENOTEMPTY",description:"directory not empty"},{errno:54,code:"ENOSPC",description:"no space left on device"},{errno:55,code:"EIO",description:"i/o error"},{errno:56,code:"EROFS",description:"read-only file system"},{errno:57,code:"ENODEV",description:"no such device"},{errno:58,code:"ESPIPE",description:"invalid seek"},{errno:59,code:"ECANCELED",description:"operation canceled"}];t.exports.errno={},t.exports.code={},r.forEach(function(e){t.exports.errno[e.errno]=e,t.exports.code[e.code]=e}),t.exports.custom=e(20)(t.exports),t.exports.create=t.exports.custom.createError},{20:20}],22:[function(e,t,n){!function(e,n,r){"undefined"!=typeof t&&t.exports?t.exports=r():n[e]=r()}("prr",this,function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e},t=function(e,t){var n="object"==typeof t,r=!n&&"string"==typeof t,i=function(e){return n?!!t[e]:r?t.indexOf(e[0])>-1:!1};return{enumerable:i("enumerable"),configurable:i("configurable"),writable:i("writable"),value:e}},n=function(n,r,i,o){var a;if(o=t(i,o),"object"==typeof r){for(a in r)Object.hasOwnProperty.call(r,a)&&(o.value=r[a],e(n,a,o));return n}return e(n,r,o)};return n})},{}],23:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function o(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,o,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(a(n))for(o=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,u=0;r>u;u++)c[u].apply(this,o);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,a(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,o,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],o=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(s=o;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],24:[function(e,t,n){function r(){try{if("undefined"==typeof localStorage)return!1;if(localStorage.setItem("Storage-Test","1"),"1"!==localStorage.getItem("Storage-Test"))return!1;localStorage.removeItem("Storage-Test")}catch(e){return!1}return!0}"object"==typeof n&&(t.exports=r)},{}],25:[function(e,t,n){(function(n){var r=t.exports={},i=e(56);r.hasLocalStorage=e(24),r.create=function(){var e;return r.hasLocalStorage()?(e=n.localStorage,e={get length(){return n.localStorage.length},getItem:n.localStorage.getItem.bind(n.localStorage),setItem:n.localStorage.setItem.bind(n.localStorage),removeItem:n.localStorage.removeItem.bind(n.localStorage),key:n.localStorage.key.bind(n.localStorage),clear:n.localStorage.clear.bind(n.localStorage)},e.isPersistent=!0):(e=i,e.isPersistent=!1),e.getObject=r.getObject.bind(null,e),e.setObject=r.setObject.bind(null,e),e},r.setObject=function(e,t,n){return"object"!=typeof n?e.setItem(t,n):e.setItem(t,JSON.stringify(n))},r.getObject=function(e,t){var n=e.getItem(t);if(!n)return null;try{return JSON.parse(n)}catch(r){return n}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{24:24,56:56}],26:[function(e,t,n){var r=e(25);t.exports=r.create()},{25:25}],27:[function(e,t,n){n.read=function(e,t,n,r,i){var o,a,s=8*i-r-1,u=(1<<s)-1,c=u>>1,f=-7,l=n?i-1:0,h=n?-1:1,d=e[t+l];for(l+=h,o=d&(1<<-f)-1,d>>=-f,f+=s;f>0;o=256*o+e[t+l],l+=h,f-=8);for(a=o&(1<<-f)-1,o>>=-f,f+=r;f>0;a=256*a+e[t+l],l+=h,f-=8);if(0===o)o=1-c;else{if(o===u)return a?NaN:(d?-1:1)*(1/0);a+=Math.pow(2,r),o-=c}return(d?-1:1)*a*Math.pow(2,o-r)},n.write=function(e,t,n,r,i,o){var a,s,u,c=8*o-i-1,f=(1<<c)-1,l=f>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,g=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=f):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),t+=a+l>=1?h/u:h*Math.pow(2,1-l),t*u>=2&&(a++,u/=2),a+l>=f?(s=0,a=f):a+l>=1?(s=(t*u-1)*Math.pow(2,i),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,i),a=0));i>=8;e[n+d]=255&s,d+=p,s/=256,i-=8);for(a=a<<i|s,c+=i;c>0;e[n+d]=255&a,d+=p,a/=256,c-=8);e[n+d-p]|=128*g}},{}],28:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||i()}var i,o=e.MutationObserver||e.WebKitMutationObserver;if(o){var a=0,s=new o(n),u=e.document.createTextNode("");s.observe(u,{characterData:!0}),i=function(){u.data=a=++a%2}}else if(e.setImmediate||"undefined"==typeof e.MessageChannel)i="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var c=new e.MessageChannel;c.port1.onmessage=n,i=function(){c.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],29:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],30:[function(e,t,n){t.exports=function(e){return!(null==e||!(e._isBuffer||e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)))}},{}],31:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],32:[function(e,t,n){(function(e){e("object"==typeof n?n:this)}).call(this,function(e){var t=Array.prototype.slice,n=Array.prototype.forEach,r=function(e){if("object"!=typeof e)throw e+" is not an object";var i=t.call(arguments,1);return n.call(i,function(t){if(t)for(var n in t)"object"==typeof t[n]&&e[n]?r.call(e,e[n],t[n]):e[n]=t[n]}),e};e.extend=r})},{}],33:[function(e,t,n){function r(e){this.opts=e||{},this.encodings=i}var i=e(34);t.exports=r,r.prototype._encoding=function(e){return"string"==typeof e&&(e=i[e]),e||(e=i.id),e},r.prototype._keyEncoding=function(e,t){return this._encoding(t&&t.keyEncoding||e&&e.keyEncoding||this.opts.keyEncoding)},r.prototype._valueEncoding=function(e,t){return this._encoding(t&&(t.valueEncoding||t.encoding)||e&&(e.valueEncoding||e.encoding)||this.opts.valueEncoding||this.opts.encoding)},r.prototype.encodeKey=function(e,t,n){return this._keyEncoding(t,n).encode(e)},r.prototype.encodeValue=function(e,t,n){return this._valueEncoding(t,n).encode(e)},r.prototype.decodeKey=function(e,t){return this._keyEncoding(t).decode(e)},r.prototype.decodeValue=function(e,t){return this._valueEncoding(t).decode(e)},r.prototype.encodeBatch=function(e,t){var n=this;return e.map(function(e){var r={type:e.type,key:n.encodeKey(e.key,t,e)};return n.keyAsBuffer(t,e)&&(r.keyEncoding="binary"),e.prefix&&(r.prefix=e.prefix),"value"in e&&(r.value=n.encodeValue(e.value,t,e),n.valueAsBuffer(t,e)&&(r.valueEncoding="binary")),r})};var o=["lt","gt","lte","gte","start","end"];r.prototype.encodeLtgt=function(e){var t=this,n={};return Object.keys(e).forEach(function(r){n[r]=o.indexOf(r)>-1?t.encodeKey(e[r],e):e[r]}),n},r.prototype.createStreamDecoder=function(e){var t=this;return e.keys&&e.values?function(n,r){return{key:t.decodeKey(n,e),value:t.decodeValue(r,e)}}:e.keys?function(n){return t.decodeKey(n,e)}:e.values?function(n,r){return t.decodeValue(r,e)}:function(){}},r.prototype.keyAsBuffer=function(e){return this._keyEncoding(e).buffer},r.prototype.valueAsBuffer=function(e){return this._valueEncoding(e).buffer}},{34:34}],34:[function(e,t,n){(function(e){function t(e){return e}function r(t){return void 0===t||null===t||e.isBuffer(t)}n.utf8=n["utf-8"]={encode:function(e){return r(e)?e:String(e)},decode:t,buffer:!1,type:"utf8"},n.json={encode:JSON.stringify,decode:JSON.parse,buffer:!1,type:"json"},n.binary={encode:function(t){return r(t)?t:new e(t)},decode:t,buffer:!0,type:"binary"},n.id={encode:function(e){return e},decode:function(e){return e},buffer:!1,type:"id"};var i=["hex","ascii","base64","ucs2","ucs-2","utf16le","utf-16le"];i.forEach(function(t){n[t]={encode:function(n){return r(n)?n:new e(n,t)},decode:function(e){return e.toString(t)},buffer:!0,type:t}})}).call(this,e(8).Buffer)},{8:8}],35:[function(e,t,n){var r=e(21).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{21:21}],36:[function(e,t,n){function r(e,t){return this instanceof r?(o.call(this,a(t,{objectMode:!0})),this._iterator=e,this._destroyed=!1,this._decoder=null,t&&t.decoder&&(this._decoder=t.decoder),void this.on("end",this._cleanup.bind(this))):new r(e,t)}var i=e(29),o=e(43).Readable,a=e(44),s=e(35).EncodingError;t.exports=r,i(r,o),r.prototype._read=function(){var e=this;this._destroyed||this._iterator.next(function(t,n,r){if(!e._destroyed){if(t)return e.emit("error",t);if(void 0===n&&void 0===r)e.push(null);else{if(!e._decoder)return e.push({key:n,value:r});try{var r=e._decoder(n,r)}catch(t){return e.emit("error",new s(t)),void e.push(null)}e.push(r)}}})},r.prototype.destroy=r.prototype._cleanup=function(){var e=this;this._destroyed||(this._destroyed=!0,this._iterator.end(function(t){return t?e.emit("error",t):void e.emit("close")}))}},{29:29,35:35,43:43,44:44}],37:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],38:[function(e,t,n){(function(n){function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||n.nextTick(this.end.bind(this))}function o(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}t.exports=r;var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},s=e(9);s.inherits=e(29);var u=e(40),c=e(42);s.inherits(r,u),o(a(c.prototype),function(e){r.prototype[e]||(r.prototype[e]=c.prototype[e])})}).call(this,e(59))},{29:29,40:40,42:42,59:59,9:9}],39:[function(e,t,n){function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(41),o=e(9);o.inherits=e(29),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{29:29,41:41,9:9}],40:[function(e,t,n){(function(n){function r(t,n){var r=e(38);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(73).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(t){e(38);return this instanceof i?(this._readableState=new r(t,this),this.readable=!0,void B.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(R.isNullOrUndefined(n))t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),i||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e)),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=L)e=L;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:isNaN(e)||R.isNull(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||R.isString(t)||R.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(O("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){O("emit readable"),e.emit("readable"),b(e)}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(O("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;O("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&x.listenerCount(e,"data")&&(t.flowing=!0,b(e))}}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,n.nextTick(function(){y(e,t)}))}function y(e,t){t.resumeScheduled=!1,e.emit("resume"),b(e),t.flowing&&!t.reading&&e.read(0)}function b(e){var t=e._readableState;if(O("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function _(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(37),S=e(8).Buffer;i.ReadableState=r;var x=e(23).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(62),R=e(9);R.inherits=e(29);var A,O=e(7);O=O&&O.debuglog?O.debuglog("stream"):function(){},R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return R.isString(e)&&!n.objectMode&&(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){return A||(A=e(73).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t,this};var L=8388608;i.prototype.read=function(e){O("read",e);var t=this._readableState,n=e;if((!R.isNumber(e)||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return O("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?m(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&m(this),null;var r=t.needReadable;O("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,O("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,O("reading or ended",r)),r&&(O("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?_(e,t):null,R.isNull(i)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&m(this),R.isNull(i)||this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){O("onunpipe"),e===l&&o()}function i(){O("onend"),e.end()}function o(){O("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){O("ondata");var n=e.write(t);!1===n&&(O("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++,l.pause())}function s(t){O("onerror",t),f(),e.removeListener("error",s),0===x.listenerCount(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){O("onfinish"),e.removeListener("close",u),f()}function f(){O("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,O("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?n.nextTick(p):l.once("end",p),e.on("unpipe",r);var v=g(l);return e.on("drain",v),l.on("data",a),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(O("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;
+for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var r=B.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&this.readable){var i=this._readableState;if(!i.readableListening)if(i.readableListening=!0,i.emittedReadable=!1,i.needReadable=!0,i.reading)i.length&&l(this,i);else{var o=this;n.nextTick(function(){O("readable nexttick read 0"),o.read(0)})}}return r},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(O("resume"),e.flowing=!0,e.reading||(O("resume read 0"),this.read(0)),v(this,e)),this},i.prototype.pause=function(){return O("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(O("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(O("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(O("wrapped data"),t.decoder&&(i=t.decoder.write(i)),i&&(t.objectMode||i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)R.isFunction(e[i])&&R.isUndefined(this[i])&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){O("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=_}).call(this,e(59))},{23:23,29:29,37:37,38:38,59:59,62:62,7:7,73:73,8:8,9:9}],41:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,u.isNullOrUndefined(n)||e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(e,this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("prefinish",function(){u.isFunction(this._flush)?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(38),u=e(9);u.inherits=e(29),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;u.isNull(t.writechunk)||!t.writecb||t.transforming?t.needTransform=!0:(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform))}},{29:29,38:38,9:9}],42:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(t,n){var r=e(38);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1}function o(t){var n=e(38);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void k.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!(E.isBuffer(r)||E.isString(r)||E.isNullOrUndefined(r)||t.objectMode)){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return!e.objectMode&&e.decodeStrings!==!1&&E.isString(t)&&(t=new w(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),E.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing||t.corked?t.buffer.push(new r(n,i,o)):f(e,t,!1,a,n,i,o),s}function f(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){t.pendingcb--,o(i)}):(t.pendingcb--,o(i)),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.corked||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),t.pendingcb--,r(),_(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){if(t.bufferProcessing=!0,e._writev&&t.buffer.length>1){for(var n=[],r=0;r<t.buffer.length;r++)n.push(t.buffer[r].callback);t.pendingcb++,f(e,t,!0,t.length,t.buffer,"",function(e){for(var r=0;r<n.length;r++)t.pendingcb--,n[r](e)}),t.buffer=[]}else{for(var r=0;r<t.buffer.length;r++){var i=t.buffer[r],o=i.chunk,a=i.encoding,s=i.callback,u=t.objectMode?1:o.length;if(f(e,t,!1,u,o,a,s),t.writing){r++;break}}r<t.buffer.length?t.buffer=t.buffer.slice(r):t.buffer.length=0}t.bufferProcessing=!1}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function _(e,t){var n=y(e,t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function m(e,t,r){t.ending=!0,_(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var w=e(8).Buffer;o.WritableState=i;var E=e(9);E.inherits=e(29);var k=e(62);E.inherits(o,k),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return E.isFunction(t)&&(n=t,t=null),E.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),E.isFunction(n)||(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(r.pendingcb++,i=c(this,r,e,t,n)),i},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.buffer.length||v(this,e))},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;E.isFunction(e)?(n=e,e=null,t=null):E.isFunction(t)&&(n=t,t=null),E.isNullOrUndefined(e)||this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||m(this,r,n)}}).call(this,e(59))},{29:29,38:38,59:59,62:62,8:8,9:9}],43:[function(e,t,n){(function(r){n=t.exports=e(40),n.Stream=e(62),n.Readable=n,n.Writable=e(42),n.Duplex=e(38),n.Transform=e(41),n.PassThrough=e(39),r.browser||"disable"!==r.env.READABLE_STREAM||(t.exports=e(62))}).call(this,e(59))},{38:38,39:39,40:40,41:41,42:42,59:59,62:62}],44:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],45:[function(e,t,n){function r(e,t){this._levelup=e,this._codec=t,this.batch=e.db.batch(),this.ops=[],this.length=0}var i=e(47),o=e(35).WriteError,a=i.getOptions,s=i.dispatchError;r.prototype.put=function(e,t,n){n=a(n);var r=this._codec.encodeKey(e,n),i=this._codec.encodeValue(t,n);try{this.batch.put(r,i)}catch(s){throw new o(s)}return this.ops.push({type:"put",key:r,value:i}),this.length++,this},r.prototype.del=function(e,t){t=a(t);var n=this._codec.encodeKey(e,t);try{this.batch.del(n)}catch(r){throw new o(r)}return this.ops.push({type:"del",key:n}),this.length++,this},r.prototype.clear=function(){try{this.batch.clear()}catch(e){throw new o(e)}return this.ops=[],this.length=0,this},r.prototype.write=function(e){var t=this._levelup,n=this.ops;try{this.batch.write(function(r){return r?s(t,new o(r),e):(t.emit("batch",n),void(e&&e()))})}catch(r){throw new o(r)}},t.exports=r},{35:35,47:47}],46:[function(e,t,n){(function(n){function r(e,t){return"function"==typeof e?e:t}function i(e,t,r){if(!(this instanceof i))return new i(e,t,r);var o;if(c.call(this),this.setMaxListeners(1/0),"function"==typeof e?(t="object"==typeof t?t:{},t.db=e,e=null):"object"==typeof e&&"function"==typeof e.db&&(t=e,e=null),"function"==typeof t&&(r=t,t={}),(!t||"function"!=typeof t.db)&&"string"!=typeof e){if(o=new E("Must provide a location for the database"),r)return n.nextTick(function(){r(o)});throw o}t=B(t),this.options=h(R,t),this._codec=new x(this.options),this._status="new",d(this,"location",e,"e"),this.open(r)}function o(e,t,n){return e._isOpening()||e.isOpen()?void 0:(O(e,new b("Database is not open"),n),!0)}function a(e,t,n){O(e,new y(t),n)}function s(e,t,n){O(e,new b(t),n)}function u(e){return function(t,n){A()[e](t,n||function(){})}}var c=e(23).EventEmitter,f=e(98).inherits,l=e(98).deprecate,h=e(48),d=e(60),p=e(12),g=e(36),v=e(35),y=v.WriteError,b=v.ReadError,_=v.NotFoundError,m=v.OpenError,w=v.EncodingError,E=v.InitializationError,k=e(47),S=e(45),x=e(33),B=k.getOptions,R=k.defaultOptions,A=k.getLevelDOWN,O=k.dispatchError;k.isDefined;f(i,c),i.prototype.open=function(e){var t,r,i=this;return this.isOpen()?(e&&n.nextTick(function(){e(null,i)}),this):this._isOpening()?e&&this.once("open",function(){e(null,i)}):(this.emit("opening"),this._status="opening",this.db=new p(this.location),t=this.options.db||A(),r=t(this.location),void r.open(this.options,function(t){return t?O(i,new m(t),e):(i.db.setDb(r),i.db=r,i._status="open",e&&e(null,i),i.emit("open"),i.emit("ready"),void 0)}))},i.prototype.close=function(e){var t=this;if(this.isOpen())this._status="closing",this.db.close(function(){t._status="closed",t.emit("closed"),e&&e.apply(null,arguments)}),this.emit("closing"),this.db=new p(this.location);else{if("closed"==this._status&&e)return n.nextTick(e);"closing"==this._status&&e?this.once("closed",e):this._isOpening()&&this.once("open",function(){t.close(e)})}},i.prototype.isOpen=function(){return"open"==this._status},i.prototype._isOpening=function(){return"opening"==this._status},i.prototype.isClosed=function(){return/^clos/.test(this._status)},i.prototype.get=function(e,t,n){var i,a=this;if(n=r(t,n),!o(this,t,n)){if(null===e||void 0===e||"function"!=typeof n)return s(this,"get() requires key and callback arguments",n);t=k.getOptions(t),i=this._codec.encodeKey(e,t),t.asBuffer=this._codec.valueAsBuffer(t),this.db.get(i,t,function(r,i){if(r)return r=/notfound/i.test(r)||r.notFound?new _("Key not found in database ["+e+"]",r):new b(r),O(a,r,n);if(n){try{i=a._codec.decodeValue(i,t)}catch(o){return n(new w(o))}n(null,i)}})}},i.prototype.put=function(e,t,n,i){var s,u,c=this;return i=r(n,i),null===e||void 0===e?a(this,"put() requires a key argument",i):void(o(this,n,i)||(n=B(n),s=this._codec.encodeKey(e,n),u=this._codec.encodeValue(t,n),this.db.put(s,u,n,function(n){return n?O(c,new y(n),i):(c.emit("put",e,t),void(i&&i()))})))},i.prototype.del=function(e,t,n){var i,s=this;return n=r(t,n),null===e||void 0===e?a(this,"del() requires a key argument",n):void(o(this,t,n)||(t=B(t),i=this._codec.encodeKey(e,t),this.db.del(i,t,function(t){return t?O(s,new y(t),n):(s.emit("del",e),void(n&&n()))})))},i.prototype.batch=function(e,t,n){var i,s=this;return arguments.length?(n=r(t,n),Array.isArray(e)?void(o(this,t,n)||(t=B(t),i=s._codec.encodeBatch(e,t),i=i.map(function(e){return e.type||void 0===e.key||void 0===e.value||(e.type="put"),e}),this.db.batch(i,t,function(t){return t?O(s,new y(t),n):(s.emit("batch",e),void(n&&n()))}))):a(this,"batch() requires an array argument",n)):new S(this,this._codec)},i.prototype.approximateSize=l(function(e,t,n,i){var o,a,u=this;return i=r(n,i),n=B(n),null===e||void 0===e||null===t||void 0===t||"function"!=typeof i?s(this,"approximateSize() requires start, end and callback arguments",i):(o=this._codec.encodeKey(e,n),a=this._codec.encodeKey(t,n),void this.db.approximateSize(o,a,function(e,t){return e?O(u,new m(e),i):void(i&&i(null,t))}))},"db.approximateSize() is deprecated. Use db.db.approximateSize() instead"),i.prototype.readStream=i.prototype.createReadStream=function(e){return e=h({keys:!0,values:!0},this.options,e),e.keyEncoding=e.keyEncoding,e.valueEncoding=e.valueEncoding,e=this._codec.encodeLtgt(e),e.keyAsBuffer=this._codec.keyAsBuffer(e),e.valueAsBuffer=this._codec.valueAsBuffer(e),"number"!=typeof e.limit&&(e.limit=-1),new g(this.db.iterator(e),h(e,{decoder:this._codec.createStreamDecoder(e)}))},i.prototype.keyStream=i.prototype.createKeyStream=function(e){return this.createReadStream(h(e,{keys:!0,values:!1}))},i.prototype.valueStream=i.prototype.createValueStream=function(e){return this.createReadStream(h(e,{keys:!1,values:!0}))},i.prototype.toString=function(){return"LevelUP"},t.exports=i,t.exports.errors=e(35),t.exports.destroy=l(u("destroy"),"levelup.destroy() is deprecated. Use leveldown.destroy() instead"),t.exports.repair=l(u("repair"),"levelup.repair() is deprecated. Use leveldown.repair() instead")}).call(this,e(59))},{12:12,23:23,33:33,35:35,36:36,45:45,47:47,48:48,59:59,60:60,98:98}],47:[function(e,t,n){function r(e){return"string"==typeof e&&(e={valueEncoding:e}),"object"!=typeof e&&(e={}),e}function i(){if(u)return u;var t,n=e(49).devDependencies.leveldown;try{t=e(7).version}catch(r){throw o(r)}if(!e(7).satisfies(t,n))throw new c("Installed version of LevelDOWN ("+t+") does not match required version ("+n+")");try{return u=e(7)}catch(r){throw o(r)}}function o(e){var t="Failed to require LevelDOWN (%s). Try `npm install leveldown` if it's missing";return new c(f(t,e.message))}function a(e,t,n){"function"==typeof n?n(t):e.emit("error",t)}function s(e){return"undefined"!=typeof e}var u,c=(e(48),e(35).LevelUPError),f=e(98).format,l={createIfMissing:!0,errorIfExists:!1,keyEncoding:"utf8",valueEncoding:"utf8",compression:!0};t.exports={defaultOptions:l,getOptions:r,getLevelDOWN:i,dispatchError:a,isDefined:s}},{35:35,48:48,49:49,7:7,98:98}],48:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],49:[function(e,t,n){t.exports={_args:[["levelup@1.3.1","/Users/nolan/workspace/pouchdb"]],_from:"levelup@1.3.1",_id:"levelup@1.3.1",_inCache:!0,_installable:!0,_location:"/levelup",_nodeVersion:"4.2.2",_npmUser:{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},_npmVersion:"3.5.0",_phantomChildren:{},_requested:{name:"levelup",raw:"levelup@1.3.1",rawSpec:"1.3.1",scope:null,spec:"1.3.1",type:"version"},_requiredBy:["/","/pouchdb"],_resolved:"http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",_shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",_shrinkwrap:null,_spec:"levelup@1.3.1",_where:"/Users/nolan/workspace/pouchdb",browser:{leveldown:!1,"leveldown/package":!1,semver:!1},bugs:{url:"https://github.com/level/levelup/issues"},contributors:[{email:"r@va.gg",name:"Rod Vagg",url:"https://github.com/rvagg"},{email:"john@chesl.es",name:"John Chesley",url:"https://github.com/chesles/"},{email:"raynos2@gmail.com",name:"Jake Verbaten",url:"https://github.com/raynos"},{email:"dominic.tarr@gmail.com",name:"Dominic Tarr",url:"https://github.com/dominictarr"},{email:"max@maxogden.com",name:"Max Ogden",url:"https://github.com/maxogden"},{email:"ralphtheninja@riseup.net",name:"Lars-Magnus Skog",url:"https://github.com/ralphtheninja"},{email:"david.bjorklund@gmail.com",name:"David Björklund",url:"https://github.com/kesla"},{email:"julian@juliangruber.com",name:"Julian Gruber",url:"https://github.com/juliangruber"},{email:"paolo@async.ly",name:"Paolo Fragomeni",url:"https://github.com/hij1nx"},{email:"anton.whalley@nearform.com",name:"Anton Whalley",url:"https://github.com/No9"},{email:"matteo.collina@gmail.com",name:"Matteo Collina",url:"https://github.com/mcollina"},{email:"pedro.teixeira@gmail.com",name:"Pedro Teixeira",url:"https://github.com/pgte"},{email:"mail@substack.net",name:"James Halliday",url:"https://github.com/substack"},{email:"jcrugzz@gmail.com",name:"Jarrett Cruger",url:"https://github.com/jcrugzz"}],dependencies:{"deferred-leveldown":"~1.2.1","level-codec":"~6.1.0","level-errors":"~1.0.3","level-iterator-stream":"~1.3.0",prr:"~1.0.1",semver:"~5.1.0",xtend:"~4.0.0"},description:"Fast & simple storage - a Node.js-style LevelDB wrapper",devDependencies:{async:"~1.5.0",bustermove:"~1.0.0",delayed:"~1.0.1",faucet:"~0.0.1",leveldown:"^1.1.0",memdown:"~1.1.0","msgpack-js":"~0.3.0",referee:"~1.2.0",rimraf:"~2.4.3","slow-stream":"0.0.4",tap:"~2.3.1",tape:"~4.2.1"},directories:{},dist:{shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",tarball:"https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"},gitHead:"40bd66872974140c79a74d9411b992ddffa926a4",homepage:"https://github.com/level/levelup",keywords:["leveldb","stream","database","db","store","storage","json"],license:"MIT",main:"lib/levelup.js",maintainers:[{email:"rod@vagg.org",name:"rvagg"},{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},{email:"julian@juliangruber.com",name:"juliangruber"}],name:"levelup",optionalDependencies:{},readme:"ERROR: No README data found!",repository:{type:"git",url:"git+https://github.com/level/levelup.git"},scripts:{test:"tape test/*-test.js | faucet"},version:"1.3.1"}},{}],50:[function(e,t,n){"use strict";function r(){}function i(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=b,this.queue=[],this.outcome=void 0,e!==r&&u(this,e)}function o(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function a(e,t,n){p(function(){var r;try{r=t(n)}catch(i){return g.reject(e,i)}r===e?g.reject(e,new TypeError("Cannot resolve promise with itself")):g.resolve(e,r)})}function s(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}function u(e,t){function n(t){o||(o=!0,g.reject(e,t))}function r(t){o||(o=!0,g.resolve(e,t))}function i(){t(r,n)}var o=!1,a=c(i);"error"===a.status&&n(a.value)}function c(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}function f(e){return e instanceof this?e:g.resolve(new this(r),e)}function l(e){var t=new this(r);return g.reject(t,e)}function h(e){function t(e,t){function r(e){a[t]=e,++s!==i||o||(o=!0,g.resolve(c,a))}n.resolve(e).then(r,function(e){o||(o=!0,g.reject(c,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=new Array(i),s=0,u=-1,c=new this(r);++u<i;)t(e[u],u);return c}function d(e){function t(e){n.resolve(e).then(function(e){o||(o=!0,g.resolve(s,e))},function(e){o||(o=!0,g.reject(s,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=-1,s=new this(r);++a<i;)t(e[a]);return s}var p=e(28),g={},v=["REJECTED"],y=["FULFILLED"],b=["PENDING"];t.exports=n=i,i.prototype["catch"]=function(e){return this.then(null,e)},i.prototype.then=function(e,t){if("function"!=typeof e&&this.state===y||"function"!=typeof t&&this.state===v)return this;var n=new this.constructor(r);if(this.state!==b){var i=this.state===y?e:t;a(n,i,this.outcome)}else this.queue.push(new o(n,e,t));return n},o.prototype.callFulfilled=function(e){g.resolve(this.promise,e)},o.prototype.otherCallFulfilled=function(e){a(this.promise,this.onFulfilled,e)},o.prototype.callRejected=function(e){g.reject(this.promise,e)},o.prototype.otherCallRejected=function(e){a(this.promise,this.onRejected,e)},g.resolve=function(e,t){var n=c(s,t);if("error"===n.status)return g.reject(e,n.value);var r=n.value;if(r)u(e,r);else{e.state=y,e.outcome=t;for(var i=-1,o=e.queue.length;++i<o;)e.queue[i].callFulfilled(t)}return e},g.reject=function(e,t){e.state=v,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},n.resolve=f,n.reject=l,n.all=h,n.race=d},{28:28}],51:[function(e,t,n){(function(n,r,i){"use strict";function o(e,t){f.call(this,e),this._reverse=!!t.reverse,this._endkey=t.end,this._startkey=t.start,this._gt=t.gt,this._gte=t.gte,this._lt=t.lt,this._lte=t.lte,this._exclusiveStart=t.exclusiveStart,this._limit=t.limit,this._count=0,this.onInitCompleteListeners=[]}function a(e){return this instanceof a?(c.call(this,e),void(this.container=new l(e))):new a(e)}function s(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if("key"===t){if(e instanceof Boolean)return new Error(t+" cannot be `null` or `undefined`");if(""===e)return new Error(t+" cannot be empty")}if(0===e.toString().indexOf("[object ArrayBuffer]")&&(0===e.byteLength||void 0===e.byteLength))return new Error(t+" cannot be an empty Buffer");if(i.isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")}var u=e(29),c=e(4).AbstractLevelDOWN,f=e(4).AbstractIterator,l=e(53).LocalStorage,h=e(52),d=e(55),p=r.setImmediate||n.nextTick;u(o,f),o.prototype._init=function(e){p(function(){e()})},o.prototype._next=function(e){function t(){if(r._pos===r._keys.length||r._pos<0)return e();var t=r._keys[r._pos];return r._endkey&&(r._reverse?t<r._endkey:t>r._endkey)?e():r._limit&&r._limit>0&&r._count++>=r._limit?e():r._lt&&t>=r._lt||r._lte&&t>r._lte||r._gt&&t<=r._gt||r._gte&&t<r._gte?e():(r._pos+=r._reverse?-1:1,void r.db.container.getItem(t,function(n,i){return n?"NotFound"===n.message?p(function(){r._next(e)}):e(n):void e(null,t,i)}))}var r=this;r.initStarted?r.initCompleted?n.nextTick(t):r.onInitCompleteListeners.push(t):n.nextTick(function(){r.initStarted=!0,r._init(function(n){return n?e(n):void r.db.container.keys(function(n,i){if(n)return e(n);if(r._keys=i,r._startkey){var o=d.sortedIndexOf(r._keys,r._startkey),a=o>=r._keys.length||0>o?void 0:r._keys[o];r._pos=o,r._reverse?(r._exclusiveStart||a!==r._startkey)&&r._pos--:r._exclusiveStart&&a===r._startkey&&r._pos++}else r._pos=r._reverse?r._keys.length-1:0;t(),r.initCompleted=!0;for(var s=-1;++s<r.onInitCompleteListeners.length;)p(r.onInitCompleteListeners[s])})})})},u(a,c),a.prototype._open=function(e,t){this.container.init(t)},a.prototype._put=function(e,t,n,r){var o=s(e,"key");if(o)return p(function(){r(o)});if(o=s(t,"value"))return p(function(){r(o)});if("object"==typeof t&&!i.isBuffer(t)&&void 0===t.buffer){var a={};a.storetype="json",a.data=t,t=JSON.stringify(a)}this.container.setItem(e,t,r)},a.prototype._get=function(e,t,n){var r=s(e,"key");return r?p(function(){n(r)}):(i.isBuffer(e)||(e=String(e)),void this.container.getItem(e,function(e,r){if(e)return n(e);if(t.asBuffer===!1||i.isBuffer(r)||(r=new i(r)),t.asBuffer===!1&&r.indexOf('{"storetype":"json","data"')>-1){var o=JSON.parse(r);r=o.data}n(null,r)}))},a.prototype._del=function(e,t,n){var r=s(e,"key");return r?p(function(){n(r)}):(i.isBuffer(e)||(e=String(e)),void this.container.removeItem(e,n))},a.prototype._batch=function(e,t,n){var r=this;p(function(){function o(){++l===e.length&&n(f)}var a,u,c,f,l=0;if(Array.isArray(e)&&e.length)for(var h=0;h<e.length;h++){var d=e[h];d?(u=i.isBuffer(d.key)?d.key:String(d.key),a=s(u,"key"),a?(f=a,o()):"del"===d.type?r._del(d.key,t,o):"put"===d.type&&(c=i.isBuffer(d.value)?d.value:String(d.value),a=s(c,"value"),a?(f=a,o()):r._put(u,c,t,o))):o()}else n()})},a.prototype._iterator=function(e){return new o(this,e)},a.destroy=function(e,t){h.destroy(e,t)},t.exports=a}).call(this,e(59),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(8).Buffer)},{29:29,4:4,52:52,53:53,55:55,59:59,8:8}],52:[function(e,t,n){(function(n,r){"use strict";function i(e,t){var n,r;try{n=t()}catch(i){r=i}s(function(){e(r,n)})}function o(e){return e.replace(/!/g,"!!")+"!"}function a(e){this._prefix=o(e)}var s=r.setImmediate||n.nextTick,u=e(26);a.prototype.getKeys=function(e){var t=this;i(e,function(){for(var e=[],n=t._prefix.length,r=-1,i=u.length;++r<i;){var o=u.key(r);o.substring(0,n)===t._prefix&&e.push(o.substring(n))}return e.sort(),e})},a.prototype.put=function(e,t,n){var r=this;i(n,function(){u.setItem(r._prefix+e,t)})},a.prototype.get=function(e,t){var n=this;i(t,function(){return u.getItem(n._prefix+e)})},a.prototype.remove=function(e,t){var n=this;i(t,function(){u.removeItem(n._prefix+e)})},a.destroy=function(e,t){var n=o(e);i(t,function(){for(var e=[],t=-1,r=u.length;++t<r;){var i=u.key(t);i.substring(0,n.length)===n&&e.push(i)}e.forEach(function(e){u.removeItem(e)})})},t.exports=a}).call(this,e(59),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{26:26,59:59}],53:[function(e,t,n){(function(t){"use strict";function r(e){this._store=new l(e),this._queue=new h}var i="ArrayBuffer:",o=new RegExp("^"+i),a="Uint8Array:",s=new RegExp("^"+a),u="Buff:",c=new RegExp("^"+u),f=e(55),l=e(52),h=e(54),d=e(10);r.prototype.sequentialize=function(e,t){this._queue.add(t,e)},r.prototype.init=function(e){var t=this;t.sequentialize(e,function(e){t._store.getKeys(function(n,r){return n?e(n):(t._keys=r,e())})})},r.prototype.keys=function(e){var t=this;t.sequentialize(e,function(e){e(null,t._keys.slice())})},r.prototype.setItem=function(e,n,r){var i=this;i.sequentialize(r,function(r){t.isBuffer(n)&&(n=u+d.encode(n));var o=f.sortedIndexOf(i._keys,e);i._keys[o]!==e&&i._keys.splice(o,0,e),i._store.put(e,n,r)})},r.prototype.getItem=function(e,t){var n=this;n.sequentialize(t,function(t){n._store.get(e,function(e,n){return e?t(e):"undefined"==typeof n||null===n?t(new Error("NotFound")):("undefined"!=typeof n&&(c.test(n)?n=d.decode(n.substring(u.length)):o.test(n)?(n=n.substring(i.length),n=new ArrayBuffer(atob(n).split("").map(function(e){return e.charCodeAt(0)}))):s.test(n)&&(n=n.substring(a.length),n=new Uint8Array(atob(n).split("").map(function(e){return e.charCodeAt(0)})))),void t(null,n))})})},r.prototype.removeItem=function(e,t){var n=this;n.sequentialize(t,function(t){var r=f.sortedIndexOf(n._keys,e);n._keys[r]===e?(n._keys.splice(r,1),n._store.remove(e,function(e){return e?t(e):void t()})):t()})},r.prototype.length=function(e){var t=this;t.sequentialize(e,function(e){e(null,t._keys.length)})},n.LocalStorage=r}).call(this,{isBuffer:e(30)})},{10:10,30:30,52:52,54:54,55:55}],54:[function(e,t,n){(function(n,r){"use strict";function i(){this.queue=new a,this.running=!1}var o=e(5),a=e(95),s=r.setImmediate||n.nextTick;i.prototype.add=function(e,t){this.queue.push({fun:e,callback:t}),this.processNext()},i.prototype.processNext=function(){var e=this;if(!e.running&&e.queue.length){e.running=!0;var t=e.queue.shift();s(function(){t.fun(o(function(n){t.callback.apply(null,n),e.running=!1,e.processNext()}))})}},t.exports=i}).call(this,e(59),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{5:5,59:59,95:95}],55:[function(e,t,n){"use strict";n.sortedIndexOf=function(e,t){for(var n,r=0,i=e.length;i>r;)n=r+i>>>1,e[n]<t?r=n+1:i=n;return r}},{}],56:[function(e,t,n){!function(e){var r={},i={};r.length=0,r.getItem=function(e){return i[e]||null},r.setItem=function(e,t){"undefined"==typeof t?r.removeItem(e):(i.hasOwnProperty(e)||r.length++,i[e]=""+t)},r.removeItem=function(e){i.hasOwnProperty(e)&&(delete i[e],r.length--)},r.key=function(e){return Object.keys(i)[e]||null},r.clear=function(){i={},r.length=0},"object"==typeof n?t.exports=r:e.localStorageMemory=r}(this)},{}],57:[function(e,t,n){"use strict";function r(){this.store={}}function i(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=i,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){for(var t=Object.keys(this.store),n=0,r=t.length;r>n;n++){var i=t[n],o=this.store[i];i=this.unmangle(i),e(o,i)}},i.prototype.add=function(e){return this.store.set(e,!0)},i.prototype.has=function(e){return this.store.has(e)},i.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],58:[function(e,t,n){(function(e){"use strict";function n(t){for(var n=new Array(arguments.length-1),r=0;r<n.length;)n[r++]=arguments[r];e.nextTick(function(){t.apply(null,n)})}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e(59))},{59:59}],59:[function(e,t,n){function r(){f=!1,s.length?c=s.concat(c):l=-1,c.length&&i()}function i(){if(!f){var e=setTimeout(r);f=!0;for(var t=c.length;t;){for(s=c,c=[];++l<t;)s&&s[l].run();l=-1,t=c.length}s=null,f=!1,clearTimeout(e)}}function o(e,t){this.fun=e,this.array=t}function a(){}var s,u=t.exports={},c=[],f=!1,l=-1;u.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new o(e,t)),1!==c.length||f||setTimeout(i,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},u.title="browser",u.browser=!0,u.env={},u.argv=[],u.version="",u.versions={},u.on=a,u.addListener=a,u.once=a,u.off=a,u.removeListener=a,u.removeAllListeners=a,u.emit=a,u.binding=function(e){throw new Error("process.binding is not supported")},u.cwd=function(){return"/"},u.chdir=function(e){throw new Error("process.chdir is not supported")},u.umask=function(){return 0}},{}],60:[function(e,t,n){arguments[4][22][0].apply(n,arguments)},{22:22}],61:[function(e,t,n){!function(e){if("object"==typeof n)t.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;try{r=window}catch(i){r=self}r.SparkMD5=e()}}(function(e){"use strict";function t(e,t,n,r,i,o){return t=_(_(t,e),_(r,o)),_(t<<i|t>>>32-i,n)}function n(e,n,r,i,o,a,s){return t(n&r|~n&i,e,n,o,a,s)}function r(e,n,r,i,o,a,s){return t(n&i|r&~i,e,n,o,a,s)}function i(e,n,r,i,o,a,s){return t(n^r^i,e,n,o,a,s)}function o(e,n,r,i,o,a,s){return t(r^(n|~i),e,n,o,a,s)}function a(e,t){var a=e[0],s=e[1],u=e[2],c=e[3];a=n(a,s,u,c,t[0],7,-680876936),c=n(c,a,s,u,t[1],12,-389564586),u=n(u,c,a,s,t[2],17,606105819),s=n(s,u,c,a,t[3],22,-1044525330),a=n(a,s,u,c,t[4],7,-176418897),c=n(c,a,s,u,t[5],12,1200080426),u=n(u,c,a,s,t[6],17,-1473231341),s=n(s,u,c,a,t[7],22,-45705983),a=n(a,s,u,c,t[8],7,1770035416),c=n(c,a,s,u,t[9],12,-1958414417),u=n(u,c,a,s,t[10],17,-42063),s=n(s,u,c,a,t[11],22,-1990404162),a=n(a,s,u,c,t[12],7,1804603682),c=n(c,a,s,u,t[13],12,-40341101),u=n(u,c,a,s,t[14],17,-1502002290),s=n(s,u,c,a,t[15],22,1236535329),a=r(a,s,u,c,t[1],5,-165796510),c=r(c,a,s,u,t[6],9,-1069501632),u=r(u,c,a,s,t[11],14,643717713),s=r(s,u,c,a,t[0],20,-373897302),a=r(a,s,u,c,t[5],5,-701558691),
+c=r(c,a,s,u,t[10],9,38016083),u=r(u,c,a,s,t[15],14,-660478335),s=r(s,u,c,a,t[4],20,-405537848),a=r(a,s,u,c,t[9],5,568446438),c=r(c,a,s,u,t[14],9,-1019803690),u=r(u,c,a,s,t[3],14,-187363961),s=r(s,u,c,a,t[8],20,1163531501),a=r(a,s,u,c,t[13],5,-1444681467),c=r(c,a,s,u,t[2],9,-51403784),u=r(u,c,a,s,t[7],14,1735328473),s=r(s,u,c,a,t[12],20,-1926607734),a=i(a,s,u,c,t[5],4,-378558),c=i(c,a,s,u,t[8],11,-2022574463),u=i(u,c,a,s,t[11],16,1839030562),s=i(s,u,c,a,t[14],23,-35309556),a=i(a,s,u,c,t[1],4,-1530992060),c=i(c,a,s,u,t[4],11,1272893353),u=i(u,c,a,s,t[7],16,-155497632),s=i(s,u,c,a,t[10],23,-1094730640),a=i(a,s,u,c,t[13],4,681279174),c=i(c,a,s,u,t[0],11,-358537222),u=i(u,c,a,s,t[3],16,-722521979),s=i(s,u,c,a,t[6],23,76029189),a=i(a,s,u,c,t[9],4,-640364487),c=i(c,a,s,u,t[12],11,-421815835),u=i(u,c,a,s,t[15],16,530742520),s=i(s,u,c,a,t[2],23,-995338651),a=o(a,s,u,c,t[0],6,-198630844),c=o(c,a,s,u,t[7],10,1126891415),u=o(u,c,a,s,t[14],15,-1416354905),s=o(s,u,c,a,t[5],21,-57434055),a=o(a,s,u,c,t[12],6,1700485571),c=o(c,a,s,u,t[3],10,-1894986606),u=o(u,c,a,s,t[10],15,-1051523),s=o(s,u,c,a,t[1],21,-2054922799),a=o(a,s,u,c,t[8],6,1873313359),c=o(c,a,s,u,t[15],10,-30611744),u=o(u,c,a,s,t[6],15,-1560198380),s=o(s,u,c,a,t[13],21,1309151649),a=o(a,s,u,c,t[4],6,-145523070),c=o(c,a,s,u,t[11],10,-1120210379),u=o(u,c,a,s,t[2],15,718787259),s=o(s,u,c,a,t[9],21,-343485551),e[0]=_(a,e[0]),e[1]=_(s,e[1]),e[2]=_(u,e[2]),e[3]=_(c,e[3])}function s(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function u(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function c(e){var t,n,r,i,o,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,s(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),u=parseInt(i[1],16)||0,r[14]=o,r[15]=u,a(f,r),f}function f(e){var t,n,r,i,o,s,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),s=parseInt(i[1],16)||0,r[14]=o,r[15]=s,a(f,r),f}function l(e){var t,n="";for(t=0;4>t;t+=1)n+=m[e>>8*t+4&15]+m[e>>8*t&15];return n}function h(e){var t;for(t=0;t<e.length;t+=1)e[t]=l(e[t]);return e.join("")}function d(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function p(e,t){var n,r=e.length,i=new ArrayBuffer(r),o=new Uint8Array(i);for(n=0;r>n;n+=1)o[n]=e.charCodeAt(n);return t?o:i}function g(e){return String.fromCharCode.apply(null,new Uint8Array(e))}function v(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}function y(e){var t,n=[],r=e.length;for(t=0;r-1>t;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function b(){this.reset()}var _=function(e,t){return e+t&4294967295},m=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==h(c("hello"))&&(_=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function t(e,t){return e=0|e||0,0>e?Math.max(e+t,0):Math.min(e,t)}ArrayBuffer.prototype.slice=function(n,r){var i,o,a,s,u=this.byteLength,c=t(n,u),f=u;return r!==e&&(f=t(r,u)),c>f?new ArrayBuffer(0):(i=f-c,o=new ArrayBuffer(i),a=new Uint8Array(o),s=new Uint8Array(this,c,i),a.set(s),o)}}(),b.prototype.append=function(e){return this.appendBinary(d(e)),this},b.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._hash,s(this._buff.substring(t-64,t)));return this._buff=this._buff.substring(t-64),this},b.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},b.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},b.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},b.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},b.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},b.prototype._finish=function(e,t){var n,r,i,o=t;if(e[o>>2]|=128<<(o%4<<3),o>55)for(a(this._hash,e),o=0;16>o;o+=1)e[o]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),i=parseInt(n[1],16)||0,e[14]=r,e[15]=i,a(this._hash,e)},b.hash=function(e,t){return b.hashBinary(d(e),t)},b.hashBinary=function(e,t){var n=c(e),r=h(n);return t?y(r):r},b.ArrayBuffer=function(){this.reset()},b.ArrayBuffer.prototype.append=function(e){var t,n=v(this._buff.buffer,e,!0),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._hash,u(n.subarray(t-64,t)));return this._buff=r>t-64?new Uint8Array(n.buffer.slice(t-64)):new Uint8Array(0),this},b.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r[t]<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},b.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},b.ArrayBuffer.prototype.getState=function(){var e=b.prototype.getState.call(this);return e.buff=g(e.buff),e},b.ArrayBuffer.prototype.setState=function(e){return e.buff=p(e.buff,!0),b.prototype.setState.call(this,e)},b.ArrayBuffer.prototype.destroy=b.prototype.destroy,b.ArrayBuffer.prototype._finish=b.prototype._finish,b.ArrayBuffer.hash=function(e,t){var n=f(new Uint8Array(e)),r=h(n);return t?y(r):r},b})},{}],62:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e(23).EventEmitter,o=e(29);o(r,i),r.Readable=e(70),r.Writable=e(72),r.Duplex=e(63),r.Transform=e(71),r.PassThrough=e(69),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&c.pause&&c.pause()}function r(){c.readable&&c.resume&&c.resume()}function o(){f||(f=!0,e.end())}function a(){f||(f=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(u(),0===i.listenerCount(this,"error"))throw e}function u(){c.removeListener("data",n),e.removeListener("drain",r),c.removeListener("end",o),c.removeListener("close",a),c.removeListener("error",s),e.removeListener("error",s),c.removeListener("end",u),c.removeListener("close",u),e.removeListener("close",u)}var c=this;c.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(c.on("end",o),c.on("close",a));var f=!1;return c.on("error",s),e.on("error",s),c.on("end",u),c.on("close",u),e.on("close",u),e.emit("pipe",c),e}},{23:23,29:29,63:63,69:69,70:70,71:71,72:72}],63:[function(e,t,n){t.exports=e(64)},{64:64}],64:[function(e,t,n){"use strict";function r(e){return this instanceof r?(c.call(this,e),f.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(o,this)}function o(e){e.end()}var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e(58),u=e(9);u.inherits=e(29);var c=e(66),f=e(68);u.inherits(r,c);for(var l=a(f.prototype),h=0;h<l.length;h++){var d=l[h];r.prototype[d]||(r.prototype[d]=f.prototype[d])}},{29:29,58:58,66:66,68:68,9:9}],65:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(67),o=e(9);o.inherits=e(29),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{29:29,67:67,9:9}],66:[function(e,t,n){(function(n){"use strict";function r(t,n){I=I||e(64),t=t||{},this.objectMode=!!t.objectMode,n instanceof I&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(T||(T=e(73).StringDecoder),this.decoder=new T(t.encoding),this.encoding=t.encoding)}function i(t){return I=I||e(64),this instanceof i?(this._readableState=new r(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void A.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n)t.reading=!1,f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e))),d(e,t)}else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){return e>=C?e=C:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(M("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?x(h,e):h(e))}function h(e){M("emit readable"),e.emit("readable"),_(e)}function d(e,t){t.readingMore||(t.readingMore=!0,x(p,e,t))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(M("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;M("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&O(e,"data")&&(t.flowing=!0,_(e))}}function v(e){M("readable nexttick read 0"),e.read(0)}function y(e,t){t.resumeScheduled||(t.resumeScheduled=!0,x(b,e,t))}function b(e,t){t.reading||(M("resume read 0"),e.read(0)),t.resumeScheduled=!1,e.emit("resume"),_(e),t.flowing&&!t.reading&&e.read(0)}function _(e){var t=e._readableState;if(M("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function m(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):1===r.length?r[0]:R.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new R(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function w(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,x(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function k(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function S(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var x=e(58),B=e(31),R=e(8).Buffer;i.ReadableState=r;var A,O=(e(23),function(e,t){return e.listeners(t).length});!function(){try{A=e("stream")}catch(t){}finally{A||(A=e(23).EventEmitter)}}();var R=e(8).Buffer,L=e(9);L.inherits=e(29);var j=e(7),M=void 0;M=j&&j.debuglog?j.debuglog("stream"):function(){};var T;L.inherits(i,A);var I,I;i.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new R(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.isPaused=function(){return this._readableState.flowing===!1},i.prototype.setEncoding=function(t){return T||(T=e(73).StringDecoder),this._readableState.decoder=new T(t),this._readableState.encoding=t,this};var C=8388608;i.prototype.read=function(e){M("read",e);var t=this._readableState,n=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return M("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?w(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&w(this),null;var r=t.needReadable;M("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,M("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,M("reading or ended",r)),r&&(M("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?m(e,t):null,null===i&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&w(this),null!==i&&this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){M("onunpipe"),e===l&&o()}function i(){M("onend"),e.end()}function o(){M("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),y=!0,!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){M("ondata");var n=e.write(t);!1===n&&(1!==h.pipesCount||h.pipes[0]!==e||1!==l.listenerCount("data")||y||(M("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++),l.pause())}function s(t){M("onerror",t),f(),e.removeListener("error",s),0===O(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){M("onfinish"),e.removeListener("close",u),f()}function f(){M("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,M("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?x(p):l.once("end",p),e.on("unpipe",r);var v=g(l);e.on("drain",v);var y=!1;return l.on("data",a),e._events&&e._events.error?B(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(M("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var o=S(t.pipes,e);return-1===o?this:(t.pipes.splice(o,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=A.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&!this._readableState.endEmitted){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):x(v,this))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(M("resume"),e.flowing=!0,y(this,e)),this},i.prototype.pause=function(){return M("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(M("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(M("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(M("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return k(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){M("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=m}).call(this,e(59))},{23:23,29:29,31:31,58:58,59:59,64:64,7:7,73:73,8:8,9:9}],67:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(64),u=e(9);u.inherits=e(29),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{29:29,64:64,9:9}],68:[function(e,t,n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){O=O||e(64),t=t||{},this.objectMode=!!t.objectMode,n instanceof O&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return O=O||e(64),this instanceof a||this instanceof O?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=b(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function b(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=b(t);return n&&(0===t.pendingcb?(_(e,t),t.finished=!0,e.emit("finish")):_(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(58),S=k,x=e(8).Buffer;a.WritableState=o;var B=e(9);B.inherits=e(29);var R,A={deprecate:e(96)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(23).EventEmitter)}}();var x=e(8).Buffer;B.inherits(a,R);var O;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var O;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}},{23:23,29:29,58:58,64:64,8:8,9:9,96:96}],69:[function(e,t,n){t.exports=e(65)},{65:65}],70:[function(e,t,n){var r=function(){try{return e("stream")}catch(t){}}();n=t.exports=e(66),n.Stream=r||n,n.Readable=n,n.Writable=e(68),n.Duplex=e(64),n.Transform=e(67),n.PassThrough=e(65)},{62:62,64:64,65:65,66:66,67:67,68:68}],71:[function(e,t,n){t.exports=e(67)},{67:67}],72:[function(e,t,n){t.exports=e(68)},{68:68}],73:[function(e,t,n){function r(e){if(e&&!u(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function o(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function a(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e(8).Buffer,u=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},c=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=o;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=a;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};c.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&56319>=r)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&56319>=r){var o=this.surrogateSize;return this.charLength+=o,this.charReceived+=o,this.charBuffer.copy(this.charBuffer,o,0,o),e.copy(this.charBuffer,0,0,o),t.substring(0,i)}return t},c.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(2>=t&&n>>4==14){this.charLength=3;break}if(3>=t&&n>>3==30){this.charLength=4;break}}this.charReceived=t},c.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{8:8}],74:[function(e,t,n){t.exports={encode:function(e){return"ÿ"+e[0]+"ÿ"+e[1]},decode:function(e){var t=e.toString(),n=t.indexOf("ÿ",1);return[t.substring(1,n),t.substring(n+1)]},lowerBound:"\x00",upperBound:"ÿ"}},{}],75:[function(e,t,n){var r=e(21).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{21:21}],76:[function(e,t,n){var r=e(77),i=e(79),o=e(33),a=new o,s=e(78),u=e(74);t.exports=function(e){return i(r(e,u,a),[],s,e.options)}},{33:33,74:74,77:77,78:78,79:79}],77:[function(e,t,n){function r(e){return"function"==typeof e}function i(e){return null==e?e:r(e.prefix)?e.prefix():e}function o(e){var t={};for(var n in e)t[n]=e[n];return t}var a=e(81);t.exports=function(e,t,n,s){function u(e,r,i,o){return t.encode([e,n.encodeKey(r,i,o)])}function c(e,t){return t&&t.options&&(e.keyEncoding=e.keyEncoding||t.options.keyEncoding,e.valueEncoding=e.valueEncoding||t.options.valueEncoding),e}function f(){for(h=!0;l.length;)l.shift()()}var l=[],h=!1;return r(e.isOpen)&&e.isOpen()?h=!0:e.open(f),{apply:function(t,r,o){for(var a=0;a<t.length;a++){var s=t[a];c(s,s.prefix),s.prefix=i(s.prefix)}if(r=r||{},"object"!=typeof r)throw new Error("opts must be object, was:"+r);"function"==typeof r&&(o=r,r={}),t.length?(e.db||e).batch(t.map(function(e){return{key:u(e.prefix,e.key,r,e),value:"del"!==e.type?n.encodeValue(e.value,r,e):void 0,type:e.type||(void 0===e.value?"del":"put")}}),r,function(e){return e?o(e):void o()}):o()},get:function(t,r,i,o){return i.asBuffer=n.valueAsBuffer(i),(e.db||e).get(u(r,t,i),i,function(e,t){e?o(e):o(null,n.decodeValue(t,i))})},createDecoder:function(e){return function(r,i){return{key:n.decodeKey(t.decode(r)[1],e),value:n.decodeValue(i,e)}}},isOpen:function(){return e.db&&r(e.db.isOpen)?e.db.isOpen():e.isOpen()},isClosed:function(){return e.db&&r(e.db.isClosed)?e.db.isClosed():e.isClosed()},close:function(t){return e.close(t)},iterator:function(r,i){function s(e){return u(d,e,f,{})}function c(e){return{next:function(t){return e.next(t)},end:function(t){e.end(t)}}}var f=o(r||{}),d=r.prefix||[];return a.toLtgt(r,f,s,t.lowerBound,t.upperBound),f.prefix=null,f.keyAsBuffer=f.valueAsBuffer=!1,"number"!=typeof f.limit&&(f.limit=-1),f.keyAsBuffer=t.buffer,f.valueAsBuffer=n.valueAsBuffer(f),h?c((e.db||e).iterator(f)):void l.push(function(){i(null,c((e.db||e).iterator(f)))})}}}},{81:81}],78:[function(e,t,n){function r(e,t){return this instanceof r?(i.call(this,{objectMode:!0,highWaterMark:e.highWaterMark}),this._waiting=!1,this._options=e,void(this._makeData=t)):new r(e,t)}var i=e(87).Readable,o=e(29),a=e(75).EncodingError;o(r,i),r.prototype.setIterator=function(e){return this._iterator=e,this._destroyed?e.end(function(){}):this._waiting?(this._waiting=!1,this._read()):this},r.prototype._read=function(){var e=this;if(!e._destroyed)return e._iterator?void e._iterator.next(function(t,n,r){if(t||void 0===n&&void 0===r)return t||e._destroyed||e.push(null),e._cleanup(t);try{r=e._makeData(n,r)}catch(i){return e._cleanup(new a(i))}e._destroyed||e.push(r)}):this._waiting=!0},r.prototype._cleanup=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;e&&t.emit("error",e),t._iterator?t._iterator.end(function(){t._iterator=null,t.emit("close")}):t.emit("close")}},r.prototype.destroy=function(){this._cleanup()},r.prototype.toString=function(){return"LevelUP.ReadStream"},t.exports=r},{29:29,75:75,87:87}],79:[function(e,t,n){(function(n){var r=e(23).EventEmitter,i=e(75),o="6.5.4",a=t.exports=function(e,t,s,u){function c(e){e&&l.emit("error",e)}function f(e){var t={};if(u)for(var n in u)void 0!=u[n]&&(t[n]=u[n]);if(e)for(var n in e)void 0!=e[n]&&(t[n]=e[n]);return t}var l=new r;return l.sublevels={},l.options=u,l.version=o,l.methods={},t=t||[],l.put=function(n,r,i,o){"function"==typeof i&&(o=i,i={}),o||(o=c),e.apply([{key:n,value:r,prefix:t.slice(),type:"put"}],f(i),function(e){return e||(l.emit("put",n,r),o(null)),e?o(e):void 0})},l.prefix=function(){return t.slice()},l.del=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),e.apply([{key:n,prefix:t.slice(),type:"del"}],f(r),function(e){return e||(l.emit("del",n),
+i(null)),e?i(e):void 0})},l.batch=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),n=n.map(function(e){return{key:e.key,value:e.value,prefix:e.prefix||t,keyEncoding:e.keyEncoding,valueEncoding:e.valueEncoding,type:e.type}}),e.apply(n,f(r),function(e){return e||(l.emit("batch",n),i(null)),e?i(e):void 0})},l.get=function(n,r,o){"function"==typeof r&&(o=r,r={}),e.get(n,t,f(r),function(e,t){e?o(new i.NotFoundError("Key not found in database",e)):o(null,t)})},l.clone=function(n){return a(e,t,s,f(n))},l.sublevel=function(n,r){return l.sublevels[n]=l.sublevels[n]||a(e,t.concat(n),s,f(r))},l.readStream=l.createReadStream=function(n){n=f(n),n.prefix=t;var r,i=e.iterator(n,function(e,t){r.setIterator(t)});return r=s(n,e.createDecoder(n)),i&&r.setIterator(i),r},l.valueStream=l.createValueStream=function(e){return e=e||{},e.values=!0,e.keys=!1,l.createReadStream(e)},l.keyStream=l.createKeyStream=function(e){return e=e||{},e.values=!1,e.keys=!0,l.createReadStream(e)},l.close=function(r){r=r||function(){},t.length?n.nextTick(r):e.close(r)},l.isOpen=e.isOpen,l.isClosed=e.isClosed,l}}).call(this,e(59))},{23:23,59:59,75:75}],80:[function(e,t,n){arguments[4][37][0].apply(n,arguments)},{37:37}],81:[function(e,t,n){(function(e){function t(e,t){return Object.hasOwnProperty.call(e,t)}function r(e){return void 0!==e&&""!==e}function t(e,t){return Object.hasOwnProperty.call(e,t)}function i(e,t){return Object.hasOwnProperty.call(e,t)&&t}function o(e){return e}n.compare=function(t,n){if(e.isBuffer(t)){for(var r=Math.min(t.length,n.length),i=0;r>i;i++){var o=t[i]-n[i];if(o)return o}return t.length-n.length}return n>t?-1:t>n?1:0};var a=n.lowerBoundKey=function(e){return i(e,"gt")||i(e,"gte")||i(e,"min")||(e.reverse?i(e,"end"):i(e,"start"))||void 0},s=n.lowerBound=function(e){var t=a(e);return t&&e[t]};n.lowerBoundInclusive=function(e){return!t(e,"gt")},n.upperBoundInclusive=function(e){return!t(e,"lt")&&e.minEx};var u=n.lowerBoundExclusive=function(e){return!(!t(e,"gt")&&!e.minEx)},c=n.upperBoundExclusive=function(e){return!!t(e,"lt")},f=n.upperBoundKey=function(e){return i(e,"lt")||i(e,"lte")||i(e,"max")||(e.reverse?i(e,"start"):i(e,"end"))||void 0},l=n.upperBound=function(e){var t=f(e);return t&&e[t]};n.toLtgt=function(e,r,i,a,s){r=r||{},i=i||o;var u=arguments.length>3,c=n.lowerBoundKey(e),f=n.upperBoundKey(e);return c?"gt"===c?r.gt=i(e.gt,!1):r.gte=i(e[c],!1):u&&(r.gte=i(a,!1)),f?"lt"===f?r.lt=i(e.lt,!0):r.lte=i(e[f],!0):u&&(r.lte=i(s,!0)),null!=e.reverse&&(r.reverse=!!e.reverse),t(r,"max")&&delete r.max,t(r,"min")&&delete r.min,t(r,"start")&&delete r.start,t(r,"end")&&delete r.end,r},n.contains=function(e,t,i){i=i||n.compare;var o=s(e);if(r(o)){var a=i(t,o);if(0>a||0===a&&u(e))return!1}var f=l(e);if(r(f)){var a=i(t,f);if(a>0||0===a&&c(e))return!1}return!0},n.filter=function(e,t){return function(r){return n.contains(e,r,t)}}}).call(this,{isBuffer:e(30)})},{30:30}],82:[function(e,t,n){arguments[4][38][0].apply(n,arguments)},{29:29,38:38,59:59,84:84,86:86,9:9}],83:[function(e,t,n){arguments[4][39][0].apply(n,arguments)},{29:29,39:39,85:85,9:9}],84:[function(e,t,n){(function(n){function r(t,n){t=t||{};var r=t.highWaterMark;this.highWaterMark=r||0===r?r:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(73).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(e){return this instanceof i?(this._readableState=new r(e,this),this.readable=!0,void B.call(this)):new i(e)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n||void 0===n)t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&l(e),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=O)e=O;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return S.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?l(e):m(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){e.emit("readable")}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&v(e)}}function v(e){function t(e,t,i){var o=e.write(n);!1===o&&r.awaitDrain++}var n,r=e._readableState;for(r.awaitDrain=0;r.pipesCount&&null!==(n=e.read());)if(1===r.pipesCount?t(r.pipes,0,null):w(r.pipes,t),e.emit("data",n),r.awaitDrain>0)return;return 0===r.pipesCount?(r.flowing=!1,void(x.listenerCount(e,"data")>0&&b(e))):void(r.ranOut=!0)}function y(){this._readableState.ranOut&&(this._readableState.ranOut=!1,v(this))}function b(e,t){var r=e._readableState;if(r.flowing)throw new Error("Cannot switch to old mode now.");var i=t||!1,o=!1;e.readable=!0,e.pipe=B.prototype.pipe,e.on=e.addListener=B.prototype.on,e.on("readable",function(){o=!0;for(var t;!i&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)}),e.pause=function(){i=!0,this.emit("pause")},e.resume=function(){i=!1,o?n.nextTick(function(){e.emit("readable")}):this.read(0),this.emit("resume")},e.emit("readable")}function _(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(80),S=e(8).Buffer;i.ReadableState=r;var x=e(23).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(62),R=e(9);R.inherits=e(29);var A;R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return"string"!=typeof e||n.objectMode||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){A||(A=e(73).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t};var O=8388608;i.prototype.read=function(e){var t=this._readableState;t.calledRead=!0;var n,r=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return l(this),null;if(e=u(e,t),0===e&&t.ended)return n=null,t.length>0&&t.decoder&&(n=_(e,t),t.length-=n.length),0===t.length&&m(this),n;var i=t.needReadable;return t.length-e<=t.highWaterMark&&(i=!0),(t.ended||t.reading)&&(i=!1),i&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),i&&!t.reading&&(e=u(r,t)),n=e>0?_(e,t):null,null===n&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&m(this),n},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){e===f&&o()}function i(){e.end()}function o(){e.removeListener("close",s),e.removeListener("finish",u),e.removeListener("drain",p),e.removeListener("error",a),e.removeListener("unpipe",r),f.removeListener("end",i),f.removeListener("end",o),e._writableState&&!e._writableState.needDrain||p()}function a(t){c(),e.removeListener("error",a),0===x.listenerCount(e,"error")&&e.emit("error",t)}function s(){e.removeListener("finish",u),c()}function u(){e.removeListener("close",s),c()}function c(){f.unpipe(e)}var f=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=e;break;case 1:l.pipes=[l.pipes,e];break;default:l.pipes.push(e)}l.pipesCount+=1;var h=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,d=h?i:o;l.endEmitted?n.nextTick(d):f.once("end",d),e.on("unpipe",r);var p=g(f);return e.on("drain",p),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(a):e._events.error=[a,e._events.error]:e.on("error",a),e.once("close",s),e.once("finish",u),e.emit("pipe",f),l.flowing||(this.on("readable",y),l.flowing=!0,n.nextTick(function(){v(f)})),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=B.prototype.on.call(this,e,t);if("data"!==e||this._readableState.flowing||b(this),"readable"===e&&this.readable){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):this.read(0))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){b(this),this.read(0),this.emit("resume")},i.prototype.pause=function(){b(this,!0),this.emit("pause")},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)"function"==typeof e[i]&&"undefined"==typeof this[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){n&&(n=!1,e.resume())},r},i._fromList=_}).call(this,e(59))},{23:23,29:29,59:59,62:62,73:73,8:8,80:80,9:9}],85:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e);var t=(this._transformState=new r(e,this),this);this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("finish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=(e._readableState,e._transformState);if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(82),u=e(9);u.inherits=e(29),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{29:29,82:82,9:9}],86:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(e,t){e=e||{};var n=e.highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var r=e.decodeStrings===!1;this.decodeStrings=!r,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(t,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.errorEmitted=!1}function o(t){var n=e(82);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void E.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!m.isBuffer(r)&&"string"!=typeof r&&null!==r&&void 0!==r&&!t.objectMode){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new m(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),m.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing?t.buffer.push(new r(n,i,o)):f(e,t,a,n,i,o),s}function f(e,t,n,r,i,o){t.writelen=n,t.writecb=o,t.writing=!0,t.sync=!0,e._write(r,i,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){o(i)}):o(i),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),r(),n&&b(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){t.bufferProcessing=!0;for(var n=0;n<t.buffer.length;n++){var r=t.buffer[n],i=r.chunk,o=r.encoding,a=r.callback,s=t.objectMode?1:i.length;if(f(e,t,s,i,o,a),t.writing){n++;break}}t.bufferProcessing=!1,n<t.buffer.length?t.buffer=t.buffer.slice(n):t.buffer.length=0}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function b(e,t){var n=y(e,t);return n&&(t.finished=!0,e.emit("finish")),n}function _(e,t,r){t.ending=!0,b(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var m=e(8).Buffer;o.WritableState=i;var w=e(9);w.inherits=e(29);var E=e(62);w.inherits(o,E),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return"function"==typeof t&&(n=t,t=null),m.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(i=c(this,r,e,t,n)),i},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),"undefined"!=typeof e&&null!==e&&this.write(e,t),r.ending||r.finished||_(this,r,n)}}).call(this,e(59))},{29:29,59:59,62:62,8:8,82:82,9:9}],87:[function(e,t,n){var r=e(62);n=t.exports=e(84),n.Stream=r,n.Readable=n,n.Writable=e(86),n.Duplex=e(82),n.Transform=e(85),n.PassThrough=e(83)},{62:62,82:82,83:83,84:84,85:85,86:86}],88:[function(e,t,n){arguments[4][64][0].apply(n,arguments)},{29:29,58:58,64:64,89:89,9:9,91:91}],89:[function(e,t,n){arguments[4][66][0].apply(n,arguments)},{23:23,29:29,31:31,58:58,59:59,66:66,7:7,73:73,8:8,88:88,9:9}],90:[function(e,t,n){arguments[4][67][0].apply(n,arguments)},{29:29,67:67,88:88,9:9}],91:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){O=O||e(88),t=t||{},this.objectMode=!!t.objectMode,n instanceof O&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return O=O||e(88),this instanceof a||this instanceof O?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=b(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function b(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=b(t);return n&&(0===t.pendingcb?(_(e,t),t.finished=!0,e.emit("finish")):_(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(58),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:k,x=e(8).Buffer;a.WritableState=o;var B=e(9);B.inherits=e(29);var R,A={deprecate:e(96)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(23).EventEmitter)}}();var x=e(8).Buffer;B.inherits(a,R);var O;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var O;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}}).call(this,e(59))},{23:23,29:29,58:58,59:59,8:8,88:88,9:9,96:96}],92:[function(e,t,n){arguments[4][71][0].apply(n,arguments)},{71:71,90:90}],93:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],94:[function(e,t,n){(function(n){function r(e){a.call(this,e),this._destroyed=!1}function i(e,t,n){n(null,e)}function o(e){return function(t,n,r){return"function"==typeof t&&(r=n,n=t,t={}),"function"!=typeof n&&(n=i),"function"!=typeof r&&(r=null),e(t,n,r)}}var a=e(92),s=e(98).inherits,u=e(93);s(r,a),r.prototype.destroy=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;n.nextTick(function(){e&&t.emit("error",e),t.emit("close")})}},t.exports=o(function(e,t,n){var i=new r(e);return i._transform=t,n&&(i._flush=n),i}),t.exports.ctor=o(function(e,t,n){function i(t){return this instanceof i?(this.options=u(e,t),void r.call(this,this.options)):new i(t)}return s(i,r),i.prototype._transform=t,n&&(i.prototype._flush=n),i}),t.exports.obj=o(function(e,t,n){var i=new r(u({objectMode:!0,highWaterMark:16},e));return i._transform=t,n&&(i._flush=n),i})}).call(this,e(59))},{59:59,92:92,93:93,98:98}],95:[function(e,t,n){"use strict";function r(){this.length=0}r.prototype.push=function(e){var t={item:e};this.last?this.last=this.last.next=t:this.last=this.first=t,this.length++},r.prototype.shift=function(){var e=this.first;return e?(this.first=e.next,--this.length||(this.last=void 0),e.item):void 0},r.prototype.slice=function(e,t){e="undefined"==typeof e?0:e,t="undefined"==typeof t?1/0:t;for(var n=[],r=0,i=this.first;i&&!(--t<0);i=i.next)++r>e&&n.push(i.item);return n},t.exports=r},{}],96:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null==r?!1:"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],97:[function(e,t,n){t.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},{}],98:[function(e,t,n){(function(t,r){function i(e,t){var r={seen:[],stylize:a};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),g(t)?r.showHidden=t:t&&n._extend(r,t),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,e,r.depth)}function o(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function u(e,t,r){if(e.customInspect&&t&&B(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return _(i)||(i=u(e,i,r)),i}var o=c(e,t);if(o)return o;var a=Object.keys(t),g=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(t)),x(t)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(t);if(0===a.length){if(B(t)){var v=t.name?": "+t.name:"";return e.stylize("[Function"+v+"]","special")}if(E(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(S(t))return e.stylize(Date.prototype.toString.call(t),"date");if(x(t))return f(t)}var y="",b=!1,m=["{","}"];if(p(t)&&(b=!0,m=["[","]"]),B(t)){var w=t.name?": "+t.name:"";y=" [Function"+w+"]"}if(E(t)&&(y=" "+RegExp.prototype.toString.call(t)),S(t)&&(y=" "+Date.prototype.toUTCString.call(t)),x(t)&&(y=" "+f(t)),0===a.length&&(!b||0==t.length))return m[0]+y+m[1];if(0>r)return E(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var k;return k=b?l(e,t,r,g,a):a.map(function(n){return h(e,t,r,g,n,b)}),e.seen.pop(),d(k,y,m)}function c(e,t){if(w(t))return e.stylize("undefined","undefined");if(_(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return b(t)?e.stylize(""+t,"number"):g(t)?e.stylize(""+t,"boolean"):v(t)?e.stylize("null","null"):void 0}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function l(e,t,n,r,i){for(var o=[],a=0,s=t.length;s>a;++a)j(t,String(a))?o.push(h(e,t,n,r,String(a),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(h(e,t,n,r,i,!0))}),o}function h(e,t,n,r,i,o){var a,s,c;if(c=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},c.get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),j(r,i)||(a="["+i+"]"),s||(e.seen.indexOf(c.value)<0?(s=v(n)?u(e,c.value,null):u(e,c.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return"  "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return"   "+e}).join("\n"))):s=e.stylize("[Circular]","special")),w(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function d(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n  ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function p(e){return Array.isArray(e)}function g(e){return"boolean"==typeof e}function v(e){return null===e}function y(e){return null==e}function b(e){return"number"==typeof e}function _(e){return"string"==typeof e}function m(e){return"symbol"==typeof e}function w(e){return void 0===e}function E(e){return k(e)&&"[object RegExp]"===A(e)}function k(e){return"object"==typeof e&&null!==e}function S(e){return k(e)&&"[object Date]"===A(e)}function x(e){return k(e)&&("[object Error]"===A(e)||e instanceof Error)}function B(e){return"function"==typeof e}function R(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function A(e){return Object.prototype.toString.call(e)}function O(e){return 10>e?"0"+e.toString(10):e.toString(10)}function L(){var e=new Date,t=[O(e.getHours()),O(e.getMinutes()),O(e.getSeconds())].join(":");return[e.getDate(),C[e.getMonth()],t].join(" ")}function j(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var M=/%[sdj%]/g;n.format=function(e){if(!_(e)){for(var t=[],n=0;n<arguments.length;n++)t.push(i(arguments[n]));return t.join(" ")}for(var n=1,r=arguments,o=r.length,a=String(e).replace(M,function(e){if("%%"===e)return"%";if(n>=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])a+=v(s)||!k(s)?" "+s:" "+i(s);return a},n.deprecate=function(e,i){function o(){if(!a){if(t.throwDeprecation)throw new Error(i);t.traceDeprecation?console.trace(i):console.error(i),a=!0}return e.apply(this,arguments)}if(w(r.process))return function(){return n.deprecate(e,i).apply(this,arguments)};if(t.noDeprecation===!0)return e;var a=!1;return o};var T,I={};n.debuglog=function(e){if(w(T)&&(T=t.env.NODE_DEBUG||""),e=e.toUpperCase(),!I[e])if(new RegExp("\\b"+e+"\\b","i").test(T)){var r=t.pid;I[e]=function(){var t=n.format.apply(n,arguments);console.error("%s %d: %s",e,r,t)}}else I[e]=function(){};return I[e]},n.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=p,n.isBoolean=g,n.isNull=v,n.isNullOrUndefined=y,n.isNumber=b,n.isString=_,n.isSymbol=m,n.isUndefined=w,n.isRegExp=E,n.isObject=k,n.isDate=S,n.isError=x,n.isFunction=B,n.isPrimitive=R,n.isBuffer=e(97);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",L(),n.format.apply(n,arguments))},n.inherits=e(29),n._extend=function(e,t){if(!t||!k(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(this,e(59),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{29:29,59:59,97:97}],99:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var i=r.element,o=r.index;if(Array.isArray(i))i.push(e);else if(o===t.length-2){var a=t.pop();i[a]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,i,o,a,s,u,c,f,l,h,d="";n=t.pop();)if(r=n.obj,i=n.prefix||"",o=n.val||"",d+=i,o)d+=o;else if("object"!=typeof r)d+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)d+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),a=r.length-1;a>=0;a--)s=0===a?"":",",t.push({obj:r[a],prefix:s});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),a=u.length-1;a>=0;a--)f=u[a],l=r[f],h=a>0?",":"",
+h+=JSON.stringify(f)+":",t.push({obj:l,prefix:h});t.push({val:"{"})}return d},n.parse=function(e){for(var t,n,i,o,a,s,u,c,f,l=[],h=[],d=0;;)if(t=e[d++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":d+=3,r(null,l,h);break;case"t":d+=3,r(!0,l,h);break;case"f":d+=4,r(!1,l,h);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",d--;;){if(i=e[d++],!/[\d\.\-e\+]/.test(i)){d--;break}n+=i}r(parseFloat(n),l,h);break;case'"':for(o="",a=void 0,s=0;;){if(u=e[d++],'"'===u&&("\\"!==a||s%2!==1))break;o+=u,a=u,"\\"===a?s++:s=0}r(JSON.parse('"'+o+'"'),l,h);break;case"[":c={element:[],index:l.length},l.push(c.element),h.push(c);break;case"{":f={element:{},index:l.length},l.push(f.element),h.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,h)}}},{}],100:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)n.hasOwnProperty(r)&&(e[r]=n[r])}return e}t.exports=r},{}]},{},[1]);
diff --git a/dist/pouchdb.memory.js b/dist/pouchdb.memory.js
new file mode 100644
index 0000000..6f88861
--- /dev/null
+++ b/dist/pouchdb.memory.js
@@ -0,0 +1,18283 @@
+// PouchDB in-memory plugin 5.3.2
+// Based on MemDOWN: https://github.com/rvagg/memdown
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var levelup = _interopDefault(_dereq_(40));
+var sublevel = _interopDefault(_dereq_(72));
+var through2 = _dereq_(90);
+var events = _dereq_(19);
+var inherits = _interopDefault(_dereq_(23));
+var pouchdbCollections = _dereq_(53);
+var getArguments = _interopDefault(_dereq_(2));
+var vuvuzela = _interopDefault(_dereq_(94));
+var lie = _interopDefault(_dereq_(44));
+var Md5 = _interopDefault(_dereq_(57));
+var Deque = _interopDefault(_dereq_(15));
+var jsExtend = _dereq_(26);
+var downAdapter = _interopDefault(_dereq_(46));
+
+function isBinaryObject(object) {
+  return object instanceof ArrayBuffer ||
+    (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+  if (typeof buff.slice === 'function') {
+    return buff.slice(0);
+  }
+  // IE10-11 slice() polyfill
+  var target = new ArrayBuffer(buff.byteLength);
+  var targetArray = new Uint8Array(target);
+  var sourceArray = new Uint8Array(buff);
+  targetArray.set(sourceArray);
+  return target;
+}
+
+function cloneBinaryObject(object) {
+  if (object instanceof ArrayBuffer) {
+    return cloneArrayBuffer(object);
+  }
+  var size = object.size;
+  var type = object.type;
+  // Blob
+  if (typeof object.slice === 'function') {
+    return object.slice(0, size, type);
+  }
+  // PhantomJS slice() replacement
+  return object.webkitSlice(0, size, type);
+}
+
+function clone(object) {
+  var newObject;
+  var i;
+  var len;
+
+  if (!object || typeof object !== 'object') {
+    return object;
+  }
+
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone(object[i]);
+    }
+    return newObject;
+  }
+
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
+
+  if (isBinaryObject(object)) {
+    return cloneBinaryObject(object);
+  }
+
+  newObject = {};
+  for (i in object) {
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
+      }
+    }
+  }
+  return newObject;
+}
+
+function isChromeApp() {
+  return (typeof chrome !== "undefined" &&
+    typeof chrome.storage !== "undefined" &&
+    typeof chrome.storage.local !== "undefined");
+}
+
+var hasLocal;
+
+if (isChromeApp()) {
+  hasLocal = false;
+} else {
+  try {
+    localStorage.setItem('_pouch_check_localstorage', 1);
+    hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+  } catch (e) {
+    hasLocal = false;
+  }
+}
+
+function hasLocalStorage() {
+  return hasLocal;
+}
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
+
+inherits(Changes, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (isChromeApp()) {
+    chrome.storage.onChanged.addListener(function (e) {
+      // make sure it's event addressed to us
+      if (e.db_name != null) {
+        //object only has oldValue, newValue members
+        self.emit(e.dbName.newValue);
+      }
+    });
+  } else if (hasLocalStorage()) {
+    if (typeof addEventListener !== 'undefined') {
+      addEventListener("storage", function (e) {
+        self.emit(e.key);
+      });
+    } else { // old IE
+      window.attachEvent("storage", function (e) {
+        self.emit(e.key);
+      });
+    }
+  }
+}
+
+function Changes() {
+  events.EventEmitter.call(this);
+  this._listeners = {};
+
+  attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
+  }
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
+    }
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
+    }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary'
+    ]);
+
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
+    }
+
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        setTimeout(function (){
+          eventFunction();
+        },0);
+      }
+      inprogress = false;
+    }).on('error', onError);
+  }
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
+
+Changes.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
+    return;
+  }
+  events.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+};
+
+
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (isChromeApp()) {
+    chrome.storage.local.set({dbName: dbName});
+  } else if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
+
+Changes.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
+
+// BEGIN Math.uuid.js
+
+/*!
+Math.uuid.js (v1.4)
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+*/
+
+/*
+ * Generate a random uuid.
+ *
+ * USAGE: Math.uuid(length, radix)
+ *   length - the desired number of characters
+ *   radix  - the number of allowable values for each character.
+ *
+ * EXAMPLES:
+ *   // No arguments  - returns RFC4122, version 4 ID
+ *   >>> Math.uuid()
+ *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ *   // One argument - returns ID of the specified length
+ *   >>> Math.uuid(15)     // 15 character ID (default base=62)
+ *   "VcydxgltxrVZSTV"
+ *
+ *   // Two arguments - returns ID of the specified length, and radix. 
+ *   // (Radix must be <= 62)
+ *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
+ *   "01001010"
+ *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
+ *   "47473046"
+ *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
+ *   "098F4D35"
+ */
+var chars = (
+  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
+  'abcdefghijklmnopqrstuvwxyz'
+).split('');
+function getValue(radix) {
+  return 0 | Math.random() * radix;
+}
+function uuid(len, radix) {
+  radix = radix || chars.length;
+  var out = '';
+  var i = -1;
+
+  if (len) {
+    // Compact form
+    while (++i < len) {
+      out += chars[getValue(radix)];
+    }
+    return out;
+  }
+    // rfc4122, version 4 form
+    // Fill in random data.  At i==19 set the high bits of clock sequence as
+    // per rfc4122, sec. 4.1.5
+  while (++i < 36) {
+    switch (i) {
+      case 8:
+      case 13:
+      case 18:
+      case 23:
+        out += '-';
+        break;
+      case 19:
+        out += chars[(getValue(16) & 0x3) | 0x8];
+        break;
+      default:
+        out += chars[getValue(16)];
+    }
+  }
+
+  return out;
+}
+
+inherits(PouchError, Error);
+
+function PouchError(opts) {
+  Error.call(this, opts.reason);
+  this.status = opts.status;
+  this.name = opts.error;
+  this.message = opts.reason;
+  this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
+
+var UNAUTHORIZED = new PouchError({
+  status: 401,
+  error: 'unauthorized',
+  reason: "Name or password is incorrect."
+});
+
+var MISSING_BULK_DOCS = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: "Missing JSON list of 'docs'"
+});
+
+var MISSING_DOC = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'missing'
+});
+
+var REV_CONFLICT = new PouchError({
+  status: 409,
+  error: 'conflict',
+  reason: 'Document update conflict'
+});
+
+var INVALID_ID = new PouchError({
+  status: 400,
+  error: 'invalid_id',
+  reason: '_id field must contain a string'
+});
+
+var MISSING_ID = new PouchError({
+  status: 412,
+  error: 'missing_id',
+  reason: '_id is required for puts'
+});
+
+var RESERVED_ID = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Only reserved document ids may start with underscore.'
+});
+
+var NOT_OPEN = new PouchError({
+  status: 412,
+  error: 'precondition_failed',
+  reason: 'Database not open'
+});
+
+var UNKNOWN_ERROR = new PouchError({
+  status: 500,
+  error: 'unknown_error',
+  reason: 'Database encountered an unknown error'
+});
+
+var BAD_ARG = new PouchError({
+  status: 500,
+  error: 'badarg',
+  reason: 'Some query argument is invalid'
+});
+
+var INVALID_REQUEST = new PouchError({
+  status: 400,
+  error: 'invalid_request',
+  reason: 'Request was invalid'
+});
+
+var QUERY_PARSE_ERROR = new PouchError({
+  status: 400,
+  error: 'query_parse_error',
+  reason: 'Some query parameter is invalid'
+});
+
+var DOC_VALIDATION = new PouchError({
+  status: 500,
+  error: 'doc_validation',
+  reason: 'Bad special document member'
+});
+
+var BAD_REQUEST = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Something wrong with the request'
+});
+
+var NOT_AN_OBJECT = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Document must be a JSON object'
+});
+
+var DB_MISSING = new PouchError({
+  status: 404,
+  error: 'not_found',
+  reason: 'Database not found'
+});
+
+var IDB_ERROR = new PouchError({
+  status: 500,
+  error: 'indexed_db_went_bad',
+  reason: 'unknown'
+});
+
+var WSQ_ERROR = new PouchError({
+  status: 500,
+  error: 'web_sql_went_bad',
+  reason: 'unknown'
+});
+
+var LDB_ERROR = new PouchError({
+  status: 500,
+  error: 'levelDB_went_went_bad',
+  reason: 'unknown'
+});
+
+var FORBIDDEN = new PouchError({
+  status: 403,
+  error: 'forbidden',
+  reason: 'Forbidden by design doc validate_doc_update function'
+});
+
+var INVALID_REV = new PouchError({
+  status: 400,
+  error: 'bad_request',
+  reason: 'Invalid rev format'
+});
+
+var FILE_EXISTS = new PouchError({
+  status: 412,
+  error: 'file_exists',
+  reason: 'The database could not be created, the file already exists.'
+});
+
+var MISSING_STUB = new PouchError({
+  status: 412,
+  error: 'missing_stub'
+});
+
+var INVALID_URL = new PouchError({
+  status: 413,
+  error: 'invalid_url',
+  reason: 'Provided URL is invalid'
+});
+
+var allErrors = {
+  UNAUTHORIZED: UNAUTHORIZED,
+  MISSING_BULK_DOCS: MISSING_BULK_DOCS,
+  MISSING_DOC: MISSING_DOC,
+  REV_CONFLICT: REV_CONFLICT,
+  INVALID_ID: INVALID_ID,
+  MISSING_ID: MISSING_ID,
+  RESERVED_ID: RESERVED_ID,
+  NOT_OPEN: NOT_OPEN,
+  UNKNOWN_ERROR: UNKNOWN_ERROR,
+  BAD_ARG: BAD_ARG,
+  INVALID_REQUEST: INVALID_REQUEST,
+  QUERY_PARSE_ERROR: QUERY_PARSE_ERROR,
+  DOC_VALIDATION: DOC_VALIDATION,
+  BAD_REQUEST: BAD_REQUEST,
+  NOT_AN_OBJECT: NOT_AN_OBJECT,
+  DB_MISSING: DB_MISSING,
+  WSQ_ERROR: WSQ_ERROR,
+  LDB_ERROR: LDB_ERROR,
+  FORBIDDEN: FORBIDDEN,
+  INVALID_REV: INVALID_REV,
+  FILE_EXISTS: FILE_EXISTS,
+  MISSING_STUB: MISSING_STUB,
+  IDB_ERROR: IDB_ERROR,
+  INVALID_URL: INVALID_URL
+};
+
+function createError(error, reason, name) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
+    }
+    /* jshint ignore:end */
+    if (name !== undefined) {
+      this.name = name;
+    }
+    if (reason !== undefined) {
+      this.reason = reason;
+    }
+  }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
+
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return createError(BAD_REQUEST, msg);
+  }
+}
+
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
+
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
+    }
+
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
+
+    if (filterReturn) {
+      return false;
+    }
+
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
+  };
+}
+
+function slowJsonParse(str) {
+  try {
+    return JSON.parse(str);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.parse(str);
+  }
+}
+
+function safeJsonParse(str) {
+  // try/catch is deoptimized in V8, leading to slower
+  // times than we'd like to have. Most documents are _not_
+  // huge, and do not require a slower code path just to parse them.
+  // We can be pretty sure that a document under 50000 characters
+  // will not be so deeply nested as to throw a stack overflow error
+  // (depends on the engine and available memory, though, so this is
+  // just a hunch). 50000 was chosen based on the average length
+  // of this string in our test suite, to try to find a number that covers
+  // most of our test cases (26 over this size, 26378 under it).
+  if (str.length < 50000) {
+    return JSON.parse(str);
+  }
+  return slowJsonParse(str);
+}
+
+function safeJsonStringify(json) {
+  try {
+    return JSON.stringify(json);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela.stringify(json);
+  }
+}
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+  var winningId;
+  var winningPos;
+  var winningDeleted;
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var tree = node.ids;
+    var branches = tree[2];
+    var pos = node.pos;
+    if (branches.length) { // non-leaf
+      for (var i = 0, len = branches.length; i < len; i++) {
+        toVisit.push({pos: pos + 1, ids: branches[i]});
+      }
+      continue;
+    }
+    var deleted = !!tree[1].deleted;
+    var id = tree[0];
+    // sort by deleted, then pos, then id
+    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+        winningPos !== pos ? winningPos < pos : winningId < id)) {
+      winningId = id;
+      winningPos = pos;
+      winningDeleted = deleted;
+    }
+  }
+
+  return winningPos + '-' + winningId;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+  var toVisit = revs.slice();
+
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var branches = tree[2];
+    var newCtx =
+      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+    }
+  }
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+  var revs = [];
+  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                               revHash, ctx, opts) {
+    if (opts.status === 'available' && !isLeaf) {
+      revs.push(pos + '-' + revHash);
+      opts.status = 'missing';
+    }
+  });
+  return revs;
+}
+
+function sortByPos(a, b) {
+  return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+  var leaves = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+    if (isLeaf) {
+      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+    }
+  });
+  leaves.sort(sortByPos).reverse();
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    delete leaves[i].pos;
+  }
+  return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+  var win = winningRev(metadata);
+  var leaves = collectLeaves(metadata.rev_tree);
+  var conflicts = [];
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    var leaf = leaves[i];
+    if (leaf.rev !== win && !leaf.opts.deleted) {
+      conflicts.push(leaf.rev);
+    }
+  }
+  return conflicts;
+}
+
+function getTrees(node) {
+  return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+//  - metadata: the metadata object from the doc store
+//  - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+  if (!rev) {
+    rev = winningRev(metadata);
+  }
+  var id = rev.substring(rev.indexOf('-') + 1);
+  var toVisit = metadata.rev_tree.map(getTrees);
+
+  var tree;
+  while ((tree = toVisit.pop())) {
+    if (tree[0] === id) {
+      return !!tree[1].deleted;
+    }
+    toVisit = toVisit.concat(tree[2]);
+  }
+}
+
+function isLocalId(id) {
+  return (/^_local/).test(id);
+}
+
+function toObject(array) {
+  return array.reduce(function (obj, item) {
+    obj[item] = true;
+    return obj;
+  }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+  '_id',
+  '_rev',
+  '_attachments',
+  '_deleted',
+  '_revisions',
+  '_revs_info',
+  '_conflicts',
+  '_deleted_conflicts',
+  '_local_seq',
+  '_rev_tree',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats',
+  // Specific to Couchbase Sync Gateway
+  '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+  '_attachments',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats'
+]);
+
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = createError(MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = createError(INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = createError(RESERVED_ID);
+  }
+  if (err) {
+    throw err;
+  }
+}
+
+function parseRevisionInfo(rev) {
+  if (!/^\d+\-./.test(rev)) {
+    return createError(INVALID_REV);
+  }
+  var idx = rev.indexOf('-');
+  var left = rev.substring(0, idx);
+  var right = rev.substring(idx + 1);
+  return {
+    prefix: parseInt(left, 10),
+    id: right
+  };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+  var pos = revisions.start - revisions.ids.length + 1;
+
+  var revisionIds = revisions.ids;
+  var ids = [revisionIds[0], opts, []];
+
+  for (var i = 1, len = revisionIds.length; i < len; i++) {
+    ids = [revisionIds[i], {status: 'missing'}, [ids]];
+  }
+
+  return [{
+    pos: pos,
+    ids: ids
+  }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits) {
+
+  var nRevNum;
+  var newRevId;
+  var revInfo;
+  var opts = {status: 'available'};
+  if (doc._deleted) {
+    opts.deleted = true;
+  }
+
+  if (newEdits) {
+    if (!doc._id) {
+      doc._id = uuid();
+    }
+    newRevId = uuid(32, 16).toLowerCase();
+    if (doc._rev) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      doc._rev_tree = [{
+        pos: revInfo.prefix,
+        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+      }];
+      nRevNum = revInfo.prefix + 1;
+    } else {
+      doc._rev_tree = [{
+        pos: 1,
+        ids : [newRevId, opts, []]
+      }];
+      nRevNum = 1;
+    }
+  } else {
+    if (doc._revisions) {
+      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+      nRevNum = doc._revisions.start;
+      newRevId = doc._revisions.ids[0];
+    }
+    if (!doc._rev_tree) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      nRevNum = revInfo.prefix;
+      newRevId = revInfo.id;
+      doc._rev_tree = [{
+        pos: nRevNum,
+        ids: [newRevId, opts, []]
+      }];
+    }
+  }
+
+  invalidIdError(doc._id);
+
+  doc._rev = nRevNum + '-' + newRevId;
+
+  var result = {metadata : {}, data : {}};
+  for (var key in doc) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(doc, key)) {
+      var specialKey = key[0] === '_';
+      if (specialKey && !reservedWords[key]) {
+        var error = createError(DOC_VALIDATION, key);
+        error.message = DOC_VALIDATION.message + ': ' + key;
+        throw error;
+      } else if (specialKey && !dataWords[key]) {
+        result.metadata[key.slice(1)] = doc[key];
+      } else {
+        result.data[key] = doc[key];
+      }
+    }
+  }
+  return result;
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+  var paths = [];
+  var toVisit = revs.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
+
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, opts: opts});
+    if (isLeaf) {
+      paths.push({pos: (pos + 1 - history.length), ids: history});
+    }
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+    }
+  }
+  return paths.reverse();
+}
+
+function sortByPos$1(a, b) {
+  return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (comparator(arr[mid], item) < 0) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+  var idx = binarySearch(arr, item, comparator);
+  arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+  var root;
+  var leaf;
+  for (var i = numStemmed, len = path.length; i < len; i++) {
+    var node = path[i];
+    var currentLeaf = [node.id, node.opts, []];
+    if (leaf) {
+      leaf[2].push(currentLeaf);
+      leaf = currentLeaf;
+    } else {
+      root = leaf = currentLeaf;
+    }
+  }
+  return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+  return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+  var queue = [{tree1: in_tree1, tree2: in_tree2}];
+  var conflicts = false;
+  while (queue.length > 0) {
+    var item = queue.pop();
+    var tree1 = item.tree1;
+    var tree2 = item.tree2;
+
+    if (tree1[1].status || tree2[1].status) {
+      tree1[1].status =
+        (tree1[1].status ===  'available' ||
+        tree2[1].status === 'available') ? 'available' : 'missing';
+    }
+
+    for (var i = 0; i < tree2[2].length; i++) {
+      if (!tree1[2][0]) {
+        conflicts = 'new_leaf';
+        tree1[2][0] = tree2[2][i];
+        continue;
+      }
+
+      var merged = false;
+      for (var j = 0; j < tree1[2].length; j++) {
+        if (tree1[2][j][0] === tree2[2][i][0]) {
+          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+          merged = true;
+        }
+      }
+      if (!merged) {
+        conflicts = 'new_branch';
+        insertSorted(tree1[2], tree2[2][i], compareTree);
+      }
+    }
+  }
+  return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+  var restree = [];
+  var conflicts = false;
+  var merged = false;
+  var res;
+
+  if (!tree.length) {
+    return {tree: [path], conflicts: 'new_leaf'};
+  }
+
+  for (var i = 0, len = tree.length; i < len; i++) {
+    var branch = tree[i];
+    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+      // Paths start at the same position and have the same root, so they need
+      // merged
+      res = mergeTree(branch.ids, path.ids);
+      restree.push({pos: branch.pos, ids: res.tree});
+      conflicts = conflicts || res.conflicts;
+      merged = true;
+    } else if (dontExpand !== true) {
+      // The paths start at a different position, take the earliest path and
+      // traverse up until it as at the same point from root as the path we
+      // want to merge.  If the keys match we return the longer path with the
+      // other merged After stemming we dont want to expand the trees
+
+      var t1 = branch.pos < path.pos ? branch : path;
+      var t2 = branch.pos < path.pos ? path : branch;
+      var diff = t2.pos - t1.pos;
+
+      var candidateParents = [];
+
+      var trees = [];
+      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+      while (trees.length > 0) {
+        var item = trees.pop();
+        if (item.diff === 0) {
+          if (item.ids[0] === t2.ids[0]) {
+            candidateParents.push(item);
+          }
+          continue;
+        }
+        var elements = item.ids[2];
+        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+          trees.push({
+            ids: elements[j],
+            diff: item.diff - 1,
+            parent: item.ids,
+            parentIdx: j
+          });
+        }
+      }
+
+      var el = candidateParents[0];
+
+      if (!el) {
+        restree.push(branch);
+      } else {
+        res = mergeTree(el.ids, t2.ids);
+        el.parent[2][el.parentIdx] = res.tree;
+        restree.push({pos: t1.pos, ids: t1.ids});
+        conflicts = conflicts || res.conflicts;
+        merged = true;
+      }
+    } else {
+      restree.push(branch);
+    }
+  }
+
+  // We didnt find
+  if (!merged) {
+    restree.push(path);
+  }
+
+  restree.sort(sortByPos$1);
+
+  return {
+    tree: restree,
+    conflicts: conflicts || 'internal_node'
+  };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+  // First we break out the tree into a complete list of root to leaf paths
+  var paths = rootToLeaf(tree);
+  var maybeStem = {};
+
+  var result;
+  for (var i = 0, len = paths.length; i < len; i++) {
+    // Then for each path, we cut off the start of the path based on the
+    // `depth` to stem to, and generate a new set of flat trees
+    var path = paths[i];
+    var stemmed = path.ids;
+    var numStemmed = Math.max(0, stemmed.length - depth);
+    var stemmedNode = {
+      pos: path.pos + numStemmed,
+      ids: pathToTree(stemmed, numStemmed)
+    };
+
+    for (var s = 0; s < numStemmed; s++) {
+      var rev = (path.pos + s) + '-' + stemmed[s].id;
+      maybeStem[rev] = true;
+    }
+
+    // Then we remerge all those flat trees together, ensuring that we dont
+    // connect trees that would go beyond the depth limit
+    if (result) {
+      result = doMerge(result, stemmedNode, true).tree;
+    } else {
+      result = [stemmedNode];
+    }
+  }
+
+  traverseRevTree(result, function (isLeaf, pos, revHash) {
+    // some revisions may have been removed in a branch but not in another
+    delete maybeStem[pos + '-' + revHash];
+  });
+
+  return {
+    tree: result,
+    revs: Object.keys(maybeStem)
+  };
+}
+
+function merge(tree, path, depth) {
+  var newTree = doMerge(tree, path);
+  var stemmed = stem(newTree.tree, depth);
+  return {
+    tree: stemmed.tree,
+    stemmedRevs: stemmed.revs,
+    conflicts: newTree.conflicts
+  };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+  var toVisit = revs.slice();
+  var splitRev = rev.split('-');
+  var targetPos = parseInt(splitRev[0], 10);
+  var targetId = splitRev[1];
+
+  var node;
+  while ((node = toVisit.pop())) {
+    if (node.pos === targetPos && node.ids[0] === targetId) {
+      return true;
+    }
+    var branches = node.ids[2];
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: node.pos + 1, ids: branches[i]});
+    }
+  }
+  return false;
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+                   i, cb, writeDoc, newEdits) {
+
+  if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
+    results[i] = docInfo;
+    return cb();
+  }
+
+  // sometimes this is pre-calculated. historically not always
+  var previousWinningRev = prev.winningRev || winningRev(prev);
+  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+    isDeleted(prev, previousWinningRev);
+  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+    isDeleted(docInfo.metadata);
+  var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+  if (previouslyDeleted && !deleted && newEdits && isRoot) {
+    var newDoc = docInfo.data;
+    newDoc._rev = previousWinningRev;
+    newDoc._id = docInfo.metadata.id;
+    docInfo = parseDoc(newDoc, newEdits);
+  }
+
+  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+  var inConflict = newEdits && (((previouslyDeleted && deleted) ||
+    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+  if (inConflict) {
+    var err = createError(REV_CONFLICT);
+    results[i] = err;
+    return cb();
+  }
+
+  var newRev = docInfo.metadata.rev;
+  docInfo.metadata.rev_tree = merged.tree;
+  docInfo.stemmedRevs = merged.stemmedRevs || [];
+  /* istanbul ignore else */
+  if (prev.rev_map) {
+    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+  }
+
+  // recalculate
+  var winningRev$$ = winningRev(docInfo.metadata);
+  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$);
+
+  // calculate the total number of documents that were added/removed,
+  // from the perspective of total_rows/doc_count
+  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+  var newRevIsDeleted;
+  if (newRev === winningRev$$) {
+    // if the new rev is the same as the winning rev, we can reuse that value
+    newRevIsDeleted = winningRevIsDeleted;
+  } else {
+    // if they're not the same, then we need to recalculate
+    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+  }
+
+  writeDoc(docInfo, winningRev$$, winningRevIsDeleted, newRevIsDeleted,
+    true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+                     writeDoc, opts, overallCallback) {
+
+  // Default to 1000 locally
+  revLimit = revLimit || 1000;
+
+  function insertDoc(docInfo, resultsIdx, callback) {
+    // Cant insert new deleted documents
+    var winningRev$$ = winningRev(docInfo.metadata);
+    var deleted = isDeleted(docInfo.metadata, winningRev$$);
+    if ('was_delete' in opts && deleted) {
+      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+      return callback();
+    }
+
+    // 4712 - detect whether a new document was inserted with a _rev
+    var inConflict = newEdits && rootIsMissing(docInfo);
+
+    if (inConflict) {
+      var err = createError(REV_CONFLICT);
+      results[resultsIdx] = err;
+      return callback();
+    }
+
+    var delta = deleted ? 0 : 1;
+
+    writeDoc(docInfo, winningRev$$, deleted, deleted, false,
+      delta, resultsIdx, callback);
+  }
+
+  var newEdits = opts.new_edits;
+  var idsToDocs = new pouchdbCollections.Map();
+
+  var docsDone = 0;
+  var docsToDo = docInfos.length;
+
+  function checkAllDocsDone() {
+    if (++docsDone === docsToDo && overallCallback) {
+      overallCallback();
+    }
+  }
+
+  docInfos.forEach(function (currentDoc, resultsIdx) {
+
+    if (currentDoc._id && isLocalId(currentDoc._id)) {
+      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+      api[fun](currentDoc, {ctx: tx}, function (err, res) {
+        results[resultsIdx] = err || res;
+        checkAllDocsDone();
+      });
+      return;
+    }
+
+    var id = currentDoc.metadata.id;
+    if (idsToDocs.has(id)) {
+      docsToDo--; // duplicate
+      idsToDocs.get(id).push([currentDoc, resultsIdx]);
+    } else {
+      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+    }
+  });
+
+  // in the case of new_edits, the user can provide multiple docs
+  // with the same id. these need to be processed sequentially
+  idsToDocs.forEach(function (docs, id) {
+    var numDone = 0;
+
+    function docWritten() {
+      if (++numDone < docs.length) {
+        nextDoc();
+      } else {
+        checkAllDocsDone();
+      }
+    }
+    function nextDoc() {
+      var value = docs[numDone];
+      var currentDoc = value[0];
+      var resultsIdx = value[1];
+
+      if (fetchedDocs.has(id)) {
+        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+          resultsIdx, docWritten, writeDoc, newEdits);
+      } else {
+        // Ensure stemming applies to new writes as well
+        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+        currentDoc.metadata.rev_tree = merged.tree;
+        currentDoc.stemmedRevs = merged.stemmedRevs || [];
+        insertDoc(currentDoc, resultsIdx, docWritten);
+      }
+    }
+    nextDoc();
+  });
+}
+
+/* istanbul ignore next */
+var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+
+function once(fun) {
+  var called = false;
+  return getArguments(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
+    }
+  });
+}
+
+function toPromise(func) {
+  //create the function we will be returning
+  return getArguments(function (args) {
+    // Clone arguments
+    args = clone(args);
+    var self = this;
+    var tempCB =
+      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    // if the last argument is a function, assume its a callback
+    var usedCB;
+    if (tempCB) {
+      // if it was a callback, create a new callback which calls it,
+      // but do so async so we don't trap any errors
+      usedCB = function (err, resp) {
+        process.nextTick(function () {
+          tempCB(err, resp);
+        });
+      };
+    }
+    var promise = new PouchPromise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
+      }
+    });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
+    }
+    return promise;
+  });
+}
+
+var thisAtob = function (str) {
+  return atob(str);
+};
+
+var thisBtoa = function (str) {
+  return btoa(str);
+};
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+  return thisBtoa(raw);
+}
+
+function appendBuffer(buffer, data, start, end) {
+  if (start > 0 || end < data.byteLength) {
+    // only create a subarray if we really need to
+    data = new Uint8Array(data, start,
+      Math.min(end, data.byteLength) - start);
+  }
+  buffer.append(data);
+}
+
+function appendString(buffer, data, start, end) {
+  if (start > 0 || end < data.length) {
+    // only create a substring if we really need to
+    data = data.substring(start, end);
+  }
+  buffer.appendBinary(data);
+}
+
+var md5 = toPromise(function (data, callback) {
+  var inputIsString = typeof data === 'string';
+  var len = inputIsString ? data.length : data.byteLength;
+  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+  var chunks = Math.ceil(len / chunkSize);
+  var currentChunk = 0;
+  var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+  var append = inputIsString ? appendString : appendBuffer;
+
+  function loadNextChunk() {
+    var start = currentChunk * chunkSize;
+    var end = start + chunkSize;
+    currentChunk++;
+    if (currentChunk < chunks) {
+      append(buffer, data, start, end);
+      setImmediateShim(loadNextChunk);
+    } else {
+      append(buffer, data, start, end);
+      var raw = buffer.end(true);
+      var base64 = rawToBase64(raw);
+      callback(null, base64);
+      buffer.destroy();
+    }
+  }
+  loadNextChunk();
+});
+
+// in the browser, LevelAlt doesn't need the
+// pre-2.2.0 LevelDB-specific migrations
+var toSublevel = function (name, db, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var localAndMetaStores = function (db, stores, callback) {
+  process.nextTick(function () {
+    callback();
+  });
+};
+
+var migrate = {
+  toSublevel: toSublevel,
+  localAndMetaStores: localAndMetaStores
+};
+
+// shim for Function.prototype.name,
+// for browsers that don't support it like IE
+
+/* istanbul ignore next */
+function f() {}
+
+var hasName = f.name;
+var res;
+
+// We dont run coverage in IE
+/* istanbul ignore else */
+if (hasName) {
+  res = function (fun) {
+    return fun.name;
+  };
+} else {
+  res = function (fun) {
+    return fun.toString().match(/^\s*function\s*(\S*)\s*\(/)[1];
+  };
+}
+
+var functionName = res;
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+  parts = parts || [];
+  properties = properties || {};
+  try {
+    return new Blob(parts, properties);
+  } catch (e) {
+    if (e.name !== "TypeError") {
+      throw e;
+    }
+    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+                  WebKitBlobBuilder;
+    var builder = new Builder();
+    for (var i = 0; i < parts.length; i += 1) {
+      builder.append(parts[i]);
+    }
+    return builder.getBlob(properties.type);
+  }
+}
+
+function readAsBlobOrBuffer(storedObject, type) {
+  // In the browser, we've stored a binary string. This now comes back as a
+  // browserified Node-style Buffer, but we want a Blob instead.
+  return createBlob([storedObject.toArrayBuffer()], {type: type});
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
+  }
+  return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  if (typeof FileReader === 'undefined') {
+    // fix for Firefox in a web worker
+    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+    return callback(arrayBufferToBinaryString(
+      new FileReaderSync().readAsArrayBuffer(blob)));
+  }
+
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
+    }
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
+  }
+}
+
+// In the browser, we store a binary string
+function prepareAttachmentForStorage(attData, cb) {
+  readAsBinaryString(attData, cb);
+}
+
+function createEmptyBlobOrBuffer(type) {
+  return createBlob([''], {type: type});
+}
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
+  }
+  return buf;
+}
+
+function binStringToBluffer(binString, type) {
+  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+function getCacheFor(transaction, store) {
+  var prefix = store.prefix()[0];
+  var cache = transaction._cache;
+  var subCache = cache.get(prefix);
+  if (!subCache) {
+    subCache = new pouchdbCollections.Map();
+    cache.set(prefix, subCache);
+  }
+  return subCache;
+}
+
+function LevelTransaction() {
+  this._batch = [];
+  this._cache = new pouchdbCollections.Map();
+}
+
+LevelTransaction.prototype.get = function (store, key, callback) {
+  var cache = getCacheFor(this, store);
+  var exists = cache.get(key);
+  if (exists) {
+    return process.nextTick(function () {
+      callback(null, exists);
+    });
+  } else if (exists === null) { // deleted marker
+    /* istanbul ignore next */
+    return process.nextTick(function () {
+      callback({name: 'NotFoundError'});
+    });
+  }
+  store.get(key, function (err, res) {
+    if (err) {
+      /* istanbul ignore else */
+      if (err.name === 'NotFoundError') {
+        cache.set(key, null);
+      }
+      return callback(err);
+    }
+    cache.set(key, res);
+    callback(null, res);
+  });
+};
+
+LevelTransaction.prototype.batch = function (batch) {
+  for (var i = 0, len = batch.length; i < len; i++) {
+    var operation = batch[i];
+
+    var cache = getCacheFor(this, operation.prefix);
+
+    if (operation.type === 'put') {
+      cache.set(operation.key, operation.value);
+    } else {
+      cache.set(operation.key, null);
+    }
+  }
+  this._batch = this._batch.concat(batch);
+};
+
+LevelTransaction.prototype.execute = function (db, callback) {
+
+  var keys = new pouchdbCollections.Set();
+  var uniqBatches = [];
+
+  // remove duplicates; last one wins
+  for (var i = this._batch.length - 1; i >= 0; i--) {
+    var operation = this._batch[i];
+    var lookupKey = operation.prefix.prefix()[0] + '\xff' + operation.key;
+    if (keys.has(lookupKey)) {
+      continue;
+    }
+    keys.add(lookupKey);
+    uniqBatches.push(operation);
+  }
+
+  db.batch(uniqBatches, callback);
+};
+
+var DOC_STORE = 'document-store';
+var BY_SEQ_STORE = 'by-sequence';
+var ATTACHMENT_STORE = 'attach-store';
+var BINARY_STORE = 'attach-binary-store';
+var LOCAL_STORE = 'local-store';
+var META_STORE = 'meta-store';
+
+// leveldb barks if we try to open a db multiple times
+// so we cache opened connections here for initstore()
+var dbStores = new pouchdbCollections.Map();
+
+// store the value of update_seq in the by-sequence store the key name will
+// never conflict, since the keys in the by-sequence store are integers
+var UPDATE_SEQ_KEY = '_local_last_update_seq';
+var DOC_COUNT_KEY = '_local_doc_count';
+var UUID_KEY = '_local_uuid';
+
+var MD5_PREFIX = 'md5-';
+
+var safeJsonEncoding = {
+  encode: safeJsonStringify,
+  decode: safeJsonParse,
+  buffer: false,
+  type: 'cheap-json'
+};
+
+var levelChanges = new Changes();
+
+// require leveldown. provide verbose output on error as it is the default
+// nodejs adapter, which we do not provide for the user
+/* istanbul ignore next */
+var requireLeveldown = function () {
+  try {
+    return _dereq_(4);
+  } catch (err) {
+    /* eslint no-ex-assign: 0*/
+    err = err || 'leveldown import error';
+    if (err.code === 'MODULE_NOT_FOUND') {
+      // handle leveldown not installed case
+      return new Error([
+        'the \'leveldown\' package is not available. install it, or,',
+        'specify another storage backend using the \'db\' option'
+      ].join(' '));
+    } else if (err.message && err.message.match('Module version mismatch')) {
+      // handle common user enviornment error
+      return new Error([
+        err.message,
+        'This generally implies that leveldown was built with a different',
+        'version of node than that which is running now.  You may try',
+        'fully removing and reinstalling PouchDB or leveldown to resolve.'
+      ].join(' '));
+    }
+    // handle general internal nodejs require error
+    return new Error(err.toString() + ': unable to import leveldown');
+  }
+};
+
+// winningRev and deleted are performance-killers, but
+// in newer versions of PouchDB, they are cached on the metadata
+function getWinningRev(metadata) {
+  return 'winningRev' in metadata ?
+    metadata.winningRev : winningRev(metadata);
+}
+
+function getIsDeleted(metadata, winningRev) {
+  return 'deleted' in metadata ?
+    metadata.deleted : isDeleted(metadata, winningRev);
+}
+
+function fetchAttachment(att, stores, opts) {
+  var type = att.content_type;
+  return new PouchPromise(function (resolve, reject) {
+    stores.binaryStore.get(att.digest, function (err, buffer) {
+      var data;
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return reject(err);
+        } else {
+          // empty
+          if (!opts.binary) {
+            data = '';
+          } else {
+            data = binStringToBluffer('', type);
+          }
+        }
+      } else { // non-empty
+        if (opts.binary) {
+          data = readAsBlobOrBuffer(buffer, type);
+        } else {
+          data = buffer.toString('base64');
+        }
+      }
+      delete att.stub;
+      delete att.length;
+      att.data = data;
+      resolve();
+    });
+  });
+}
+
+function fetchAttachments(results, stores, opts) {
+  var atts = [];
+  results.forEach(function (row) {
+    if (!(row.doc && row.doc._attachments)) {
+      return;
+    }
+    var attNames = Object.keys(row.doc._attachments);
+    attNames.forEach(function (attName) {
+      var att = row.doc._attachments[attName];
+      if (!('data' in att)) {
+        atts.push(att);
+      }
+    });
+  });
+
+  return PouchPromise.all(atts.map(function (att) {
+    return fetchAttachment(att, stores, opts);
+  }));
+}
+
+function LevelPouch(opts, callback) {
+  opts = clone(opts);
+  var api = this;
+  var instanceId;
+  var stores = {};
+  var revLimit = opts.revs_limit;
+  var db;
+  var name = opts.name;
+  if (typeof opts.createIfMissing === 'undefined') {
+    opts.createIfMissing = true;
+  }
+
+  var leveldown = opts.db || requireLeveldown();
+  /* istanbul ignore if */
+  if (leveldown instanceof Error) {
+    return callback(leveldown);
+  }
+
+  if (typeof leveldown.destroy !== 'function') {
+    /* istanbul ignore next */
+    leveldown.destroy = function (name, cb) { cb(); };
+  }
+  var dbStore;
+  var leveldownName = functionName(leveldown);
+  if (dbStores.has(leveldownName)) {
+    dbStore = dbStores.get(leveldownName);
+  } else {
+    dbStore = new pouchdbCollections.Map();
+    dbStores.set(leveldownName, dbStore);
+  }
+  if (dbStore.has(name)) {
+    db = dbStore.get(name);
+    afterDBCreated();
+  } else {
+    dbStore.set(name, sublevel(levelup(name, opts, function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        dbStore["delete"](name);
+        return callback(err);
+      }
+      db = dbStore.get(name);
+      db._docCount  = -1;
+      db._queue = new Deque();
+      if (opts.db || opts.noMigrate) {
+        afterDBCreated();
+      } else {
+        migrate.toSublevel(name, db, afterDBCreated);
+      }
+    })));
+  }
+
+  function afterDBCreated() {
+    stores.docStore = db.sublevel(DOC_STORE, {valueEncoding: safeJsonEncoding});
+    stores.bySeqStore = db.sublevel(BY_SEQ_STORE, {valueEncoding: 'json'});
+    stores.attachmentStore =
+      db.sublevel(ATTACHMENT_STORE, {valueEncoding: 'json'});
+    stores.binaryStore = db.sublevel(BINARY_STORE, {valueEncoding: 'binary'});
+    stores.localStore = db.sublevel(LOCAL_STORE, {valueEncoding: 'json'});
+    stores.metaStore = db.sublevel(META_STORE, {valueEncoding: 'json'});
+    migrate.localAndMetaStores(db, stores, function () {
+      stores.metaStore.get(UPDATE_SEQ_KEY, function (err, value) {
+        if (typeof db._updateSeq === 'undefined') {
+          db._updateSeq = value || 0;
+        }
+        stores.metaStore.get(DOC_COUNT_KEY, function (err, value) {
+          db._docCount = !err ? value : 0;
+          stores.metaStore.get(UUID_KEY, function (err, value) {
+            instanceId = !err ? value : uuid();
+            stores.metaStore.put(UUID_KEY, instanceId, function () {
+              process.nextTick(function () {
+                callback(null, api);
+              });
+            });
+          });
+        });
+      });
+    });
+  }
+
+  function countDocs(callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(new Error('database is closed'));
+    }
+    return callback(null, db._docCount); // use cached value
+  }
+
+  api.type = function () {
+    return 'leveldb';
+  };
+
+  api._id = function (callback) {
+    callback(null, instanceId);
+  };
+
+  api._info = function (callback) {
+    var res = {
+      doc_count: db._docCount,
+      update_seq: db._updateSeq,
+      backend_adapter: functionName(leveldown)
+    };
+    return process.nextTick(function () {
+      callback(null, res);
+    });
+  };
+
+  function tryCode(fun, args) {
+    try {
+      fun.apply(null, args);
+    } catch (err) {
+      args[args.length - 1](err);
+    }
+  }
+
+  function executeNext() {
+    var firstTask = db._queue.peekFront();
+
+    if (firstTask.type === 'read') {
+      runReadOperation(firstTask);
+    } else { // write, only do one at a time
+      runWriteOperation(firstTask);
+    }
+  }
+
+  function runReadOperation(firstTask) {
+    // do multiple reads at once simultaneously, because it's safe
+
+    var readTasks = [firstTask];
+    var i = 1;
+    var nextTask = db._queue.get(i);
+    while (typeof nextTask !== 'undefined' && nextTask.type === 'read') {
+      readTasks.push(nextTask);
+      i++;
+      nextTask = db._queue.get(i);
+    }
+
+    var numDone = 0;
+
+    readTasks.forEach(function (readTask) {
+      var args = readTask.args;
+      var callback = args[args.length - 1];
+      args[args.length - 1] = getArguments(function (cbArgs) {
+        callback.apply(null, cbArgs);
+        if (++numDone === readTasks.length) {
+          process.nextTick(function () {
+            // all read tasks have finished
+            readTasks.forEach(function () {
+              db._queue.shift();
+            });
+            if (db._queue.length) {
+              executeNext();
+            }
+          });
+        }
+      });
+      tryCode(readTask.fun, args);
+    });
+  }
+
+  function runWriteOperation(firstTask) {
+    var args = firstTask.args;
+    var callback = args[args.length - 1];
+    args[args.length - 1] = getArguments(function (cbArgs) {
+      callback.apply(null, cbArgs);
+      process.nextTick(function () {
+        db._queue.shift();
+        if (db._queue.length) {
+          executeNext();
+        }
+      });
+    });
+    tryCode(firstTask.fun, args);
+  }
+
+  // all read/write operations to the database are done in a queue,
+  // similar to how websql/idb works. this avoids problems such
+  // as e.g. compaction needing to have a lock on the database while
+  // it updates stuff. in the future we can revisit this.
+  function writeLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'write'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  // same as the writelock, but multiple can run at once
+  function readLock(fun) {
+    return getArguments(function (args) {
+      db._queue.push({
+        fun: fun,
+        args: args,
+        type: 'read'
+      });
+
+      if (db._queue.length === 1) {
+        process.nextTick(executeNext);
+      }
+    });
+  }
+
+  function formatSeq(n) {
+    return ('0000000000000000' + n).slice(-16);
+  }
+
+  function parseSeq(s) {
+    return parseInt(s, 10);
+  }
+
+  api._get = readLock(function (id, opts, callback) {
+    opts = clone(opts);
+
+    stores.docStore.get(id, function (err, metadata) {
+
+      if (err || !metadata) {
+        return callback(createError(MISSING_DOC, 'missing'));
+      }
+
+      var rev = getWinningRev(metadata);
+      var deleted = getIsDeleted(metadata, rev);
+      if (deleted && !opts.rev) {
+        return callback(createError(MISSING_DOC, "deleted"));
+      }
+
+      rev = opts.rev ? opts.rev : rev;
+
+      var seq = metadata.rev_map[rev];
+
+      stores.bySeqStore.get(formatSeq(seq), function (err, doc) {
+        if (!doc) {
+          return callback(createError(MISSING_DOC));
+        }
+        /* istanbul ignore if */
+        if ('_id' in doc && doc._id !== metadata.id) {
+          // this failing implies something very wrong
+          return callback(new Error('wrong doc returned'));
+        }
+        doc._id = metadata.id;
+        if ('_rev' in doc) {
+          /* istanbul ignore if */
+          if (doc._rev !== rev) {
+            // this failing implies something very wrong
+            return callback(new Error('wrong doc returned'));
+          }
+        } else {
+          // we didn't always store this
+          doc._rev = rev;
+        }
+        return callback(null, {doc: doc, metadata: metadata});
+      });
+    });
+  });
+
+  // not technically part of the spec, but if putAttachment has its own
+  // method...
+  api._getAttachment = function (attachment, opts, callback) {
+    var digest = attachment.digest;
+    var type = attachment.content_type;
+
+    stores.binaryStore.get(digest, function (err, attach) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        }
+        // Empty attachment
+        return callback(null, opts.binary ? createEmptyBlobOrBuffer(type) : '');
+      }
+
+      if (opts.binary) {
+        callback(null, readAsBlobOrBuffer(attach, type));
+      } else {
+        callback(null, attach.toString('base64'));
+      }
+    });
+  };
+
+  api._bulkDocs = writeLock(function (req, opts, callback) {
+    var newEdits = opts.new_edits;
+    var results = new Array(req.docs.length);
+    var fetchedDocs = new pouchdbCollections.Map();
+    var stemmedRevs = new pouchdbCollections.Map();
+
+    var txn = new LevelTransaction();
+    var docCountDelta = 0;
+    var newUpdateSeq = db._updateSeq;
+
+    // parse the docs and give each a sequence number
+    var userDocs = req.docs;
+    var docInfos = userDocs.map(function (doc) {
+      if (doc._id && isLocalId(doc._id)) {
+        return doc;
+      }
+      var newDoc = parseDoc(doc, newEdits);
+
+      if (newDoc.metadata && !newDoc.metadata.rev_map) {
+        newDoc.metadata.rev_map = {};
+      }
+
+      return newDoc;
+    });
+    var infoErrors = docInfos.filter(function (doc) {
+      return doc.error;
+    });
+
+    if (infoErrors.length) {
+      return callback(infoErrors[0]);
+    }
+
+    // verify any stub attachments as a precondition test
+
+    function verifyAttachment(digest, callback) {
+      txn.get(stores.attachmentStore, digest, function (levelErr) {
+        if (levelErr) {
+          var err = createError(MISSING_STUB,
+                                'unknown stub attachment with digest ' +
+                                digest);
+          callback(err);
+        } else {
+          callback();
+        }
+      });
+    }
+
+    function verifyAttachments(finish) {
+      var digests = [];
+      userDocs.forEach(function (doc) {
+        if (doc && doc._attachments) {
+          Object.keys(doc._attachments).forEach(function (filename) {
+            var att = doc._attachments[filename];
+            if (att.stub) {
+              digests.push(att.digest);
+            }
+          });
+        }
+      });
+      if (!digests.length) {
+        return finish();
+      }
+      var numDone = 0;
+      var err;
+
+      digests.forEach(function (digest) {
+        verifyAttachment(digest, function (attErr) {
+          if (attErr && !err) {
+            err = attErr;
+          }
+
+          if (++numDone === digests.length) {
+            finish(err);
+          }
+        });
+      });
+    }
+
+    function fetchExistingDocs(finish) {
+      var numDone = 0;
+      var overallErr;
+      function checkDone() {
+        if (++numDone === userDocs.length) {
+          return finish(overallErr);
+        }
+      }
+
+      userDocs.forEach(function (doc) {
+        if (doc._id && isLocalId(doc._id)) {
+          // skip local docs
+          return checkDone();
+        }
+        txn.get(stores.docStore, doc._id, function (err, info) {
+          if (err) {
+            /* istanbul ignore if */
+            if (err.name !== 'NotFoundError') {
+              overallErr = err;
+            }
+          } else {
+            fetchedDocs.set(doc._id, info);
+          }
+          checkDone();
+        });
+      });
+    }
+
+    function compact(revsMap, callback) {
+      var promise = PouchPromise.resolve();
+      revsMap.forEach(function (revs, docId) {
+        // TODO: parallelize, for now need to be sequential to
+        // pass orphaned attachment tests
+        promise = promise.then(function () {
+          return new PouchPromise(function (resolve, reject) {
+            api._doCompactionNoLock(docId, revs, {ctx: txn}, function (err) {
+              /* istanbul ignore if */
+              if (err) {
+                return reject(err);
+              }
+              resolve();
+            });
+          });
+        });
+      });
+
+      promise.then(function () {
+        callback();
+      }, callback);
+    }
+
+    function autoCompact(callback) {
+      var revsMap = new pouchdbCollections.Map();
+      fetchedDocs.forEach(function (metadata, docId) {
+        revsMap.set(docId, compactTree(metadata));
+      });
+      compact(revsMap, callback);
+    }
+
+    function finish() {
+      if (api.auto_compaction) {
+        return autoCompact(complete);
+      } else {
+        compact(stemmedRevs, complete);
+      }
+    }
+
+    function writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
+                      isUpdate, delta, resultsIdx, callback2) {
+      docCountDelta += delta;
+
+      var err = null;
+      var recv = 0;
+
+      docInfo.metadata.winningRev = winningRev;
+      docInfo.metadata.deleted = winningRevIsDeleted;
+
+      docInfo.data._id = docInfo.metadata.id;
+      docInfo.data._rev = docInfo.metadata.rev;
+
+      if (newRevIsDeleted) {
+        docInfo.data._deleted = true;
+      }
+
+      if (docInfo.stemmedRevs.length) {
+        stemmedRevs.set(docInfo.metadata.id, docInfo.stemmedRevs);
+      }
+
+      var attachments = docInfo.data._attachments ?
+        Object.keys(docInfo.data._attachments) :
+        [];
+
+      function attachmentSaved(attachmentErr) {
+        recv++;
+        if (!err) {
+          /* istanbul ignore if */
+          if (attachmentErr) {
+            err = attachmentErr;
+            callback2(err);
+          } else if (recv === attachments.length) {
+            finish();
+          }
+        }
+      }
+
+      function onMD5Load(doc, key, data, attachmentSaved) {
+        return function (result) {
+          saveAttachment(doc, MD5_PREFIX + result, key, data, attachmentSaved);
+        };
+      }
+
+      function doMD5(doc, key, attachmentSaved) {
+        return function (data) {
+          md5(data).then(
+            onMD5Load(doc, key, data, attachmentSaved)
+          );
+        };
+      }
+
+      for (var i = 0; i < attachments.length; i++) {
+        var key = attachments[i];
+        var att = docInfo.data._attachments[key];
+
+        if (att.stub) {
+          // still need to update the refs mapping
+          var id = docInfo.data._id;
+          var rev = docInfo.data._rev;
+          saveAttachmentRefs(id, rev, att.digest, attachmentSaved);
+          continue;
+        }
+        var data;
+        if (typeof att.data === 'string') {
+          // input is assumed to be a base64 string
+          try {
+            data = thisAtob(att.data);
+          } catch (e) {
+            callback(createError(BAD_ARG,
+                     'Attachment is not a valid base64 string'));
+            return;
+          }
+          doMD5(docInfo, key, attachmentSaved)(data);
+        } else {
+          prepareAttachmentForStorage(att.data,
+            doMD5(docInfo, key, attachmentSaved));
+        }
+      }
+
+      function finish() {
+        var seq = docInfo.metadata.rev_map[docInfo.metadata.rev];
+        /* istanbul ignore if */
+        if (seq) {
+          // check that there aren't any existing revisions with the same
+          // revision id, else we shouldn't do anything
+          return callback2(null, docInfo.revsStemmed);
+        }
+        seq = ++newUpdateSeq;
+        docInfo.metadata.rev_map[docInfo.metadata.rev] =
+          docInfo.metadata.seq = seq;
+        var seqKey = formatSeq(seq);
+        var batch = [{
+          key: seqKey,
+          value: docInfo.data,
+          prefix: stores.bySeqStore,
+          type: 'put'
+        }, {
+          key: docInfo.metadata.id,
+          value: docInfo.metadata,
+          prefix: stores.docStore,
+          type: 'put'
+        }];
+        txn.batch(batch);
+        results[resultsIdx] = {
+          ok: true,
+          id: docInfo.metadata.id,
+          rev: winningRev
+        };
+        fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+        callback2(null, docInfo.revsStemmed);
+      }
+
+      if (!attachments.length) {
+        finish();
+      }
+    }
+
+    // attachments are queued per-digest, otherwise the refs could be
+    // overwritten by concurrent writes in the same bulkDocs session
+    var attachmentQueues = {};
+
+    function saveAttachmentRefs(id, rev, digest, callback) {
+
+      function fetchAtt() {
+        return new PouchPromise(function (resolve, reject) {
+          txn.get(stores.attachmentStore, digest, function (err, oldAtt) {
+            /* istanbul ignore if */
+            if (err && err.name !== 'NotFoundError') {
+              return reject(err);
+            }
+            resolve(oldAtt);
+          });
+        });
+      }
+
+      function saveAtt(oldAtt) {
+        var ref = [id, rev].join('@');
+        var newAtt = {};
+
+        if (oldAtt) {
+          if (oldAtt.refs) {
+            // only update references if this attachment already has them
+            // since we cannot migrate old style attachments here without
+            // doing a full db scan for references
+            newAtt.refs = oldAtt.refs;
+            newAtt.refs[ref] = true;
+          }
+        } else {
+          newAtt.refs = {};
+          newAtt.refs[ref] = true;
+        }
+
+        return new PouchPromise(function (resolve) {
+          txn.batch([{
+            type: 'put',
+            prefix: stores.attachmentStore,
+            key: digest,
+            value: newAtt
+          }]);
+          resolve(!oldAtt);
+        });
+      }
+
+      // put attachments in a per-digest queue, to avoid two docs with the same
+      // attachment overwriting each other
+      var queue = attachmentQueues[digest] || PouchPromise.resolve();
+      attachmentQueues[digest] = queue.then(function () {
+        return fetchAtt().then(saveAtt).then(function (isNewAttachment) {
+          callback(null, isNewAttachment);
+        }, callback);
+      });
+    }
+
+    function saveAttachment(docInfo, digest, key, data, callback) {
+      var att = docInfo.data._attachments[key];
+      delete att.data;
+      att.digest = digest;
+      att.length = data.length;
+      var id = docInfo.metadata.id;
+      var rev = docInfo.metadata.rev;
+      att.revpos = parseInt(rev, 10);
+
+      saveAttachmentRefs(id, rev, digest, function (err, isNewAttachment) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        // do not try to store empty attachments
+        if (data.length === 0) {
+          return callback(err);
+        }
+        if (!isNewAttachment) {
+          // small optimization - don't bother writing it again
+          return callback(err);
+        }
+        txn.batch([{
+          type: 'put',
+          prefix: stores.binaryStore,
+          key: digest,
+          value: new Buffer(data, 'binary')
+        }]);
+        callback();
+      });
+    }
+
+    function complete(err) {
+      /* istanbul ignore if */
+      if (err) {
+        return process.nextTick(function () {
+          callback(err);
+        });
+      }
+      txn.batch([
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: UPDATE_SEQ_KEY,
+          value: newUpdateSeq
+        },
+        {
+          prefix: stores.metaStore,
+          type: 'put',
+          key: DOC_COUNT_KEY,
+          value: db._docCount + docCountDelta
+        }
+      ]);
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        db._docCount += docCountDelta;
+        db._updateSeq = newUpdateSeq;
+        levelChanges.notify(name);
+        process.nextTick(function () {
+          callback(null, results);
+        });
+      });
+    }
+
+    if (!docInfos.length) {
+      return callback(null, []);
+    }
+
+    verifyAttachments(function (err) {
+      if (err) {
+        return callback(err);
+      }
+      fetchExistingDocs(function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        processDocs(revLimit, docInfos, api, fetchedDocs, txn, results,
+                    writeDoc, opts, finish);
+      });
+    });
+  });
+  api._allDocs = readLock(function (opts, callback) {
+    opts = clone(opts);
+    countDocs(function (err, docCount) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var readstreamOpts = {};
+      var skip = opts.skip || 0;
+      if (opts.startkey) {
+        readstreamOpts.gte = opts.startkey;
+      }
+      if (opts.endkey) {
+        readstreamOpts.lte = opts.endkey;
+      }
+      if (opts.key) {
+        readstreamOpts.gte = readstreamOpts.lte = opts.key;
+      }
+      if (opts.descending) {
+        readstreamOpts.reverse = true;
+        // switch start and ends
+        var tmp = readstreamOpts.lte;
+        readstreamOpts.lte = readstreamOpts.gte;
+        readstreamOpts.gte = tmp;
+      }
+      var limit;
+      if (typeof opts.limit === 'number') {
+        limit = opts.limit;
+      }
+      if (limit === 0 ||
+          ('start' in readstreamOpts && 'end' in readstreamOpts &&
+          readstreamOpts.start > readstreamOpts.end)) {
+        // should return 0 results when start is greater than end.
+        // normally level would "fix" this for us by reversing the order,
+        // so short-circuit instead
+        return callback(null, {
+          total_rows: docCount,
+          offset: opts.skip,
+          rows: []
+        });
+      }
+      var results = [];
+      var docstream = stores.docStore.readStream(readstreamOpts);
+
+      var throughStream = through2.obj(function (entry, _, next) {
+        var metadata = entry.value;
+        // winningRev and deleted are performance-killers, but
+        // in newer versions of PouchDB, they are cached on the metadata
+        var winningRev = getWinningRev(metadata);
+        var deleted = getIsDeleted(metadata, winningRev);
+        if (!deleted) {
+          if (skip-- > 0) {
+            next();
+            return;
+          } else if (typeof limit === 'number' && limit-- <= 0) {
+            docstream.unpipe();
+            docstream.destroy();
+            next();
+            return;
+          }
+        } else if (opts.deleted !== 'ok') {
+          next();
+          return;
+        }
+        function allDocsInner(data) {
+          var doc = {
+            id: metadata.id,
+            key: metadata.id,
+            value: {
+              rev: winningRev
+            }
+          };
+          if (opts.include_docs) {
+            doc.doc = data;
+            doc.doc._rev = doc.value.rev;
+            if (opts.conflicts) {
+              doc.doc._conflicts = collectConflicts(metadata);
+            }
+            for (var att in doc.doc._attachments) {
+              if (doc.doc._attachments.hasOwnProperty(att)) {
+                doc.doc._attachments[att].stub = true;
+              }
+            }
+          }
+          if (opts.inclusive_end === false && metadata.id === opts.endkey) {
+            return next();
+          } else if (deleted) {
+            if (opts.deleted === 'ok') {
+              doc.value.deleted = true;
+              doc.doc = null;
+            } else {
+              /* istanbul ignore next */
+              return next();
+            }
+          }
+          results.push(doc);
+          next();
+        }
+        if (opts.include_docs) {
+          var seq = metadata.rev_map[winningRev];
+          stores.bySeqStore.get(formatSeq(seq), function (err, data) {
+            allDocsInner(data);
+          });
+        }
+        else {
+          allDocsInner();
+        }
+      }, function (next) {
+        PouchPromise.resolve().then(function () {
+          if (opts.include_docs && opts.attachments) {
+            return fetchAttachments(results, stores, opts);
+          }
+        }).then(function () {
+          callback(null, {
+            total_rows: docCount,
+            offset: opts.skip,
+            rows: results
+          });
+        }, callback);
+        next();
+      }).on('unpipe', function () {
+        throughStream.end();
+      });
+
+      docstream.on('error', callback);
+
+      docstream.pipe(throughStream);
+    });
+  });
+
+  api._changes = function (opts) {
+    opts = clone(opts);
+
+    if (opts.continuous) {
+      var id = name + ':' + uuid();
+      levelChanges.addListener(name, id, api, opts);
+      levelChanges.notify(name);
+      return {
+        cancel: function () {
+          levelChanges.removeListener(name, id);
+        }
+      };
+    }
+
+    var descending = opts.descending;
+    var results = [];
+    var lastSeq = opts.since || 0;
+    var called = 0;
+    var streamOpts = {
+      reverse: descending
+    };
+    var limit;
+    if ('limit' in opts && opts.limit > 0) {
+      limit = opts.limit;
+    }
+    if (!streamOpts.reverse) {
+      streamOpts.start = formatSeq(opts.since || 0);
+    }
+
+    var docIds = opts.doc_ids && new pouchdbCollections.Set(opts.doc_ids);
+    var filter = filterChange(opts);
+    var docIdsToMetadata = new pouchdbCollections.Map();
+
+    var returnDocs;
+    if ('return_docs' in opts) {
+      returnDocs = opts.return_docs;
+    } else if ('returnDocs' in opts) {
+      // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
+      returnDocs = opts.returnDocs;
+    } else {
+      returnDocs = true;
+    }
+
+    function complete() {
+      opts.done = true;
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+      changeStream.unpipe(throughStream);
+      changeStream.destroy();
+      if (!opts.continuous && !opts.cancelled) {
+        if (opts.include_docs && opts.attachments) {
+          fetchAttachments(results, stores, opts).then(function () {
+            opts.complete(null, {results: results, last_seq: lastSeq});
+          });
+        } else {
+          opts.complete(null, {results: results, last_seq: lastSeq});
+        }
+      }
+    }
+    var changeStream = stores.bySeqStore.readStream(streamOpts);
+    var throughStream = through2.obj(function (data, _, next) {
+      if (limit && called >= limit) {
+        complete();
+        return next();
+      }
+      if (opts.cancelled || opts.done) {
+        return next();
+      }
+
+      var seq = parseSeq(data.key);
+      var doc = data.value;
+
+      if (seq === opts.since && !descending) {
+        // couchdb ignores `since` if descending=true
+        return next();
+      }
+
+      if (docIds && !docIds.has(doc._id)) {
+        return next();
+      }
+
+      var metadata;
+
+      function onGetMetadata(metadata) {
+        var winningRev = getWinningRev(metadata);
+
+        function onGetWinningDoc(winningDoc) {
+
+          var change = opts.processChange(winningDoc, metadata, opts);
+          change.seq = metadata.seq;
+
+          var filtered = filter(change);
+          if (typeof filtered === 'object') {
+            return opts.complete(filtered);
+          }
+
+          if (filtered) {
+            called++;
+
+            if (opts.attachments && opts.include_docs) {
+              // fetch attachment immediately for the benefit
+              // of live listeners
+              fetchAttachments([change], stores, opts).then(function () {
+                opts.onChange(change);
+              });
+            } else {
+              opts.onChange(change);
+            }
+
+            if (returnDocs) {
+              results.push(change);
+            }
+          }
+          next();
+        }
+
+        if (metadata.seq !== seq) {
+          // some other seq is later
+          return next();
+        }
+
+        lastSeq = seq;
+
+        if (winningRev === doc._rev) {
+          return onGetWinningDoc(doc);
+        }
+
+        // fetch the winner
+
+        var winningSeq = metadata.rev_map[winningRev];
+
+        stores.bySeqStore.get(formatSeq(winningSeq), function (err, doc) {
+          onGetWinningDoc(doc);
+        });
+      }
+
+      metadata = docIdsToMetadata.get(doc._id);
+      if (metadata) { // cached
+        return onGetMetadata(metadata);
+      }
+      // metadata not cached, have to go fetch it
+      stores.docStore.get(doc._id, function (err, metadata) {
+        /* istanbul ignore if */
+        if (opts.cancelled || opts.done || db.isClosed() ||
+          isLocalId(metadata.id)) {
+          return next();
+        }
+        docIdsToMetadata.set(doc._id, metadata);
+        onGetMetadata(metadata);
+      });
+    }, function (next) {
+      if (opts.cancelled) {
+        return next();
+      }
+      if (returnDocs && opts.limit) {
+        /* istanbul ignore if */
+        if (opts.limit < results.length) {
+          results.length = opts.limit;
+        }
+      }
+
+      next();
+    }).on('unpipe', function () {
+      throughStream.end();
+      complete();
+    });
+    changeStream.pipe(throughStream);
+    return {
+      cancel: function () {
+        opts.cancelled = true;
+        complete();
+      }
+    };
+  };
+
+  api._close = function (callback) {
+    /* istanbul ignore if */
+    if (db.isClosed()) {
+      return callback(createError(NOT_OPEN));
+    }
+    db.close(function (err) {
+      /* istanbul ignore if */
+      if (err) {
+        callback(err);
+      } else {
+        dbStore["delete"](name);
+        callback();
+      }
+    });
+  };
+
+  api._getRevisionTree = function (docId, callback) {
+    stores.docStore.get(docId, function (err, metadata) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, metadata.rev_tree);
+      }
+    });
+  };
+
+  api._doCompaction = writeLock(function (docId, revs, opts, callback) {
+    api._doCompactionNoLock(docId, revs, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._doCompactionNoLock = function (docId, revs, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+
+    if (!revs.length) {
+      return callback();
+    }
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.docStore, docId, function (err, metadata) {
+      /* istanbul ignore if */
+      if (err) {
+        return callback(err);
+      }
+      var seqs = revs.map(function (rev) {
+        var seq = metadata.rev_map[rev];
+        delete metadata.rev_map[rev];
+        return seq;
+      });
+      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                         revHash, ctx, opts) {
+        var rev = pos + '-' + revHash;
+        if (revs.indexOf(rev) !== -1) {
+          opts.status = 'missing';
+        }
+      });
+
+      var batch = [];
+      batch.push({
+        key: metadata.id,
+        value: metadata,
+        type: 'put',
+        prefix: stores.docStore
+      });
+
+      var digestMap = {};
+      var numDone = 0;
+      var overallErr;
+      function checkDone(err) {
+        /* istanbul ignore if */
+        if (err) {
+          overallErr = err;
+        }
+        if (++numDone === revs.length) { // done
+          /* istanbul ignore if */
+          if (overallErr) {
+            return callback(overallErr);
+          }
+          deleteOrphanedAttachments();
+        }
+      }
+
+      function finish(err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        txn.batch(batch);
+        if (opts.ctx) {
+          // don't execute immediately
+          return callback();
+        }
+        txn.execute(db, callback);
+      }
+
+      function deleteOrphanedAttachments() {
+        var possiblyOrphanedAttachments = Object.keys(digestMap);
+        if (!possiblyOrphanedAttachments.length) {
+          return finish();
+        }
+        var numDone = 0;
+        var overallErr;
+        function checkDone(err) {
+          /* istanbul ignore if */
+          if (err) {
+            overallErr = err;
+          }
+          if (++numDone === possiblyOrphanedAttachments.length) {
+            finish(overallErr);
+          }
+        }
+        var refsToDelete = new pouchdbCollections.Map();
+        revs.forEach(function (rev) {
+          refsToDelete.set(docId + '@' + rev, true);
+        });
+        possiblyOrphanedAttachments.forEach(function (digest) {
+          txn.get(stores.attachmentStore, digest, function (err, attData) {
+            /* istanbul ignore if */
+            if (err) {
+              if (err.name === 'NotFoundError') {
+                return checkDone();
+              } else {
+                return checkDone(err);
+              }
+            }
+            var refs = Object.keys(attData.refs || {}).filter(function (ref) {
+              return !refsToDelete.has(ref);
+            });
+            var newRefs = {};
+            refs.forEach(function (ref) {
+              newRefs[ref] = true;
+            });
+            if (refs.length) { // not orphaned
+              batch.push({
+                key: digest,
+                type: 'put',
+                value: {refs: newRefs},
+                prefix: stores.attachmentStore
+              });
+            } else { // orphaned, can safely delete
+              batch = batch.concat([{
+                key: digest,
+                type: 'del',
+                prefix: stores.attachmentStore
+              }, {
+                key: digest,
+                type: 'del',
+                prefix: stores.binaryStore
+              }]);
+            }
+            checkDone();
+          });
+        });
+      }
+
+      seqs.forEach(function (seq) {
+        batch.push({
+          key: formatSeq(seq),
+          type: 'del',
+          prefix: stores.bySeqStore
+        });
+        txn.get(stores.bySeqStore, formatSeq(seq), function (err, doc) {
+          /* istanbul ignore if */
+          if (err) {
+            if (err.name === 'NotFoundError') {
+              return checkDone();
+            } else {
+              return checkDone(err);
+            }
+          }
+          var atts = Object.keys(doc._attachments || {});
+          atts.forEach(function (attName) {
+            var digest = doc._attachments[attName].digest;
+            digestMap[digest] = true;
+          });
+          checkDone();
+        });
+      });
+    });
+  };
+
+  api._getLocal = function (id, callback) {
+    stores.localStore.get(id, function (err, doc) {
+      if (err) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, doc);
+      }
+    });
+  };
+
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._putLocalNoLock(doc, opts, callback);
+    } else {
+      api._putLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._putLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._putLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._putLocalNoLock = function (doc, opts, callback) {
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+
+    var txn = opts.ctx || new LevelTransaction();
+
+    txn.get(stores.localStore, id, function (err, resp) {
+      if (err && oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      if (resp && resp._rev !== oldRev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      doc._rev =
+          oldRev ? '0-' + (parseInt(oldRev.split('-')[1], 10) + 1) : '0-1';
+      var batch = [
+        {
+          type: 'put',
+          prefix: stores.localStore,
+          key: id,
+          value: doc
+        }
+      ];
+
+      txn.batch(batch);
+      var ret = {ok: true, id: doc._id, rev: doc._rev};
+
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    if (opts.ctx) {
+      api._removeLocalNoLock(doc, opts, callback);
+    } else {
+      api._removeLocalWithLock(doc, opts, callback);
+    }
+  };
+
+  api._removeLocalWithLock = writeLock(function (doc, opts, callback) {
+    api._removeLocalNoLock(doc, opts, callback);
+  });
+
+  // the NoLock version is for use by bulkDocs
+  api._removeLocalNoLock = function (doc, opts, callback) {
+    var txn = opts.ctx || new LevelTransaction();
+    txn.get(stores.localStore, doc._id, function (err, resp) {
+      if (err) {
+        /* istanbul ignore if */
+        if (err.name !== 'NotFoundError') {
+          return callback(err);
+        } else {
+          return callback(createError(MISSING_DOC));
+        }
+      }
+      if (resp._rev !== doc._rev) {
+        return callback(createError(REV_CONFLICT));
+      }
+      txn.batch([{
+        prefix: stores.localStore,
+        type: 'del',
+        key: doc._id
+      }]);
+      var ret = {ok: true, id: doc._id, rev: '0-0'};
+      if (opts.ctx) {
+        // don't execute immediately
+        return callback(null, ret);
+      }
+      txn.execute(db, function (err) {
+        /* istanbul ignore if */
+        if (err) {
+          return callback(err);
+        }
+        callback(null, ret);
+      });
+    });
+  };
+
+  // close and delete open leveldb stores
+  api._destroy = function (opts, callback) {
+    var dbStore;
+    var leveldownName = functionName(leveldown);
+    /* istanbul ignore else */
+    if (dbStores.has(leveldownName)) {
+      dbStore = dbStores.get(leveldownName);
+    } else {
+      return callDestroy(name, callback);
+    }
+
+    /* istanbul ignore else */
+    if (dbStore.has(name)) {
+      levelChanges.removeAllListeners(name);
+
+      dbStore.get(name).close(function () {
+        dbStore["delete"](name);
+        callDestroy(name, callback);
+      });
+    } else {
+      callDestroy(name, callback);
+    }
+  };
+  function callDestroy(name, cb) {
+    /* istanbul ignore else */
+    if (typeof leveldown.destroy === 'function') {
+      leveldown.destroy(name, cb);
+    } else {
+      process.nextTick(cb);
+    }
+  }
+}
+
+LevelPouch.valid = function () {
+  // this gets overriden by the *down-based browser adapters
+  return true;
+};
+
+LevelPouch.use_prefix = false;
+
+function altFactory(adapterConfig, downAdapter) {
+
+  function LevelPouchAlt(opts, callback) {
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    LevelPouch.call(this, _opts, callback);
+  }
+
+  // overrides for normal LevelDB behavior on Node
+  LevelPouchAlt.valid = function () {
+    return adapterConfig.valid();
+  };
+  LevelPouchAlt.use_prefix = adapterConfig.use_prefix;
+
+  LevelPouchAlt.destroy = toPromise(function (name, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var _opts = jsExtend.extend({
+      db: downAdapter
+    }, opts);
+
+    return LevelPouch.destroy(name, _opts, callback);
+  });
+  return LevelPouchAlt;
+}
+
+function pluginBase(adapterConfig, downAdapter) {
+  var adapterName = adapterConfig.name;
+  var adapter = altFactory(adapterConfig, downAdapter);
+  // use global PouchDB if it's there (e.g. window.PouchDB)
+  var PDB = (typeof PouchDB !== 'undefined') ? PouchDB : _dereq_("pouchdb");
+  if (!PDB) {
+    console.error(adapterConfig.name + ' adapter plugin error: ' +
+      'Cannot find global "PouchDB" object! ' +
+      'Did you remember to include pouchdb.js?');
+  } else {
+    PDB.adapter(adapterName, adapter, true);
+  }
+}
+
+var adapterConfig = {
+  name: 'memory',
+  valid: function () {
+    return true;
+  },
+  use_prefix: false
+};
+
+pluginBase(adapterConfig, downAdapter);
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(5).Buffer)
+},{"15":15,"19":19,"2":2,"23":23,"26":26,"4":4,"40":40,"44":44,"46":46,"5":5,"53":53,"55":55,"57":57,"72":72,"90":90,"94":94,"pouchdb":"pouchdb"}],2:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+  return function () {
+    var len = arguments.length;
+    if (len) {
+      var args = [];
+      var i = -1;
+      while (++i < len) {
+        args[i] = arguments[i];
+      }
+      return fun.call(this, args);
+    } else {
+      return fun.call(this, []);
+    }
+  };
+}
+},{}],3:[function(_dereq_,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+	'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+	var PLUS   = '+'.charCodeAt(0)
+	var SLASH  = '/'.charCodeAt(0)
+	var NUMBER = '0'.charCodeAt(0)
+	var LOWER  = 'a'.charCodeAt(0)
+	var UPPER  = 'A'.charCodeAt(0)
+	var PLUS_URL_SAFE = '-'.charCodeAt(0)
+	var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+	function decode (elt) {
+		var code = elt.charCodeAt(0)
+		if (code === PLUS ||
+		    code === PLUS_URL_SAFE)
+			return 62 // '+'
+		if (code === SLASH ||
+		    code === SLASH_URL_SAFE)
+			return 63 // '/'
+		if (code < NUMBER)
+			return -1 //no match
+		if (code < NUMBER + 10)
+			return code - NUMBER + 26 + 26
+		if (code < UPPER + 26)
+			return code - UPPER
+		if (code < LOWER + 26)
+			return code - LOWER + 26
+	}
+
+	function b64ToByteArray (b64) {
+		var i, j, l, tmp, placeHolders, arr
+
+		if (b64.length % 4 > 0) {
+			throw new Error('Invalid string. Length must be a multiple of 4')
+		}
+
+		// the number of equal signs (place holders)
+		// if there are two placeholders, than the two characters before it
+		// represent one byte
+		// if there is only one, then the three characters before it represent 2 bytes
+		// this is just a cheap hack to not do indexOf twice
+		var len = b64.length
+		placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+		// base64 is 4/3 + up to two characters of the original data
+		arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+		// if there are placeholders, only get up to the last complete 4 chars
+		l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+		var L = 0
+
+		function push (v) {
+			arr[L++] = v
+		}
+
+		for (i = 0, j = 0; i < l; i += 4, j += 3) {
+			tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+			push((tmp & 0xFF0000) >> 16)
+			push((tmp & 0xFF00) >> 8)
+			push(tmp & 0xFF)
+		}
+
+		if (placeHolders === 2) {
+			tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+			push(tmp & 0xFF)
+		} else if (placeHolders === 1) {
+			tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+			push((tmp >> 8) & 0xFF)
+			push(tmp & 0xFF)
+		}
+
+		return arr
+	}
+
+	function uint8ToBase64 (uint8) {
+		var i,
+			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+			output = "",
+			temp, length
+
+		function encode (num) {
+			return lookup.charAt(num)
+		}
+
+		function tripletToBase64 (num) {
+			return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+		}
+
+		// go through the array every three bytes, we'll deal with trailing stuff later
+		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+			output += tripletToBase64(temp)
+		}
+
+		// pad the end with zeros, but make sure to not forget the extra bytes
+		switch (extraBytes) {
+			case 1:
+				temp = uint8[uint8.length - 1]
+				output += encode(temp >> 2)
+				output += encode((temp << 4) & 0x3F)
+				output += '=='
+				break
+			case 2:
+				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+				output += encode(temp >> 10)
+				output += encode((temp >> 4) & 0x3F)
+				output += encode((temp << 2) & 0x3F)
+				output += '='
+				break
+		}
+
+		return output
+	}
+
+	exports.toByteArray = b64ToByteArray
+	exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],4:[function(_dereq_,module,exports){
+
+},{}],5:[function(_dereq_,module,exports){
+(function (global){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+/* eslint-disable no-proto */
+
+'use strict'
+
+var base64 = _dereq_(3)
+var ieee754 = _dereq_(21)
+var isArray = _dereq_(25)
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ *     on objects.
+ *
+ *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *     incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
+  ? global.TYPED_ARRAY_SUPPORT
+  : typedArraySupport()
+
+function typedArraySupport () {
+  function Bar () {}
+  try {
+    var arr = new Uint8Array(1)
+    arr.foo = function () { return 42 }
+    arr.constructor = Bar
+    return arr.foo() === 42 && // typed array instances can be augmented
+        arr.constructor === Bar && // constructor can be set
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+}
+
+function kMaxLength () {
+  return Buffer.TYPED_ARRAY_SUPPORT
+    ? 0x7fffffff
+    : 0x3fffffff
+}
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (arg) {
+  if (!(this instanceof Buffer)) {
+    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+    if (arguments.length > 1) return new Buffer(arg, arguments[1])
+    return new Buffer(arg)
+  }
+
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    this.length = 0
+    this.parent = undefined
+  }
+
+  // Common case.
+  if (typeof arg === 'number') {
+    return fromNumber(this, arg)
+  }
+
+  // Slightly less common case.
+  if (typeof arg === 'string') {
+    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+  }
+
+  // Unusual.
+  return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < length; i++) {
+      that[i] = 0
+    }
+  }
+  return that
+}
+
+function fromString (that, string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+  // Assumption: byteLength() return value is always < kMaxLength.
+  var length = byteLength(string, encoding) | 0
+  that = allocate(that, length)
+
+  that.write(string, encoding)
+  return that
+}
+
+function fromObject (that, object) {
+  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+  if (isArray(object)) return fromArray(that, object)
+
+  if (object == null) {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (typeof ArrayBuffer !== 'undefined') {
+    if (object.buffer instanceof ArrayBuffer) {
+      return fromTypedArray(that, object)
+    }
+    if (object instanceof ArrayBuffer) {
+      return fromArrayBuffer(that, object)
+    }
+  }
+
+  if (object.length) return fromArrayLike(that, object)
+
+  return fromJsonObject(that, object)
+}
+
+function fromBuffer (that, buffer) {
+  var length = checked(buffer.length) | 0
+  that = allocate(that, length)
+  buffer.copy(that, 0, 0, length)
+  return that
+}
+
+function fromArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  // Truncating the elements is probably not what people expect from typed
+  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+  // of the old Buffer constructor.
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function fromArrayBuffer (that, array) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    array.byteLength
+    that = Buffer._augment(new Uint8Array(array))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that = fromTypedArray(that, new Uint8Array(array))
+  }
+  return that
+}
+
+function fromArrayLike (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject (that, object) {
+  var array
+  var length = 0
+
+  if (object.type === 'Buffer' && isArray(object.data)) {
+    array = object.data
+    length = checked(array.length) | 0
+  }
+  that = allocate(that, length)
+
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+if (Buffer.TYPED_ARRAY_SUPPORT) {
+  Buffer.prototype.__proto__ = Uint8Array.prototype
+  Buffer.__proto__ = Uint8Array
+} else {
+  // pre-set for values that may exist in the future
+  Buffer.prototype.length = undefined
+  Buffer.prototype.parent = undefined
+}
+
+function allocate (that, length) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    that = Buffer._augment(new Uint8Array(length))
+    that.__proto__ = Buffer.prototype
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that.length = length
+    that._isBuffer = true
+  }
+
+  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+  if (fromPool) that.parent = rootParent
+
+  return that
+}
+
+function checked (length) {
+  // Note: cannot use `length < kMaxLength` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= kMaxLength()) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  var i = 0
+  var len = Math.min(x, y)
+  while (i < len) {
+    if (a[i] !== b[i]) break
+
+    ++i
+  }
+
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; i++) {
+      length += list[i].length
+    }
+  }
+
+  var buf = new Buffer(length)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+function byteLength (string, encoding) {
+  if (typeof string !== 'string') string = '' + string
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'binary':
+      // Deprecated
+      case 'raw':
+      case 'raws':
+        return len
+      case 'utf8':
+      case 'utf-8':
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start | 0
+  end = end === undefined || end === Infinity ? this.length : end | 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length | 0
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` is deprecated
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` is deprecated
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset | 0
+    if (isFinite(length)) {
+      length = length | 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  // legacy write(string, encoding, offset, length) - remove in v0.13
+  } else {
+    var swap = encoding
+    encoding = offset
+    offset = length | 0
+    length = swap
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'binary':
+        return binaryWrite(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = (value & 0xff)
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value & 0xff)
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = (value & 0xff)
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; i--) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    // ascending copy from start
+    for (i = 0; i < len; i++) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), targetStart)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function fill (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function _augment (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array set method before overwriting
+  arr._set = arr.set
+
+  // deprecated
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.indexOf = BP.indexOf
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"21":21,"25":25,"3":3}],6:[function(_dereq_,module,exports){
+(function (Buffer){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+  if (Array.isArray) {
+    return Array.isArray(arg);
+  }
+  return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+}).call(this,{"isBuffer":_dereq_(24)})
+},{"24":24}],7:[function(_dereq_,module,exports){
+var util = _dereq_(93)
+  , AbstractIterator = _dereq_(12).AbstractIterator
+
+
+function DeferredIterator (options) {
+  AbstractIterator.call(this, options)
+
+  this._options = options
+  this._iterator = null
+  this._operations = []
+}
+
+util.inherits(DeferredIterator, AbstractIterator)
+
+DeferredIterator.prototype.setDb = function (db) {
+  var it = this._iterator = db.iterator(this._options)
+  this._operations.forEach(function (op) {
+    it[op.method].apply(it, op.args)
+  })
+}
+
+DeferredIterator.prototype._operation = function (method, args) {
+  if (this._iterator)
+    return this._iterator[method].apply(this._iterator, args)
+  this._operations.push({ method: method, args: args })
+}
+
+'next end'.split(' ').forEach(function (m) {
+  DeferredIterator.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+module.exports = DeferredIterator;
+
+},{"12":12,"93":93}],8:[function(_dereq_,module,exports){
+(function (Buffer,process){
+var util              = _dereq_(93)
+  , AbstractLevelDOWN = _dereq_(12).AbstractLevelDOWN
+  , DeferredIterator  = _dereq_(7)
+
+function DeferredLevelDOWN (location) {
+  AbstractLevelDOWN.call(this, typeof location == 'string' ? location : '') // optional location, who cares?
+  this._db         = undefined
+  this._operations = []
+  this._iterators  = []
+}
+
+util.inherits(DeferredLevelDOWN, AbstractLevelDOWN)
+
+// called by LevelUP when we have a real DB to take its place
+DeferredLevelDOWN.prototype.setDb = function (db) {
+  this._db = db
+  this._operations.forEach(function (op) {
+    db[op.method].apply(db, op.args)
+  })
+  this._iterators.forEach(function (it) {
+    it.setDb(db)
+  })
+}
+
+DeferredLevelDOWN.prototype._open = function (options, callback) {
+  return process.nextTick(callback)
+}
+
+// queue a new deferred operation
+DeferredLevelDOWN.prototype._operation = function (method, args) {
+  if (this._db)
+    return this._db[method].apply(this._db, args)
+  this._operations.push({ method: method, args: args })
+}
+
+// deferrables
+'put get del batch approximateSize'.split(' ').forEach(function (m) {
+  DeferredLevelDOWN.prototype['_' + m] = function () {
+    this._operation(m, arguments)
+  }
+})
+
+DeferredLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+DeferredLevelDOWN.prototype._iterator = function (options) {
+  if (this._db)
+    return this._db.iterator.apply(this._db, arguments)
+  var it = new DeferredIterator(options)
+  this._iterators.push(it)
+  return it
+}
+
+module.exports                  = DeferredLevelDOWN
+module.exports.DeferredIterator = DeferredIterator
+
+}).call(this,{"isBuffer":_dereq_(24)},_dereq_(55))
+},{"12":12,"24":24,"55":55,"7":7,"93":93}],9:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err)
+    throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+  if (!this._db._isBuffer(value)) value = String(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  if (!this._db._isBuffer(key)) key = String(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+}).call(this,_dereq_(55))
+},{"55":55}],10:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractIterator (db) {
+  this.db = db
+  this._ended = false
+  this._nexting = false
+}
+
+AbstractIterator.prototype.next = function (callback) {
+  var self = this
+
+  if (typeof callback != 'function')
+    throw new Error('next() requires a callback argument')
+
+  if (self._ended)
+    return callback(new Error('cannot call next() after end()'))
+  if (self._nexting)
+    return callback(new Error('cannot call next() before previous next() has completed'))
+
+  self._nexting = true
+  if (typeof self._next == 'function') {
+    return self._next(function () {
+      self._nexting = false
+      callback.apply(null, arguments)
+    })
+  }
+
+  process.nextTick(function () {
+    self._nexting = false
+    callback()
+  })
+}
+
+AbstractIterator.prototype.end = function (callback) {
+  if (typeof callback != 'function')
+    throw new Error('end() requires a callback argument')
+
+  if (this._ended)
+    return callback(new Error('end() already called on iterator'))
+
+  this._ended = true
+
+  if (typeof this._end == 'function')
+    return this._end(callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractIterator
+
+}).call(this,_dereq_(55))
+},{"55":55}],11:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(14)
+  , AbstractIterator     = _dereq_(10)
+  , AbstractChainedBatch = _dereq_(9)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+  this.status = 'new'
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.createIfMissing = options.createIfMissing != false
+  options.errorIfExists = !!options.errorIfExists
+
+  if (typeof this._open == 'function') {
+    this.status = 'opening'
+    this._open(options, function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'open'
+      callback()
+    })
+  } else {
+    this.status = 'open'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function') {
+    this.status = 'closing'
+    this._close(function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'closed'
+      callback()
+    })
+  } else {
+    this.status = 'closed'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.asBuffer = options.asBuffer != false
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  // coerce value to string in node, don't touch it in browser
+  // (indexeddb can store any JS type)
+  if (value != null && !this._isBuffer(value) && !process.browser)
+    value = String(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key', this._isBuffer))
+    return callback(err)
+
+  if (!this._isBuffer(key))
+    key = String(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof array == 'function')
+    callback = array
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (!options || typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKey(e.type, 'type', this._isBuffer))
+      return callback(err)
+
+    if (err = this._checkKey(e.key, 'key', this._isBuffer))
+      return callback(err)
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  if (!this._isBuffer(start))
+    start = String(start)
+
+  if (!this._isBuffer(end))
+    end = String(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+  options.keys = options.keys != false
+  options.values = options.values != false
+  options.limit = 'limit' in options ? options.limit : -1
+  options.keyAsBuffer = options.keyAsBuffer != false
+  options.valueAsBuffer = options.valueAsBuffer != false
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._checkKey = function (obj, type) {
+
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj)) {
+    if (obj.length === 0)
+      return new Error(type + ' cannot be an empty Buffer')
+  } else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports = AbstractLevelDOWN
+
+}).call(this,{"isBuffer":_dereq_(24)},_dereq_(55))
+},{"10":10,"14":14,"24":24,"55":55,"9":9}],12:[function(_dereq_,module,exports){
+exports.AbstractLevelDOWN    = _dereq_(11)
+exports.AbstractIterator     = _dereq_(10)
+exports.AbstractChainedBatch = _dereq_(9)
+exports.isLevelDOWN          = _dereq_(13)
+
+},{"10":10,"11":11,"13":13,"9":9}],13:[function(_dereq_,module,exports){
+var AbstractLevelDOWN = _dereq_(11)
+
+function isLevelDOWN (db) {
+  if (!db || typeof db !== 'object')
+    return false
+  return Object.keys(AbstractLevelDOWN.prototype).filter(function (name) {
+    // TODO remove approximateSize check when method is gone
+    return name[0] != '_' && name != 'approximateSize'
+  }).every(function (name) {
+    return typeof db[name] == 'function'
+  })
+}
+
+module.exports = isLevelDOWN
+
+},{"11":11}],14:[function(_dereq_,module,exports){
+module.exports = extend
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function extend() {
+    var target = {}
+
+    for (var i = 0; i < arguments.length; i++) {
+        var source = arguments[i]
+
+        for (var key in source) {
+            if (hasOwnProperty.call(source, key)) {
+                target[key] = source[key]
+            }
+        }
+    }
+
+    return target
+}
+
+},{}],15:[function(_dereq_,module,exports){
+/**
+ * Copyright (c) 2013 Petka Antonov
+ * 
+ * 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:</p>
+ * 
+ * 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.
+ */
+"use strict";
+function Deque(capacity) {
+    this._capacity = getCapacity(capacity);
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+    if (isArray(capacity)) {
+        var len = capacity.length;
+        for (var i = 0; i < len; ++i) {
+            this[i] = capacity[i];
+        }
+        this._length = len;
+    }
+}
+
+Deque.prototype.toArray = function Deque$toArray() {
+    var len = this._length;
+    var ret = new Array(len);
+    var front = this._front;
+    var capacity = this._capacity;
+    for (var j = 0; j < len; ++j) {
+        ret[j] = this[(front + j) & (capacity - 1)];
+    }
+    return ret;
+};
+
+Deque.prototype.push = function Deque$push(item) {
+    var argsLength = arguments.length;
+    var length = this._length;
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = 0; i < argsLength; ++i) {
+                this._checkCapacity(length + 1);
+                var j = (this._front + length) & (this._capacity - 1);
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+            }
+            return length;
+        }
+        else {
+            var j = this._front;
+            for (var i = 0; i < argsLength; ++i) {
+                this[(j + length) & (capacity - 1)] = arguments[i];
+                j++;
+            }
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var i = (this._front + length) & (this._capacity - 1);
+    this[i] = item;
+    this._length = length + 1;
+    return length + 1;
+};
+
+Deque.prototype.pop = function Deque$pop() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var i = (this._front + length - 1) & (this._capacity - 1);
+    var ret = this[i];
+    this[i] = void 0;
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.shift = function Deque$shift() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var front = this._front;
+    var ret = this[front];
+    this[front] = void 0;
+    this._front = (front + 1) & (this._capacity - 1);
+    this._length = length - 1;
+    return ret;
+};
+
+Deque.prototype.unshift = function Deque$unshift(item) {
+    var length = this._length;
+    var argsLength = arguments.length;
+
+
+    if (argsLength > 1) {
+        var capacity = this._capacity;
+        if (length + argsLength > capacity) {
+            for (var i = argsLength - 1; i >= 0; i--) {
+                this._checkCapacity(length + 1);
+                var capacity = this._capacity;
+                var j = (((( this._front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                length++;
+                this._length = length;
+                this._front = j;
+            }
+            return length;
+        }
+        else {
+            var front = this._front;
+            for (var i = argsLength - 1; i >= 0; i--) {
+                var j = (((( front - 1 ) &
+                    ( capacity - 1) ) ^ capacity ) - capacity );
+                this[j] = arguments[i];
+                front = j;
+            }
+            this._front = front;
+            this._length = length + argsLength;
+            return length + argsLength;
+        }
+    }
+
+    if (argsLength === 0) return length;
+
+    this._checkCapacity(length + 1);
+    var capacity = this._capacity;
+    var i = (((( this._front - 1 ) &
+        ( capacity - 1) ) ^ capacity ) - capacity );
+    this[i] = item;
+    this._length = length + 1;
+    this._front = i;
+    return length + 1;
+};
+
+Deque.prototype.peekBack = function Deque$peekBack() {
+    var length = this._length;
+    if (length === 0) {
+        return void 0;
+    }
+    var index = (this._front + length - 1) & (this._capacity - 1);
+    return this[index];
+};
+
+Deque.prototype.peekFront = function Deque$peekFront() {
+    if (this._length === 0) {
+        return void 0;
+    }
+    return this[this._front];
+};
+
+Deque.prototype.get = function Deque$get(index) {
+    var i = index;
+    if ((i !== (i | 0))) {
+        return void 0;
+    }
+    var len = this._length;
+    if (i < 0) {
+        i = i + len;
+    }
+    if (i < 0 || i >= len) {
+        return void 0;
+    }
+    return this[(this._front + i) & (this._capacity - 1)];
+};
+
+Deque.prototype.isEmpty = function Deque$isEmpty() {
+    return this._length === 0;
+};
+
+Deque.prototype.clear = function Deque$clear() {
+    this._length = 0;
+    this._front = 0;
+    this._makeCapacity();
+};
+
+Deque.prototype.toString = function Deque$toString() {
+    return this.toArray().toString();
+};
+
+Deque.prototype.valueOf = Deque.prototype.toString;
+Deque.prototype.removeFront = Deque.prototype.shift;
+Deque.prototype.removeBack = Deque.prototype.pop;
+Deque.prototype.insertFront = Deque.prototype.unshift;
+Deque.prototype.insertBack = Deque.prototype.push;
+Deque.prototype.enqueue = Deque.prototype.push;
+Deque.prototype.dequeue = Deque.prototype.shift;
+Deque.prototype.toJSON = Deque.prototype.toArray;
+
+Object.defineProperty(Deque.prototype, "length", {
+    get: function() {
+        return this._length;
+    },
+    set: function() {
+        throw new RangeError("");
+    }
+});
+
+Deque.prototype._makeCapacity = function Deque$_makeCapacity() {
+    var len = this._capacity;
+    for (var i = 0; i < len; ++i) {
+        this[i] = void 0;
+    }
+};
+
+Deque.prototype._checkCapacity = function Deque$_checkCapacity(size) {
+    if (this._capacity < size) {
+        this._resizeTo(getCapacity(this._capacity * 1.5 + 16));
+    }
+};
+
+Deque.prototype._resizeTo = function Deque$_resizeTo(capacity) {
+    var oldFront = this._front;
+    var oldCapacity = this._capacity;
+    var oldDeque = new Array(oldCapacity);
+    var length = this._length;
+
+    arrayCopy(this, 0, oldDeque, 0, oldCapacity);
+    this._capacity = capacity;
+    this._makeCapacity();
+    this._front = 0;
+    if (oldFront + length <= oldCapacity) {
+        arrayCopy(oldDeque, oldFront, this, 0, length);
+    } else {        var lengthBeforeWrapping =
+            length - ((oldFront + length) & (oldCapacity - 1));
+
+        arrayCopy(oldDeque, oldFront, this, 0, lengthBeforeWrapping);
+        arrayCopy(oldDeque, 0, this, lengthBeforeWrapping,
+            length - lengthBeforeWrapping);
+    }
+};
+
+
+var isArray = Array.isArray;
+
+function arrayCopy(src, srcIndex, dst, dstIndex, len) {
+    for (var j = 0; j < len; ++j) {
+        dst[j + dstIndex] = src[j + srcIndex];
+    }
+}
+
+function pow2AtLeast(n) {
+    n = n >>> 0;
+    n = n - 1;
+    n = n | (n >> 1);
+    n = n | (n >> 2);
+    n = n | (n >> 4);
+    n = n | (n >> 8);
+    n = n | (n >> 16);
+    return n + 1;
+}
+
+function getCapacity(capacity) {
+    if (typeof capacity !== "number") {
+        if (isArray(capacity)) {
+            capacity = capacity.length;
+        }
+        else {
+            return 16;
+        }
+    }
+    return pow2AtLeast(
+        Math.min(
+            Math.max(16, capacity), 1073741824)
+    );
+}
+
+module.exports = Deque;
+
+},{}],16:[function(_dereq_,module,exports){
+var prr = _dereq_(18)
+
+function init (type, message, cause) {
+  prr(this, {
+      type    : type
+    , name    : type
+      // can be passed just a 'cause'
+    , cause   : typeof message != 'string' ? message : cause
+    , message : !!message && typeof message != 'string' ? message.message : message
+
+  }, 'ewr')
+}
+
+// generic prototype, not intended to be actually used - helpful for `instanceof`
+function CustomError (message, cause) {
+  Error.call(this)
+  if (Error.captureStackTrace)
+    Error.captureStackTrace(this, arguments.callee)
+  init.call(this, 'CustomError', message, cause)
+}
+
+CustomError.prototype = new Error()
+
+function createError (errno, type, proto) {
+  var err = function (message, cause) {
+    init.call(this, type, message, cause)
+    //TODO: the specificity here is stupid, errno should be available everywhere
+    if (type == 'FilesystemError') {
+      this.code    = this.cause.code
+      this.path    = this.cause.path
+      this.errno   = this.cause.errno
+      this.message =
+        (errno.errno[this.cause.errno]
+          ? errno.errno[this.cause.errno].description
+          : this.cause.message)
+        + (this.cause.path ? ' [' + this.cause.path + ']' : '')
+    }
+    Error.call(this)
+    if (Error.captureStackTrace)
+      Error.captureStackTrace(this, arguments.callee)
+  }
+  err.prototype = !!proto ? new proto() : new CustomError()
+  return err
+}
+
+module.exports = function (errno) {
+  var ce = function (type, proto) {
+    return createError(errno, type, proto)
+  }
+  return {
+      CustomError     : CustomError
+    , FilesystemError : ce('FilesystemError')
+    , createError     : ce
+  }
+}
+
+},{"18":18}],17:[function(_dereq_,module,exports){
+var all = module.exports.all = [
+  {
+    errno: -2,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: -1,
+    code: 'UNKNOWN',
+    description: 'unknown error'
+  },
+  {
+    errno: 0,
+    code: 'OK',
+    description: 'success'
+  },
+  {
+    errno: 1,
+    code: 'EOF',
+    description: 'end of file'
+  },
+  {
+    errno: 2,
+    code: 'EADDRINFO',
+    description: 'getaddrinfo error'
+  },
+  {
+    errno: 3,
+    code: 'EACCES',
+    description: 'permission denied'
+  },
+  {
+    errno: 4,
+    code: 'EAGAIN',
+    description: 'resource temporarily unavailable'
+  },
+  {
+    errno: 5,
+    code: 'EADDRINUSE',
+    description: 'address already in use'
+  },
+  {
+    errno: 6,
+    code: 'EADDRNOTAVAIL',
+    description: 'address not available'
+  },
+  {
+    errno: 7,
+    code: 'EAFNOSUPPORT',
+    description: 'address family not supported'
+  },
+  {
+    errno: 8,
+    code: 'EALREADY',
+    description: 'connection already in progress'
+  },
+  {
+    errno: 9,
+    code: 'EBADF',
+    description: 'bad file descriptor'
+  },
+  {
+    errno: 10,
+    code: 'EBUSY',
+    description: 'resource busy or locked'
+  },
+  {
+    errno: 11,
+    code: 'ECONNABORTED',
+    description: 'software caused connection abort'
+  },
+  {
+    errno: 12,
+    code: 'ECONNREFUSED',
+    description: 'connection refused'
+  },
+  {
+    errno: 13,
+    code: 'ECONNRESET',
+    description: 'connection reset by peer'
+  },
+  {
+    errno: 14,
+    code: 'EDESTADDRREQ',
+    description: 'destination address required'
+  },
+  {
+    errno: 15,
+    code: 'EFAULT',
+    description: 'bad address in system call argument'
+  },
+  {
+    errno: 16,
+    code: 'EHOSTUNREACH',
+    description: 'host is unreachable'
+  },
+  {
+    errno: 17,
+    code: 'EINTR',
+    description: 'interrupted system call'
+  },
+  {
+    errno: 18,
+    code: 'EINVAL',
+    description: 'invalid argument'
+  },
+  {
+    errno: 19,
+    code: 'EISCONN',
+    description: 'socket is already connected'
+  },
+  {
+    errno: 20,
+    code: 'EMFILE',
+    description: 'too many open files'
+  },
+  {
+    errno: 21,
+    code: 'EMSGSIZE',
+    description: 'message too long'
+  },
+  {
+    errno: 22,
+    code: 'ENETDOWN',
+    description: 'network is down'
+  },
+  {
+    errno: 23,
+    code: 'ENETUNREACH',
+    description: 'network is unreachable'
+  },
+  {
+    errno: 24,
+    code: 'ENFILE',
+    description: 'file table overflow'
+  },
+  {
+    errno: 25,
+    code: 'ENOBUFS',
+    description: 'no buffer space available'
+  },
+  {
+    errno: 26,
+    code: 'ENOMEM',
+    description: 'not enough memory'
+  },
+  {
+    errno: 27,
+    code: 'ENOTDIR',
+    description: 'not a directory'
+  },
+  {
+    errno: 28,
+    code: 'EISDIR',
+    description: 'illegal operation on a directory'
+  },
+  {
+    errno: 29,
+    code: 'ENONET',
+    description: 'machine is not on the network'
+  },
+  {
+    errno: 31,
+    code: 'ENOTCONN',
+    description: 'socket is not connected'
+  },
+  {
+    errno: 32,
+    code: 'ENOTSOCK',
+    description: 'socket operation on non-socket'
+  },
+  {
+    errno: 33,
+    code: 'ENOTSUP',
+    description: 'operation not supported on socket'
+  },
+  {
+    errno: 34,
+    code: 'ENOENT',
+    description: 'no such file or directory'
+  },
+  {
+    errno: 35,
+    code: 'ENOSYS',
+    description: 'function not implemented'
+  },
+  {
+    errno: 36,
+    code: 'EPIPE',
+    description: 'broken pipe'
+  },
+  {
+    errno: 37,
+    code: 'EPROTO',
+    description: 'protocol error'
+  },
+  {
+    errno: 38,
+    code: 'EPROTONOSUPPORT',
+    description: 'protocol not supported'
+  },
+  {
+    errno: 39,
+    code: 'EPROTOTYPE',
+    description: 'protocol wrong type for socket'
+  },
+  {
+    errno: 40,
+    code: 'ETIMEDOUT',
+    description: 'connection timed out'
+  },
+  {
+    errno: 41,
+    code: 'ECHARSET',
+    description: 'invalid Unicode character'
+  },
+  {
+    errno: 42,
+    code: 'EAIFAMNOSUPPORT',
+    description: 'address family for hostname not supported'
+  },
+  {
+    errno: 44,
+    code: 'EAISERVICE',
+    description: 'servname not supported for ai_socktype'
+  },
+  {
+    errno: 45,
+    code: 'EAISOCKTYPE',
+    description: 'ai_socktype not supported'
+  },
+  {
+    errno: 46,
+    code: 'ESHUTDOWN',
+    description: 'cannot send after transport endpoint shutdown'
+  },
+  {
+    errno: 47,
+    code: 'EEXIST',
+    description: 'file already exists'
+  },
+  {
+    errno: 48,
+    code: 'ESRCH',
+    description: 'no such process'
+  },
+  {
+    errno: 49,
+    code: 'ENAMETOOLONG',
+    description: 'name too long'
+  },
+  {
+    errno: 50,
+    code: 'EPERM',
+    description: 'operation not permitted'
+  },
+  {
+    errno: 51,
+    code: 'ELOOP',
+    description: 'too many symbolic links encountered'
+  },
+  {
+    errno: 52,
+    code: 'EXDEV',
+    description: 'cross-device link not permitted'
+  },
+  {
+    errno: 53,
+    code: 'ENOTEMPTY',
+    description: 'directory not empty'
+  },
+  {
+    errno: 54,
+    code: 'ENOSPC',
+    description: 'no space left on device'
+  },
+  {
+    errno: 55,
+    code: 'EIO',
+    description: 'i/o error'
+  },
+  {
+    errno: 56,
+    code: 'EROFS',
+    description: 'read-only file system'
+  },
+  {
+    errno: 57,
+    code: 'ENODEV',
+    description: 'no such device'
+  },
+  {
+    errno: 58,
+    code: 'ESPIPE',
+    description: 'invalid seek'
+  },
+  {
+    errno: 59,
+    code: 'ECANCELED',
+    description: 'operation canceled'
+  }
+]
+
+module.exports.errno = {}
+module.exports.code = {}
+
+all.forEach(function (error) {
+  module.exports.errno[error.errno] = error
+  module.exports.code[error.code] = error
+})
+
+module.exports.custom = _dereq_(16)(module.exports)
+module.exports.create = module.exports.custom.createError
+
+},{"16":16}],18:[function(_dereq_,module,exports){
+/*!
+  * prr
+  * (c) 2013 Rod Vagg <rod@vagg.org>
+  * https://github.com/rvagg/prr
+  * License: MIT
+  */
+
+(function (name, context, definition) {
+  if (typeof module != 'undefined' && module.exports)
+    module.exports = definition()
+  else
+    context[name] = definition()
+})('prr', this, function() {
+
+  var setProperty = typeof Object.defineProperty == 'function'
+      ? function (obj, key, options) {
+          Object.defineProperty(obj, key, options)
+          return obj
+        }
+      : function (obj, key, options) { // < es5
+          obj[key] = options.value
+          return obj
+        }
+
+    , makeOptions = function (value, options) {
+        var oo = typeof options == 'object'
+          , os = !oo && typeof options == 'string'
+          , op = function (p) {
+              return oo
+                ? !!options[p]
+                : os
+                  ? options.indexOf(p[0]) > -1
+                  : false
+            }
+
+        return {
+            enumerable   : op('enumerable')
+          , configurable : op('configurable')
+          , writable     : op('writable')
+          , value        : value
+        }
+      }
+
+    , prr = function (obj, key, value, options) {
+        var k
+
+        options = makeOptions(value, options)
+
+        if (typeof key == 'object') {
+          for (k in key) {
+            if (Object.hasOwnProperty.call(key, k)) {
+              options.value = key[k]
+              setProperty(obj, k, options)
+            }
+          }
+          return obj
+        }
+
+        return setProperty(obj, key, options)
+      }
+
+  return prr
+})
+},{}],19:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      }
+      throw TypeError('Uncaught, unspecified "error" event.');
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],20:[function(_dereq_,module,exports){
+"use strict"
+
+module.exports = createRBTree
+
+var RED   = 0
+var BLACK = 1
+
+function RBNode(color, key, value, left, right, count) {
+  this._color = color
+  this.key = key
+  this.value = value
+  this.left = left
+  this.right = right
+  this._count = count
+}
+
+function cloneNode(node) {
+  return new RBNode(node._color, node.key, node.value, node.left, node.right, node._count)
+}
+
+function repaint(color, node) {
+  return new RBNode(color, node.key, node.value, node.left, node.right, node._count)
+}
+
+function recount(node) {
+  node._count = 1 + (node.left ? node.left._count : 0) + (node.right ? node.right._count : 0)
+}
+
+function RedBlackTree(compare, root) {
+  this._compare = compare
+  this.root = root
+}
+
+var proto = RedBlackTree.prototype
+
+Object.defineProperty(proto, "keys", {
+  get: function() {
+    var result = []
+    this.forEach(function(k,v) {
+      result.push(k)
+    })
+    return result
+  }
+})
+
+Object.defineProperty(proto, "values", {
+  get: function() {
+    var result = []
+    this.forEach(function(k,v) {
+      result.push(v)
+    })
+    return result
+  }
+})
+
+//Returns the number of nodes in the tree
+Object.defineProperty(proto, "length", {
+  get: function() {
+    if(this.root) {
+      return this.root._count
+    }
+    return 0
+  }
+})
+
+//Insert a new item into the tree
+proto.insert = function(key, value) {
+  var cmp = this._compare
+  //Find point to insert new node at
+  var n = this.root
+  var n_stack = []
+  var d_stack = []
+  while(n) {
+    var d = cmp(key, n.key)
+    n_stack.push(n)
+    d_stack.push(d)
+    if(d <= 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  //Rebuild path to leaf node
+  n_stack.push(new RBNode(RED, key, value, null, null, 1))
+  for(var s=n_stack.length-2; s>=0; --s) {
+    var n = n_stack[s]
+    if(d_stack[s] <= 0) {
+      n_stack[s] = new RBNode(n._color, n.key, n.value, n_stack[s+1], n.right, n._count+1)
+    } else {
+      n_stack[s] = new RBNode(n._color, n.key, n.value, n.left, n_stack[s+1], n._count+1)
+    }
+  }
+  //Rebalance tree using rotations
+  //console.log("start insert", key, d_stack)
+  for(var s=n_stack.length-1; s>1; --s) {
+    var p = n_stack[s-1]
+    var n = n_stack[s]
+    if(p._color === BLACK || n._color === BLACK) {
+      break
+    }
+    var pp = n_stack[s-2]
+    if(pp.left === p) {
+      if(p.left === n) {
+        var y = pp.right
+        if(y && y._color === RED) {
+          //console.log("LLr")
+          p._color = BLACK
+          pp.right = repaint(BLACK, y)
+          pp._color = RED
+          s -= 1
+        } else {
+          //console.log("LLb")
+          pp._color = RED
+          pp.left = p.right
+          p._color = BLACK
+          p.right = pp
+          n_stack[s-2] = p
+          n_stack[s-1] = n
+          recount(pp)
+          recount(p)
+          if(s >= 3) {
+            var ppp = n_stack[s-3]
+            if(ppp.left === pp) {
+              ppp.left = p
+            } else {
+              ppp.right = p
+            }
+          }
+          break
+        }
+      } else {
+        var y = pp.right
+        if(y && y._color === RED) {
+          //console.log("LRr")
+          p._color = BLACK
+          pp.right = repaint(BLACK, y)
+          pp._color = RED
+          s -= 1
+        } else {
+          //console.log("LRb")
+          p.right = n.left
+          pp._color = RED
+          pp.left = n.right
+          n._color = BLACK
+          n.left = p
+          n.right = pp
+          n_stack[s-2] = n
+          n_stack[s-1] = p
+          recount(pp)
+          recount(p)
+          recount(n)
+          if(s >= 3) {
+            var ppp = n_stack[s-3]
+            if(ppp.left === pp) {
+              ppp.left = n
+            } else {
+              ppp.right = n
+            }
+          }
+          break
+        }
+      }
+    } else {
+      if(p.right === n) {
+        var y = pp.left
+        if(y && y._color === RED) {
+          //console.log("RRr", y.key)
+          p._color = BLACK
+          pp.left = repaint(BLACK, y)
+          pp._color = RED
+          s -= 1
+        } else {
+          //console.log("RRb")
+          pp._color = RED
+          pp.right = p.left
+          p._color = BLACK
+          p.left = pp
+          n_stack[s-2] = p
+          n_stack[s-1] = n
+          recount(pp)
+          recount(p)
+          if(s >= 3) {
+            var ppp = n_stack[s-3]
+            if(ppp.right === pp) {
+              ppp.right = p
+            } else {
+              ppp.left = p
+            }
+          }
+          break
+        }
+      } else {
+        var y = pp.left
+        if(y && y._color === RED) {
+          //console.log("RLr")
+          p._color = BLACK
+          pp.left = repaint(BLACK, y)
+          pp._color = RED
+          s -= 1
+        } else {
+          //console.log("RLb")
+          p.left = n.right
+          pp._color = RED
+          pp.right = n.left
+          n._color = BLACK
+          n.right = p
+          n.left = pp
+          n_stack[s-2] = n
+          n_stack[s-1] = p
+          recount(pp)
+          recount(p)
+          recount(n)
+          if(s >= 3) {
+            var ppp = n_stack[s-3]
+            if(ppp.right === pp) {
+              ppp.right = n
+            } else {
+              ppp.left = n
+            }
+          }
+          break
+        }
+      }
+    }
+  }
+  //Return new tree
+  n_stack[0]._color = BLACK
+  return new RedBlackTree(cmp, n_stack[0])
+}
+
+
+//Visit all nodes inorder
+function doVisitFull(visit, node) {
+  if(node.left) {
+    var v = doVisitFull(visit, node.left)
+    if(v) { return v }
+  }
+  var v = visit(node.key, node.value)
+  if(v) { return v }
+  if(node.right) {
+    return doVisitFull(visit, node.right)
+  }
+}
+
+//Visit half nodes in order
+function doVisitHalf(lo, compare, visit, node) {
+  var l = compare(lo, node.key)
+  if(l <= 0) {
+    if(node.left) {
+      var v = doVisitHalf(lo, compare, visit, node.left)
+      if(v) { return v }
+    }
+    var v = visit(node.key, node.value)
+    if(v) { return v }
+  }
+  if(node.right) {
+    return doVisitHalf(lo, compare, visit, node.right)
+  }
+}
+
+//Visit all nodes within a range
+function doVisit(lo, hi, compare, visit, node) {
+  var l = compare(lo, node.key)
+  var h = compare(hi, node.key)
+  var v
+  if(l <= 0) {
+    if(node.left) {
+      v = doVisit(lo, hi, compare, visit, node.left)
+      if(v) { return v }
+    }
+    if(h > 0) {
+      v = visit(node.key, node.value)
+      if(v) { return v }
+    }
+  }
+  if(h > 0 && node.right) {
+    return doVisit(lo, hi, compare, visit, node.right)
+  }
+}
+
+
+proto.forEach = function rbTreeForEach(visit, lo, hi) {
+  if(!this.root) {
+    return
+  }
+  switch(arguments.length) {
+    case 1:
+      return doVisitFull(visit, this.root)
+    break
+
+    case 2:
+      return doVisitHalf(lo, this._compare, visit, this.root)
+    break
+
+    case 3:
+      if(this._compare(lo, hi) >= 0) {
+        return
+      }
+      return doVisit(lo, hi, this._compare, visit, this.root)
+    break
+  }
+}
+
+//First item in list
+Object.defineProperty(proto, "begin", {
+  get: function() {
+    var stack = []
+    var n = this.root
+    while(n) {
+      stack.push(n)
+      n = n.left
+    }
+    return new RedBlackTreeIterator(this, stack)
+  }
+})
+
+//Last item in list
+Object.defineProperty(proto, "end", {
+  get: function() {
+    var stack = []
+    var n = this.root
+    while(n) {
+      stack.push(n)
+      n = n.right
+    }
+    return new RedBlackTreeIterator(this, stack)
+  }
+})
+
+//Find the ith item in the tree
+proto.at = function(idx) {
+  if(idx < 0) {
+    return new RedBlackTreeIterator(this, [])
+  }
+  var n = this.root
+  var stack = []
+  while(true) {
+    stack.push(n)
+    if(n.left) {
+      if(idx < n.left._count) {
+        n = n.left
+        continue
+      }
+      idx -= n.left._count
+    }
+    if(!idx) {
+      return new RedBlackTreeIterator(this, stack)
+    }
+    idx -= 1
+    if(n.right) {
+      if(idx >= n.right._count) {
+        break
+      }
+      n = n.right
+    } else {
+      break
+    }
+  }
+  return new RedBlackTreeIterator(this, [])
+}
+
+proto.ge = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  var stack = []
+  var last_ptr = 0
+  while(n) {
+    var d = cmp(key, n.key)
+    stack.push(n)
+    if(d <= 0) {
+      last_ptr = stack.length
+    }
+    if(d <= 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  stack.length = last_ptr
+  return new RedBlackTreeIterator(this, stack)
+}
+
+proto.gt = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  var stack = []
+  var last_ptr = 0
+  while(n) {
+    var d = cmp(key, n.key)
+    stack.push(n)
+    if(d < 0) {
+      last_ptr = stack.length
+    }
+    if(d < 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  stack.length = last_ptr
+  return new RedBlackTreeIterator(this, stack)
+}
+
+proto.lt = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  var stack = []
+  var last_ptr = 0
+  while(n) {
+    var d = cmp(key, n.key)
+    stack.push(n)
+    if(d > 0) {
+      last_ptr = stack.length
+    }
+    if(d <= 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  stack.length = last_ptr
+  return new RedBlackTreeIterator(this, stack)
+}
+
+proto.le = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  var stack = []
+  var last_ptr = 0
+  while(n) {
+    var d = cmp(key, n.key)
+    stack.push(n)
+    if(d >= 0) {
+      last_ptr = stack.length
+    }
+    if(d < 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  stack.length = last_ptr
+  return new RedBlackTreeIterator(this, stack)
+}
+
+//Finds the item with key if it exists
+proto.find = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  var stack = []
+  while(n) {
+    var d = cmp(key, n.key)
+    stack.push(n)
+    if(d === 0) {
+      return new RedBlackTreeIterator(this, stack)
+    }
+    if(d <= 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  return new RedBlackTreeIterator(this, [])
+}
+
+//Removes item with key from tree
+proto.remove = function(key) {
+  var iter = this.find(key)
+  if(iter) {
+    return iter.remove()
+  }
+  return this
+}
+
+//Returns the item at `key`
+proto.get = function(key) {
+  var cmp = this._compare
+  var n = this.root
+  while(n) {
+    var d = cmp(key, n.key)
+    if(d === 0) {
+      return n.value
+    }
+    if(d <= 0) {
+      n = n.left
+    } else {
+      n = n.right
+    }
+  }
+  return
+}
+
+//Iterator for red black tree
+function RedBlackTreeIterator(tree, stack) {
+  this.tree = tree
+  this._stack = stack
+}
+
+var iproto = RedBlackTreeIterator.prototype
+
+//Test if iterator is valid
+Object.defineProperty(iproto, "valid", {
+  get: function() {
+    return this._stack.length > 0
+  }
+})
+
+//Node of the iterator
+Object.defineProperty(iproto, "node", {
+  get: function() {
+    if(this._stack.length > 0) {
+      return this._stack[this._stack.length-1]
+    }
+    return null
+  },
+  enumerable: true
+})
+
+//Makes a copy of an iterator
+iproto.clone = function() {
+  return new RedBlackTreeIterator(this.tree, this._stack.slice())
+}
+
+//Swaps two nodes
+function swapNode(n, v) {
+  n.key = v.key
+  n.value = v.value
+  n.left = v.left
+  n.right = v.right
+  n._color = v._color
+  n._count = v._count
+}
+
+//Fix up a double black node in a tree
+function fixDoubleBlack(stack) {
+  var n, p, s, z
+  for(var i=stack.length-1; i>=0; --i) {
+    n = stack[i]
+    if(i === 0) {
+      n._color = BLACK
+      return
+    }
+    //console.log("visit node:", n.key, i, stack[i].key, stack[i-1].key)
+    p = stack[i-1]
+    if(p.left === n) {
+      //console.log("left child")
+      s = p.right
+      if(s.right && s.right._color === RED) {
+        //console.log("case 1: right sibling child red")
+        s = p.right = cloneNode(s)
+        z = s.right = cloneNode(s.right)
+        p.right = s.left
+        s.left = p
+        s.right = z
+        s._color = p._color
+        n._color = BLACK
+        p._color = BLACK
+        z._color = BLACK
+        recount(p)
+        recount(s)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.left === p) {
+            pp.left = s
+          } else {
+            pp.right = s
+          }
+        }
+        stack[i-1] = s
+        return
+      } else if(s.left && s.left._color === RED) {
+        //console.log("case 1: left sibling child red")
+        s = p.right = cloneNode(s)
+        z = s.left = cloneNode(s.left)
+        p.right = z.left
+        s.left = z.right
+        z.left = p
+        z.right = s
+        z._color = p._color
+        p._color = BLACK
+        s._color = BLACK
+        n._color = BLACK
+        recount(p)
+        recount(s)
+        recount(z)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.left === p) {
+            pp.left = z
+          } else {
+            pp.right = z
+          }
+        }
+        stack[i-1] = z
+        return
+      }
+      if(s._color === BLACK) {
+        if(p._color === RED) {
+          //console.log("case 2: black sibling, red parent", p.right.value)
+          p._color = BLACK
+          p.right = repaint(RED, s)
+          return
+        } else {
+          //console.log("case 2: black sibling, black parent", p.right.value)
+          p.right = repaint(RED, s)
+          continue  
+        }
+      } else {
+        //console.log("case 3: red sibling")
+        s = cloneNode(s)
+        p.right = s.left
+        s.left = p
+        s._color = p._color
+        p._color = RED
+        recount(p)
+        recount(s)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.left === p) {
+            pp.left = s
+          } else {
+            pp.right = s
+          }
+        }
+        stack[i-1] = s
+        stack[i] = p
+        if(i+1 < stack.length) {
+          stack[i+1] = n
+        } else {
+          stack.push(n)
+        }
+        i = i+2
+      }
+    } else {
+      //console.log("right child")
+      s = p.left
+      if(s.left && s.left._color === RED) {
+        //console.log("case 1: left sibling child red", p.value, p._color)
+        s = p.left = cloneNode(s)
+        z = s.left = cloneNode(s.left)
+        p.left = s.right
+        s.right = p
+        s.left = z
+        s._color = p._color
+        n._color = BLACK
+        p._color = BLACK
+        z._color = BLACK
+        recount(p)
+        recount(s)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.right === p) {
+            pp.right = s
+          } else {
+            pp.left = s
+          }
+        }
+        stack[i-1] = s
+        return
+      } else if(s.right && s.right._color === RED) {
+        //console.log("case 1: right sibling child red")
+        s = p.left = cloneNode(s)
+        z = s.right = cloneNode(s.right)
+        p.left = z.right
+        s.right = z.left
+        z.right = p
+        z.left = s
+        z._color = p._color
+        p._color = BLACK
+        s._color = BLACK
+        n._color = BLACK
+        recount(p)
+        recount(s)
+        recount(z)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.right === p) {
+            pp.right = z
+          } else {
+            pp.left = z
+          }
+        }
+        stack[i-1] = z
+        return
+      }
+      if(s._color === BLACK) {
+        if(p._color === RED) {
+          //console.log("case 2: black sibling, red parent")
+          p._color = BLACK
+          p.left = repaint(RED, s)
+          return
+        } else {
+          //console.log("case 2: black sibling, black parent")
+          p.left = repaint(RED, s)
+          continue  
+        }
+      } else {
+        //console.log("case 3: red sibling")
+        s = cloneNode(s)
+        p.left = s.right
+        s.right = p
+        s._color = p._color
+        p._color = RED
+        recount(p)
+        recount(s)
+        if(i > 1) {
+          var pp = stack[i-2]
+          if(pp.right === p) {
+            pp.right = s
+          } else {
+            pp.left = s
+          }
+        }
+        stack[i-1] = s
+        stack[i] = p
+        if(i+1 < stack.length) {
+          stack[i+1] = n
+        } else {
+          stack.push(n)
+        }
+        i = i+2
+      }
+    }
+  }
+}
+
+//Removes item at iterator from tree
+iproto.remove = function() {
+  var stack = this._stack
+  if(stack.length === 0) {
+    return this.tree
+  }
+  //First copy path to node
+  var cstack = new Array(stack.length)
+  var n = stack[stack.length-1]
+  cstack[cstack.length-1] = new RBNode(n._color, n.key, n.value, n.left, n.right, n._count)
+  for(var i=stack.length-2; i>=0; --i) {
+    var n = stack[i]
+    if(n.left === stack[i+1]) {
+      cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)
+    } else {
+      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
+    }
+  }
+
+  //Get node
+  n = cstack[cstack.length-1]
+  //console.log("start remove: ", n.value)
+
+  //If not leaf, then swap with previous node
+  if(n.left && n.right) {
+    //console.log("moving to leaf")
+
+    //First walk to previous leaf
+    var split = cstack.length
+    n = n.left
+    while(n.right) {
+      cstack.push(n)
+      n = n.right
+    }
+    //Copy path to leaf
+    var v = cstack[split-1]
+    cstack.push(new RBNode(n._color, v.key, v.value, n.left, n.right, n._count))
+    cstack[split-1].key = n.key
+    cstack[split-1].value = n.value
+
+    //Fix up stack
+    for(var i=cstack.length-2; i>=split; --i) {
+      n = cstack[i]
+      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
+    }
+    cstack[split-1].left = cstack[split]
+  }
+  //console.log("stack=", cstack.map(function(v) { return v.value }))
+
+  //Remove leaf node
+  n = cstack[cstack.length-1]
+  if(n._color === RED) {
+    //Easy case: removing red leaf
+    //console.log("RED leaf")
+    var p = cstack[cstack.length-2]
+    if(p.left === n) {
+      p.left = null
+    } else if(p.right === n) {
+      p.right = null
+    }
+    cstack.pop()
+    for(var i=0; i<cstack.length; ++i) {
+      cstack[i]._count--
+    }
+    return new RedBlackTree(this.tree._compare, cstack[0])
+  } else {
+    if(n.left || n.right) {
+      //Second easy case:  Single child black parent
+      //console.log("BLACK single child")
+      if(n.left) {
+        swapNode(n, n.left)
+      } else if(n.right) {
+        swapNode(n, n.right)
+      }
+      //Child must be red, so repaint it black to balance color
+      n._color = BLACK
+      for(var i=0; i<cstack.length-1; ++i) {
+        cstack[i]._count--
+      }
+      return new RedBlackTree(this.tree._compare, cstack[0])
+    } else if(cstack.length === 1) {
+      //Third easy case: root
+      //console.log("ROOT")
+      return new RedBlackTree(this.tree._compare, null)
+    } else {
+      //Hard case: Repaint n, and then do some nasty stuff
+      //console.log("BLACK leaf no children")
+      for(var i=0; i<cstack.length; ++i) {
+        cstack[i]._count--
+      }
+      var parent = cstack[cstack.length-2]
+      fixDoubleBlack(cstack)
+      //Fix up links
+      if(parent.left === n) {
+        parent.left = null
+      } else {
+        parent.right = null
+      }
+    }
+  }
+  return new RedBlackTree(this.tree._compare, cstack[0])
+}
+
+//Returns key
+Object.defineProperty(iproto, "key", {
+  get: function() {
+    if(this._stack.length > 0) {
+      return this._stack[this._stack.length-1].key
+    }
+    return
+  },
+  enumerable: true
+})
+
+//Returns value
+Object.defineProperty(iproto, "value", {
+  get: function() {
+    if(this._stack.length > 0) {
+      return this._stack[this._stack.length-1].value
+    }
+    return
+  },
+  enumerable: true
+})
+
+
+//Returns the position of this iterator in the sorted list
+Object.defineProperty(iproto, "index", {
+  get: function() {
+    var idx = 0
+    var stack = this._stack
+    if(stack.length === 0) {
+      var r = this.tree.root
+      if(r) {
+        return r._count
+      }
+      return 0
+    } else if(stack[stack.length-1].left) {
+      idx = stack[stack.length-1].left._count
+    }
+    for(var s=stack.length-2; s>=0; --s) {
+      if(stack[s+1] === stack[s].right) {
+        ++idx
+        if(stack[s].left) {
+          idx += stack[s].left._count
+        }
+      }
+    }
+    return idx
+  },
+  enumerable: true
+})
+
+//Advances iterator to next element in list
+iproto.next = function() {
+  var stack = this._stack
+  if(stack.length === 0) {
+    return
+  }
+  var n = stack[stack.length-1]
+  if(n.right) {
+    n = n.right
+    while(n) {
+      stack.push(n)
+      n = n.left
+    }
+  } else {
+    stack.pop()
+    while(stack.length > 0 && stack[stack.length-1].right === n) {
+      n = stack[stack.length-1]
+      stack.pop()
+    }
+  }
+}
+
+//Checks if iterator is at end of tree
+Object.defineProperty(iproto, "hasNext", {
+  get: function() {
+    var stack = this._stack
+    if(stack.length === 0) {
+      return false
+    }
+    if(stack[stack.length-1].right) {
+      return true
+    }
+    for(var s=stack.length-1; s>0; --s) {
+      if(stack[s-1].left === stack[s]) {
+        return true
+      }
+    }
+    return false
+  }
+})
+
+//Update value
+iproto.update = function(value) {
+  var stack = this._stack
+  if(stack.length === 0) {
+    throw new Error("Can't update empty node!")
+  }
+  var cstack = new Array(stack.length)
+  var n = stack[stack.length-1]
+  cstack[cstack.length-1] = new RBNode(n._color, n.key, value, n.left, n.right, n._count)
+  for(var i=stack.length-2; i>=0; --i) {
+    n = stack[i]
+    if(n.left === stack[i+1]) {
+      cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)
+    } else {
+      cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)
+    }
+  }
+  return new RedBlackTree(this.tree._compare, cstack[0])
+}
+
+//Moves iterator backward one element
+iproto.prev = function() {
+  var stack = this._stack
+  if(stack.length === 0) {
+    return
+  }
+  var n = stack[stack.length-1]
+  if(n.left) {
+    n = n.left
+    while(n) {
+      stack.push(n)
+      n = n.right
+    }
+  } else {
+    stack.pop()
+    while(stack.length > 0 && stack[stack.length-1].left === n) {
+      n = stack[stack.length-1]
+      stack.pop()
+    }
+  }
+}
+
+//Checks if iterator is at start of tree
+Object.defineProperty(iproto, "hasPrev", {
+  get: function() {
+    var stack = this._stack
+    if(stack.length === 0) {
+      return false
+    }
+    if(stack[stack.length-1].left) {
+      return true
+    }
+    for(var s=stack.length-1; s>0; --s) {
+      if(stack[s-1].right === stack[s]) {
+        return true
+      }
+    }
+    return false
+  }
+})
+
+//Default comparison function
+function defaultCompare(a, b) {
+  if(a < b) {
+    return -1
+  }
+  if(a > b) {
+    return 1
+  }
+  return 0
+}
+
+//Build a tree
+function createRBTree(compare) {
+  return new RedBlackTree(compare || defaultCompare, null)
+}
+},{}],21:[function(_dereq_,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],22:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
+
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
+
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
+  }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],23:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
+
+},{}],24:[function(_dereq_,module,exports){
+/**
+ * Determine if an object is Buffer
+ *
+ * Author:   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * License:  MIT
+ *
+ * `npm install is-buffer`
+ */
+
+module.exports = function (obj) {
+  return !!(obj != null &&
+    (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
+      (obj.constructor &&
+      typeof obj.constructor.isBuffer === 'function' &&
+      obj.constructor.isBuffer(obj))
+    ))
+}
+
+},{}],25:[function(_dereq_,module,exports){
+var toString = {}.toString;
+
+module.exports = Array.isArray || function (arr) {
+  return toString.call(arr) == '[object Array]';
+};
+
+},{}],26:[function(_dereq_,module,exports){
+(function(factory) {
+  if(typeof exports === 'object') {
+    factory(exports);
+  } else {
+    factory(this);
+  }
+}).call(this, function(root) { 
+
+  var slice   = Array.prototype.slice,
+      each    = Array.prototype.forEach;
+
+  var extend = function(obj) {
+    if(typeof obj !== 'object') throw obj + ' is not an object' ;
+
+    var sources = slice.call(arguments, 1); 
+
+    each.call(sources, function(source) {
+      if(source) {
+        for(var prop in source) {
+          if(typeof source[prop] === 'object' && obj[prop]) {
+            extend.call(obj, obj[prop], source[prop]);
+          } else {
+            obj[prop] = source[prop];
+          }
+        } 
+      }
+    });
+
+    return obj;
+  }
+
+  root.extend = extend;
+});
+
+},{}],27:[function(_dereq_,module,exports){
+var encodings = _dereq_(28);
+
+module.exports = Codec;
+
+function Codec(opts){
+  this.opts = opts || {};
+  this.encodings = encodings;
+}
+
+Codec.prototype._encoding = function(encoding){
+  if (typeof encoding == 'string') encoding = encodings[encoding];
+  if (!encoding) encoding = encodings.id;
+  return encoding;
+};
+
+Codec.prototype._keyEncoding = function(opts, batchOpts){
+  return this._encoding(batchOpts && batchOpts.keyEncoding
+    || opts && opts.keyEncoding
+    || this.opts.keyEncoding);
+};
+
+Codec.prototype._valueEncoding = function(opts, batchOpts){
+  return this._encoding(
+    batchOpts && (batchOpts.valueEncoding || batchOpts.encoding)
+    || opts && (opts.valueEncoding || opts.encoding)
+    || (this.opts.valueEncoding || this.opts.encoding));
+};
+
+Codec.prototype.encodeKey = function(key, opts, batchOpts){
+  return this._keyEncoding(opts, batchOpts).encode(key);
+};
+
+Codec.prototype.encodeValue = function(value, opts, batchOpts){
+  return this._valueEncoding(opts, batchOpts).encode(value);
+};
+
+Codec.prototype.decodeKey = function(key, opts){
+  return this._keyEncoding(opts).decode(key);
+};
+
+Codec.prototype.decodeValue = function(value, opts){
+  return this._valueEncoding(opts).decode(value);
+};
+
+Codec.prototype.encodeBatch = function(ops, opts){
+  var self = this;
+
+  return ops.map(function(_op){
+    var op = {
+      type: _op.type,
+      key: self.encodeKey(_op.key, opts, _op)
+    };
+    if (self.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary';
+    if (_op.prefix) op.prefix = _op.prefix;
+    if ('value' in _op) {
+      op.value = self.encodeValue(_op.value, opts, _op);
+      if (self.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary';
+    }
+    return op;
+  });
+};
+
+var ltgtKeys = ['lt', 'gt', 'lte', 'gte', 'start', 'end'];
+
+Codec.prototype.encodeLtgt = function(ltgt){
+  var self = this;
+  var ret = {};
+  Object.keys(ltgt).forEach(function(key){
+    ret[key] = ltgtKeys.indexOf(key) > -1
+      ? self.encodeKey(ltgt[key], ltgt)
+      : ltgt[key]
+  });
+  return ret;
+};
+
+Codec.prototype.createStreamDecoder = function(opts){
+  var self = this;
+
+  if (opts.keys && opts.values) {
+    return function(key, value){
+      return {
+        key: self.decodeKey(key, opts),
+        value: self.decodeValue(value, opts)
+      };
+    };
+  } else if (opts.keys) {
+    return function(key) {
+      return self.decodeKey(key, opts);
+    }; 
+  } else if (opts.values) {
+    return function(_, value){
+      return self.decodeValue(value, opts);
+    }
+  } else {
+    return function(){};
+  }
+};
+
+Codec.prototype.keyAsBuffer = function(opts){
+  return this._keyEncoding(opts).buffer;
+};
+
+Codec.prototype.valueAsBuffer = function(opts){
+  return this._valueEncoding(opts).buffer;
+};
+
+
+},{"28":28}],28:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.utf8 = exports['utf-8'] = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : String(data);
+  },
+  decode: identity,
+  buffer: false,
+  type: 'utf8'
+};
+
+exports.json = {
+  encode: JSON.stringify,
+  decode: JSON.parse,
+  buffer: false,
+  type: 'json'
+};
+
+exports.binary = {
+  encode: function(data){
+    return isBinary(data)
+      ? data
+      : new Buffer(data);      
+  },
+  decode: identity,
+  buffer: true,
+  type: 'binary'
+};
+
+exports.id = {
+  encode: function(data){
+    return data;
+  },
+  decode: function(data){
+    return data;
+  },
+  buffer: false,
+  type: 'id'
+};
+
+var bufferEncodings = [
+  'hex',
+  'ascii',
+  'base64',
+  'ucs2',
+  'ucs-2',
+  'utf16le',
+  'utf-16le'
+];
+
+bufferEncodings.forEach(function(type){
+  exports[type] = {
+    encode: function(data){
+      return isBinary(data)
+        ? data
+        : new Buffer(data, type);
+    },
+    decode: function(buffer){
+      return buffer.toString(type);
+    },
+    buffer: true,
+    type: type
+  };
+});
+
+function identity(value){
+  return value;
+}
+
+function isBinary(data){
+  return data === undefined
+    || data === null
+    || Buffer.isBuffer(data);
+}
+
+
+}).call(this,_dereq_(5).Buffer)
+},{"5":5}],29:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(17).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+    LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"17":17}],30:[function(_dereq_,module,exports){
+var inherits = _dereq_(23);
+var Readable = _dereq_(37).Readable;
+var extend = _dereq_(38);
+var EncodingError = _dereq_(29).EncodingError;
+
+module.exports = ReadStream;
+inherits(ReadStream, Readable);
+
+function ReadStream(iterator, options){
+  if (!(this instanceof ReadStream)) return new ReadStream(iterator, options);
+  Readable.call(this, extend(options, {
+    objectMode: true
+  }));
+  this._iterator = iterator;
+  this._destroyed = false;
+  this._decoder = null;
+  if (options && options.decoder) this._decoder = options.decoder;
+  this.on('end', this._cleanup.bind(this));
+}
+
+ReadStream.prototype._read = function(){
+  var self = this;
+  if (this._destroyed) return;
+
+  this._iterator.next(function(err, key, value){
+    if (self._destroyed) return;
+    if (err) return self.emit('error', err);
+    if (key === undefined && value === undefined) {
+      self.push(null);
+    } else {
+      if (!self._decoder) return self.push({ key: key, value: value });
+
+      try {
+        var value = self._decoder(key, value);
+      } catch (err) {
+        self.emit('error', new EncodingError(err));
+        self.push(null);
+        return;
+      }
+      self.push(value);
+    }
+  });
+};
+
+ReadStream.prototype.destroy =
+ReadStream.prototype._cleanup = function(){
+  var self = this;
+  if (this._destroyed) return;
+  this._destroyed = true;
+
+  this._iterator.end(function(err){
+    if (err) return self.emit('error', err);
+    self.emit('close');
+  });
+};
+
+
+},{"23":23,"29":29,"37":37,"38":38}],31:[function(_dereq_,module,exports){
+module.exports = Array.isArray || function (arr) {
+  return Object.prototype.toString.call(arr) == '[object Array]';
+};
+
+},{}],32:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) keys.push(key);
+  return keys;
+}
+/*</replacement>*/
+
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var Readable = _dereq_(34);
+var Writable = _dereq_(36);
+
+util.inherits(Duplex, Readable);
+
+forEach(objectKeys(Writable.prototype), function(method) {
+  if (!Duplex.prototype[method])
+    Duplex.prototype[method] = Writable.prototype[method];
+});
+
+function Duplex(options) {
+  if (!(this instanceof Duplex))
+    return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false)
+    this.readable = false;
+
+  if (options && options.writable === false)
+    this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false)
+    this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended)
+    return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  process.nextTick(this.end.bind(this));
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"34":34,"36":36,"55":55,"6":6}],33:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(35);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough))
+    return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function(chunk, encoding, cb) {
+  cb(null, chunk);
+};
+
+},{"23":23,"35":35,"6":6}],34:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(31);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(19).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var StringDecoder;
+
+
+/*<replacement>*/
+var debug = _dereq_(4);
+if (debug && debug.debuglog) {
+  debug = debug.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  var Duplex = _dereq_(32);
+
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  var Duplex = _dereq_(32);
+
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (util.isString(chunk) && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (util.isNullOrUndefined(chunk)) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      if (!addToFront)
+        state.reading = false;
+
+      // if we want the data now, just emit it.
+      if (state.flowing && state.length === 0 && !state.sync) {
+        stream.emit('data', chunk);
+        stream.read(0);
+      } else {
+        // update the buffer info.
+        state.length += state.objectMode ? 1 : chunk.length;
+        if (addToFront)
+          state.buffer.unshift(chunk);
+        else
+          state.buffer.push(chunk);
+
+        if (state.needReadable)
+          emitReadable(stream);
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (isNaN(n) || util.isNull(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (!util.isNumber(n) || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended)
+      endReadable(this);
+    else
+      emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0)
+      endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (util.isNull(ret)) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0)
+    endReadable(this);
+
+  if (!util.isNull(ret))
+    this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync)
+      process.nextTick(function() {
+        emitReadable_(stream);
+      });
+    else
+      emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain &&
+        (!dest._writableState || dest._writableState.needDrain))
+      ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      debug('false write response, pause',
+            src._readableState.awaitDrain);
+      src._readableState.awaitDrain++;
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain)
+      state.awaitDrain--;
+    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        var self = this;
+        process.nextTick(function() {
+          debug('readable nexttick read 0');
+          self.read(0);
+        });
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    if (!state.reading) {
+      debug('resume read 0');
+      this.read(0);
+    }
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    process.nextTick(function() {
+      resume_(stream, state);
+    });
+  }
+}
+
+function resume_(stream, state) {
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading)
+    stream.read(0);
+}
+
+Readable.prototype.pause = function() {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    debug('wrapped data');
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+    if (!chunk || !state.objectMode && !chunk.length)
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(55))
+},{"19":19,"23":23,"31":31,"32":32,"4":4,"5":5,"55":55,"58":58,"6":6,"69":69}],35:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(32);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (!util.isNullOrUndefined(data))
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('prefinish', function() {
+    if (util.isFunction(this._flush))
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"23":23,"32":32,"6":6}],36:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  var Duplex = _dereq_(32);
+
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex)
+    this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(32);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!util.isBuffer(chunk) &&
+      !util.isString(chunk) &&
+      !util.isNullOrUndefined(chunk) &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (!util.isFunction(cb))
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function() {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function() {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing &&
+        !state.corked &&
+        !state.finished &&
+        !state.bufferProcessing &&
+        state.buffer.length)
+      clearBuffer(this, state);
+  }
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      util.isString(chunk)) {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (util.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing || state.corked)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev)
+    stream._writev(chunk, state.onwrite);
+  else
+    stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      state.pendingcb--;
+      cb(er);
+    });
+  else {
+    state.pendingcb--;
+    cb(er);
+  }
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished &&
+        !state.corked &&
+        !state.bufferProcessing &&
+        state.buffer.length) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  if (stream._writev && state.buffer.length > 1) {
+    // Fast case, write everything using _writev()
+    var cbs = [];
+    for (var c = 0; c < state.buffer.length; c++)
+      cbs.push(state.buffer[c].callback);
+
+    // count the one we are adding, as well.
+    // TODO(isaacs) clean this up
+    state.pendingcb++;
+    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
+      for (var i = 0; i < cbs.length; i++) {
+        state.pendingcb--;
+        cbs[i](err);
+      }
+    });
+
+    // Clear buffer
+    state.buffer = [];
+  } else {
+    // Slow case, write chunks one-by-one
+    for (var c = 0; c < state.buffer.length; c++) {
+      var entry = state.buffer[c];
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        c++;
+        break;
+      }
+    }
+
+    if (c < state.buffer.length)
+      state.buffer = state.buffer.slice(c);
+    else
+      state.buffer.length = 0;
+  }
+
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (util.isFunction(chunk)) {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (util.isFunction(encoding)) {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (!util.isNullOrUndefined(chunk))
+    this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else
+      prefinish(stream, state);
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"32":32,"5":5,"55":55,"58":58,"6":6}],37:[function(_dereq_,module,exports){
+(function (process){
+exports = module.exports = _dereq_(34);
+exports.Stream = _dereq_(58);
+exports.Readable = exports;
+exports.Writable = _dereq_(36);
+exports.Duplex = _dereq_(32);
+exports.Transform = _dereq_(35);
+exports.PassThrough = _dereq_(33);
+if (!process.browser && process.env.READABLE_STREAM === 'disable') {
+  module.exports = _dereq_(58);
+}
+
+}).call(this,_dereq_(55))
+},{"32":32,"33":33,"34":34,"35":35,"36":36,"55":55,"58":58}],38:[function(_dereq_,module,exports){
+arguments[4][14][0].apply(exports,arguments)
+},{"14":14}],39:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var util          = _dereq_(41)
+  , WriteError    = _dereq_(29).WriteError
+
+  , getOptions    = util.getOptions
+  , dispatchError = util.dispatchError
+
+function Batch (levelup, codec) {
+  this._levelup = levelup
+  this._codec = codec
+  this.batch = levelup.db.batch()
+  this.ops = []
+  this.length = 0
+}
+
+Batch.prototype.put = function (key_, value_, options) {
+  options = getOptions(options)
+
+  var key   = this._codec.encodeKey(key_, options)
+    , value = this._codec.encodeValue(value_, options)
+
+  try {
+    this.batch.put(key, value)
+  } catch (e) {
+    throw new WriteError(e)
+  }
+  this.ops.push({ type : 'put', key : key, value : value })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.del = function (key_, options) {
+  options = getOptions(options)
+
+  var key = this._codec.encodeKey(key_, options)
+
+  try {
+    this.batch.del(key)
+  } catch (err) {
+    throw new WriteError(err)
+  }
+  this.ops.push({ type : 'del', key : key })
+  this.length++
+
+  return this
+}
+
+Batch.prototype.clear = function () {
+  try {
+    this.batch.clear()
+  } catch (err) {
+    throw new WriteError(err)
+  }
+
+  this.ops = []
+  this.length = 0
+  return this
+}
+
+Batch.prototype.write = function (callback) {
+  var levelup = this._levelup
+    , ops     = this.ops
+
+  try {
+    this.batch.write(function (err) {
+      if (err)
+        return dispatchError(levelup, new WriteError(err), callback)
+      levelup.emit('batch', ops)
+      if (callback)
+        callback()
+    })
+  } catch (err) {
+    throw new WriteError(err)
+  }
+}
+
+module.exports = Batch
+
+},{"29":29,"41":41}],40:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var EventEmitter        = _dereq_(19).EventEmitter
+  , inherits            = _dereq_(93).inherits
+  , deprecate           = _dereq_(93).deprecate
+  , extend              = _dereq_(42)
+  , prr                 = _dereq_(56)
+  , DeferredLevelDOWN   = _dereq_(8)
+  , IteratorStream      = _dereq_(30)
+
+  , errors              = _dereq_(29)
+  , WriteError          = errors.WriteError
+  , ReadError           = errors.ReadError
+  , NotFoundError       = errors.NotFoundError
+  , OpenError           = errors.OpenError
+  , EncodingError       = errors.EncodingError
+  , InitializationError = errors.InitializationError
+
+  , util                = _dereq_(41)
+  , Batch               = _dereq_(39)
+  , Codec               = _dereq_(27)
+
+  , getOptions          = util.getOptions
+  , defaultOptions      = util.defaultOptions
+  , getLevelDOWN        = util.getLevelDOWN
+  , dispatchError       = util.dispatchError
+  , isDefined           = util.isDefined
+
+function getCallback (options, callback) {
+  return typeof options == 'function' ? options : callback
+}
+
+// Possible LevelUP#_status values:
+//  - 'new'     - newly created, not opened or closed
+//  - 'opening' - waiting for the database to be opened, post open()
+//  - 'open'    - successfully opened the database, available for use
+//  - 'closing' - waiting for the database to be closed, post close()
+//  - 'closed'  - database has been successfully closed, should not be
+//                 used except for another open() operation
+
+function LevelUP (location, options, callback) {
+  if (!(this instanceof LevelUP))
+    return new LevelUP(location, options, callback)
+
+  var error
+
+  EventEmitter.call(this)
+  this.setMaxListeners(Infinity)
+
+  if (typeof location == 'function') {
+    options = typeof options == 'object' ? options : {}
+    options.db = location
+    location = null
+  } else if (typeof location == 'object' && typeof location.db == 'function') {
+    options = location
+    location = null
+  }
+
+
+  if (typeof options == 'function') {
+    callback = options
+    options  = {}
+  }
+
+  if ((!options || typeof options.db != 'function') && typeof location != 'string') {
+    error = new InitializationError(
+        'Must provide a location for the database')
+    if (callback) {
+      return process.nextTick(function () {
+        callback(error)
+      })
+    }
+    throw error
+  }
+
+  options      = getOptions(options)
+  this.options = extend(defaultOptions, options)
+  this._codec = new Codec(this.options)
+  this._status = 'new'
+  // set this.location as enumerable but not configurable or writable
+  prr(this, 'location', location, 'e')
+
+  this.open(callback)
+}
+
+inherits(LevelUP, EventEmitter)
+
+LevelUP.prototype.open = function (callback) {
+  var self = this
+    , dbFactory
+    , db
+
+  if (this.isOpen()) {
+    if (callback)
+      process.nextTick(function () { callback(null, self) })
+    return this
+  }
+
+  if (this._isOpening()) {
+    return callback && this.once(
+        'open'
+      , function () { callback(null, self) }
+    )
+  }
+
+  this.emit('opening')
+
+  this._status = 'opening'
+  this.db      = new DeferredLevelDOWN(this.location)
+  dbFactory    = this.options.db || getLevelDOWN()
+  db           = dbFactory(this.location)
+
+  db.open(this.options, function (err) {
+    if (err) {
+      return dispatchError(self, new OpenError(err), callback)
+    } else {
+      self.db.setDb(db)
+      self.db = db
+      self._status = 'open'
+      if (callback)
+        callback(null, self)
+      self.emit('open')
+      self.emit('ready')
+    }
+  })
+}
+
+LevelUP.prototype.close = function (callback) {
+  var self = this
+
+  if (this.isOpen()) {
+    this._status = 'closing'
+    this.db.close(function () {
+      self._status = 'closed'
+      self.emit('closed')
+      if (callback)
+        callback.apply(null, arguments)
+    })
+    this.emit('closing')
+    this.db = new DeferredLevelDOWN(this.location)
+  } else if (this._status == 'closed' && callback) {
+    return process.nextTick(callback)
+  } else if (this._status == 'closing' && callback) {
+    this.once('closed', callback)
+  } else if (this._isOpening()) {
+    this.once('open', function () {
+      self.close(callback)
+    })
+  }
+}
+
+LevelUP.prototype.isOpen = function () {
+  return this._status == 'open'
+}
+
+LevelUP.prototype._isOpening = function () {
+  return this._status == 'opening'
+}
+
+LevelUP.prototype.isClosed = function () {
+  return (/^clos/).test(this._status)
+}
+
+function maybeError(db, options, callback) {
+  if (!db._isOpening() && !db.isOpen()) {
+    dispatchError(
+        db
+      , new ReadError('Database is not open')
+      , callback
+    )
+    return true
+  }
+}
+
+function writeError (db, message, callback) {
+  dispatchError(
+      db
+     , new WriteError(message)
+     , callback
+  )
+}
+
+function readError (db, message, callback) {
+  dispatchError(
+      db
+     , new ReadError(message)
+     , callback
+  )
+}
+
+
+LevelUP.prototype.get = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  if (key_ === null || key_ === undefined || 'function' !== typeof callback)
+    return readError(this
+      , 'get() requires key and callback arguments', callback)
+
+  options = util.getOptions(options)
+  key = this._codec.encodeKey(key_, options)
+
+  options.asBuffer = this._codec.valueAsBuffer(options)
+
+  this.db.get(key, options, function (err, value) {
+    if (err) {
+      if ((/notfound/i).test(err) || err.notFound) {
+        err = new NotFoundError(
+            'Key not found in database [' + key_ + ']', err)
+      } else {
+        err = new ReadError(err)
+      }
+      return dispatchError(self, err, callback)
+    }
+    if (callback) {
+      try {
+        value = self._codec.decodeValue(value, options)
+      } catch (e) {
+        return callback(new EncodingError(e))
+      }
+      callback(null, value)
+    }
+  })
+}
+
+LevelUP.prototype.put = function (key_, value_, options, callback) {
+  var self = this
+    , key
+    , value
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'put() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+  value   = this._codec.encodeValue(value_, options)
+
+  this.db.put(key, value, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('put', key_, value_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.del = function (key_, options, callback) {
+  var self = this
+    , key
+
+  callback = getCallback(options, callback)
+
+  if (key_ === null || key_ === undefined)
+    return writeError(this, 'del() requires a key argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options = getOptions(options)
+  key     = this._codec.encodeKey(key_, options)
+
+  this.db.del(key, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('del', key_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.batch = function (arr_, options, callback) {
+  var self = this
+    , keyEnc
+    , valueEnc
+    , arr
+
+  if (!arguments.length)
+    return new Batch(this, this._codec)
+
+  callback = getCallback(options, callback)
+
+  if (!Array.isArray(arr_))
+    return writeError(this, 'batch() requires an array argument', callback)
+
+  if (maybeError(this, options, callback))
+    return
+
+  options  = getOptions(options)
+  arr      = self._codec.encodeBatch(arr_, options)
+  arr      = arr.map(function (op) {
+    if (!op.type && op.key !== undefined && op.value !== undefined)
+      op.type = 'put'
+    return op
+  })
+
+  this.db.batch(arr, options, function (err) {
+    if (err) {
+      return dispatchError(self, new WriteError(err), callback)
+    } else {
+      self.emit('batch', arr_)
+      if (callback)
+        callback()
+    }
+  })
+}
+
+LevelUP.prototype.approximateSize = deprecate(function (start_, end_, options, callback) {   
+  var self = this    
+    , start    
+    , end    
+   
+  callback = getCallback(options, callback)    
+   
+  options = getOptions(options)    
+   
+  if (start_ === null || start_ === undefined    
+        || end_ === null || end_ === undefined || 'function' !== typeof callback)    
+    return readError(this, 'approximateSize() requires start, end and callback arguments', callback)   
+   
+  start = this._codec.encodeKey(start_, options)   
+  end   = this._codec.encodeKey(end_, options)   
+   
+  this.db.approximateSize(start, end, function (err, size) {   
+    if (err) {   
+      return dispatchError(self, new OpenError(err), callback)   
+    } else if (callback) {   
+      callback(null, size)   
+    }    
+  })   
+}, 'db.approximateSize() is deprecated. Use db.db.approximateSize() instead')
+
+LevelUP.prototype.readStream =
+LevelUP.prototype.createReadStream = function (options) {
+  options = extend( {keys: true, values: true}, this.options, options)
+
+  options.keyEncoding   = options.keyEncoding
+  options.valueEncoding = options.valueEncoding
+
+  options = this._codec.encodeLtgt(options);
+  options.keyAsBuffer   = this._codec.keyAsBuffer(options)
+  options.valueAsBuffer = this._codec.valueAsBuffer(options)
+
+  if ('number' !== typeof options.limit)
+    options.limit = -1
+
+  return new IteratorStream(this.db.iterator(options), extend(options, {
+    decoder: this._codec.createStreamDecoder(options)
+  }))
+}
+
+LevelUP.prototype.keyStream =
+LevelUP.prototype.createKeyStream = function (options) {
+  return this.createReadStream(extend(options, { keys: true, values: false }))
+}
+
+LevelUP.prototype.valueStream =
+LevelUP.prototype.createValueStream = function (options) {
+  return this.createReadStream(extend(options, { keys: false, values: true }))
+}
+
+LevelUP.prototype.toString = function () {
+  return 'LevelUP'
+}
+
+function utilStatic (name) {
+  return function (location, callback) {
+    getLevelDOWN()[name](location, callback || function () {})
+  }
+}
+
+module.exports         = LevelUP
+module.exports.errors  = _dereq_(29)
+module.exports.destroy = deprecate(
+    utilStatic('destroy')
+  , 'levelup.destroy() is deprecated. Use leveldown.destroy() instead'
+)
+module.exports.repair  = deprecate(
+    utilStatic('repair')
+  , 'levelup.repair() is deprecated. Use leveldown.repair() instead'
+)
+
+
+}).call(this,_dereq_(55))
+},{"19":19,"27":27,"29":29,"30":30,"39":39,"41":41,"42":42,"55":55,"56":56,"8":8,"93":93}],41:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2015 LevelUP contributors
+ * See list at <https://github.com/level/levelup#contributing>
+ * MIT License
+ * <https://github.com/level/levelup/blob/master/LICENSE.md>
+ */
+
+var extend         = _dereq_(42)
+  , LevelUPError   = _dereq_(29).LevelUPError
+  , format         = _dereq_(93).format
+  , defaultOptions = {
+        createIfMissing : true
+      , errorIfExists   : false
+      , keyEncoding     : 'utf8'
+      , valueEncoding   : 'utf8'
+      , compression     : true
+    }
+
+  , leveldown
+
+function getOptions (options) {
+  if (typeof options == 'string')
+    options = { valueEncoding: options }
+  if (typeof options != 'object')
+    options = {}
+  return options
+}
+
+function getLevelDOWN () {
+  if (leveldown)
+    return leveldown
+
+  var requiredVersion  = _dereq_(43).devDependencies.leveldown
+    , leveldownVersion
+
+  try {
+    leveldownVersion = _dereq_(4).version
+  } catch (e) {
+    throw requireError(e)
+  }
+
+  if (!_dereq_(4).satisfies(leveldownVersion, requiredVersion)) {
+    throw new LevelUPError(
+        'Installed version of LevelDOWN ('
+      + leveldownVersion
+      + ') does not match required version ('
+      + requiredVersion
+      + ')'
+    )
+  }
+
+  try {
+    return leveldown = _dereq_(4)
+  } catch (e) {
+    throw requireError(e)
+  }
+}
+
+function requireError (e) {
+  var template = 'Failed to require LevelDOWN (%s). Try `npm install leveldown` if it\'s missing'
+  return new LevelUPError(format(template, e.message))
+}
+
+function dispatchError (db, error, callback) {
+  typeof callback == 'function' ? callback(error) : db.emit('error', error)
+}
+
+function isDefined (v) {
+  return typeof v !== 'undefined'
+}
+
+module.exports = {
+    defaultOptions  : defaultOptions
+  , getOptions      : getOptions
+  , getLevelDOWN    : getLevelDOWN
+  , dispatchError   : dispatchError
+  , isDefined       : isDefined
+}
+
+},{"29":29,"4":4,"42":42,"43":43,"93":93}],42:[function(_dereq_,module,exports){
+arguments[4][14][0].apply(exports,arguments)
+},{"14":14}],43:[function(_dereq_,module,exports){
+module.exports={
+  "_args": [
+    [
+      "levelup@1.3.1",
+      "/Users/nolan/workspace/pouchdb"
+    ]
+  ],
+  "_from": "levelup@1.3.1",
+  "_id": "levelup@1.3.1",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/levelup",
+  "_nodeVersion": "4.2.2",
+  "_npmUser": {
+    "email": "ralphtheninja@riseup.net",
+    "name": "ralphtheninja"
+  },
+  "_npmVersion": "3.5.0",
+  "_phantomChildren": {},
+  "_requested": {
+    "name": "levelup",
+    "raw": "levelup@1.3.1",
+    "rawSpec": "1.3.1",
+    "scope": null,
+    "spec": "1.3.1",
+    "type": "version"
+  },
+  "_requiredBy": [
+    "/",
+    "/pouchdb"
+  ],
+  "_resolved": "http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",
+  "_shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+  "_shrinkwrap": null,
+  "_spec": "levelup@1.3.1",
+  "_where": "/Users/nolan/workspace/pouchdb",
+  "browser": {
+    "leveldown": false,
+    "leveldown/package": false,
+    "semver": false
+  },
+  "bugs": {
+    "url": "https://github.com/level/levelup/issues"
+  },
+  "contributors": [
+    {
+      "email": "r@va.gg",
+      "name": "Rod Vagg",
+      "url": "https://github.com/rvagg"
+    },
+    {
+      "email": "john@chesl.es",
+      "name": "John Chesley",
+      "url": "https://github.com/chesles/"
+    },
+    {
+      "email": "raynos2@gmail.com",
+      "name": "Jake Verbaten",
+      "url": "https://github.com/raynos"
+    },
+    {
+      "email": "dominic.tarr@gmail.com",
+      "name": "Dominic Tarr",
+      "url": "https://github.com/dominictarr"
+    },
+    {
+      "email": "max@maxogden.com",
+      "name": "Max Ogden",
+      "url": "https://github.com/maxogden"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "Lars-Magnus Skog",
+      "url": "https://github.com/ralphtheninja"
+    },
+    {
+      "email": "david.bjorklund@gmail.com",
+      "name": "David Björklund",
+      "url": "https://github.com/kesla"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "Julian Gruber",
+      "url": "https://github.com/juliangruber"
+    },
+    {
+      "email": "paolo@async.ly",
+      "name": "Paolo Fragomeni",
+      "url": "https://github.com/hij1nx"
+    },
+    {
+      "email": "anton.whalley@nearform.com",
+      "name": "Anton Whalley",
+      "url": "https://github.com/No9"
+    },
+    {
+      "email": "matteo.collina@gmail.com",
+      "name": "Matteo Collina",
+      "url": "https://github.com/mcollina"
+    },
+    {
+      "email": "pedro.teixeira@gmail.com",
+      "name": "Pedro Teixeira",
+      "url": "https://github.com/pgte"
+    },
+    {
+      "email": "mail@substack.net",
+      "name": "James Halliday",
+      "url": "https://github.com/substack"
+    },
+    {
+      "email": "jcrugzz@gmail.com",
+      "name": "Jarrett Cruger",
+      "url": "https://github.com/jcrugzz"
+    }
+  ],
+  "dependencies": {
+    "deferred-leveldown": "~1.2.1",
+    "level-codec": "~6.1.0",
+    "level-errors": "~1.0.3",
+    "level-iterator-stream": "~1.3.0",
+    "prr": "~1.0.1",
+    "semver": "~5.1.0",
+    "xtend": "~4.0.0"
+  },
+  "description": "Fast & simple storage - a Node.js-style LevelDB wrapper",
+  "devDependencies": {
+    "async": "~1.5.0",
+    "bustermove": "~1.0.0",
+    "delayed": "~1.0.1",
+    "faucet": "~0.0.1",
+    "leveldown": "^1.1.0",
+    "memdown": "~1.1.0",
+    "msgpack-js": "~0.3.0",
+    "referee": "~1.2.0",
+    "rimraf": "~2.4.3",
+    "slow-stream": "0.0.4",
+    "tap": "~2.3.1",
+    "tape": "~4.2.1"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "8030758bb1b1dafdb71bfb55fff0caa2740cb846",
+    "tarball": "https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"
+  },
+  "gitHead": "40bd66872974140c79a74d9411b992ddffa926a4",
+  "homepage": "https://github.com/level/levelup",
+  "keywords": [
+    "leveldb",
+    "stream",
+    "database",
+    "db",
+    "store",
+    "storage",
+    "json"
+  ],
+  "license": "MIT",
+  "main": "lib/levelup.js",
+  "maintainers": [
+    {
+      "email": "rod@vagg.org",
+      "name": "rvagg"
+    },
+    {
+      "email": "ralphtheninja@riseup.net",
+      "name": "ralphtheninja"
+    },
+    {
+      "email": "julian@juliangruber.com",
+      "name": "juliangruber"
+    }
+  ],
+  "name": "levelup",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/level/levelup.git"
+  },
+  "scripts": {
+    "test": "tape test/*-test.js | faucet"
+  },
+  "version": "1.3.1"
+}
+
+},{}],44:[function(_dereq_,module,exports){
+'use strict';
+var immediate = _dereq_(22);
+
+/* istanbul ignore next */
+function INTERNAL() {}
+
+var handlers = {};
+
+var REJECTED = ['REJECTED'];
+var FULFILLED = ['FULFILLED'];
+var PENDING = ['PENDING'];
+
+module.exports = exports = Promise;
+
+function Promise(resolver) {
+  if (typeof resolver !== 'function') {
+    throw new TypeError('resolver must be a function');
+  }
+  this.state = PENDING;
+  this.queue = [];
+  this.outcome = void 0;
+  if (resolver !== INTERNAL) {
+    safelyResolveThenable(this, resolver);
+  }
+}
+
+Promise.prototype["catch"] = function (onRejected) {
+  return this.then(null, onRejected);
+};
+Promise.prototype.then = function (onFulfilled, onRejected) {
+  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
+    typeof onRejected !== 'function' && this.state === REJECTED) {
+    return this;
+  }
+  var promise = new this.constructor(INTERNAL);
+  if (this.state !== PENDING) {
+    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
+    unwrap(promise, resolver, this.outcome);
+  } else {
+    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
+  }
+
+  return promise;
+};
+function QueueItem(promise, onFulfilled, onRejected) {
+  this.promise = promise;
+  if (typeof onFulfilled === 'function') {
+    this.onFulfilled = onFulfilled;
+    this.callFulfilled = this.otherCallFulfilled;
+  }
+  if (typeof onRejected === 'function') {
+    this.onRejected = onRejected;
+    this.callRejected = this.otherCallRejected;
+  }
+}
+QueueItem.prototype.callFulfilled = function (value) {
+  handlers.resolve(this.promise, value);
+};
+QueueItem.prototype.otherCallFulfilled = function (value) {
+  unwrap(this.promise, this.onFulfilled, value);
+};
+QueueItem.prototype.callRejected = function (value) {
+  handlers.reject(this.promise, value);
+};
+QueueItem.prototype.otherCallRejected = function (value) {
+  unwrap(this.promise, this.onRejected, value);
+};
+
+function unwrap(promise, func, value) {
+  immediate(function () {
+    var returnValue;
+    try {
+      returnValue = func(value);
+    } catch (e) {
+      return handlers.reject(promise, e);
+    }
+    if (returnValue === promise) {
+      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
+    } else {
+      handlers.resolve(promise, returnValue);
+    }
+  });
+}
+
+handlers.resolve = function (self, value) {
+  var result = tryCatch(getThen, value);
+  if (result.status === 'error') {
+    return handlers.reject(self, result.value);
+  }
+  var thenable = result.value;
+
+  if (thenable) {
+    safelyResolveThenable(self, thenable);
+  } else {
+    self.state = FULFILLED;
+    self.outcome = value;
+    var i = -1;
+    var len = self.queue.length;
+    while (++i < len) {
+      self.queue[i].callFulfilled(value);
+    }
+  }
+  return self;
+};
+handlers.reject = function (self, error) {
+  self.state = REJECTED;
+  self.outcome = error;
+  var i = -1;
+  var len = self.queue.length;
+  while (++i < len) {
+    self.queue[i].callRejected(error);
+  }
+  return self;
+};
+
+function getThen(obj) {
+  // Make sure we only access the accessor once as required by the spec
+  var then = obj && obj.then;
+  if (obj && typeof obj === 'object' && typeof then === 'function') {
+    return function appyThen() {
+      then.apply(obj, arguments);
+    };
+  }
+}
+
+function safelyResolveThenable(self, thenable) {
+  // Either fulfill, reject or reject with error
+  var called = false;
+  function onError(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.reject(self, value);
+  }
+
+  function onSuccess(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.resolve(self, value);
+  }
+
+  function tryToUnwrap() {
+    thenable(onSuccess, onError);
+  }
+
+  var result = tryCatch(tryToUnwrap);
+  if (result.status === 'error') {
+    onError(result.value);
+  }
+}
+
+function tryCatch(func, value) {
+  var out = {};
+  try {
+    out.value = func(value);
+    out.status = 'success';
+  } catch (e) {
+    out.status = 'error';
+    out.value = e;
+  }
+  return out;
+}
+
+exports.resolve = resolve;
+function resolve(value) {
+  if (value instanceof this) {
+    return value;
+  }
+  return handlers.resolve(new this(INTERNAL), value);
+}
+
+exports.reject = reject;
+function reject(reason) {
+  var promise = new this(INTERNAL);
+  return handlers.reject(promise, reason);
+}
+
+exports.all = all;
+function all(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var values = new Array(len);
+  var resolved = 0;
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    allResolver(iterable[i], i);
+  }
+  return promise;
+  function allResolver(value, i) {
+    self.resolve(value).then(resolveFromAll, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+    function resolveFromAll(outValue) {
+      values[i] = outValue;
+      if (++resolved === len && !called) {
+        called = true;
+        handlers.resolve(promise, values);
+      }
+    }
+  }
+}
+
+exports.race = race;
+function race(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    resolver(iterable[i]);
+  }
+  return promise;
+  function resolver(value) {
+    self.resolve(value).then(function (response) {
+      if (!called) {
+        called = true;
+        handlers.resolve(promise, response);
+      }
+    }, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+  }
+}
+
+},{"22":22}],45:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.compare = function (a, b) {
+
+  if(Buffer.isBuffer(a)) {
+    var l = Math.min(a.length, b.length)
+    for(var i = 0; i < l; i++) {
+      var cmp = a[i] - b[i]
+      if(cmp) return cmp
+    }
+    return a.length - b.length
+  }
+
+  return a < b ? -1 : a > b ? 1 : 0
+}
+
+function has(obj, key) {
+  return Object.hasOwnProperty.call(obj, key)
+}
+
+// to be compatible with the current abstract-leveldown tests
+// nullish or empty strings.
+// I could use !!val but I want to permit numbers and booleans,
+// if possible.
+
+function isDef (val) {
+  return val != null && val !== ''
+}
+
+var lowerBound = exports.lowerBound = function (range) {
+  return (
+      isDef(range.gt)                      ? range.gt
+    : isDef(range.gte)                     ? range.gte
+    : isDef(range.min)                     ? range.min
+    : isDef(range.start) && !range.reverse ? range.start
+    : isDef(range.end) && range.reverse    ? range.end
+    :                                        undefined
+  )
+}
+
+exports.lowerBoundInclusive = function (range) {
+  return isDef(range.gt) ? false : true
+}
+
+exports.upperBoundInclusive =
+  function (range) {
+    return isDef(range.lt) ? false : true
+  }
+
+var lowerBoundExclusive = exports.lowerBoundExclusive =
+  function (range) {
+    return isDef(range.gt) ? true : false
+  }
+
+var upperBoundExclusive = exports.upperBoundExclusive =
+  function (range) {
+    return isDef(range.lt) ? true : false
+  }
+
+var upperBound = exports.upperBound = function (range) {
+  return (
+      isDef(range.lt)                     ? range.lt
+    : isDef(range.lte)                    ? range.lte
+    : isDef(range.max)                    ? range.max
+    : isDef(range.start) && range.reverse ? range.start
+    : isDef(range.end) && !range.reverse  ? range.end
+    :                                       undefined
+  )
+}
+
+
+exports.contains = function (range, key, compare) {
+  compare = compare || exports.compare
+
+  var lb = lowerBound(range)
+  if(isDef(lb)) {
+    var cmp = compare(key, lb)
+    if(cmp < 0 || (cmp === 0 && lowerBoundExclusive(range)))
+      return false
+  }
+
+  var ub = upperBound(range)
+  if(isDef(ub)) {
+    var cmp = compare(key, ub)
+    if(cmp > 0 || (cmp === 0) && upperBoundExclusive(range))
+      return false
+  }
+
+  return true
+}
+
+exports.filter = function (range, compare) {
+  return function (key) {
+    return exports.contains(range, key, compare)
+  }
+}
+
+}).call(this,{"isBuffer":_dereq_(24)})
+},{"24":24}],46:[function(_dereq_,module,exports){
+(function (process,global,Buffer){
+var inherits          = _dereq_(23)
+  , AbstractLevelDOWN = _dereq_(50).AbstractLevelDOWN
+  , AbstractIterator  = _dereq_(50).AbstractIterator
+  , ltgt              = _dereq_(45)
+  , setImmediate      = global.setImmediate || process.nextTick
+  , createRBT = _dereq_(20)
+  , globalStore       = {}
+
+function toKey (key) {
+  return typeof key == 'string' ? '$' + key : JSON.stringify(key)
+}
+
+function gt(value) {
+  return ltgt.compare(value, this._end) > 0
+}
+
+function gte(value) {
+  return ltgt.compare(value, this._end) >= 0
+}
+
+function lt(value) {
+  return ltgt.compare(value, this._end) < 0
+}
+
+function lte(value) {
+  return ltgt.compare(value, this._end) <= 0
+}
+
+
+function MemIterator (db, options) {
+  AbstractIterator.call(this, db)
+  this._limit   = options.limit
+
+  if (this._limit === -1)
+    this._limit = Infinity
+
+  var tree = db._store[db._location];
+
+  this.keyAsBuffer = options.keyAsBuffer !== false
+  this.valueAsBuffer = options.valueAsBuffer !== false
+  this._reverse   = options.reverse
+  this._options = options
+  this._done = 0
+
+  if (!this._reverse) {
+    this._incr = 'next';
+    this._start = ltgt.lowerBound(options);
+    this._end = ltgt.upperBound(options)
+
+    if (typeof this._start === 'undefined')
+      this._tree = tree.begin;
+    else if (ltgt.lowerBoundInclusive(options))
+      this._tree = tree.ge(this._start);
+    else
+      this._tree = tree.gt(this._start);
+
+    if (this._end) {
+      if (ltgt.upperBoundInclusive(options))
+        this._test = lte
+      else
+        this._test = lt
+    }
+
+  } else {
+    this._incr = 'prev';
+    this._start = ltgt.upperBound(options)
+    this._end = ltgt.lowerBound(options)
+
+    if (typeof this._start === 'undefined')
+      this._tree = tree.end;
+    else if (ltgt.upperBoundInclusive(options))
+      this._tree = tree.le(this._start)
+    else
+      this._tree = tree.lt(this._start)
+
+    if (this._end) {
+      if (ltgt.lowerBoundInclusive(options))
+        this._test = gte
+      else
+        this._test = gt
+    }
+
+  }
+
+}
+
+inherits(MemIterator, AbstractIterator)
+
+MemIterator.prototype._next = function (callback) {
+  var key
+    , value
+
+  if (this._done++ >= this._limit)
+    return setImmediate(callback)
+
+  if (!this._tree.valid)
+    return setImmediate(callback)
+
+  key = this._tree.key
+  value = this._tree.value
+
+  if (!this._test(key))
+    return setImmediate(callback)
+
+  if (this.keyAsBuffer)
+    key = new Buffer(key)
+
+  if (this.valueAsBuffer)
+    value = new Buffer(value)
+
+  this._tree[this._incr]()
+
+  setImmediate(function callNext() {
+    callback(null, key, value)
+  })
+}
+
+MemIterator.prototype._test = function () {return true}
+
+function MemDOWN (location) {
+  if (!(this instanceof MemDOWN))
+    return new MemDOWN(location)
+
+  AbstractLevelDOWN.call(this, typeof location == 'string' ? location : '')
+
+  this._location = this.location ? toKey(this.location) : '_tree'
+  this._store = this.location ? globalStore: this
+  this._store[this._location] = this._store[this._location] || createRBT(ltgt.compare)
+}
+
+MemDOWN.clearGlobalStore = function (strict) {
+  if (strict) {
+    Object.keys(globalStore).forEach(function (key) {
+      delete globalStore[key];
+    })
+  } else {
+    globalStore = {}
+  }
+}
+
+inherits(MemDOWN, AbstractLevelDOWN)
+
+MemDOWN.prototype._open = function (options, callback) {
+  var self = this
+  setImmediate(function callNext() { callback(null, self) })
+}
+
+MemDOWN.prototype._put = function (key, value, options, callback) {
+  if (typeof value === 'undefined' || value === null) value = ''
+
+  var iter = this._store[this._location].find(key)
+
+  if (iter.valid) {
+    this._store[this._location] = iter.update(value)
+  } else {
+    this._store[this._location] = this._store[this._location].insert(key, value)
+  }
+
+  setImmediate(callback)
+}
+
+MemDOWN.prototype._get = function (key, options, callback) {
+  var value = this._store[this._location].get(key)
+
+  if (value === undefined) {
+    // 'NotFound' error, consistent with LevelDOWN API
+    var err = new Error('NotFound')
+    return setImmediate(function callNext() { callback(err) })
+  }
+
+  if (options.asBuffer !== false && !this._isBuffer(value))
+    value = new Buffer(String(value))
+
+  setImmediate(function callNext () {
+    callback(null, value)
+  })
+
+}
+
+MemDOWN.prototype._del = function (key, options, callback) {
+  this._store[this._location] = this._store[this._location].remove(key)
+  setImmediate(callback)
+}
+
+MemDOWN.prototype._batch = function (array, options, callback) {
+  var err
+    , i = -1
+    , key
+    , value
+    , iter
+    , len = array.length
+    , tree = this._store[this._location]
+
+  while (++i < len) {
+    if (!array[i])
+      continue;
+
+    key = this._isBuffer(array[i].key) ? array[i].key : String(array[i].key)
+    err = this._checkKey(key, 'key')
+    if (err)
+      return setImmediate(function errorCall() { callback(err) })
+
+    iter = tree.find(key)
+
+    if (array[i].type === 'put') {
+      value = this._isBuffer(array[i].value) ? array[i].value : String(array[i].value)
+      err = this._checkKey(value, 'value')
+
+      if (err)
+        return setImmediate(function errorCall() { callback(err) })
+
+      tree = iter.valid ? iter.update(value) : tree.insert(key, value)
+    } else {
+      tree = iter.remove()
+    }
+  }
+
+  this._store[this._location] = tree;
+
+  setImmediate(callback)
+}
+
+MemDOWN.prototype._iterator = function (options) {
+  return new MemIterator(this, options)
+}
+
+MemDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+MemDOWN.destroy = function (name, callback) {
+  var key = toKey(name)
+
+  if (key in globalStore)
+    delete globalStore[key]
+
+  setImmediate(callback)
+}
+
+module.exports = MemDOWN
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},_dereq_(5).Buffer)
+},{"20":20,"23":23,"45":45,"5":5,"50":50,"55":55}],47:[function(_dereq_,module,exports){
+(function (process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+function AbstractChainedBatch (db) {
+  this._db         = db
+  this._operations = []
+  this._written    = false
+}
+
+AbstractChainedBatch.prototype._serializeKey = function (key) {
+  return this._db._serializeKey(key)
+}
+
+AbstractChainedBatch.prototype._serializeValue = function (value) {
+  return this._db._serializeValue(value)
+}
+
+AbstractChainedBatch.prototype._checkWritten = function () {
+  if (this._written)
+    throw new Error('write() already called on this batch')
+}
+
+AbstractChainedBatch.prototype.put = function (key, value) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err)
+    throw err
+
+  key = this._serializeKey(key)
+  value = this._serializeValue(value)
+
+  if (typeof this._put == 'function' )
+    this._put(key, value)
+  else
+    this._operations.push({ type: 'put', key: key, value: value })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.del = function (key) {
+  this._checkWritten()
+
+  var err = this._db._checkKey(key, 'key', this._db._isBuffer)
+  if (err) throw err
+
+  key = this._serializeKey(key)
+
+  if (typeof this._del == 'function' )
+    this._del(key)
+  else
+    this._operations.push({ type: 'del', key: key })
+
+  return this
+}
+
+AbstractChainedBatch.prototype.clear = function () {
+  this._checkWritten()
+
+  this._operations = []
+
+  if (typeof this._clear == 'function' )
+    this._clear()
+
+  return this
+}
+
+AbstractChainedBatch.prototype.write = function (options, callback) {
+  this._checkWritten()
+
+  if (typeof options == 'function')
+    callback = options
+  if (typeof callback != 'function')
+    throw new Error('write() requires a callback argument')
+  if (typeof options != 'object')
+    options = {}
+
+  this._written = true
+
+  if (typeof this._write == 'function' )
+    return this._write(callback)
+
+  if (typeof this._db._batch == 'function')
+    return this._db._batch(this._operations, options, callback)
+
+  process.nextTick(callback)
+}
+
+module.exports = AbstractChainedBatch
+
+}).call(this,_dereq_(55))
+},{"55":55}],48:[function(_dereq_,module,exports){
+arguments[4][10][0].apply(exports,arguments)
+},{"10":10,"55":55}],49:[function(_dereq_,module,exports){
+(function (Buffer,process){
+/* Copyright (c) 2013 Rod Vagg, MIT License */
+
+var xtend                = _dereq_(52)
+  , AbstractIterator     = _dereq_(48)
+  , AbstractChainedBatch = _dereq_(47)
+
+function AbstractLevelDOWN (location) {
+  if (!arguments.length || location === undefined)
+    throw new Error('constructor requires at least a location argument')
+
+  if (typeof location != 'string')
+    throw new Error('constructor requires a location string argument')
+
+  this.location = location
+  this.status = 'new'
+}
+
+AbstractLevelDOWN.prototype.open = function (options, callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('open() requires a callback argument')
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.createIfMissing = options.createIfMissing != false
+  options.errorIfExists = !!options.errorIfExists
+
+  if (typeof this._open == 'function') {
+    this.status = 'opening'
+    this._open(options, function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'open'
+      callback()
+    })
+  } else {
+    this.status = 'open'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.close = function (callback) {
+  var self      = this
+    , oldStatus = this.status
+
+  if (typeof callback != 'function')
+    throw new Error('close() requires a callback argument')
+
+  if (typeof this._close == 'function') {
+    this.status = 'closing'
+    this._close(function (err) {
+      if (err) {
+        self.status = oldStatus
+        return callback(err)
+      }
+      self.status = 'closed'
+      callback()
+    })
+  } else {
+    this.status = 'closed'
+    process.nextTick(callback)
+  }
+}
+
+AbstractLevelDOWN.prototype.get = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('get() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key'))
+    return callback(err)
+
+  key = this._serializeKey(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  options.asBuffer = options.asBuffer != false
+
+  if (typeof this._get == 'function')
+    return this._get(key, options, callback)
+
+  process.nextTick(function () { callback(new Error('NotFound')) })
+}
+
+AbstractLevelDOWN.prototype.put = function (key, value, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('put() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key'))
+    return callback(err)
+
+  key = this._serializeKey(key)
+  value = this._serializeValue(value)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._put == 'function')
+    return this._put(key, value, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.del = function (key, options, callback) {
+  var err
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof callback != 'function')
+    throw new Error('del() requires a callback argument')
+
+  if (err = this._checkKey(key, 'key'))
+    return callback(err)
+
+  key = this._serializeKey(key)
+
+  if (typeof options != 'object')
+    options = {}
+
+  if (typeof this._del == 'function')
+    return this._del(key, options, callback)
+
+  process.nextTick(callback)
+}
+
+AbstractLevelDOWN.prototype.batch = function (array, options, callback) {
+  if (!arguments.length)
+    return this._chainedBatch()
+
+  if (typeof options == 'function')
+    callback = options
+
+  if (typeof array == 'function')
+    callback = array
+
+  if (typeof callback != 'function')
+    throw new Error('batch(array) requires a callback argument')
+
+  if (!Array.isArray(array))
+    return callback(new Error('batch(array) requires an array argument'))
+
+  if (!options || typeof options != 'object')
+    options = {}
+
+  var i = 0
+    , l = array.length
+    , e
+    , err
+
+  for (; i < l; i++) {
+    e = array[i]
+    if (typeof e != 'object')
+      continue
+
+    if (err = this._checkKey(e.type, 'type'))
+      return callback(err)
+
+    if (err = this._checkKey(e.key, 'key'))
+      return callback(err)
+  }
+
+  if (typeof this._batch == 'function')
+    return this._batch(array, options, callback)
+
+  process.nextTick(callback)
+}
+
+//TODO: remove from here, not a necessary primitive
+AbstractLevelDOWN.prototype.approximateSize = function (start, end, callback) {
+  if (   start == null
+      || end == null
+      || typeof start == 'function'
+      || typeof end == 'function') {
+    throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
+  }
+
+  if (typeof callback != 'function')
+    throw new Error('approximateSize() requires a callback argument')
+
+  start = this._serializeKey(start)
+  end = this._serializeKey(end)
+
+  if (typeof this._approximateSize == 'function')
+    return this._approximateSize(start, end, callback)
+
+  process.nextTick(function () {
+    callback(null, 0)
+  })
+}
+
+AbstractLevelDOWN.prototype._setupIteratorOptions = function (options) {
+  var self = this
+
+  options = xtend(options)
+
+  ;[ 'start', 'end', 'gt', 'gte', 'lt', 'lte' ].forEach(function (o) {
+    if (options[o] && self._isBuffer(options[o]) && options[o].length === 0)
+      delete options[o]
+  })
+
+  options.reverse = !!options.reverse
+  options.keys = options.keys != false
+  options.values = options.values != false
+  options.limit = 'limit' in options ? options.limit : -1
+  options.keyAsBuffer = options.keyAsBuffer != false
+  options.valueAsBuffer = options.valueAsBuffer != false
+
+  return options
+}
+
+AbstractLevelDOWN.prototype.iterator = function (options) {
+  if (typeof options != 'object')
+    options = {}
+
+  options = this._setupIteratorOptions(options)
+
+  if (typeof this._iterator == 'function')
+    return this._iterator(options)
+
+  return new AbstractIterator(this)
+}
+
+AbstractLevelDOWN.prototype._chainedBatch = function () {
+  return new AbstractChainedBatch(this)
+}
+
+AbstractLevelDOWN.prototype._isBuffer = function (obj) {
+  return Buffer.isBuffer(obj)
+}
+
+AbstractLevelDOWN.prototype._serializeKey = function (key) {
+  return this._isBuffer(key)
+    ? key
+    : String(key)
+}
+
+AbstractLevelDOWN.prototype._serializeValue = function (value) {
+  return this._isBuffer(value) || process.browser
+    ? value
+    : String(value)
+}
+
+AbstractLevelDOWN.prototype._checkKey = function (obj, type) {
+  if (obj === null || obj === undefined)
+    return new Error(type + ' cannot be `null` or `undefined`')
+
+  if (this._isBuffer(obj) && obj.length === 0)
+    return new Error(type + ' cannot be an empty Buffer')
+  else if (String(obj) === '')
+    return new Error(type + ' cannot be an empty String')
+}
+
+module.exports = AbstractLevelDOWN
+
+}).call(this,{"isBuffer":_dereq_(24)},_dereq_(55))
+},{"24":24,"47":47,"48":48,"52":52,"55":55}],50:[function(_dereq_,module,exports){
+arguments[4][12][0].apply(exports,arguments)
+},{"12":12,"47":47,"48":48,"49":49,"51":51}],51:[function(_dereq_,module,exports){
+arguments[4][13][0].apply(exports,arguments)
+},{"13":13,"49":49}],52:[function(_dereq_,module,exports){
+arguments[4][14][0].apply(exports,arguments)
+},{"14":14}],53:[function(_dereq_,module,exports){
+'use strict';
+exports.Map = LazyMap; // TODO: use ES6 map
+exports.Set = LazySet; // TODO: use ES6 set
+// based on https://github.com/montagejs/collections
+function LazyMap() {
+  this.store = {};
+}
+LazyMap.prototype.mangle = function (key) {
+  if (typeof key !== "string") {
+    throw new TypeError("key must be a string but Got " + key);
+  }
+  return '$' + key;
+};
+LazyMap.prototype.unmangle = function (key) {
+  return key.substring(1);
+};
+LazyMap.prototype.get = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    return this.store[mangled];
+  }
+  return void 0;
+};
+LazyMap.prototype.set = function (key, value) {
+  var mangled = this.mangle(key);
+  this.store[mangled] = value;
+  return true;
+};
+LazyMap.prototype.has = function (key) {
+  var mangled = this.mangle(key);
+  return mangled in this.store;
+};
+LazyMap.prototype.delete = function (key) {
+  var mangled = this.mangle(key);
+  if (mangled in this.store) {
+    delete this.store[mangled];
+    return true;
+  }
+  return false;
+};
+LazyMap.prototype.forEach = function (cb) {
+  var keys = Object.keys(this.store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this.store[key];
+    key = this.unmangle(key);
+    cb(value, key);
+  }
+};
+
+function LazySet(array) {
+  this.store = new LazyMap();
+
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
+    }
+  }
+}
+LazySet.prototype.add = function (key) {
+  return this.store.set(key, true);
+};
+LazySet.prototype.has = function (key) {
+  return this.store.has(key);
+};
+LazySet.prototype.delete = function (key) {
+  return this.store.delete(key);
+};
+
+},{}],54:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+if (!process.version ||
+    process.version.indexOf('v0.') === 0 ||
+    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+  module.exports = nextTick;
+} else {
+  module.exports = process.nextTick;
+}
+
+function nextTick(fn) {
+  var args = new Array(arguments.length - 1);
+  var i = 0;
+  while (i < args.length) {
+    args[i++] = arguments[i];
+  }
+  process.nextTick(function afterTick() {
+    fn.apply(null, args);
+  });
+}
+
+}).call(this,_dereq_(55))
+},{"55":55}],55:[function(_dereq_,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = setTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    clearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],56:[function(_dereq_,module,exports){
+arguments[4][18][0].apply(exports,arguments)
+},{"18":18}],57:[function(_dereq_,module,exports){
+(function (factory) {
+    if (typeof exports === 'object') {
+        // Node/CommonJS
+        module.exports = factory();
+    } else if (typeof define === 'function' && define.amd) {
+        // AMD
+        define(factory);
+    } else {
+        // Browser globals (with support for web workers)
+        var glob;
+
+        try {
+            glob = window;
+        } catch (e) {
+            glob = self;
+        }
+
+        glob.SparkMD5 = factory();
+    }
+}(function (undefined) {
+
+    'use strict';
+
+    /*
+     * Fastest md5 implementation around (JKM md5).
+     * Credits: Joseph Myers
+     *
+     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+     * @see http://jsperf.com/md5-shootout/7
+     */
+
+    /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+    var add32 = function (a, b) {
+        return (a + b) & 0xFFFFFFFF;
+    },
+        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+    function cmn(q, a, b, x, s, t) {
+        a = add32(add32(a, q), add32(x, t));
+        return add32((a << s) | (a >>> (32 - s)), b);
+    }
+
+    function ff(a, b, c, d, x, s, t) {
+        return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+    }
+
+    function gg(a, b, c, d, x, s, t) {
+        return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+    }
+
+    function hh(a, b, c, d, x, s, t) {
+        return cmn(b ^ c ^ d, a, b, x, s, t);
+    }
+
+    function ii(a, b, c, d, x, s, t) {
+        return cmn(c ^ (b | (~d)), a, b, x, s, t);
+    }
+
+    function md5cycle(x, k) {
+        var a = x[0],
+            b = x[1],
+            c = x[2],
+            d = x[3];
+
+        a = ff(a, b, c, d, k[0], 7, -680876936);
+        d = ff(d, a, b, c, k[1], 12, -389564586);
+        c = ff(c, d, a, b, k[2], 17, 606105819);
+        b = ff(b, c, d, a, k[3], 22, -1044525330);
+        a = ff(a, b, c, d, k[4], 7, -176418897);
+        d = ff(d, a, b, c, k[5], 12, 1200080426);
+        c = ff(c, d, a, b, k[6], 17, -1473231341);
+        b = ff(b, c, d, a, k[7], 22, -45705983);
+        a = ff(a, b, c, d, k[8], 7, 1770035416);
+        d = ff(d, a, b, c, k[9], 12, -1958414417);
+        c = ff(c, d, a, b, k[10], 17, -42063);
+        b = ff(b, c, d, a, k[11], 22, -1990404162);
+        a = ff(a, b, c, d, k[12], 7, 1804603682);
+        d = ff(d, a, b, c, k[13], 12, -40341101);
+        c = ff(c, d, a, b, k[14], 17, -1502002290);
+        b = ff(b, c, d, a, k[15], 22, 1236535329);
+
+        a = gg(a, b, c, d, k[1], 5, -165796510);
+        d = gg(d, a, b, c, k[6], 9, -1069501632);
+        c = gg(c, d, a, b, k[11], 14, 643717713);
+        b = gg(b, c, d, a, k[0], 20, -373897302);
+        a = gg(a, b, c, d, k[5], 5, -701558691);
+        d = gg(d, a, b, c, k[10], 9, 38016083);
+        c = gg(c, d, a, b, k[15], 14, -660478335);
+        b = gg(b, c, d, a, k[4], 20, -405537848);
+        a = gg(a, b, c, d, k[9], 5, 568446438);
+        d = gg(d, a, b, c, k[14], 9, -1019803690);
+        c = gg(c, d, a, b, k[3], 14, -187363961);
+        b = gg(b, c, d, a, k[8], 20, 1163531501);
+        a = gg(a, b, c, d, k[13], 5, -1444681467);
+        d = gg(d, a, b, c, k[2], 9, -51403784);
+        c = gg(c, d, a, b, k[7], 14, 1735328473);
+        b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+        a = hh(a, b, c, d, k[5], 4, -378558);
+        d = hh(d, a, b, c, k[8], 11, -2022574463);
+        c = hh(c, d, a, b, k[11], 16, 1839030562);
+        b = hh(b, c, d, a, k[14], 23, -35309556);
+        a = hh(a, b, c, d, k[1], 4, -1530992060);
+        d = hh(d, a, b, c, k[4], 11, 1272893353);
+        c = hh(c, d, a, b, k[7], 16, -155497632);
+        b = hh(b, c, d, a, k[10], 23, -1094730640);
+        a = hh(a, b, c, d, k[13], 4, 681279174);
+        d = hh(d, a, b, c, k[0], 11, -358537222);
+        c = hh(c, d, a, b, k[3], 16, -722521979);
+        b = hh(b, c, d, a, k[6], 23, 76029189);
+        a = hh(a, b, c, d, k[9], 4, -640364487);
+        d = hh(d, a, b, c, k[12], 11, -421815835);
+        c = hh(c, d, a, b, k[15], 16, 530742520);
+        b = hh(b, c, d, a, k[2], 23, -995338651);
+
+        a = ii(a, b, c, d, k[0], 6, -198630844);
+        d = ii(d, a, b, c, k[7], 10, 1126891415);
+        c = ii(c, d, a, b, k[14], 15, -1416354905);
+        b = ii(b, c, d, a, k[5], 21, -57434055);
+        a = ii(a, b, c, d, k[12], 6, 1700485571);
+        d = ii(d, a, b, c, k[3], 10, -1894986606);
+        c = ii(c, d, a, b, k[10], 15, -1051523);
+        b = ii(b, c, d, a, k[1], 21, -2054922799);
+        a = ii(a, b, c, d, k[8], 6, 1873313359);
+        d = ii(d, a, b, c, k[15], 10, -30611744);
+        c = ii(c, d, a, b, k[6], 15, -1560198380);
+        b = ii(b, c, d, a, k[13], 21, 1309151649);
+        a = ii(a, b, c, d, k[4], 6, -145523070);
+        d = ii(d, a, b, c, k[11], 10, -1120210379);
+        c = ii(c, d, a, b, k[2], 15, 718787259);
+        b = ii(b, c, d, a, k[9], 21, -343485551);
+
+        x[0] = add32(a, x[0]);
+        x[1] = add32(b, x[1]);
+        x[2] = add32(c, x[2]);
+        x[3] = add32(d, x[3]);
+    }
+
+    function md5blk(s) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+        }
+        return md5blks;
+    }
+
+    function md5blk_array(a) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
+
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+        }
+        return md5blks;
+    }
+
+    function md51(s) {
+        var n = s.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk(s.substring(i - 64, i)));
+        }
+        s = s.substring(i - 64);
+        length = s.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+        }
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+        return state;
+    }
+
+    function md51_array(a) {
+        var n = a.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
+
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+        }
+
+        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+        // containing the last element of the parent array if the sub array specified starts
+        // beyond the length of the parent array - weird.
+        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+        length = a.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= a[i] << ((i % 4) << 3);
+        }
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+
+        md5cycle(state, tail);
+
+        return state;
+    }
+
+    function rhex(n) {
+        var s = '',
+            j;
+        for (j = 0; j < 4; j += 1) {
+            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+        }
+        return s;
+    }
+
+    function hex(x) {
+        var i;
+        for (i = 0; i < x.length; i += 1) {
+            x[i] = rhex(x[i]);
+        }
+        return x.join('');
+    }
+
+    // In some cases the fast add32 function cannot be used..
+    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+        add32 = function (x, y) {
+            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+            return (msw << 16) | (lsw & 0xFFFF);
+        };
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * ArrayBuffer slice polyfill.
+     *
+     * @see https://github.com/ttaubert/node-arraybuffer-slice
+     */
+
+    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+        (function () {
+            function clamp(val, length) {
+                val = (val | 0) || 0;
+
+                if (val < 0) {
+                    return Math.max(val + length, 0);
+                }
+
+                return Math.min(val, length);
+            }
+
+            ArrayBuffer.prototype.slice = function (from, to) {
+                var length = this.byteLength,
+                    begin = clamp(from, length),
+                    end = length,
+                    num,
+                    target,
+                    targetArray,
+                    sourceArray;
+
+                if (to !== undefined) {
+                    end = clamp(to, length);
+                }
+
+                if (begin > end) {
+                    return new ArrayBuffer(0);
+                }
+
+                num = end - begin;
+                target = new ArrayBuffer(num);
+                targetArray = new Uint8Array(target);
+
+                sourceArray = new Uint8Array(this, begin, num);
+                targetArray.set(sourceArray);
+
+                return target;
+            };
+        })();
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * Helpers.
+     */
+
+    function toUtf8(str) {
+        if (/[\u0080-\uFFFF]/.test(str)) {
+            str = unescape(encodeURIComponent(str));
+        }
+
+        return str;
+    }
+
+    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+        var length = str.length,
+           buff = new ArrayBuffer(length),
+           arr = new Uint8Array(buff),
+           i;
+
+        for (i = 0; i < length; i += 1) {
+            arr[i] = str.charCodeAt(i);
+        }
+
+        return returnUInt8Array ? arr : buff;
+    }
+
+    function arrayBuffer2Utf8Str(buff) {
+        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    }
+
+    function concatenateArrayBuffers(first, second, returnUInt8Array) {
+        var result = new Uint8Array(first.byteLength + second.byteLength);
+
+        result.set(new Uint8Array(first));
+        result.set(new Uint8Array(second), first.byteLength);
+
+        return returnUInt8Array ? result : result.buffer;
+    }
+
+    function hexToBinaryString(hex) {
+        var bytes = [],
+            length = hex.length,
+            x;
+
+        for (x = 0; x < length - 1; x += 2) {
+            bytes.push(parseInt(hex.substr(x, 2), 16));
+        }
+
+        return String.fromCharCode.apply(String, bytes);
+    }
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation.
+     *
+     * Use this class to perform an incremental md5, otherwise use the
+     * static methods instead.
+     */
+
+    function SparkMD5() {
+        // call reset to init the instance
+        this.reset();
+    }
+
+    /**
+     * Appends a string.
+     * A conversion will be applied if an utf8 string is detected.
+     *
+     * @param {String} str The string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.append = function (str) {
+        // Converts the string to utf8 bytes if necessary
+        // Then append as binary
+        this.appendBinary(toUtf8(str));
+
+        return this;
+    };
+
+    /**
+     * Appends a binary string.
+     *
+     * @param {String} contents The binary string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.appendBinary = function (contents) {
+        this._buff += contents;
+        this._length += contents.length;
+
+        var length = this._buff.length,
+            i;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+        }
+
+        this._buff = this._buff.substring(i - 64);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            i,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.reset = function () {
+        this._buff = '';
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.prototype.getState = function () {
+        return {
+            buff: this._buff,
+            length: this._length,
+            hash: this._hash
+        };
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.setState = function (state) {
+        this._buff = state.buff;
+        this._length = state.length;
+        this._hash = state.hash;
+
+        return this;
+    };
+
+    /**
+     * Releases memory used by the incremental buffer and other additional
+     * resources. If you plan to use the instance again, use reset instead.
+     */
+    SparkMD5.prototype.destroy = function () {
+        delete this._hash;
+        delete this._buff;
+        delete this._length;
+    };
+
+    /**
+     * Finish the final calculation based on the tail.
+     *
+     * @param {Array}  tail   The tail (will be modified)
+     * @param {Number} length The length of the remaining buffer
+     */
+    SparkMD5.prototype._finish = function (tail, length) {
+        var i = length,
+            tmp,
+            lo,
+            hi;
+
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(this._hash, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
+
+        // Do the final computation based on the tail and length
+        // Beware that the final length may not fit in 32 bits so we take care of that
+        tmp = this._length * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
+
+        tail[14] = lo;
+        tail[15] = hi;
+        md5cycle(this._hash, tail);
+    };
+
+    /**
+     * Performs the md5 hash on a string.
+     * A conversion will be applied if utf8 string is detected.
+     *
+     * @param {String}  str The string
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hash = function (str, raw) {
+        // Converts the string to utf8 bytes if necessary
+        // Then compute it using the binary function
+        return SparkMD5.hashBinary(toUtf8(str), raw);
+    };
+
+    /**
+     * Performs the md5 hash on a binary string.
+     *
+     * @param {String}  content The binary string
+     * @param {Boolean} raw     True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hashBinary = function (content, raw) {
+        var hash = md51(content),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    // ---------------------------------------------------
+
+    /**
+     * SparkMD5 OOP implementation for array buffers.
+     *
+     * Use this class to perform an incremental md5 ONLY for array buffers.
+     */
+    SparkMD5.ArrayBuffer = function () {
+        // call reset to init the instance
+        this.reset();
+    };
+
+    /**
+     * Appends an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array to be appended
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+            length = buff.length,
+            i;
+
+        this._length += arr.byteLength;
+
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+        }
+
+        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+        return this;
+    };
+
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            i,
+            ret;
+
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+        }
+
+        this._finish(tail, length);
+        ret = hex(this._hash);
+
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
+
+        this.reset();
+
+        return ret;
+    };
+
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.reset = function () {
+        this._buff = new Uint8Array(0);
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+        return this;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.ArrayBuffer.prototype.getState = function () {
+        var state = SparkMD5.prototype.getState.call(this);
+
+        // Convert buffer to a string
+        state.buff = arrayBuffer2Utf8Str(state.buff);
+
+        return state;
+    };
+
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+        // Convert string to buffer
+        state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+        return SparkMD5.prototype.setState.call(this, state);
+    };
+
+    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+    /**
+     * Performs the md5 hash on an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array buffer
+     * @param {Boolean}     raw True to get the raw string, false to get the hex one
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+        var hash = md51_array(new Uint8Array(arr)),
+            ret = hex(hash);
+
+        return raw ? hexToBinaryString(ret) : ret;
+    };
+
+    return SparkMD5;
+}));
+
+},{}],58:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Stream;
+
+var EE = _dereq_(19).EventEmitter;
+var inherits = _dereq_(23);
+
+inherits(Stream, EE);
+Stream.Readable = _dereq_(66);
+Stream.Writable = _dereq_(68);
+Stream.Duplex = _dereq_(59);
+Stream.Transform = _dereq_(67);
+Stream.PassThrough = _dereq_(65);
+
+// Backwards-compat with node 0.4.x
+Stream.Stream = Stream;
+
+
+
+// old-style streams.  Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+  EE.call(this);
+}
+
+Stream.prototype.pipe = function(dest, options) {
+  var source = this;
+
+  function ondata(chunk) {
+    if (dest.writable) {
+      if (false === dest.write(chunk) && source.pause) {
+        source.pause();
+      }
+    }
+  }
+
+  source.on('data', ondata);
+
+  function ondrain() {
+    if (source.readable && source.resume) {
+      source.resume();
+    }
+  }
+
+  dest.on('drain', ondrain);
+
+  // If the 'end' option is not supplied, dest.end() will be called when
+  // source gets the 'end' or 'close' events.  Only dest.end() once.
+  if (!dest._isStdio && (!options || options.end !== false)) {
+    source.on('end', onend);
+    source.on('close', onclose);
+  }
+
+  var didOnEnd = false;
+  function onend() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    dest.end();
+  }
+
+
+  function onclose() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    if (typeof dest.destroy === 'function') dest.destroy();
+  }
+
+  // don't leave dangling pipes when there are errors.
+  function onerror(er) {
+    cleanup();
+    if (EE.listenerCount(this, 'error') === 0) {
+      throw er; // Unhandled stream error in pipe.
+    }
+  }
+
+  source.on('error', onerror);
+  dest.on('error', onerror);
+
+  // remove all the event listeners that were added.
+  function cleanup() {
+    source.removeListener('data', ondata);
+    dest.removeListener('drain', ondrain);
+
+    source.removeListener('end', onend);
+    source.removeListener('close', onclose);
+
+    source.removeListener('error', onerror);
+    dest.removeListener('error', onerror);
+
+    source.removeListener('end', cleanup);
+    source.removeListener('close', cleanup);
+
+    dest.removeListener('close', cleanup);
+  }
+
+  source.on('end', cleanup);
+  source.on('close', cleanup);
+
+  dest.on('close', cleanup);
+
+  dest.emit('pipe', source);
+
+  // Allow for unix-like usage: A.pipe(B).pipe(C)
+  return dest;
+};
+
+},{"19":19,"23":23,"59":59,"65":65,"66":66,"67":67,"68":68}],59:[function(_dereq_,module,exports){
+module.exports = _dereq_(60)
+
+},{"60":60}],60:[function(_dereq_,module,exports){
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+'use strict';
+
+/*<replacement>*/
+
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) {
+    keys.push(key);
+  }return keys;
+};
+/*</replacement>*/
+
+module.exports = Duplex;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var Readable = _dereq_(62);
+var Writable = _dereq_(64);
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+  var method = keys[v];
+  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+  if (!(this instanceof Duplex)) return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false) this.readable = false;
+
+  if (options && options.writable === false) this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended) return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+  self.end();
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+},{"23":23,"54":54,"6":6,"62":62,"64":64}],61:[function(_dereq_,module,exports){
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+'use strict';
+
+module.exports = PassThrough;
+
+var Transform = _dereq_(63);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+  cb(null, chunk);
+};
+},{"23":23,"6":6,"63":63}],62:[function(_dereq_,module,exports){
+(function (process){
+'use strict';
+
+module.exports = Readable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var isArray = _dereq_(25);
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(19);
+
+/*<replacement>*/
+var EElistenerCount = function (emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(19).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(5).Buffer;
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+/*<replacement>*/
+var debugUtil = _dereq_(4);
+var debug = undefined;
+if (debugUtil && debugUtil.debuglog) {
+  debug = debugUtil.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+var Duplex;
+function ReadableState(options, stream) {
+  Duplex = Duplex || _dereq_(60);
+
+  options = options || {};
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+  this.resumeScheduled = false;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder) StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+var Duplex;
+function Readable(options) {
+  Duplex = Duplex || _dereq_(60);
+
+  if (!(this instanceof Readable)) return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  if (options && typeof options.read === 'function') this._read = options.read;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function (chunk, encoding) {
+  var state = this._readableState;
+
+  if (!state.objectMode && typeof chunk === 'string') {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function (chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+Readable.prototype.isPaused = function () {
+  return this._readableState.flowing === false;
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null) {
+    state.reading = false;
+    onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      var skipAdd;
+      if (state.decoder && !addToFront && !encoding) {
+        chunk = state.decoder.write(chunk);
+        skipAdd = !state.objectMode && chunk.length === 0;
+      }
+
+      if (!addToFront) state.reading = false;
+
+      // Don't add to the buffer if we've decoded to an empty string chunk and
+      // we're not in object mode
+      if (!skipAdd) {
+        // if we want the data now, just emit it.
+        if (state.flowing && state.length === 0 && !state.sync) {
+          stream.emit('data', chunk);
+          stream.read(0);
+        } else {
+          // update the buffer info.
+          state.length += state.objectMode ? 1 : chunk.length;
+          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
+
+          if (state.needReadable) emitReadable(stream);
+        }
+      }
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function (enc) {
+  if (!StringDecoder) StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 8MB
+var MAX_HWM = 0x800000;
+function computeNewHighWaterMark(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    n |= n >>> 1;
+    n |= n >>> 2;
+    n |= n >>> 4;
+    n |= n >>> 8;
+    n |= n >>> 16;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended) return 0;
+
+  if (state.objectMode) return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
+  }
+
+  if (n <= 0) return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else {
+      return state.length;
+    }
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function (n) {
+  debug('read', n);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0) endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  }
+
+  if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0) state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read pushed data synchronously, then `reading` will be false,
+  // and we need to re-evaluate how much data we can return to the user.
+  if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
+
+  var ret;
+  if (n > 0) ret = fromList(n, state);else ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended) state.needReadable = true;
+
+  // If we tried to read() past the EOF, then emit end on the next tick.
+  if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
+
+  if (ret !== null) this.emit('data', ret);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+function onEofChunk(stream, state) {
+  if (state.ended) return;
+  if (state.decoder) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    processNextTick(maybeReadMore_, stream, state);
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;else len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function (n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function (dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    debug('onunpipe');
+    if (readable === src) {
+      cleanup();
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  var cleanedUp = false;
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+    src.removeListener('data', ondata);
+
+    cleanedUp = true;
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
+  }
+
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    var ret = dest.write(chunk);
+    if (false === ret) {
+      // If the user unpiped during `dest.write()`, it is possible
+      // to get stuck in a permanently paused state if that write
+      // also returned false.
+      if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
+        debug('false write response, pause', src._readableState.awaitDrain);
+        src._readableState.awaitDrain++;
+      }
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function () {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain) state.awaitDrain--;
+    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+Readable.prototype.unpipe = function (dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0) return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes) return this;
+
+    if (!dest) dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest) dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var _i = 0; _i < len; _i++) {
+      dests[_i].emit('unpipe', this);
+    }return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1) return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1) state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function (ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  // If listening to data, and it has not explicitly been paused,
+  // then call resume to start the flow of data on the next tick.
+  if (ev === 'data' && false !== this._readableState.flowing) {
+    this.resume();
+  }
+
+  if (ev === 'readable' && !this._readableState.endEmitted) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        processNextTick(nReadingNextTick, this);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+function nReadingNextTick(self) {
+  debug('readable nexttick read 0');
+  self.read(0);
+}
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function () {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    processNextTick(resume_, stream, state);
+  }
+}
+
+function resume_(stream, state) {
+  if (!state.reading) {
+    debug('resume read 0');
+    stream.read(0);
+  }
+
+  state.resumeScheduled = false;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading) stream.read(0);
+}
+
+Readable.prototype.pause = function () {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  if (state.flowing) {
+    do {
+      var chunk = stream.read();
+    } while (null !== chunk && state.flowing);
+  }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function (stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function () {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length) self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function (chunk) {
+    debug('wrapped data');
+    if (state.decoder) chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (this[i] === undefined && typeof stream[i] === 'function') {
+      this[i] = function (method) {
+        return function () {
+          return stream[method].apply(stream, arguments);
+        };
+      }(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function (ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function (n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0) return null;
+
+  if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode) ret = '';else ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0) throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    processNextTick(endReadableNT, state, stream);
+  }
+}
+
+function endReadableNT(state, stream) {
+  // Check that we didn't get one last unshift.
+  if (!state.endEmitted && state.length === 0) {
+    state.endEmitted = true;
+    stream.readable = false;
+    stream.emit('end');
+  }
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf(xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+}).call(this,_dereq_(55))
+},{"19":19,"23":23,"25":25,"4":4,"5":5,"54":54,"55":55,"6":6,"60":60,"69":69}],63:[function(_dereq_,module,exports){
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+'use strict';
+
+module.exports = Transform;
+
+var Duplex = _dereq_(60);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+function TransformState(stream) {
+  this.afterTransform = function (er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+  this.writeencoding = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined) stream.push(data);
+
+  cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+function Transform(options) {
+  if (!(this instanceof Transform)) return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  if (options) {
+    if (typeof options.transform === 'function') this._transform = options.transform;
+
+    if (typeof options.flush === 'function') this._flush = options.flush;
+  }
+
+  this.once('prefinish', function () {
+    if (typeof this._flush === 'function') this._flush(function (er) {
+      done(stream, er);
+    });else done(stream);
+  });
+}
+
+Transform.prototype.push = function (chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function (chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function (chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function (n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+function done(stream, er) {
+  if (er) return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length) throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming) throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+},{"23":23,"6":6,"60":60}],64:[function(_dereq_,module,exports){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !true ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(91)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(19).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(5).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(60);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(60);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+},{"19":19,"23":23,"5":5,"54":54,"6":6,"60":60,"91":91}],65:[function(_dereq_,module,exports){
+module.exports = _dereq_(61)
+
+},{"61":61}],66:[function(_dereq_,module,exports){
+var Stream = (function (){
+  try {
+    return _dereq_('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
+  } catch(_){}
+}());
+exports = module.exports = _dereq_(62);
+exports.Stream = Stream || exports;
+exports.Readable = exports;
+exports.Writable = _dereq_(64);
+exports.Duplex = _dereq_(60);
+exports.Transform = _dereq_(63);
+exports.PassThrough = _dereq_(61);
+
+// inline-process-browser and unreachable-branch-transform make sure this is
+// removed in browserify builds
+if (!true) {
+  module.exports = _dereq_(58);
+}
+
+},{"58":58,"60":60,"61":61,"62":62,"63":63,"64":64}],67:[function(_dereq_,module,exports){
+module.exports = _dereq_(63)
+
+},{"63":63}],68:[function(_dereq_,module,exports){
+module.exports = _dereq_(64)
+
+},{"64":64}],69:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Buffer = _dereq_(5).Buffer;
+
+var isBufferEncoding = Buffer.isEncoding
+  || function(encoding) {
+       switch (encoding && encoding.toLowerCase()) {
+         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
+         default: return false;
+       }
+     }
+
+
+function assertEncoding(encoding) {
+  if (encoding && !isBufferEncoding(encoding)) {
+    throw new Error('Unknown encoding: ' + encoding);
+  }
+}
+
+// StringDecoder provides an interface for efficiently splitting a series of
+// buffers into a series of JS strings without breaking apart multi-byte
+// characters. CESU-8 is handled as part of the UTF-8 encoding.
+//
+// @TODO Handling all encodings inside a single object makes it very difficult
+// to reason about this code, so it should be split up in the future.
+// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
+// points as used by CESU-8.
+var StringDecoder = exports.StringDecoder = function(encoding) {
+  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+  assertEncoding(encoding);
+  switch (this.encoding) {
+    case 'utf8':
+      // CESU-8 represents each of Surrogate Pair by 3-bytes
+      this.surrogateSize = 3;
+      break;
+    case 'ucs2':
+    case 'utf16le':
+      // UTF-16 represents each of Surrogate Pair by 2-bytes
+      this.surrogateSize = 2;
+      this.detectIncompleteChar = utf16DetectIncompleteChar;
+      break;
+    case 'base64':
+      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+      this.surrogateSize = 3;
+      this.detectIncompleteChar = base64DetectIncompleteChar;
+      break;
+    default:
+      this.write = passThroughWrite;
+      return;
+  }
+
+  // Enough space to store all bytes of a single character. UTF-8 needs 4
+  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
+  this.charBuffer = new Buffer(6);
+  // Number of bytes received for the current incomplete multi-byte character.
+  this.charReceived = 0;
+  // Number of bytes expected for the current incomplete multi-byte character.
+  this.charLength = 0;
+};
+
+
+// write decodes the given buffer and returns it as JS string that is
+// guaranteed to not contain any partial multi-byte characters. Any partial
+// character found at the end of the buffer is buffered up, and will be
+// returned when calling write again with the remaining bytes.
+//
+// Note: Converting a Buffer containing an orphan surrogate to a String
+// currently works, but converting a String to a Buffer (via `new Buffer`, or
+// Buffer#write) will replace incomplete surrogates with the unicode
+// replacement character. See https://codereview.chromium.org/121173009/ .
+StringDecoder.prototype.write = function(buffer) {
+  var charStr = '';
+  // if our last write ended with an incomplete multibyte character
+  while (this.charLength) {
+    // determine how many remaining bytes this buffer has to offer for this char
+    var available = (buffer.length >= this.charLength - this.charReceived) ?
+        this.charLength - this.charReceived :
+        buffer.length;
+
+    // add the new bytes to the char buffer
+    buffer.copy(this.charBuffer, this.charReceived, 0, available);
+    this.charReceived += available;
+
+    if (this.charReceived < this.charLength) {
+      // still not enough chars in this buffer? wait for more ...
+      return '';
+    }
+
+    // remove bytes belonging to the current character from the buffer
+    buffer = buffer.slice(available, buffer.length);
+
+    // get the character that was split
+    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
+
+    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+    var charCode = charStr.charCodeAt(charStr.length - 1);
+    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      this.charLength += this.surrogateSize;
+      charStr = '';
+      continue;
+    }
+    this.charReceived = this.charLength = 0;
+
+    // if there are no more bytes in this buffer, just emit our char
+    if (buffer.length === 0) {
+      return charStr;
+    }
+    break;
+  }
+
+  // determine and set charLength / charReceived
+  this.detectIncompleteChar(buffer);
+
+  var end = buffer.length;
+  if (this.charLength) {
+    // buffer the incomplete character bytes we got
+    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
+    end -= this.charReceived;
+  }
+
+  charStr += buffer.toString(this.encoding, 0, end);
+
+  var end = charStr.length - 1;
+  var charCode = charStr.charCodeAt(end);
+  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+  if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+    var size = this.surrogateSize;
+    this.charLength += size;
+    this.charReceived += size;
+    this.charBuffer.copy(this.charBuffer, size, 0, size);
+    buffer.copy(this.charBuffer, 0, 0, size);
+    return charStr.substring(0, end);
+  }
+
+  // or just emit the charStr
+  return charStr;
+};
+
+// detectIncompleteChar determines if there is an incomplete UTF-8 character at
+// the end of the given buffer. If so, it sets this.charLength to the byte
+// length that character, and sets this.charReceived to the number of bytes
+// that are available for this character.
+StringDecoder.prototype.detectIncompleteChar = function(buffer) {
+  // determine how many bytes we have to check at the end of this buffer
+  var i = (buffer.length >= 3) ? 3 : buffer.length;
+
+  // Figure out if one of the last i bytes of our buffer announces an
+  // incomplete char.
+  for (; i > 0; i--) {
+    var c = buffer[buffer.length - i];
+
+    // See http://en.wikipedia.org/wiki/UTF-8#Description
+
+    // 110XXXXX
+    if (i == 1 && c >> 5 == 0x06) {
+      this.charLength = 2;
+      break;
+    }
+
+    // 1110XXXX
+    if (i <= 2 && c >> 4 == 0x0E) {
+      this.charLength = 3;
+      break;
+    }
+
+    // 11110XXX
+    if (i <= 3 && c >> 3 == 0x1E) {
+      this.charLength = 4;
+      break;
+    }
+  }
+  this.charReceived = i;
+};
+
+StringDecoder.prototype.end = function(buffer) {
+  var res = '';
+  if (buffer && buffer.length)
+    res = this.write(buffer);
+
+  if (this.charReceived) {
+    var cr = this.charReceived;
+    var buf = this.charBuffer;
+    var enc = this.encoding;
+    res += buf.slice(0, cr).toString(enc);
+  }
+
+  return res;
+};
+
+function passThroughWrite(buffer) {
+  return buffer.toString(this.encoding);
+}
+
+function utf16DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 2;
+  this.charLength = this.charReceived ? 2 : 0;
+}
+
+function base64DetectIncompleteChar(buffer) {
+  this.charReceived = buffer.length % 3;
+  this.charLength = this.charReceived ? 3 : 0;
+}
+
+},{"5":5}],70:[function(_dereq_,module,exports){
+module.exports = {
+  encode: function (decodedKey) {
+    return '\xff' + decodedKey[0] + '\xff' + decodedKey[1]
+  },
+  decode: function (encodedKeyAsBuffer) {
+    var str = encodedKeyAsBuffer.toString()
+    var idx = str.indexOf('\xff', 1)
+    return [str.substring(1, idx), str.substring(idx + 1)]
+  },
+  lowerBound: '\x00',
+  upperBound: '\xff'
+}
+
+
+},{}],71:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License
+ * <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+var createError   = _dereq_(17).create
+  , LevelUPError  = createError('LevelUPError')
+  , NotFoundError = createError('NotFoundError', LevelUPError)
+
+NotFoundError.prototype.notFound = true
+NotFoundError.prototype.status   = 404
+
+module.exports = {
+  LevelUPError        : LevelUPError
+  , InitializationError : createError('InitializationError', LevelUPError)
+  , OpenError           : createError('OpenError', LevelUPError)
+  , ReadError           : createError('ReadError', LevelUPError)
+  , WriteError          : createError('WriteError', LevelUPError)
+  , NotFoundError       : NotFoundError
+  , EncodingError       : createError('EncodingError', LevelUPError)
+}
+
+},{"17":17}],72:[function(_dereq_,module,exports){
+var nut   = _dereq_(73)
+var shell = _dereq_(75) //the shell surrounds the nut
+var Codec = _dereq_(27)
+var codec = new Codec();
+
+var ReadStream = _dereq_(74)
+
+var precodec = _dereq_(70)
+
+module.exports = function (db) {
+  return shell ( nut ( db, precodec, codec ), [], ReadStream, db.options)
+}
+
+
+},{"27":27,"70":70,"73":73,"74":74,"75":75}],73:[function(_dereq_,module,exports){
+var ltgt = _dereq_(77)
+
+function isFunction (f) {
+  return 'function' === typeof f
+}
+
+function getPrefix (db) {
+  if(db == null) return db
+  if(isFunction(db.prefix)) return db.prefix()
+  return db
+}
+
+function clone (_obj) {
+  var obj = {}
+  for(var k in _obj)
+    obj[k] = _obj[k]
+  return obj
+}
+
+module.exports = function (db, precodec, codec, compare) {
+  var waiting = [], ready = false
+
+  function encodePrefix(prefix, key, opts1, opts2) {
+    return precodec.encode([ prefix, codec.encodeKey(key, opts1, opts2 ) ])
+  }
+
+  function decodePrefix(data) {
+    return precodec.decode(data)
+  }
+
+  function addEncodings(op, prefix) {
+    if(prefix && prefix.options) {
+      op.keyEncoding =
+        op.keyEncoding || prefix.options.keyEncoding
+      op.valueEncoding =
+        op.valueEncoding || prefix.options.valueEncoding
+    }
+    return op
+  }
+
+  function start () {
+    ready = true
+    while(waiting.length)
+      waiting.shift()()
+  }
+
+  if(isFunction(db.isOpen)) {
+    if(db.isOpen())
+      ready = true
+    else
+      db.open(start)
+  } else {
+    db.open(start)
+  }
+
+  return {
+    apply: function (ops, opts, cb) {
+      for(var i = 0; i < ops.length; i++) {
+        var op = ops[i]
+        addEncodings(op, op.prefix)
+        op.prefix = getPrefix(op.prefix)
+      }
+
+      opts = opts || {}
+
+      if('object' !== typeof opts) throw new Error('opts must be object, was:'+ opts) 
+
+      if('function' === typeof opts) cb = opts, opts = {}
+
+      if(ops.length)
+        (db.db || db).batch(
+          ops.map(function (op) {
+            return {
+              key: encodePrefix(op.prefix, op.key, opts, op),
+              value:
+                  op.type !== 'del'
+                ? codec.encodeValue(
+                    op.value,
+                    opts,
+                    op
+                  )
+                : undefined,
+              type:
+                op.type || (op.value === undefined ? 'del' : 'put')
+            }
+          }),
+          opts,
+          function (err) {
+              if(err) return cb(err)
+            cb()
+          }
+        )
+      else
+        cb()
+    },
+    get: function (key, prefix, opts, cb) {
+      opts.asBuffer = codec.valueAsBuffer(opts)
+      return (db.db || db).get(
+        encodePrefix(prefix, key, opts),
+        opts,
+        function (err, value) {
+          if(err) cb(err)
+          else    cb(null, codec.decodeValue(value, opts))
+        }
+      )
+    },
+    createDecoder: function (opts) {
+      return function (key, value) {
+        return {
+          key: codec.decodeKey(precodec.decode(key)[1], opts),
+          value: codec.decodeValue(value, opts)
+        }
+      }
+    },
+    isOpen: function isOpen() {
+      if (db.db && isFunction(db.db.isOpen))
+        return db.db.isOpen()
+
+      return db.isOpen()
+    },
+    isClosed: function isClosed() {
+      if (db.db && isFunction(db.db.isClosed))
+        return db.db.isClosed()
+
+      return db.isClosed()
+    },
+    close: function close (cb) {
+      return db.close(cb)
+    },
+    iterator: function (_opts, cb) {
+      var opts = clone(_opts || {})
+      var prefix = _opts.prefix || []
+
+      function encodeKey(key) {
+        return encodePrefix(prefix, key, opts, {})
+      }
+
+      ltgt.toLtgt(_opts, opts, encodeKey, precodec.lowerBound, precodec.upperBound)
+
+      // if these legacy values are in the options, remove them
+
+      opts.prefix = null
+
+      //************************************************
+      //hard coded defaults, for now...
+      //TODO: pull defaults and encoding out of levelup.
+      opts.keyAsBuffer = opts.valueAsBuffer = false
+      //************************************************
+
+
+      //this is vital, otherwise limit: undefined will
+      //create an empty stream.
+      if ('number' !== typeof opts.limit)
+        opts.limit = -1
+
+      opts.keyAsBuffer = precodec.buffer
+      opts.valueAsBuffer = codec.valueAsBuffer(opts)
+
+      function wrapIterator (iterator) {
+        return {
+          next: function (cb) {
+            return iterator.next(cb)
+          },
+          end: function (cb) {
+            iterator.end(cb)
+          }
+        }
+      }
+
+      if(ready)
+        return wrapIterator((db.db || db).iterator(opts))
+      else
+        waiting.push(function () {
+          cb(null, wrapIterator((db.db || db).iterator(opts)))
+        })
+
+    }
+  }
+
+}
+
+},{"77":77}],74:[function(_dereq_,module,exports){
+/* Copyright (c) 2012-2014 LevelUP contributors
+ * See list at <https://github.com/rvagg/node-levelup#contributing>
+ * MIT License <https://github.com/rvagg/node-levelup/blob/master/LICENSE.md>
+ */
+
+// NOTE: we are fixed to readable-stream@1.0.x for now
+// for pure Streams2 across Node versions
+var Readable      = _dereq_(83).Readable
+  , inherits      = _dereq_(23)
+  , EncodingError = _dereq_(71).EncodingError;
+
+function ReadStream (options, makeData) {
+  if (!(this instanceof ReadStream))
+    return new ReadStream(options, makeData)
+
+  Readable.call(this, { objectMode: true, highWaterMark: options.highWaterMark })
+
+  // purely to keep `db` around until we're done so it's not GCed if the user doesn't keep a ref
+
+  this._waiting = false
+  this._options = options
+  this._makeData = makeData
+}
+
+inherits(ReadStream, Readable)
+
+ReadStream.prototype.setIterator = function (it) {
+  var self = this
+  this._iterator = it
+  if(this._destroyed) return it.end(function () {})
+  if(this._waiting) {
+    this._waiting = false
+    return this._read()
+  }
+  return this
+}
+
+ReadStream.prototype._read = function read () {
+  var self = this
+  if (self._destroyed)
+    return
+  if(!self._iterator)
+    return this._waiting = true
+
+  self._iterator.next(function(err, key, value) {
+    if (err || (key === undefined && value === undefined)) {
+      if (!err && !self._destroyed)
+        self.push(null)
+      return self._cleanup(err)
+    }
+
+
+    try {
+      value = self._makeData(key, value)
+    } catch (e) {
+      return self._cleanup(new EncodingError(e))
+    }
+    if (!self._destroyed)
+      self.push(value)
+  })
+}
+
+ReadStream.prototype._cleanup = function (err) {
+  if (this._destroyed)
+    return
+
+  this._destroyed = true
+
+  var self = this
+  if (err)
+    self.emit('error', err)
+
+  if (self._iterator) {
+    self._iterator.end(function () {
+      self._iterator = null
+      self.emit('close')
+    })
+  } else {
+    self.emit('close')
+  }
+}
+
+ReadStream.prototype.destroy = function () {
+  this._cleanup()
+}
+
+ReadStream.prototype.toString = function () {
+  return 'LevelUP.ReadStream'
+}
+
+
+module.exports = ReadStream
+
+
+},{"23":23,"71":71,"83":83}],75:[function(_dereq_,module,exports){
+(function (process){
+var EventEmitter = _dereq_(19).EventEmitter
+
+var errors = _dereq_(71)
+
+var version = "6.5.4"
+
+var sublevel = module.exports = function (nut, prefix, createStream, options) {
+  var emitter = new EventEmitter()
+  emitter.sublevels = {}
+  emitter.options = options
+
+  emitter.version = version
+
+  emitter.methods = {}
+  prefix = prefix || []
+
+  function errback (err) { if (err) emitter.emit('error', err) }
+
+  function mergeOpts(opts) {
+    var o = {}
+    if(options)
+      for(var k in options)
+        if(options[k] != undefined)o[k] = options[k]
+    if(opts)
+      for(var k in opts)
+        if(opts[k] != undefined) o[k] = opts[k]
+    return o
+  }
+
+  emitter.put = function (key, value, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key, value: value,
+      prefix: prefix.slice(), type: 'put'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('put', key, value); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.prefix = function () {
+    return prefix.slice()
+  }
+
+  emitter.del = function (key, opts, cb) {
+    if('function' === typeof opts) cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    nut.apply([{
+      key: key,
+      prefix: prefix.slice(), type: 'del'
+    }], mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('del', key); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.batch = function (ops, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    if(!cb) cb = errback
+
+    ops = ops.map(function (op) {
+      return {
+        key:           op.key,
+        value:         op.value,
+        prefix:        op.prefix || prefix,
+        keyEncoding:   op.keyEncoding,    // *
+        valueEncoding: op.valueEncoding,  // * (TODO: encodings on sublevel)
+        type:          op.type
+      }
+    })
+
+    nut.apply(ops, mergeOpts(opts), function (err) {
+      if(!err) { emitter.emit('batch', ops); cb(null) }
+      if(err) return cb(err)
+    })
+  }
+
+  emitter.get = function (key, opts, cb) {
+    if('function' === typeof opts)
+      cb = opts, opts = {}
+    nut.get(key, prefix, mergeOpts(opts), function (err, value) {
+      if(err) cb(new errors.NotFoundError('Key not found in database', err))
+      else cb(null, value)
+    })
+  }
+
+  emitter.clone = function(opts) {
+    return sublevel(nut, prefix, createStream, mergeOpts(opts))
+  }
+
+  emitter.sublevel = function (name, opts) {
+    return emitter.sublevels[name] =
+      emitter.sublevels[name] || sublevel(nut, prefix.concat(name), createStream, mergeOpts(opts))
+  }
+
+  emitter.readStream = emitter.createReadStream = function (opts) {
+    opts = mergeOpts(opts)
+    opts.prefix = prefix
+    var stream
+    var it = nut.iterator(opts, function (err, it) {
+      stream.setIterator(it)
+    })
+
+    stream = createStream(opts, nut.createDecoder(opts))
+    if(it) stream.setIterator(it)
+
+    return stream
+  }
+
+  emitter.valueStream =
+  emitter.createValueStream = function (opts) {
+    opts = opts || {}
+    opts.values = true
+    opts.keys = false
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.keyStream =
+  emitter.createKeyStream = function (opts) {
+    opts = opts || {}
+    opts.values = false
+    opts.keys = true
+    return emitter.createReadStream(opts)
+  }
+
+  emitter.close = function (cb) {
+    //TODO: deregister all hooks
+    cb = cb || function () {}
+    if (!prefix.length) nut.close(cb)
+    else process.nextTick(cb)
+  }
+
+  emitter.isOpen = nut.isOpen
+  emitter.isClosed = nut.isClosed
+
+  return emitter
+}
+
+}).call(this,_dereq_(55))
+},{"19":19,"55":55,"71":71}],76:[function(_dereq_,module,exports){
+arguments[4][31][0].apply(exports,arguments)
+},{"31":31}],77:[function(_dereq_,module,exports){
+(function (Buffer){
+
+exports.compare = function (a, b) {
+
+  if(Buffer.isBuffer(a)) {
+    var l = Math.min(a.length, b.length)
+    for(var i = 0; i < l; i++) {
+      var cmp = a[i] - b[i]
+      if(cmp) return cmp
+    }
+    return a.length - b.length
+  }
+
+  return a < b ? -1 : a > b ? 1 : 0
+}
+
+function has(obj, key) {
+  return Object.hasOwnProperty.call(obj, key)
+}
+
+// to be compatible with the current abstract-leveldown tests
+// nullish or empty strings.
+// I could use !!val but I want to permit numbers and booleans,
+// if possible.
+
+function isDef (val) {
+  return val !== undefined && val !== ''
+}
+
+function has (range, name) {
+  return Object.hasOwnProperty.call(range, name)
+}
+
+function hasKey(range, name) {
+  return Object.hasOwnProperty.call(range, name) && name
+}
+
+var lowerBoundKey = exports.lowerBoundKey = function (range) {
+    return (
+       hasKey(range, 'gt')
+    || hasKey(range, 'gte')
+    || hasKey(range, 'min')
+    || (range.reverse ? hasKey(range, 'end') : hasKey(range, 'start'))
+    || undefined
+    )
+}
+
+var lowerBound = exports.lowerBound = function (range) {
+  var k = lowerBoundKey(range)
+  return k && range[k]
+}
+
+exports.lowerBoundInclusive = function (range) {
+  return has(range, 'gt') ? false : true
+}
+
+exports.upperBoundInclusive =
+  function (range) {
+    return has(range, 'lt') || !range.minEx ? false : true
+  }
+
+var lowerBoundExclusive = exports.lowerBoundExclusive =
+  function (range) {
+    return has(range, 'gt') || range.minEx ? true : false
+  }
+
+var upperBoundExclusive = exports.upperBoundExclusive =
+  function (range) {
+    return has(range, 'lt') ? true : false
+  }
+
+var upperBoundKey = exports.upperBoundKey = function (range) {
+    return (
+       hasKey(range, 'lt')
+    || hasKey(range, 'lte')
+    || hasKey(range, 'max')
+    || (range.reverse ? hasKey(range, 'start') : hasKey(range, 'end'))
+    || undefined
+    )
+}
+
+var upperBound = exports.upperBound = function (range) {
+  var k = upperBoundKey(range)
+  return k && range[k]
+}
+
+function id (e) { return e }
+
+exports.toLtgt = function (range, _range, map, lower, upper) {
+  _range = _range || {}
+  map = map || id
+  var defaults = arguments.length > 3
+  var lb = exports.lowerBoundKey(range)
+  var ub = exports.upperBoundKey(range)
+  if(lb) {
+    if(lb === 'gt') _range.gt = map(range.gt, false)
+    else            _range.gte = map(range[lb], false)
+  }
+  else if(defaults)
+    _range.gte = map(lower, false)
+
+  if(ub) {
+    if(ub === 'lt') _range.lt = map(range.lt, true)
+    else            _range.lte = map(range[ub], true)
+  }
+  else if(defaults)
+    _range.lte = map(upper, true)
+
+  if(range.reverse != null)
+    _range.reverse = !!range.reverse
+
+  //if range was used mutably
+  //(in level-sublevel it's part of an options object
+  //that has more properties on it.)
+  if(has(_range, 'max'))   delete _range.max
+  if(has(_range, 'min'))   delete _range.min
+  if(has(_range, 'start')) delete _range.start
+  if(has(_range, 'end'))   delete _range.end
+
+  return _range
+}
+
+exports.contains = function (range, key, compare) {
+  compare = compare || exports.compare
+
+  var lb = lowerBound(range)
+  if(isDef(lb)) {
+    var cmp = compare(key, lb)
+    if(cmp < 0 || (cmp === 0 && lowerBoundExclusive(range)))
+      return false
+  }
+
+  var ub = upperBound(range)
+  if(isDef(ub)) {
+    var cmp = compare(key, ub)
+    if(cmp > 0 || (cmp === 0) && upperBoundExclusive(range))
+      return false
+  }
+
+  return true
+}
+
+exports.filter = function (range, compare) {
+  return function (key) {
+    return exports.contains(range, key, compare)
+  }
+}
+
+}).call(this,{"isBuffer":_dereq_(24)})
+},{"24":24}],78:[function(_dereq_,module,exports){
+arguments[4][32][0].apply(exports,arguments)
+},{"23":23,"32":32,"55":55,"6":6,"80":80,"82":82}],79:[function(_dereq_,module,exports){
+arguments[4][33][0].apply(exports,arguments)
+},{"23":23,"33":33,"6":6,"81":81}],80:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Readable;
+
+/*<replacement>*/
+var isArray = _dereq_(76);
+/*</replacement>*/
+
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Readable.ReadableState = ReadableState;
+
+var EE = _dereq_(19).EventEmitter;
+
+/*<replacement>*/
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+  return emitter.listeners(type).length;
+};
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+function ReadableState(options, stream) {
+  options = options || {};
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.buffer = [];
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = false;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // In streams that never have any data, and do push(null) right away,
+  // the consumer can miss the 'end' event if they do some I/O before
+  // consuming the stream.  So, we don't emit('end') until some reading
+  // happens.
+  this.calledRead = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // when piping, we only care about 'readable' events that happen
+  // after read()ing all the bytes and not getting any pushback.
+  this.ranOut = false;
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder)
+      StringDecoder = _dereq_(69).StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  if (!(this instanceof Readable))
+    return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (typeof chunk === 'string' && !state.objectMode) {
+    encoding = encoding || state.defaultEncoding;
+    if (encoding !== state.encoding) {
+      chunk = new Buffer(chunk, encoding);
+      encoding = '';
+    }
+  }
+
+  return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function(chunk) {
+  var state = this._readableState;
+  return readableAddChunk(this, state, chunk, '', true);
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+  var er = chunkInvalid(state, chunk);
+  if (er) {
+    stream.emit('error', er);
+  } else if (chunk === null || chunk === undefined) {
+    state.reading = false;
+    if (!state.ended)
+      onEofChunk(stream, state);
+  } else if (state.objectMode || chunk && chunk.length > 0) {
+    if (state.ended && !addToFront) {
+      var e = new Error('stream.push() after EOF');
+      stream.emit('error', e);
+    } else if (state.endEmitted && addToFront) {
+      var e = new Error('stream.unshift() after end event');
+      stream.emit('error', e);
+    } else {
+      if (state.decoder && !addToFront && !encoding)
+        chunk = state.decoder.write(chunk);
+
+      // update the buffer info.
+      state.length += state.objectMode ? 1 : chunk.length;
+      if (addToFront) {
+        state.buffer.unshift(chunk);
+      } else {
+        state.reading = false;
+        state.buffer.push(chunk);
+      }
+
+      if (state.needReadable)
+        emitReadable(stream);
+
+      maybeReadMore(stream, state);
+    }
+  } else if (!addToFront) {
+    state.reading = false;
+  }
+
+  return needMoreData(state);
+}
+
+
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes.  This is to work around cases where hwm=0,
+// such as the repl.  Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended &&
+         (state.needReadable ||
+          state.length < state.highWaterMark ||
+          state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function(enc) {
+  if (!StringDecoder)
+    StringDecoder = _dereq_(69).StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+};
+
+// Don't raise the hwm > 128MB
+var MAX_HWM = 0x800000;
+function roundUpToNextPowerOf2(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2
+    n--;
+    for (var p = 1; p < 32; p <<= 1) n |= n >> p;
+    n++;
+  }
+  return n;
+}
+
+function howMuchToRead(n, state) {
+  if (state.length === 0 && state.ended)
+    return 0;
+
+  if (state.objectMode)
+    return n === 0 ? 0 : 1;
+
+  if (n === null || isNaN(n)) {
+    // only flow one buffer at a time
+    if (state.flowing && state.buffer.length)
+      return state.buffer[0].length;
+    else
+      return state.length;
+  }
+
+  if (n <= 0)
+    return 0;
+
+  // If we're asking for more than the target buffer level,
+  // then raise the water mark.  Bump up to the next highest
+  // power of 2, to prevent increasing it excessively in tiny
+  // amounts.
+  if (n > state.highWaterMark)
+    state.highWaterMark = roundUpToNextPowerOf2(n);
+
+  // don't have that much.  return null, unless we've ended.
+  if (n > state.length) {
+    if (!state.ended) {
+      state.needReadable = true;
+      return 0;
+    } else
+      return state.length;
+  }
+
+  return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function(n) {
+  var state = this._readableState;
+  state.calledRead = true;
+  var nOrig = n;
+  var ret;
+
+  if (typeof n !== 'number' || n > 0)
+    state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 &&
+      state.needReadable &&
+      (state.length >= state.highWaterMark || state.ended)) {
+    emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    ret = null;
+
+    // In cases where the decoder did not receive enough data
+    // to produce a full chunk, then immediately received an
+    // EOF, state.buffer will contain [<Buffer >, <Buffer 00 ...>].
+    // howMuchToRead will see this and coerce the amount to
+    // read to zero (because it's looking at the length of the
+    // first <Buffer > in state.buffer), and we'll end up here.
+    //
+    // This can only happen via state.decoder -- no other venue
+    // exists for pushing a zero-length chunk into state.buffer
+    // and triggering this behavior. In this case, we return our
+    // remaining data and end the stream, if appropriate.
+    if (state.length > 0 && state.decoder) {
+      ret = fromList(n, state);
+      state.length -= ret.length;
+    }
+
+    if (state.length === 0)
+      endReadable(this);
+
+    return ret;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read.  The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous.  Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length - n <= state.highWaterMark)
+    doRead = true;
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading)
+    doRead = false;
+
+  if (doRead) {
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0)
+      state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+  }
+
+  // If _read called its callback synchronously, then `reading`
+  // will be false, and we need to re-evaluate how much data we
+  // can return to the user.
+  if (doRead && !state.reading)
+    n = howMuchToRead(nOrig, state);
+
+  if (n > 0)
+    ret = fromList(n, state);
+  else
+    ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  }
+
+  state.length -= n;
+
+  // If we have nothing in the buffer, then we want to know
+  // as soon as we *do* get something into the buffer.
+  if (state.length === 0 && !state.ended)
+    state.needReadable = true;
+
+  // If we happened to read() exactly the remaining amount in the
+  // buffer, and the EOF has been seen at this point, then make sure
+  // that we emit 'end' on the very next tick.
+  if (state.ended && !state.endEmitted && state.length === 0)
+    endReadable(this);
+
+  return ret;
+};
+
+function chunkInvalid(state, chunk) {
+  var er = null;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+
+function onEofChunk(stream, state) {
+  if (state.decoder && !state.ended) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // if we've ended and we have some data left, then emit
+  // 'readable' now to make sure it gets picked up.
+  if (state.length > 0)
+    emitReadable(stream);
+  else
+    endReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow.  This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (state.emittedReadable)
+    return;
+
+  state.emittedReadable = true;
+  if (state.sync)
+    process.nextTick(function() {
+      emitReadable_(stream);
+    });
+  else
+    emitReadable_(stream);
+}
+
+function emitReadable_(stream) {
+  stream.emit('readable');
+}
+
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data.  that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    process.nextTick(function() {
+      maybeReadMore_(stream, state);
+    });
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended &&
+         state.length < state.highWaterMark) {
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;
+    else
+      len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method.  to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function(n) {
+  this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function(dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
+              dest !== process.stdout &&
+              dest !== process.stderr;
+
+  var endFn = doEnd ? onend : cleanup;
+  if (state.endEmitted)
+    process.nextTick(endFn);
+  else
+    src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable) {
+    if (readable !== src) return;
+    cleanup();
+  }
+
+  function onend() {
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source.  This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  function cleanup() {
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', cleanup);
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (!dest._writableState || dest._writableState.needDrain)
+      ondrain();
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EE.listenerCount(dest, 'error') === 0)
+      dest.emit('error', er);
+  }
+  // This is a brutally ugly hack to make sure that our error handler
+  // is attached before any userland ones.  NEVER DO THIS.
+  if (!dest._events || !dest._events.error)
+    dest.on('error', onerror);
+  else if (isArray(dest._events.error))
+    dest._events.error.unshift(onerror);
+  else
+    dest._events.error = [onerror, dest._events.error];
+
+
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    // the handler that waits for readable events after all
+    // the data gets sucked out in flow.
+    // This would be easier to follow with a .once() handler
+    // in flow(), but that is too slow.
+    this.on('readable', pipeOnReadable);
+
+    state.flowing = true;
+    process.nextTick(function() {
+      flow(src);
+    });
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function() {
+    var dest = this;
+    var state = src._readableState;
+    state.awaitDrain--;
+    if (state.awaitDrain === 0)
+      flow(src);
+  };
+}
+
+function flow(src) {
+  var state = src._readableState;
+  var chunk;
+  state.awaitDrain = 0;
+
+  function write(dest, i, list) {
+    var written = dest.write(chunk);
+    if (false === written) {
+      state.awaitDrain++;
+    }
+  }
+
+  while (state.pipesCount && null !== (chunk = src.read())) {
+
+    if (state.pipesCount === 1)
+      write(state.pipes, 0, null);
+    else
+      forEach(state.pipes, write);
+
+    src.emit('data', chunk);
+
+    // if anyone needs a drain, then we have to wait for that.
+    if (state.awaitDrain > 0)
+      return;
+  }
+
+  // if every destination was unpiped, either before entering this
+  // function, or in the while loop, then stop flowing.
+  //
+  // NB: This is a pretty rare edge case.
+  if (state.pipesCount === 0) {
+    state.flowing = false;
+
+    // if there were data event listeners added, then switch to old mode.
+    if (EE.listenerCount(src, 'data') > 0)
+      emitDataEvents(src);
+    return;
+  }
+
+  // at this point, no one needed a drain, so we just ran out of data
+  // on the next readable event, start it over again.
+  state.ranOut = true;
+}
+
+function pipeOnReadable() {
+  if (this._readableState.ranOut) {
+    this._readableState.ranOut = false;
+    flow(this);
+  }
+}
+
+
+Readable.prototype.unpipe = function(dest) {
+  var state = this._readableState;
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0)
+    return this;
+
+  // just one destination.  most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes)
+      return this;
+
+    if (!dest)
+      dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+    if (dest)
+      dest.emit('unpipe', this);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++)
+      dests[i].emit('unpipe', this);
+    return this;
+  }
+
+  // try to find the right one.
+  var i = indexOf(state.pipes, dest);
+  if (i === -1)
+    return this;
+
+  state.pipes.splice(i, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1)
+    state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function(ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  if (ev === 'data' && !this._readableState.flowing)
+    emitDataEvents(this);
+
+  if (ev === 'readable' && this.readable) {
+    var state = this._readableState;
+    if (!state.readableListening) {
+      state.readableListening = true;
+      state.emittedReadable = false;
+      state.needReadable = true;
+      if (!state.reading) {
+        this.read(0);
+      } else if (state.length) {
+        emitReadable(this, state);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function() {
+  emitDataEvents(this);
+  this.read(0);
+  this.emit('resume');
+};
+
+Readable.prototype.pause = function() {
+  emitDataEvents(this, true);
+  this.emit('pause');
+};
+
+function emitDataEvents(stream, startPaused) {
+  var state = stream._readableState;
+
+  if (state.flowing) {
+    // https://github.com/isaacs/readable-stream/issues/16
+    throw new Error('Cannot switch to old mode now.');
+  }
+
+  var paused = startPaused || false;
+  var readable = false;
+
+  // convert to an old-style stream.
+  stream.readable = true;
+  stream.pipe = Stream.prototype.pipe;
+  stream.on = stream.addListener = Stream.prototype.on;
+
+  stream.on('readable', function() {
+    readable = true;
+
+    var c;
+    while (!paused && (null !== (c = stream.read())))
+      stream.emit('data', c);
+
+    if (c === null) {
+      readable = false;
+      stream._readableState.needReadable = true;
+    }
+  });
+
+  stream.pause = function() {
+    paused = true;
+    this.emit('pause');
+  };
+
+  stream.resume = function() {
+    paused = false;
+    if (readable)
+      process.nextTick(function() {
+        stream.emit('readable');
+      });
+    else
+      this.read(0);
+    this.emit('resume');
+  };
+
+  // now make it start, just in case it hadn't already.
+  stream.emit('readable');
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function(stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function() {
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length)
+        self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function(chunk) {
+    if (state.decoder)
+      chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    //if (state.objectMode && util.isNullOrUndefined(chunk))
+    if (state.objectMode && (chunk === null || chunk === undefined))
+      return;
+    else if (!state.objectMode && (!chunk || !chunk.length))
+      return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (typeof stream[i] === 'function' &&
+        typeof this[i] === 'undefined') {
+      this[i] = function(method) { return function() {
+        return stream[method].apply(stream, arguments);
+      }}(i);
+    }
+  }
+
+  // proxy certain important events.
+  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+  forEach(events, function(ev) {
+    stream.on(ev, self.emit.bind(self, ev));
+  });
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function(n) {
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+  var list = state.buffer;
+  var length = state.length;
+  var stringMode = !!state.decoder;
+  var objectMode = !!state.objectMode;
+  var ret;
+
+  // nothing in the list, definitely empty.
+  if (list.length === 0)
+    return null;
+
+  if (length === 0)
+    ret = null;
+  else if (objectMode)
+    ret = list.shift();
+  else if (!n || n >= length) {
+    // read it all, truncate the array.
+    if (stringMode)
+      ret = list.join('');
+    else
+      ret = Buffer.concat(list, length);
+    list.length = 0;
+  } else {
+    // read just some of it.
+    if (n < list[0].length) {
+      // just take a part of the first list item.
+      // slice is the same for buffers and strings.
+      var buf = list[0];
+      ret = buf.slice(0, n);
+      list[0] = buf.slice(n);
+    } else if (n === list[0].length) {
+      // first list is a perfect match
+      ret = list.shift();
+    } else {
+      // complex case.
+      // we have enough to cover it, but it spans past the first buffer.
+      if (stringMode)
+        ret = '';
+      else
+        ret = new Buffer(n);
+
+      var c = 0;
+      for (var i = 0, l = list.length; i < l && c < n; i++) {
+        var buf = list[0];
+        var cpy = Math.min(n - c, buf.length);
+
+        if (stringMode)
+          ret += buf.slice(0, cpy);
+        else
+          buf.copy(ret, c, 0, cpy);
+
+        if (cpy < buf.length)
+          list[0] = buf.slice(cpy);
+        else
+          list.shift();
+
+        c += cpy;
+      }
+    }
+  }
+
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node.  Should never happen.
+  if (state.length > 0)
+    throw new Error('endReadable called on non-empty stream');
+
+  if (!state.endEmitted && state.calledRead) {
+    state.ended = true;
+    process.nextTick(function() {
+      // Check that we didn't get one last unshift.
+      if (!state.endEmitted && state.length === 0) {
+        state.endEmitted = true;
+        stream.readable = false;
+        stream.emit('end');
+      }
+    });
+  }
+}
+
+function forEach (xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf (xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+
+}).call(this,_dereq_(55))
+},{"19":19,"23":23,"5":5,"55":55,"58":58,"6":6,"69":69,"76":76}],81:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// a transform stream is a readable/writable stream where you do
+// something with the data.  Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored.  (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation.  For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes.  When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up.  When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer.  When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks.  If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk.  However,
+// a pathological inflate type of transform can cause excessive buffering
+// here.  For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output.  In this case, you could write a very small
+// amount of input, and end up with a very large amount of output.  In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform.  A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+module.exports = Transform;
+
+var Duplex = _dereq_(78);
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+util.inherits(Transform, Duplex);
+
+
+function TransformState(options, stream) {
+  this.afterTransform = function(er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb)
+    return stream.emit('error', new Error('no writecb in Transform class'));
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined)
+    stream.push(data);
+
+  if (cb)
+    cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+
+function Transform(options) {
+  if (!(this instanceof Transform))
+    return new Transform(options);
+
+  Duplex.call(this, options);
+
+  var ts = this._transformState = new TransformState(options, this);
+
+  // when the writable side finishes, then flush out anything remaining.
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  this.once('finish', function() {
+    if ('function' === typeof this._flush)
+      this._flush(function(er) {
+        done(stream, er);
+      });
+    else
+      done(stream);
+  });
+}
+
+Transform.prototype.push = function(chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side.  You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk.  If you pass
+// an error, then that'll put the hurt on the whole operation.  If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function(chunk, encoding, cb) {
+  throw new Error('not implemented');
+};
+
+Transform.prototype._write = function(chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform ||
+        rs.needReadable ||
+        rs.length < rs.highWaterMark)
+      this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function(n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+
+function done(stream, er) {
+  if (er)
+    return stream.emit('error', er);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var rs = stream._readableState;
+  var ts = stream._transformState;
+
+  if (ws.length)
+    throw new Error('calling transform done when ws.length != 0');
+
+  if (ts.transforming)
+    throw new Error('calling transform done when still transforming');
+
+  return stream.push(null);
+}
+
+},{"23":23,"6":6,"78":78}],82:[function(_dereq_,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, cb), and it'll handle all
+// the drain event emission and buffering.
+
+module.exports = Writable;
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+var Stream = _dereq_(58);
+
+util.inherits(Writable, Stream);
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+}
+
+function WritableState(options, stream) {
+  options = options || {};
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  // cast to ints.
+  this.highWaterMark = ~~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, becuase any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function(er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.buffer = [];
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+}
+
+function Writable(options) {
+  var Duplex = _dereq_(78);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex))
+    return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function() {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+
+function writeAfterEnd(stream, state, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  process.nextTick(function() {
+    cb(er);
+  });
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
+      !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    process.nextTick(function() {
+      cb(er);
+    });
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function(chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  else if (!encoding)
+    encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function')
+    cb = function() {};
+
+  if (state.ended)
+    writeAfterEnd(this, state, cb);
+  else if (validChunk(this, state, chunk, cb))
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+
+  return ret;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode &&
+      state.decodeStrings !== false &&
+      typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+  if (Buffer.isBuffer(chunk))
+    encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret)
+    state.needDrain = true;
+
+  if (state.writing)
+    state.buffer.push(new WriteReq(chunk, encoding, cb));
+  else
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+  return ret;
+}
+
+function doWrite(stream, state, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  if (sync)
+    process.nextTick(function() {
+      cb(er);
+    });
+  else
+    cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er)
+    onwriteError(stream, state, sync, er, cb);
+  else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(stream, state);
+
+    if (!finished && !state.bufferProcessing && state.buffer.length)
+      clearBuffer(stream, state);
+
+    if (sync) {
+      process.nextTick(function() {
+        afterWrite(stream, state, finished, cb);
+      });
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished)
+    onwriteDrain(stream, state);
+  cb();
+  if (finished)
+    finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+
+  for (var c = 0; c < state.buffer.length; c++) {
+    var entry = state.buffer[c];
+    var chunk = entry.chunk;
+    var encoding = entry.encoding;
+    var cb = entry.callback;
+    var len = state.objectMode ? 1 : chunk.length;
+
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+    // if we didn't call the onwrite immediately, then
+    // it means that we need to wait until it does.
+    // also, that means that the chunk and cb are currently
+    // being processed, so move the buffer counter past them.
+    if (state.writing) {
+      c++;
+      break;
+    }
+  }
+
+  state.bufferProcessing = false;
+  if (c < state.buffer.length)
+    state.buffer = state.buffer.slice(c);
+  else
+    state.buffer.length = 0;
+}
+
+Writable.prototype._write = function(chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype.end = function(chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (typeof chunk !== 'undefined' && chunk !== null)
+    this.write(chunk, encoding);
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished)
+    endWritable(this, state, cb);
+};
+
+
+function needFinish(stream, state) {
+  return (state.ending &&
+          state.length === 0 &&
+          !state.finished &&
+          !state.writing);
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(stream, state);
+  if (need) {
+    state.finished = true;
+    stream.emit('finish');
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished)
+      process.nextTick(cb);
+    else
+      stream.once('finish', cb);
+  }
+  state.ended = true;
+}
+
+}).call(this,_dereq_(55))
+},{"23":23,"5":5,"55":55,"58":58,"6":6,"78":78}],83:[function(_dereq_,module,exports){
+var Stream = _dereq_(58); // hack to fix a circular dependency issue when used with browserify
+exports = module.exports = _dereq_(80);
+exports.Stream = Stream;
+exports.Readable = exports;
+exports.Writable = _dereq_(82);
+exports.Duplex = _dereq_(78);
+exports.Transform = _dereq_(81);
+exports.PassThrough = _dereq_(79);
+
+},{"58":58,"78":78,"79":79,"80":80,"81":81,"82":82}],84:[function(_dereq_,module,exports){
+arguments[4][60][0].apply(exports,arguments)
+},{"23":23,"54":54,"6":6,"60":60,"85":85,"87":87}],85:[function(_dereq_,module,exports){
+arguments[4][62][0].apply(exports,arguments)
+},{"19":19,"23":23,"25":25,"4":4,"5":5,"54":54,"55":55,"6":6,"62":62,"69":69,"84":84}],86:[function(_dereq_,module,exports){
+arguments[4][63][0].apply(exports,arguments)
+},{"23":23,"6":6,"63":63,"84":84}],87:[function(_dereq_,module,exports){
+(function (process){
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/*<replacement>*/
+var processNextTick = _dereq_(54);
+/*</replacement>*/
+
+/*<replacement>*/
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/*</replacement>*/
+
+/*<replacement>*/
+var Buffer = _dereq_(5).Buffer;
+/*</replacement>*/
+
+Writable.WritableState = WritableState;
+
+/*<replacement>*/
+var util = _dereq_(6);
+util.inherits = _dereq_(23);
+/*</replacement>*/
+
+/*<replacement>*/
+var internalUtil = {
+  deprecate: _dereq_(91)
+};
+/*</replacement>*/
+
+/*<replacement>*/
+var Stream;
+(function () {
+  try {
+    Stream = _dereq_('st' + 'ream');
+  } catch (_) {} finally {
+    if (!Stream) Stream = _dereq_(19).EventEmitter;
+  }
+})();
+/*</replacement>*/
+
+var Buffer = _dereq_(5).Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+  Duplex = Duplex || _dereq_(84);
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = ~ ~this.highWaterMark;
+
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty.  Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick.  We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // create the two objects needed to store the corked requests
+  // they are not a linked list, as no new elements are inserted in there
+  this.corkedRequestsFree = new CorkedRequest(this);
+  this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+    });
+  } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+  Duplex = Duplex || _dereq_(84);
+
+  // Writable ctor is applied to Duplexes, though they're not
+  // instanceof Writable, they're instanceof Readable.
+  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+
+  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+    var er = new TypeError('Invalid non-string/buffer chunk');
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = new Buffer(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn.  Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+  chunk = decodeChunk(state, chunk, encoding);
+
+  if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+  if (sync) processNextTick(cb, er);else cb(er);
+
+  stream._writableState.errorEmitted = true;
+  stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /*<replacement>*/
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /*</replacement>*/
+    } else {
+        afterWrite(stream, state, finished, cb);
+      }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    while (entry) {
+      buffer[count] = entry;
+      entry = entry.next;
+      count += 1;
+    }
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    state.corkedRequestsFree = holder.next;
+    holder.next = null;
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+  if (!state.prefinished) {
+    state.prefinished = true;
+    stream.emit('prefinish');
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    if (state.pendingcb === 0) {
+      prefinish(stream, state);
+      state.finished = true;
+      stream.emit('finish');
+    } else {
+      prefinish(stream, state);
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+
+  this.finish = function (err) {
+    var entry = _this.entry;
+    _this.entry = null;
+    while (entry) {
+      var cb = entry.callback;
+      state.pendingcb--;
+      cb(err);
+      entry = entry.next;
+    }
+    if (state.corkedRequestsFree) {
+      state.corkedRequestsFree.next = _this;
+    } else {
+      state.corkedRequestsFree = _this;
+    }
+  };
+}
+}).call(this,_dereq_(55))
+},{"19":19,"23":23,"5":5,"54":54,"55":55,"6":6,"84":84,"91":91}],88:[function(_dereq_,module,exports){
+arguments[4][67][0].apply(exports,arguments)
+},{"67":67,"86":86}],89:[function(_dereq_,module,exports){
+arguments[4][14][0].apply(exports,arguments)
+},{"14":14}],90:[function(_dereq_,module,exports){
+(function (process){
+var Transform = _dereq_(88)
+  , inherits  = _dereq_(93).inherits
+  , xtend     = _dereq_(89)
+
+function DestroyableTransform(opts) {
+  Transform.call(this, opts)
+  this._destroyed = false
+}
+
+inherits(DestroyableTransform, Transform)
+
+DestroyableTransform.prototype.destroy = function(err) {
+  if (this._destroyed) return
+  this._destroyed = true
+  
+  var self = this
+  process.nextTick(function() {
+    if (err)
+      self.emit('error', err)
+    self.emit('close')
+  })
+}
+
+// a noop _transform function
+function noop (chunk, enc, callback) {
+  callback(null, chunk)
+}
+
+
+// create a new export function, used by both the main export and
+// the .ctor export, contains common logic for dealing with arguments
+function through2 (construct) {
+  return function (options, transform, flush) {
+    if (typeof options == 'function') {
+      flush     = transform
+      transform = options
+      options   = {}
+    }
+
+    if (typeof transform != 'function')
+      transform = noop
+
+    if (typeof flush != 'function')
+      flush = null
+
+    return construct(options, transform, flush)
+  }
+}
+
+
+// main export, just make me a transform stream!
+module.exports = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(options)
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+
+// make me a reusable prototype that I can `new`, or implicitly `new`
+// with a constructor call
+module.exports.ctor = through2(function (options, transform, flush) {
+  function Through2 (override) {
+    if (!(this instanceof Through2))
+      return new Through2(override)
+
+    this.options = xtend(options, override)
+
+    DestroyableTransform.call(this, this.options)
+  }
+
+  inherits(Through2, DestroyableTransform)
+
+  Through2.prototype._transform = transform
+
+  if (flush)
+    Through2.prototype._flush = flush
+
+  return Through2
+})
+
+
+module.exports.obj = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options))
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+}).call(this,_dereq_(55))
+},{"55":55,"88":88,"89":89,"93":93}],91:[function(_dereq_,module,exports){
+(function (global){
+
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used.
+ * Returns a modified function which warns once by default.
+ *
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ *
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ *
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ *
+ * @param {Function} fn - the function to deprecate
+ * @param {String} msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+  if (config('noDeprecation')) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (config('throwDeprecation')) {
+        throw new Error(msg);
+      } else if (config('traceDeprecation')) {
+        console.trace(msg);
+      } else {
+        console.warn(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ *
+ * @param {String} name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
+  try {
+    if (!global.localStorage) return false;
+  } catch (_) {
+    return false;
+  }
+  var val = global.localStorage[name];
+  if (null == val) return false;
+  return String(val).toLowerCase() === 'true';
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],92:[function(_dereq_,module,exports){
+module.exports = function isBuffer(arg) {
+  return arg && typeof arg === 'object'
+    && typeof arg.copy === 'function'
+    && typeof arg.fill === 'function'
+    && typeof arg.readUInt8 === 'function';
+}
+},{}],93:[function(_dereq_,module,exports){
+(function (process,global){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+  if (!isString(f)) {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j':
+        try {
+          return JSON.stringify(args[i++]);
+        } catch (_) {
+          return '[Circular]';
+        }
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (isNull(x) || !isObject(x)) {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+  // Allow for deprecating things in the process of starting up.
+  if (isUndefined(global.process)) {
+    return function() {
+      return exports.deprecate(fn, msg).apply(this, arguments);
+    };
+  }
+
+  if (process.noDeprecation === true) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (process.throwDeprecation) {
+        throw new Error(msg);
+      } else if (process.traceDeprecation) {
+        console.trace(msg);
+      } else {
+        console.error(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+  if (isUndefined(debugEnviron))
+    debugEnviron = process.env.NODE_DEBUG || '';
+  set = set.toUpperCase();
+  if (!debugs[set]) {
+    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+      var pid = process.pid;
+      debugs[set] = function() {
+        var msg = exports.format.apply(exports, arguments);
+        console.error('%s %d: %s', set, pid, msg);
+      };
+    } else {
+      debugs[set] = function() {};
+    }
+  }
+  return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+  // default options
+  var ctx = {
+    seen: [],
+    stylize: stylizeNoColor
+  };
+  // legacy...
+  if (arguments.length >= 3) ctx.depth = arguments[2];
+  if (arguments.length >= 4) ctx.colors = arguments[3];
+  if (isBoolean(opts)) {
+    // legacy...
+    ctx.showHidden = opts;
+  } else if (opts) {
+    // got an "options" object
+    exports._extend(ctx, opts);
+  }
+  // set default options
+  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+  if (isUndefined(ctx.depth)) ctx.depth = 2;
+  if (isUndefined(ctx.colors)) ctx.colors = false;
+  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+  if (ctx.colors) ctx.stylize = stylizeWithColor;
+  return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+  'bold' : [1, 22],
+  'italic' : [3, 23],
+  'underline' : [4, 24],
+  'inverse' : [7, 27],
+  'white' : [37, 39],
+  'grey' : [90, 39],
+  'black' : [30, 39],
+  'blue' : [34, 39],
+  'cyan' : [36, 39],
+  'green' : [32, 39],
+  'magenta' : [35, 39],
+  'red' : [31, 39],
+  'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+  'special': 'cyan',
+  'number': 'yellow',
+  'boolean': 'yellow',
+  'undefined': 'grey',
+  'null': 'bold',
+  'string': 'green',
+  'date': 'magenta',
+  // "name": intentionally not styling
+  'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+  var style = inspect.styles[styleType];
+
+  if (style) {
+    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+           '\u001b[' + inspect.colors[style][1] + 'm';
+  } else {
+    return str;
+  }
+}
+
+
+function stylizeNoColor(str, styleType) {
+  return str;
+}
+
+
+function arrayToHash(array) {
+  var hash = {};
+
+  array.forEach(function(val, idx) {
+    hash[val] = true;
+  });
+
+  return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+  // Provide a hook for user-specified inspect functions.
+  // Check that value is an object with an inspect function on it
+  if (ctx.customInspect &&
+      value &&
+      isFunction(value.inspect) &&
+      // Filter out the util module, it's inspect function is special
+      value.inspect !== exports.inspect &&
+      // Also filter out any prototype objects using the circular check.
+      !(value.constructor && value.constructor.prototype === value)) {
+    var ret = value.inspect(recurseTimes, ctx);
+    if (!isString(ret)) {
+      ret = formatValue(ctx, ret, recurseTimes);
+    }
+    return ret;
+  }
+
+  // Primitive types cannot have properties
+  var primitive = formatPrimitive(ctx, value);
+  if (primitive) {
+    return primitive;
+  }
+
+  // Look up the keys of the object.
+  var keys = Object.keys(value);
+  var visibleKeys = arrayToHash(keys);
+
+  if (ctx.showHidden) {
+    keys = Object.getOwnPropertyNames(value);
+  }
+
+  // IE doesn't make error fields non-enumerable
+  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+  if (isError(value)
+      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+    return formatError(value);
+  }
+
+  // Some type of object without properties can be shortcutted.
+  if (keys.length === 0) {
+    if (isFunction(value)) {
+      var name = value.name ? ': ' + value.name : '';
+      return ctx.stylize('[Function' + name + ']', 'special');
+    }
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    }
+    if (isDate(value)) {
+      return ctx.stylize(Date.prototype.toString.call(value), 'date');
+    }
+    if (isError(value)) {
+      return formatError(value);
+    }
+  }
+
+  var base = '', array = false, braces = ['{', '}'];
+
+  // Make Array say that they are Array
+  if (isArray(value)) {
+    array = true;
+    braces = ['[', ']'];
+  }
+
+  // Make functions say that they are functions
+  if (isFunction(value)) {
+    var n = value.name ? ': ' + value.name : '';
+    base = ' [Function' + n + ']';
+  }
+
+  // Make RegExps say that they are RegExps
+  if (isRegExp(value)) {
+    base = ' ' + RegExp.prototype.toString.call(value);
+  }
+
+  // Make dates with properties first say the date
+  if (isDate(value)) {
+    base = ' ' + Date.prototype.toUTCString.call(value);
+  }
+
+  // Make error with message first say the error
+  if (isError(value)) {
+    base = ' ' + formatError(value);
+  }
+
+  if (keys.length === 0 && (!array || value.length == 0)) {
+    return braces[0] + base + braces[1];
+  }
+
+  if (recurseTimes < 0) {
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    } else {
+      return ctx.stylize('[Object]', 'special');
+    }
+  }
+
+  ctx.seen.push(value);
+
+  var output;
+  if (array) {
+    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+  } else {
+    output = keys.map(function(key) {
+      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+    });
+  }
+
+  ctx.seen.pop();
+
+  return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+  if (isUndefined(value))
+    return ctx.stylize('undefined', 'undefined');
+  if (isString(value)) {
+    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+                                             .replace(/'/g, "\\'")
+                                             .replace(/\\"/g, '"') + '\'';
+    return ctx.stylize(simple, 'string');
+  }
+  if (isNumber(value))
+    return ctx.stylize('' + value, 'number');
+  if (isBoolean(value))
+    return ctx.stylize('' + value, 'boolean');
+  // For some reason typeof null is "object", so special case here.
+  if (isNull(value))
+    return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+  return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+  var output = [];
+  for (var i = 0, l = value.length; i < l; ++i) {
+    if (hasOwnProperty(value, String(i))) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          String(i), true));
+    } else {
+      output.push('');
+    }
+  }
+  keys.forEach(function(key) {
+    if (!key.match(/^\d+$/)) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          key, true));
+    }
+  });
+  return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+  var name, str, desc;
+  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+  if (desc.get) {
+    if (desc.set) {
+      str = ctx.stylize('[Getter/Setter]', 'special');
+    } else {
+      str = ctx.stylize('[Getter]', 'special');
+    }
+  } else {
+    if (desc.set) {
+      str = ctx.stylize('[Setter]', 'special');
+    }
+  }
+  if (!hasOwnProperty(visibleKeys, key)) {
+    name = '[' + key + ']';
+  }
+  if (!str) {
+    if (ctx.seen.indexOf(desc.value) < 0) {
+      if (isNull(recurseTimes)) {
+        str = formatValue(ctx, desc.value, null);
+      } else {
+        str = formatValue(ctx, desc.value, recurseTimes - 1);
+      }
+      if (str.indexOf('\n') > -1) {
+        if (array) {
+          str = str.split('\n').map(function(line) {
+            return '  ' + line;
+          }).join('\n').substr(2);
+        } else {
+          str = '\n' + str.split('\n').map(function(line) {
+            return '   ' + line;
+          }).join('\n');
+        }
+      }
+    } else {
+      str = ctx.stylize('[Circular]', 'special');
+    }
+  }
+  if (isUndefined(name)) {
+    if (array && key.match(/^\d+$/)) {
+      return str;
+    }
+    name = JSON.stringify('' + key);
+    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+      name = name.substr(1, name.length - 2);
+      name = ctx.stylize(name, 'name');
+    } else {
+      name = name.replace(/'/g, "\\'")
+                 .replace(/\\"/g, '"')
+                 .replace(/(^"|"$)/g, "'");
+      name = ctx.stylize(name, 'string');
+    }
+  }
+
+  return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+  var numLinesEst = 0;
+  var length = output.reduce(function(prev, cur) {
+    numLinesEst++;
+    if (cur.indexOf('\n') >= 0) numLinesEst++;
+    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+  }, 0);
+
+  if (length > 60) {
+    return braces[0] +
+           (base === '' ? '' : base + '\n ') +
+           ' ' +
+           output.join(',\n  ') +
+           ' ' +
+           braces[1];
+  }
+
+  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+  return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return isObject(e) &&
+      (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = _dereq_(92);
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+  return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+              'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+  var d = new Date();
+  var time = [pad(d.getHours()),
+              pad(d.getMinutes()),
+              pad(d.getSeconds())].join(':');
+  return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ *     prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = _dereq_(23);
+
+exports._extend = function(origin, add) {
+  // Don't do anything if add isn't an object
+  if (!add || !isObject(add)) return origin;
+
+  var keys = Object.keys(add);
+  var i = keys.length;
+  while (i--) {
+    origin[keys[i]] = add[keys[i]];
+  }
+  return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+}).call(this,_dereq_(55),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"23":23,"55":55,"92":92}],94:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+  var queue = [];
+  queue.push({obj: input});
+
+  var res = '';
+  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+  while ((next = queue.pop())) {
+    obj = next.obj;
+    prefix = next.prefix || '';
+    val = next.val || '';
+    res += prefix;
+    if (val) {
+      res += val;
+    } else if (typeof obj !== 'object') {
+      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+    } else if (obj === null) {
+      res += 'null';
+    } else if (Array.isArray(obj)) {
+      queue.push({val: ']'});
+      for (i = obj.length - 1; i >= 0; i--) {
+        arrayPrefix = i === 0 ? '' : ',';
+        queue.push({obj: obj[i], prefix: arrayPrefix});
+      }
+      queue.push({val: '['});
+    } else { // object
+      keys = [];
+      for (k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          keys.push(k);
+        }
+      }
+      queue.push({val: '}'});
+      for (i = keys.length - 1; i >= 0; i--) {
+        key = keys[i];
+        value = obj[key];
+        objPrefix = (i > 0 ? ',' : '');
+        objPrefix += JSON.stringify(key) + ':';
+        queue.push({obj: value, prefix: objPrefix});
+      }
+      queue.push({val: '{'});
+    }
+  }
+  return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+  var lastMetaElement = metaStack[metaStack.length - 1];
+  if (obj === lastMetaElement.element) {
+    // popping a meta-element, e.g. an object whose value is another object
+    metaStack.pop();
+    lastMetaElement = metaStack[metaStack.length - 1];
+  }
+  var element = lastMetaElement.element;
+  var lastElementIndex = lastMetaElement.index;
+  if (Array.isArray(element)) {
+    element.push(obj);
+  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+    var key = stack.pop();
+    element[key] = obj;
+  } else {
+    stack.push(obj); // obj with key only
+  }
+}
+
+exports.parse = function (str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
+  var collationIndex,parsedNum,numChar;
+  var parsedString,lastCh,numConsecutiveSlashes,ch;
+  var arrayElement, objElement;
+  while (true) {
+    collationIndex = str[i++];
+    if (collationIndex === '}' ||
+        collationIndex === ']' ||
+        typeof collationIndex === 'undefined') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack.pop(), stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case ' ':
+      case '\t':
+      case '\n':
+      case ':':
+      case ',':
+        break;
+      case 'n':
+        i += 3; // 'ull'
+        pop(null, stack, metaStack);
+        break;
+      case 't':
+        i += 3; // 'rue'
+        pop(true, stack, metaStack);
+        break;
+      case 'f':
+        i += 4; // 'alse'
+        pop(false, stack, metaStack);
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '-':
+        parsedNum = '';
+        i--;
+        while (true) {
+          numChar = str[i++];
+          if (/[\d\.\-e\+]/.test(numChar)) {
+            parsedNum += numChar;
+          } else {
+            i--;
+            break;
+          }
+        }
+        pop(parseFloat(parsedNum), stack, metaStack);
+        break;
+      case '"':
+        parsedString = '';
+        lastCh = void 0;
+        numConsecutiveSlashes = 0;
+        while (true) {
+          ch = str[i++];
+          if (ch !== '"' || (lastCh === '\\' &&
+              numConsecutiveSlashes % 2 === 1)) {
+            parsedString += ch;
+            lastCh = ch;
+            if (lastCh === '\\') {
+              numConsecutiveSlashes++;
+            } else {
+              numConsecutiveSlashes = 0;
+            }
+          } else {
+            break;
+          }
+        }
+        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+        break;
+      case '[':
+        arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '{':
+        objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      default:
+        throw new Error(
+          'unexpectedly reached end of input: ' + collationIndex);
+    }
+  }
+};
+
+},{}]},{},[1]);
diff --git a/dist/pouchdb.memory.min.js b/dist/pouchdb.memory.min.js
new file mode 100644
index 0000000..16ff15d
--- /dev/null
+++ b/dist/pouchdb.memory.min.js
@@ -0,0 +1,14 @@
+// PouchDB in-memory plugin 5.3.2
+// Based on MemDOWN: https://github.com/rvagg/memdown
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+!function e(t,n,r){function i(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return i(n?n:e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<r.length;a++)i(r[a]);return i}({1:[function(e,t,n){(function(t,n,r){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e["default"]:e}function o(e){return e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}function a(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}function s(e){if(e instanceof ArrayBuffer)return a(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}function u(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;r>n;n++)t[n]=u(e[n]);return t}if(e instanceof Date)return e.toISOString();if(o(e))return s(e);t={};for(n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var i=u(e[n]);"undefined"!=typeof i&&(t[n]=i)}return t}function c(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function f(){return me}function l(e,t){for(var n={},r=0,i=t.length;i>r;r++){var o=t[r];o in e&&(n[o]=e[o])}return n}function h(e){c()?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):f()&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}function d(){Se.EventEmitter.call(this),this._listeners={},h(this)}function p(e){return 0|Math.random()*e}function g(e,t){t=t||Ie.length;var n="",r=-1;if(e){for(;++r<e;)n+=Ie[p(t)];return n}for(;++r<36;)switch(r){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=Ie[3&p(16)|8];break;default:n+=Ie[p(16)]}return n}function v(e){Error.call(this,e.reason),this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}function y(e,t,n){function r(t){for(var r in e)"function"!=typeof e[r]&&(this[r]=e[r]);void 0!==n&&(this.name=n),void 0!==t&&(this.reason=t)}return r.prototype=v.prototype,new r(t)}function _(e,t,n){try{return!e(t,n)}catch(r){var i="Filter function threw: "+r.toString();return y(Ye,i)}}function b(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){r.doc||(r.doc={});var i=n&&_(e.filter,r.doc,t);if("object"==typeof i)return i;if(i)return!1;if(e.include_docs){if(!e.attachments)for(var o in r.doc._attachments)r.doc._attachments.hasOwnProperty(o)&&(r.doc._attachments[o].stub=!0)}else delete r.doc;return!0}}function m(e){try{return JSON.parse(e)}catch(t){return Ae.parse(e)}}function w(e){return e.length<5e4?JSON.parse(e):m(e)}function E(e){try{return JSON.stringify(e)}catch(t){return Ae.stringify(e)}}function k(e){for(var t,n,r,i,o=e.rev_tree.slice();i=o.pop();){var a=i.ids,s=a[2],u=i.pos;if(s.length)for(var c=0,f=s.length;f>c;c++)o.push({pos:u+1,ids:s[c]});else{var l=!!a[1].deleted,h=a[0];t&&!(r!==l?r:n!==u?u>n:h>t)||(t=h,n=u,r=l)}}return n+"-"+t}function S(e,t){for(var n,r=e.slice();n=r.pop();)for(var i=n.pos,o=n.ids,a=o[2],s=t(0===a.length,i,o[0],n.ctx,o[1]),u=0,c=a.length;c>u;u++)r.push({pos:i+1,ids:a[u],ctx:s})}function x(e){var t=[];return S(e.rev_tree,function(e,n,r,i,o){"available"!==o.status||e||(t.push(n+"-"+r),o.status="missing")}),t}function B(e,t){return e.pos-t.pos}function R(e){var t=[];S(e,function(e,n,r,i,o){e&&t.push({rev:n+"-"+r,pos:n,opts:o})}),t.sort(B).reverse();for(var n=0,r=t.length;r>n;n++)delete t[n].pos;return t}function A(e){for(var t=k(e),n=R(e.rev_tree),r=[],i=0,o=n.length;o>i;i++){var a=n[i];a.rev===t||a.opts.deleted||r.push(a.rev)}return r}function M(e){return e.ids}function j(e,t){t||(t=k(e));for(var n,r=t.substring(t.indexOf("-")+1),i=e.rev_tree.map(M);n=i.pop();){if(n[0]===r)return!!n[1].deleted;i=i.concat(n[2])}}function O(e){return/^_local/.test(e)}function L(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function T(e){var t;if(e?"string"!=typeof e?t=y(qe):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=y(We)):t=y(Ue),t)throw t}function C(e){if(!/^\d+\-./.test(e))return y(Je);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function I(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,i=[r[0],t,[]],o=1,a=r.length;a>o;o++)i=[r[o],{status:"missing"},[i]];return[{pos:n,ids:i}]}function D(e,t){var n,r,i,o={status:"available"};if(e._deleted&&(o.deleted=!0),t)if(e._id||(e._id=g()),r=g(32,16).toLowerCase(),e._rev){if(i=C(e._rev),i.error)return i;e._rev_tree=[{pos:i.prefix,ids:[i.id,{status:"missing"},[[r,o,[]]]]}],n=i.prefix+1}else e._rev_tree=[{pos:1,ids:[r,o,[]]}],n=1;else if(e._revisions&&(e._rev_tree=I(e._revisions,o),n=e._revisions.start,r=e._revisions.ids[0]),!e._rev_tree){if(i=C(e._rev),i.error)return i;n=i.prefix,r=i.id,e._rev_tree=[{pos:n,ids:[r,o,[]]}]}T(e._id),e._rev=n+"-"+r;var a={metadata:{},data:{}};for(var s in e)if(Object.prototype.hasOwnProperty.call(e,s)){var u="_"===s[0];if(u&&!He[s]){var c=y(Ke,s);throw c.message=Ke.message+": "+s,c}u&&!Ge[s]?a.metadata[s.slice(1)]=e[s]:a.data[s]=e[s]}return a}function P(e){for(var t,n=[],r=e.slice();t=r.pop();){var i=t.pos,o=t.ids,a=o[0],s=o[1],u=o[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:a,opts:s}),c&&n.push({pos:i+1-f.length,ids:f});for(var l=0,h=u.length;h>l;l++)r.push({pos:i+1,ids:u[l],history:f})}return n.reverse()}function N(e,t){return e.pos-t.pos}function q(e,t,n){for(var r,i=0,o=e.length;o>i;)r=i+o>>>1,n(e[r],t)<0?i=r+1:o=r;return i}function U(e,t,n){var r=q(e,t,n);e.splice(r,0,t)}function W(e,t){for(var n,r,i=t,o=e.length;o>i;i++){var a=e[i],s=[a.id,a.opts,[]];r?(r[2].push(s),r=s):n=r=s}return n}function F(e,t){return e[0]<t[0]?-1:1}function z(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var i=n.pop(),o=i.tree1,a=i.tree2;(o[1].status||a[1].status)&&(o[1].status="available"===o[1].status||"available"===a[1].status?"available":"missing");for(var s=0;s<a[2].length;s++)if(o[2][0]){for(var u=!1,c=0;c<o[2].length;c++)o[2][c][0]===a[2][s][0]&&(n.push({tree1:o[2][c],tree2:a[2][s]}),u=!0);u||(r="new_branch",U(o[2],a[2][s],F))}else r="new_leaf",o[2][0]=a[2][s]}return{conflicts:r,tree:e}}function K(e,t,n){var r,i=[],o=!1,a=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var s=0,u=e.length;u>s;s++){var c=e[s];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=z(c.ids,t.ids),i.push({pos:c.pos,ids:r.tree}),o=o||r.conflicts,a=!0;else if(n!==!0){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,h=l.pos-f.pos,d=[],p=[];for(p.push({ids:f.ids,diff:h,parent:null,parentIdx:null});p.length>0;){var g=p.pop();if(0!==g.diff)for(var v=g.ids[2],y=0,_=v.length;_>y;y++)p.push({ids:v[y],diff:g.diff-1,parent:g.ids,parentIdx:y});else g.ids[0]===l.ids[0]&&d.push(g)}var b=d[0];b?(r=z(b.ids,l.ids),b.parent[2][b.parentIdx]=r.tree,i.push({pos:f.pos,ids:f.ids}),o=o||r.conflicts,a=!0):i.push(c)}else i.push(c)}return a||i.push(t),i.sort(N),{tree:i,conflicts:o||"internal_node"}}function Y(e,t){for(var n,r=P(e),i={},o=0,a=r.length;a>o;o++){for(var s=r[o],u=s.ids,c=Math.max(0,u.length-t),f={pos:s.pos+c,ids:W(u,c)},l=0;c>l;l++){var h=s.pos+l+"-"+u[l].id;i[h]=!0}n=n?K(n,f,!0).tree:[f]}return S(n,function(e,t,n){delete i[t+"-"+n]}),{tree:n,revs:Object.keys(i)}}function J(e,t,n){var r=K(e,t),i=Y(r.tree,n);return{tree:i.tree,stemmedRevs:i.revs,conflicts:r.conflicts}}function V(e,t){for(var n,r=e.slice(),i=t.split("-"),o=parseInt(i[0],10),a=i[1];n=r.pop();){if(n.pos===o&&n.ids[0]===a)return!0;for(var s=n.ids[2],u=0,c=s.length;c>u;u++)r.push({pos:n.pos+1,ids:s[u]})}return!1}function H(e,t,n,r,i,o,a,s){if(V(t.rev_tree,n.metadata.rev))return r[i]=n,o();var u=t.winningRev||k(t),c="deleted"in t?t.deleted:j(t,u),f="deleted"in n.metadata?n.metadata.deleted:j(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&s&&l){var h=n.data;h._rev=u,h._id=n.metadata.id,n=D(h,s)}var d=J(t.rev_tree,n.metadata.rev_tree[0],e),p=s&&(c&&f||!c&&"new_leaf"!==d.conflicts||c&&!f&&"new_branch"===d.conflicts);if(p){var g=y(Ne);return r[i]=g,o()}var v=n.metadata.rev;n.metadata.rev_tree=d.tree,n.stemmedRevs=d.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var _,b=k(n.metadata),m=j(n.metadata,b),w=c===m?0:m>c?-1:1;_=v===b?m:j(n.metadata,v),a(n,b,m,_,!0,w,i,o)}function G(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}function $(e,t,n,r,i,o,a,s,u){function c(e,t,n){var r=k(e.metadata),i=j(e.metadata,r);if("was_delete"in s&&i)return o[t]=y(Pe,"deleted"),n();var u=l&&G(e);if(u){var c=y(Ne);return o[t]=c,n()}var f=i?0:1;a(e,r,i,i,!1,f,t,n)}function f(){++d===p&&u&&u()}e=e||1e3;var l=s.new_edits,h=new Be.Map,d=0,p=t.length;t.forEach(function(e,t){if(e._id&&O(e._id)){var r=e._deleted?"_removeLocal":"_putLocal";return void n[r](e,{ctx:i},function(e,n){o[t]=e||n,f()})}var a=e.metadata.id;h.has(a)?(p--,h.get(a).push([e,t])):h.set(a,[[e,t]])}),h.forEach(function(t,n){function i(){++u<t.length?s():f()}function s(){var s=t[u],f=s[0],h=s[1];if(r.has(n))H(e,r.get(n),f,o,h,i,a,l);else{var d=J([],f.metadata.rev_tree[0],e);f.metadata.rev_tree=d.tree,f.stemmedRevs=d.stemmedRevs||[],c(f,h,i)}}var u=0;s()})}function X(e){var t=!1;return Re(function(n){if(t)throw new Error("once called more than once");t=!0,e.apply(this,n)})}function Z(e){return Re(function(n){n=u(n);var r,i=this,o="function"==typeof n[n.length-1]?n.pop():!1;o&&(r=function(e,n){t.nextTick(function(){o(e,n)})});var a=new $e(function(t,r){var o;try{var a=X(function(e,n){e?r(e):t(n)});n.push(a),o=e.apply(i,n),o&&"function"==typeof o.then&&t(o)}catch(s){r(s)}});return r&&a.then(function(e){r(null,e)},r),a})}function Q(e){return Ze(e)}function ee(e,t,n,r){(n>0||r<t.byteLength)&&(t=new Uint8Array(t,n,Math.min(r,t.byteLength)-n)),e.append(t)}function te(e,t,n,r){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t)}function ne(){}function re(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(n){if("TypeError"!==n.name)throw n;for(var r="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,i=new r,o=0;o<e.length;o+=1)i.append(e[o]);return i.getBlob(t.type)}}function ie(e,t){return re([e.toArrayBuffer()],{type:t})}function oe(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,i=0;r>i;i++)t+=String.fromCharCode(n[i]);return t}function ae(e,t){if("undefined"==typeof FileReader)return t(oe((new FileReaderSync).readAsArrayBuffer(e)));var n=new FileReader,r="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";return r?t(n):void t(oe(n))},r?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}function se(e,t){ae(e,t)}function ue(e){return re([""],{type:e})}function ce(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),i=0;t>i;i++)r[i]=e.charCodeAt(i);return n}function fe(e,t){return re([ce(e)],{type:t})}function le(e,t){var n=t.prefix()[0],r=e._cache,i=r.get(n);return i||(i=new Be.Map,r.set(n,i)),i}function he(){this._batch=[],this._cache=new Be.Map}function de(e){return"winningRev"in e?e.winningRev:k(e)}function pe(e,t){return"deleted"in e?e.deleted:j(e,t)}function ge(e,t,n){var r=e.content_type;return new $e(function(i,o){t.binaryStore.get(e.digest,function(t,a){var s;if(t){if("NotFoundError"!==t.name)return o(t);s=n.binary?fe("",r):""}else s=n.binary?ie(a,r):a.toString("base64");delete e.stub,delete e.length,e.data=s,i()})})}function ve(e,t,n){var r=[];return e.forEach(function(e){if(e.doc&&e.doc._attachments){var t=Object.keys(e.doc._attachments);t.forEach(function(t){var n=e.doc._attachments[t];"data"in n||r.push(n)})}}),$e.all(r.map(function(e){return ge(e,t,n)}))}function ye(e,n){function i(){E.docStore=m.sublevel(st,{valueEncoding:_t}),E.bySeqStore=m.sublevel(ut,{valueEncoding:"json"}),E.attachmentStore=m.sublevel(ct,{valueEncoding:"json"}),E.binaryStore=m.sublevel(ft,{valueEncoding:"binary"}),E.localStore=m.sublevel(lt,{valueEncoding:"json"}),E.metaStore=m.sublevel(ht,{valueEncoding:"json"}),it.localAndMetaStores(m,E,function(){E.metaStore.get(pt,function(e,r){"undefined"==typeof m._updateSeq&&(m._updateSeq=r||0),E.metaStore.get(gt,function(e,r){m._docCount=e?0:r,E.metaStore.get(vt,function(e,r){_=e?g():r,E.metaStore.put(vt,_,function(){t.nextTick(function(){n(null,w)})})})})})})}function o(e){return m.isClosed()?e(new Error("database is closed")):e(null,m._docCount)}function a(e,t){try{e.apply(null,t)}catch(n){t[t.length-1](n)}}function s(){var e=m._queue.peekFront();"read"===e.type?c(e):f(e)}function c(e){for(var n=[e],r=1,i=m._queue.get(r);"undefined"!=typeof i&&"read"===i.type;)n.push(i),r++,i=m._queue.get(r);var o=0;n.forEach(function(e){var r=e.args,i=r[r.length-1];r[r.length-1]=Re(function(e){i.apply(null,e),++o===n.length&&t.nextTick(function(){n.forEach(function(){m._queue.shift()}),m._queue.length&&s()})}),a(e.fun,r)})}function f(e){var n=e.args,r=n[n.length-1];n[n.length-1]=Re(function(e){r.apply(null,e),t.nextTick(function(){m._queue.shift(),m._queue.length&&s()})}),a(e.fun,n)}function l(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"write"}),1===m._queue.length&&t.nextTick(s)})}function h(e){return Re(function(n){m._queue.push({fun:e,args:n,type:"read"}),1===m._queue.length&&t.nextTick(s)})}function d(e){return("0000000000000000"+e).slice(-16)}function p(e){return parseInt(e,10)}function v(e,n){"function"==typeof R.destroy?R.destroy(e,n):t.nextTick(n)}e=u(e);var _,m,w=this,E={},k=e.revs_limit,B=e.name;"undefined"==typeof e.createIfMissing&&(e.createIfMissing=!0);var R=e.db||mt();if(R instanceof Error)return n(R);"function"!=typeof R.destroy&&(R.destroy=function(e,t){t()});var M,j=at(R);dt.has(j)?M=dt.get(j):(M=new Be.Map,dt.set(j,M)),M.has(B)?(m=M.get(B),i()):M.set(B,Ee(we(B,e,function(t){return t?(M["delete"](B),n(t)):(m=M.get(B),m._docCount=-1,m._queue=new Oe,void(e.db||e.noMigrate?i():it.toSublevel(B,m,i)))}))),w.type=function(){return"leveldb"},w._id=function(e){e(null,_)},w._info=function(e){var n={doc_count:m._docCount,update_seq:m._updateSeq,backend_adapter:at(R)};return t.nextTick(function(){e(null,n)})},w._get=h(function(e,t,n){t=u(t),E.docStore.get(e,function(e,r){if(e||!r)return n(y(Pe,"missing"));var i=de(r),o=pe(r,i);if(o&&!t.rev)return n(y(Pe,"deleted"));i=t.rev?t.rev:i;var a=r.rev_map[i];E.bySeqStore.get(d(a),function(e,t){if(!t)return n(y(Pe));if("_id"in t&&t._id!==r.id)return n(new Error("wrong doc returned"));if(t._id=r.id,"_rev"in t){if(t._rev!==i)return n(new Error("wrong doc returned"))}else t._rev=i;return n(null,{doc:t,metadata:r})})})}),w._getAttachment=function(e,t,n){var r=e.digest,i=e.content_type;E.binaryStore.get(r,function(e,r){return e?"NotFoundError"!==e.name?n(e):n(null,t.binary?ue(i):""):void(t.binary?n(null,ie(r,i)):n(null,r.toString("base64")))})},w._bulkDocs=l(function(e,n,i){function o(e,t){R.get(E.attachmentStore,e,function(n){if(n){var r=y(Ve,"unknown stub attachment with digest "+e);t(r)}else t()})}function a(e){var t=[];if(j.forEach(function(e){e&&e._attachments&&Object.keys(e._attachments).forEach(function(n){var r=e._attachments[n];r.stub&&t.push(r.digest)})}),!t.length)return e();var n,r=0;t.forEach(function(i){o(i,function(i){i&&!n&&(n=i),++r===t.length&&e(n)})})}function s(e){function t(){return++r===j.length?e(n):void 0}var n,r=0;j.forEach(function(e){return e._id&&O(e._id)?t():void R.get(E.docStore,e._id,function(r,i){r?"NotFoundError"!==r.name&&(n=r):b.set(e._id,i),t()})})}function u(e,t){var n=$e.resolve();e.forEach(function(e,t){n=n.then(function(){return new $e(function(n,r){w._doCompactionNoLock(t,e,{ctx:R},function(e){return e?r(e):void n()})})})}),n.then(function(){t()},t)}function c(e){var t=new Be.Map;b.forEach(function(e,n){t.set(n,x(e))}),u(t,e)}function f(){return w.auto_compaction?c(g):void u(S,g)}function l(e,t,n,r,o,a,s,u){function c(e){m++,v||(e?(v=e,u(v)):m===w.length&&g())}function f(e,t,n,r){return function(i){p(e,yt+i,t,n,r)}}function l(e,t,n){return function(r){tt(r).then(f(e,t,r,n))}}function g(){var n=e.metadata.rev_map[e.metadata.rev];if(n)return u(null,e.revsStemmed);n=++M,e.metadata.rev_map[e.metadata.rev]=e.metadata.seq=n;var r=d(n),i=[{key:r,value:e.data,prefix:E.bySeqStore,type:"put"},{key:e.metadata.id,value:e.metadata,prefix:E.docStore,type:"put"}];R.batch(i),_[s]={ok:!0,id:e.metadata.id,rev:t},b.set(e.metadata.id,e.metadata),u(null,e.revsStemmed)}A+=a;var v=null,m=0;e.metadata.winningRev=t,e.metadata.deleted=n,e.data._id=e.metadata.id,e.data._rev=e.metadata.rev,r&&(e.data._deleted=!0),e.stemmedRevs.length&&S.set(e.metadata.id,e.stemmedRevs);for(var w=e.data._attachments?Object.keys(e.data._attachments):[],k=0;k<w.length;k++){var x=w[k],B=e.data._attachments[x];if(B.stub){var j=e.data._id,O=e.data._rev;h(j,O,B.digest,c)}else{var L;if("string"==typeof B.data){try{L=Xe(B.data)}catch(T){return void i(y(ze,"Attachment is not a valid base64 string"))}l(e,x,c)(L)}else se(B.data,l(e,x,c))}}w.length||g()}function h(e,t,n,r){function i(){return new $e(function(e,t){R.get(E.attachmentStore,n,function(n,r){return n&&"NotFoundError"!==n.name?t(n):void e(r)})})}function o(r){var i=[e,t].join("@"),o={};return r?r.refs&&(o.refs=r.refs,o.refs[i]=!0):(o.refs={},o.refs[i]=!0),new $e(function(e){R.batch([{type:"put",prefix:E.attachmentStore,key:n,value:o}]),e(!r)})}var a=C[n]||$e.resolve();C[n]=a.then(function(){return i().then(o).then(function(e){r(null,e)},r)})}function p(e,t,n,i,o){var a=e.data._attachments[n];delete a.data,a.digest=t,a.length=i.length;var s=e.metadata.id,u=e.metadata.rev;a.revpos=parseInt(u,10),h(s,u,t,function(e,n){return e?o(e):0===i.length?o(e):n?(R.batch([{type:"put",prefix:E.binaryStore,key:t,value:new r(i,"binary")}]),void o()):o(e)})}function g(e){return e?t.nextTick(function(){i(e)}):(R.batch([{prefix:E.metaStore,type:"put",key:pt,value:M},{prefix:E.metaStore,type:"put",key:gt,value:m._docCount+A}]),void R.execute(m,function(e){return e?i(e):(m._docCount+=A,m._updateSeq=M,bt.notify(B),void t.nextTick(function(){i(null,_)}))}))}var v=n.new_edits,_=new Array(e.docs.length),b=new Be.Map,S=new Be.Map,R=new he,A=0,M=m._updateSeq,j=e.docs,L=j.map(function(e){if(e._id&&O(e._id))return e;var t=D(e,v);return t.metadata&&!t.metadata.rev_map&&(t.metadata.rev_map={}),t}),T=L.filter(function(e){return e.error});if(T.length)return i(T[0]);var C={};return L.length?void a(function(e){return e?i(e):void s(function(e){return e?i(e):void $(k,L,w,b,R,_,l,n,f)})}):i(null,[])}),w._allDocs=h(function(e,t){e=u(e),o(function(n,r){if(n)return t(n);var i={},o=e.skip||0;if(e.startkey&&(i.gte=e.startkey),e.endkey&&(i.lte=e.endkey),e.key&&(i.gte=i.lte=e.key),e.descending){i.reverse=!0;var a=i.lte;i.lte=i.gte,i.gte=a}var s;if("number"==typeof e.limit&&(s=e.limit),0===s||"start"in i&&"end"in i&&i.start>i.end)return t(null,{total_rows:r,offset:e.skip,rows:[]});var u=[],c=E.docStore.readStream(i),f=ke.obj(function(t,n,r){function i(t){var n={id:a.id,key:a.id,value:{rev:f}};if(e.include_docs){n.doc=t,n.doc._rev=n.value.rev,e.conflicts&&(n.doc._conflicts=A(a));for(var i in n.doc._attachments)n.doc._attachments.hasOwnProperty(i)&&(n.doc._attachments[i].stub=!0)}if(e.inclusive_end===!1&&a.id===e.endkey)return r();if(l){if("ok"!==e.deleted)return r();n.value.deleted=!0,n.doc=null}u.push(n),r()}var a=t.value,f=de(a),l=pe(a,f);if(l){if("ok"!==e.deleted)return void r()}else{if(o-- >0)return void r();if("number"==typeof s&&s--<=0)return c.unpipe(),c.destroy(),void r()}if(e.include_docs){var h=a.rev_map[f];E.bySeqStore.get(d(h),function(e,t){i(t)})}else i()},function(n){$e.resolve().then(function(){return e.include_docs&&e.attachments?ve(u,E,e):void 0}).then(function(){t(null,{total_rows:r,offset:e.skip,rows:u})},t),n()}).on("unpipe",function(){f.end()});c.on("error",t),c.pipe(f)})}),w._changes=function(e){function t(){e.done=!0,f&&e.limit&&e.limit<o.length&&(o.length=e.limit),y.unpipe(_),y.destroy(),e.continuous||e.cancelled||(e.include_docs&&e.attachments?ve(o,E,e).then(function(){e.complete(null,{results:o,last_seq:a})}):e.complete(null,{results:o,last_seq:a}))}if(e=u(e),e.continuous){var n=B+":"+g();return bt.addListener(B,n,w,e),bt.notify(B),{cancel:function(){bt.removeListener(B,n)}}}var r,i=e.descending,o=[],a=e.since||0,s=0,c={reverse:i};"limit"in e&&e.limit>0&&(r=e.limit),c.reverse||(c.start=d(e.since||0));var f,l=e.doc_ids&&new Be.Set(e.doc_ids),h=b(e),v=new Be.Map;f="return_docs"in e?e.return_docs:"returnDocs"in e?e.returnDocs:!0;var y=E.bySeqStore.readStream(c),_=ke.obj(function(n,u,c){function g(t){function n(n){var r=e.processChange(n,t,e);r.seq=t.seq;var i=h(r);return"object"==typeof i?e.complete(i):(i&&(s++,e.attachments&&e.include_docs?ve([r],E,e).then(function(){e.onChange(r)}):e.onChange(r),f&&o.push(r)),void c())}var r=de(t);if(t.seq!==y)return c();if(a=y,r===_._rev)return n(_);var i=t.rev_map[r];E.bySeqStore.get(d(i),function(e,t){n(t)})}if(r&&s>=r)return t(),c();if(e.cancelled||e.done)return c();var y=p(n.key),_=n.value;if(y===e.since&&!i)return c();if(l&&!l.has(_._id))return c();var b;return(b=v.get(_._id))?g(b):void E.docStore.get(_._id,function(t,n){return e.cancelled||e.done||m.isClosed()||O(n.id)?c():(v.set(_._id,n),void g(n))})},function(t){return e.cancelled?t():(f&&e.limit&&e.limit<o.length&&(o.length=e.limit),void t())}).on("unpipe",function(){_.end(),t()});return y.pipe(_),{cancel:function(){e.cancelled=!0,t()}}},w._close=function(e){return m.isClosed()?e(y(Fe)):void m.close(function(t){t?e(t):(M["delete"](B),e())})},w._getRevisionTree=function(e,t){E.docStore.get(e,function(e,n){e?t(y(Pe)):t(null,n.rev_tree)})},w._doCompaction=l(function(e,t,n,r){w._doCompactionNoLock(e,t,n,r)}),w._doCompactionNoLock=function(e,t,n,r){if("function"==typeof n&&(r=n,n={}),!t.length)return r();var i=n.ctx||new he;i.get(E.docStore,e,function(o,a){function s(e){if(e&&(h=e),++g===t.length){if(h)return r(h);c()}}function u(e){return e?r(e):(i.batch(l),n.ctx?r():void i.execute(m,r))}function c(){function n(e){e&&(o=e),++a===r.length&&u(o)}var r=Object.keys(p);if(!r.length)return u();var o,a=0,s=new Be.Map;t.forEach(function(t){s.set(e+"@"+t,!0)}),r.forEach(function(e){i.get(E.attachmentStore,e,function(t,r){if(t)return"NotFoundError"===t.name?n():n(t);var i=Object.keys(r.refs||{}).filter(function(e){return!s.has(e)}),o={};i.forEach(function(e){o[e]=!0}),i.length?l.push({key:e,type:"put",value:{refs:o},prefix:E.attachmentStore}):l=l.concat([{key:e,type:"del",prefix:E.attachmentStore},{key:e,type:"del",prefix:E.binaryStore}]),n()})})}if(o)return r(o);var f=t.map(function(e){var t=a.rev_map[e];return delete a.rev_map[e],t});S(a.rev_tree,function(e,n,r,i,o){var a=n+"-"+r;-1!==t.indexOf(a)&&(o.status="missing")});var l=[];l.push({key:a.id,value:a,type:"put",prefix:E.docStore});var h,p={},g=0;f.forEach(function(e){l.push({key:d(e),type:"del",prefix:E.bySeqStore}),i.get(E.bySeqStore,d(e),function(e,t){if(e)return"NotFoundError"===e.name?s():s(e);var n=Object.keys(t._attachments||{});n.forEach(function(e){var n=t._attachments[e].digest;p[n]=!0}),s()})})})},w._getLocal=function(e,t){E.localStore.get(e,function(e,n){e?t(y(Pe)):t(null,n)})},w._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._putLocalNoLock(e,t,n):w._putLocalWithLock(e,t,n)},w._putLocalWithLock=l(function(e,t,n){w._putLocalNoLock(e,t,n)}),w._putLocalNoLock=function(e,t,n){delete e._revisions;var r=e._rev,i=e._id,o=t.ctx||new he;o.get(E.localStore,i,function(a,s){if(a&&r)return n(y(Ne));if(s&&s._rev!==r)return n(y(Ne));e._rev=r?"0-"+(parseInt(r.split("-")[1],10)+1):"0-1";var u=[{type:"put",prefix:E.localStore,key:i,value:e}];o.batch(u);var c={ok:!0,id:e._id,rev:e._rev};return t.ctx?n(null,c):void o.execute(m,function(e){return e?n(e):void n(null,c)})})},w._removeLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),t.ctx?w._removeLocalNoLock(e,t,n):w._removeLocalWithLock(e,t,n)},w._removeLocalWithLock=l(function(e,t,n){w._removeLocalNoLock(e,t,n)}),w._removeLocalNoLock=function(e,t,n){var r=t.ctx||new he;r.get(E.localStore,e._id,function(i,o){if(i)return n("NotFoundError"!==i.name?i:y(Pe));if(o._rev!==e._rev)return n(y(Ne));r.batch([{prefix:E.localStore,type:"del",key:e._id}]);var a={ok:!0,id:e._id,rev:"0-0"};return t.ctx?n(null,a):void r.execute(m,function(e){return e?n(e):void n(null,a)})})},w._destroy=function(e,t){var n,r=at(R);return dt.has(r)?(n=dt.get(r),void(n.has(B)?(bt.removeAllListeners(B),n.get(B).close(function(){n["delete"](B),v(B,t)})):v(B,t))):v(B,t)}}function _e(e,t){function n(e,n){var r=Le.extend({db:t},e);ye.call(this,r,n)}return n.valid=function(){return e.valid()},n.use_prefix=e.use_prefix,n.destroy=Z(function(e,n,r){"function"==typeof n&&(r=n,n={});var i=Le.extend({db:t},n);return ye.destroy(e,i,r)}),n}function be(t,n){var r=t.name,i=_e(t,n),o="undefined"!=typeof PouchDB?PouchDB:e("pouchdb");o?o.adapter(r,i,!0):console.error(t.name+' adapter plugin error: Cannot find global "PouchDB" object! Did you remember to include pouchdb.js?')}var me,we=i(e(40)),Ee=i(e(72)),ke=e(90),Se=e(19),xe=i(e(23)),Be=e(53),Re=i(e(2)),Ae=i(e(94)),Me=i(e(44)),je=i(e(57)),Oe=i(e(15)),Le=e(26),Te=i(e(46));if(c())me=!1;else try{localStorage.setItem("_pouch_check_localstorage",1),me=!!localStorage.getItem("_pouch_check_localstorage")}catch(Ce){me=!1}xe(d,Se.EventEmitter),d.prototype.addListener=function(e,t,n,r){function i(){function e(){a=!1}if(o._listeners[t]){if(a)return void(a="waiting");a=!0;var s=l(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary"]);n.changes(s).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===a&&setTimeout(function(){i()},0),a=!1}).on("error",e)}}if(!this._listeners[t]){var o=this,a=!1;this._listeners[t]=i,this.on(e,i)}},d.prototype.removeListener=function(e,t){t in this._listeners&&Se.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t])},d.prototype.notifyLocalWindows=function(e){c()?chrome.storage.local.set({dbName:e}):f()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},d.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var Ie="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");xe(v,Error),v.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};var De,Pe=(new v({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),new v({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),new v({status:404,error:"not_found",reason:"missing"})),Ne=new v({status:409,error:"conflict",reason:"Document update conflict"}),qe=new v({status:400,error:"invalid_id",reason:"_id field must contain a string"}),Ue=new v({status:412,error:"missing_id",reason:"_id is required for puts"}),We=new v({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),Fe=new v({status:412,error:"precondition_failed",reason:"Database not open"}),ze=(new v({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),new v({status:500,error:"badarg",reason:"Some query argument is invalid"})),Ke=(new v({status:400,error:"invalid_request",reason:"Request was invalid"}),new v({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),new v({status:500,error:"doc_validation",reason:"Bad special document member"})),Ye=new v({status:400,error:"bad_request",reason:"Something wrong with the request"}),Je=(new v({status:400,error:"bad_request",reason:"Document must be a JSON object"}),new v({status:404,error:"not_found",reason:"Database not found"}),new v({status:500,error:"indexed_db_went_bad",reason:"unknown"}),new v({status:500,error:"web_sql_went_bad",reason:"unknown"}),new v({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),new v({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),new v({status:400,error:"bad_request",reason:"Invalid rev format"})),Ve=(new v({status:412,error:"file_exists",reason:"The database could not be created, the file already exists."}),new v({status:412,error:"missing_stub"})),He=(new v({status:413,error:"invalid_url",reason:"Provided URL is invalid"}),L(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"])),Ge=L(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]),$e="function"==typeof Promise?Promise:Me,Xe=function(e){return atob(e)},Ze=function(e){return btoa(e)},Qe=n.setImmediate||n.setTimeout,et=32768,tt=Z(function(e,t){function n(){var r=s*o,i=r+o;if(s++,a>s)c(u,e,r,i),Qe(n);else{c(u,e,r,i);var f=u.end(!0),l=Q(f);t(null,l),u.destroy()}}var r="string"==typeof e,i=r?e.length:e.byteLength,o=Math.min(et,i),a=Math.ceil(i/o),s=0,u=r?new je:new je.ArrayBuffer,c=r?te:ee;n()}),nt=function(e,n,r){t.nextTick(function(){r()})},rt=function(e,n,r){t.nextTick(function(){r()})},it={toSublevel:nt,localAndMetaStores:rt},ot=ne.name;De=ot?function(e){return e.name}:function(e){return e.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]};var at=De;he.prototype.get=function(e,n,r){var i=le(this,e),o=i.get(n);return o?t.nextTick(function(){r(null,o)}):null===o?t.nextTick(function(){r({name:"NotFoundError"})}):void e.get(n,function(e,t){return e?("NotFoundError"===e.name&&i.set(n,null),r(e)):(i.set(n,t),void r(null,t))})},he.prototype.batch=function(e){for(var t=0,n=e.length;n>t;t++){var r=e[t],i=le(this,r.prefix);"put"===r.type?i.set(r.key,r.value):i.set(r.key,null)}this._batch=this._batch.concat(e)},he.prototype.execute=function(e,t){for(var n=new Be.Set,r=[],i=this._batch.length-1;i>=0;i--){var o=this._batch[i],a=o.prefix.prefix()[0]+"ÿ"+o.key;n.has(a)||(n.add(a),r.push(o))}e.batch(r,t)};var st="document-store",ut="by-sequence",ct="attach-store",ft="attach-binary-store",lt="local-store",ht="meta-store",dt=new Be.Map,pt="_local_last_update_seq",gt="_local_doc_count",vt="_local_uuid",yt="md5-",_t={encode:E,decode:w,buffer:!1,type:"cheap-json"},bt=new d,mt=function(){try{return e(4)}catch(t){return t=t||"leveldown import error","MODULE_NOT_FOUND"===t.code?new Error(["the 'leveldown' package is not available. install it, or,","specify another storage backend using the 'db' option"].join(" ")):t.message&&t.message.match("Module version mismatch")?new Error([t.message,"This generally implies that leveldown was built with a different","version of node than that which is running now.  You may try","fully removing and reinstalling PouchDB or leveldown to resolve."].join(" ")):new Error(t.toString()+": unable to import leveldown")}};ye.valid=function(){return!0},ye.use_prefix=!1;var wt={name:"memory",valid:function(){return!0},use_prefix:!1};be(wt,Te)}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(5).Buffer)},{15:15,19:19,2:2,23:23,26:26,4:4,40:40,44:44,46:46,5:5,53:53,55:55,57:57,72:72,90:90,94:94,pouchdb:"pouchdb"}],2:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],3:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===a||t===l?62:t===s||t===h?63:u>t?-1:u+10>t?t-u+26+26:f+26>t?t-f:c+26>t?t-c+26:void 0}function n(e){function n(e){c[l++]=e}var r,i,a,s,u,c;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var f=e.length;u="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0,c=new o(3*e.length/4-u),a=u>0?e.length-4:e.length;
+var l=0;for(r=0,i=0;a>r;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===u?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===u&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(s>>8&255),n(255&s)),c}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,o,a,s=e.length%3,u="";for(i=0,a=e.length-s;a>i;i+=3)o=(e[i]<<16)+(e[i+1]<<8)+e[i+2],u+=n(o);switch(s){case 1:o=e[e.length-1],u+=t(o>>2),u+=t(o<<4&63),u+="==";break;case 2:o=(e[e.length-2]<<8)+e[e.length-1],u+=t(o>>10),u+=t(o>>4&63),u+=t(o<<2&63),u+="="}return u}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="+".charCodeAt(0),s="/".charCodeAt(0),u="0".charCodeAt(0),c="a".charCodeAt(0),f="A".charCodeAt(0),l="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],4:[function(e,t,n){},{}],5:[function(e,t,n){(function(t){"use strict";function r(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(e){return this instanceof o?(o.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof e?a(this,e):"string"==typeof e?s(this,e,arguments.length>1?arguments[1]:"utf8"):u(this,e)):arguments.length>1?new o(e,arguments[1]):new o(e)}function a(e,t){if(e=g(e,0>t?0:0|v(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)e[n]=0;return e}function s(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|_(t,n);return e=g(e,r),e.write(t,n),e}function u(e,t){if(o.isBuffer(t))return c(e,t);if($(t))return f(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return l(e,t);if(t instanceof ArrayBuffer)return h(e,t)}return t.length?d(e,t):p(e,t)}function c(e,t){var n=0|v(t.length);return e=g(e,n),t.copy(e,0,0,n),e}function f(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function l(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function h(e,t){return o.TYPED_ARRAY_SUPPORT?(t.byteLength,e=o._augment(new Uint8Array(t))):e=l(e,new Uint8Array(t)),e}function d(e,t){var n=0|v(t.length);e=g(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function p(e,t){var n,r=0;"Buffer"===t.type&&$(t.data)&&(n=t.data,r=0|v(n.length)),e=g(e,r);for(var i=0;r>i;i+=1)e[i]=255&n[i];return e}function g(e,t){o.TYPED_ARRAY_SUPPORT?(e=o._augment(new Uint8Array(t)),e.__proto__=o.prototype):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=o.poolSize>>>1;return n&&(e.parent=X),e}function v(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function y(e,t){if(!(this instanceof y))return new y(e,t);var n=new o(e,t);return delete n.parent,n}function _(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return z(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return J(e).length;default:if(r)return z(e).length;t=(""+t).toLowerCase(),r=!0}}function b(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(e){case"hex":return O(this,t,n);case"utf8":case"utf-8":return R(this,t,n);case"ascii":return M(this,t,n);case"binary":return j(this,t,n);case"base64":return B(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return L(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function m(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;r>a;a++){var s=parseInt(t.substr(2*a,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+a]=s}return a}function w(e,t,n,r){return V(z(t,e.length-n),e,n,r)}function E(e,t,n,r){return V(K(t),e,n,r)}function k(e,t,n,r){return E(e,t,n,r)}function S(e,t,n,r){return V(J(t),e,n,r)}function x(e,t,n,r){return V(Y(t,e.length-n),e,n,r)}function B(e,t,n){return 0===t&&n===e.length?H.fromByteArray(e):H.fromByteArray(e.slice(t,n))}function R(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;n>i;){var o=e[i],a=null,s=o>239?4:o>223?3:o>191?2:1;if(n>=i+s){var u,c,f,l;switch(s){case 1:128>o&&(a=o);break;case 2:u=e[i+1],128===(192&u)&&(l=(31&o)<<6|63&u,l>127&&(a=l));break;case 3:u=e[i+1],c=e[i+2],128===(192&u)&&128===(192&c)&&(l=(15&o)<<12|(63&u)<<6|63&c,l>2047&&(55296>l||l>57343)&&(a=l));break;case 4:u=e[i+1],c=e[i+2],f=e[i+3],128===(192&u)&&128===(192&c)&&128===(192&f)&&(l=(15&o)<<18|(63&u)<<12|(63&c)<<6|63&f,l>65535&&1114112>l&&(a=l))}}null===a?(a=65533,s=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),i+=s}return A(r)}function A(e){var t=e.length;if(Z>=t)return String.fromCharCode.apply(String,e);for(var n="",r=0;t>r;)n+=String.fromCharCode.apply(String,e.slice(r,r+=Z));return n}function M(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(127&e[i]);return r}function j(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(e[i]);return r}function O(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var i="",o=t;n>o;o++)i+=F(e[o]);return i}function L(e,t,n){for(var r=e.slice(t,n),i="",o=0;o<r.length;o+=2)i+=String.fromCharCode(r[o]+256*r[o+1]);return i}function T(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function C(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>i||a>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function I(e,t,n,r){0>t&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);o>i;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function D(e,t,n,r){0>t&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);o>i;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function P(e,t,n,r,i,o){if(t>i||o>t)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(0>n)throw new RangeError("index out of range")}function N(e,t,n,r,i){return i||P(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),G.write(e,t,n,r,23,4),n+4}function q(e,t,n,r,i){return i||P(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),G.write(e,t,n,r,52,8),n+8}function U(e){if(e=W(e).replace(ee,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function W(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function F(e){return 16>e?"0"+e.toString(16):e.toString(16)}function z(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],a=0;r>a;a++){if(n=e.charCodeAt(a),n>55295&&57344>n){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(56320>n){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,128>n){if((t-=1)<0)break;o.push(n)}else if(2048>n){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function K(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function Y(e,t){for(var n,r,i,o=[],a=0;a<e.length&&!((t-=2)<0);a++)n=e.charCodeAt(a),r=n>>8,i=n%256,o.push(i),o.push(r);return o}function J(e){return H.toByteArray(U(e))}function V(e,t,n,r){for(var i=0;r>i&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var H=e(3),G=e(21),$=e(25);n.Buffer=o,n.SlowBuffer=y,n.INSPECT_MAX_BYTES=50,o.poolSize=8192;var X={};o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),o.TYPED_ARRAY_SUPPORT?(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array):(o.prototype.length=void 0,o.prototype.parent=void 0),o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);a>i&&e[i]===t[i];)++i;return i!==a&&(n=e[i],r=t[i]),r>n?-1:n>r?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!$(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new o(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new o(t),i=0;for(n=0;n<e.length;n++){var a=e[n];a.copy(r,i),i+=a.length}return r},o.byteLength=_,o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?R(this,0,e):b.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:o.compare(this,e)},o.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[-1===r?0:i-r]){if(-1===r&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(o.isBuffer(e))return n(this,e,t);if("number"==typeof e)return o.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},o.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},o.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return E(this,e,t,n);case"binary":return k(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Z=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=o._augment(this.subarray(e,t));else{var i=t-e;r=new o(i,void 0);for(var a=0;i>a;a++)r[a]=this[a+e]}return r.length&&(r.parent=this.parent||this),r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||T(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||T(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||T(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||T(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||T(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||T(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(e,t){return t||T(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},o.prototype.readInt16LE=function(e,t){t||T(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||T(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||T(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||T(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||T(e,4,this.length),G.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||T(e,8,this.length),G.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||C(this,e,t,n,Math.pow(2,8*n),0);var i=1,o=0;for(this[t]=255&e;++o<n&&(i*=256);)this[t+o]=e/i&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||C(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):D(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);C(this,e,t,n,i-1,-i)}var o=0,a=1,s=0>e?1:0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);C(this,e,t,n,i-1,-i)}var o=n-1,a=1,s=0>e?1:0;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):D(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||C(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):D(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return q(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return q(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&n>r&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&t>n&&r>t)for(i=a-1;i>=0;i--)e[i+t]=this[i+n];else if(1e3>a||!o.TYPED_ARRAY_SUPPORT)for(i=0;a>i;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),t>n)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new RangeError("start out of bounds");if(0>n||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;n>r;r++)this[r]=e;else{var i=z(e.toString()),o=i.length;for(r=t;n>r;r++)this[r]=i[r%o]}return this}},o.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(o.TYPED_ARRAY_SUPPORT)return new o(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;n>t;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var Q=o.prototype;o._augment=function(e){return e.constructor=o,e._isBuffer=!0,e._set=e.set,e.get=Q.get,e.set=Q.set,e.write=Q.write,e.toString=Q.toString,e.toLocaleString=Q.toString,e.toJSON=Q.toJSON,e.equals=Q.equals,e.compare=Q.compare,e.indexOf=Q.indexOf,e.copy=Q.copy,e.slice=Q.slice,e.readUIntLE=Q.readUIntLE,e.readUIntBE=Q.readUIntBE,e.readUInt8=Q.readUInt8,e.readUInt16LE=Q.readUInt16LE,e.readUInt16BE=Q.readUInt16BE,e.readUInt32LE=Q.readUInt32LE,e.readUInt32BE=Q.readUInt32BE,e.readIntLE=Q.readIntLE,e.readIntBE=Q.readIntBE,e.readInt8=Q.readInt8,e.readInt16LE=Q.readInt16LE,e.readInt16BE=Q.readInt16BE,e.readInt32LE=Q.readInt32LE,e.readInt32BE=Q.readInt32BE,e.readFloatLE=Q.readFloatLE,e.readFloatBE=Q.readFloatBE,e.readDoubleLE=Q.readDoubleLE,e.readDoubleBE=Q.readDoubleBE,e.writeUInt8=Q.writeUInt8,e.writeUIntLE=Q.writeUIntLE,e.writeUIntBE=Q.writeUIntBE,e.writeUInt16LE=Q.writeUInt16LE,e.writeUInt16BE=Q.writeUInt16BE,e.writeUInt32LE=Q.writeUInt32LE,e.writeUInt32BE=Q.writeUInt32BE,e.writeIntLE=Q.writeIntLE,e.writeIntBE=Q.writeIntBE,e.writeInt8=Q.writeInt8,e.writeInt16LE=Q.writeInt16LE,e.writeInt16BE=Q.writeInt16BE,e.writeInt32LE=Q.writeInt32LE,e.writeInt32BE=Q.writeInt32BE,e.writeFloatLE=Q.writeFloatLE,e.writeFloatBE=Q.writeFloatBE,e.writeDoubleLE=Q.writeDoubleLE,e.writeDoubleBE=Q.writeDoubleBE,e.fill=Q.fill,e.inspect=Q.inspect,e.toArrayBuffer=Q.toArrayBuffer,e};var ee=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{21:21,25:25,3:3}],6:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===v(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function o(e){return null==e}function a(e){return"number"==typeof e}function s(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function c(e){return void 0===e}function f(e){return"[object RegExp]"===v(e)}function l(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===v(e)}function d(e){return"[object Error]"===v(e)||e instanceof Error}function p(e){return"function"==typeof e}function g(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function v(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=o,n.isNumber=a,n.isString=s,n.isSymbol=u,n.isUndefined=c,n.isRegExp=f,n.isObject=l,n.isDate=h,n.isError=d,n.isFunction=p,n.isPrimitive=g,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e(24)})},{24:24}],7:[function(e,t,n){function r(e){o.call(this,e),this._options=e,this._iterator=null,this._operations=[]}var i=e(93),o=e(12).AbstractIterator;i.inherits(r,o),r.prototype.setDb=function(e){var t=this._iterator=e.iterator(this._options);this._operations.forEach(function(e){t[e.method].apply(t,e.args)})},r.prototype._operation=function(e,t){return this._iterator?this._iterator[e].apply(this._iterator,t):void this._operations.push({method:e,args:t})},"next end".split(" ").forEach(function(e){r.prototype["_"+e]=function(){this._operation(e,arguments)}}),t.exports=r},{12:12,93:93}],8:[function(e,t,n){(function(n,r){function i(e){a.call(this,"string"==typeof e?e:""),this._db=void 0,this._operations=[],this._iterators=[]}var o=e(93),a=e(12).AbstractLevelDOWN,s=e(7);o.inherits(i,a),i.prototype.setDb=function(e){this._db=e,this._operations.forEach(function(t){e[t.method].apply(e,t.args)}),this._iterators.forEach(function(t){t.setDb(e)})},i.prototype._open=function(e,t){return r.nextTick(t)},i.prototype._operation=function(e,t){return this._db?this._db[e].apply(this._db,t):void this._operations.push({method:e,args:t})},"put get del batch approximateSize".split(" ").forEach(function(e){i.prototype["_"+e]=function(){this._operation(e,arguments)}}),i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._iterator=function(e){if(this._db)return this._db.iterator.apply(this._db,arguments);var t=new s(e);return this._iterators.push(t),t},t.exports=i,t.exports.DeferredIterator=s}).call(this,{isBuffer:e(24)},e(55))},{12:12,24:24,55:55,7:7,93:93}],9:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKey(e,"key",this._db._isBuffer);if(n)throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKey(e,"key",this._db._isBuffer);if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(55))},{55:55}],10:[function(e,t,n){(function(e){function n(e){this.db=e,this._ended=!1,this._nexting=!1}n.prototype.next=function(t){var n=this;if("function"!=typeof t)throw new Error("next() requires a callback argument");return n._ended?t(new Error("cannot call next() after end()")):n._nexting?t(new Error("cannot call next() before previous next() has completed")):(n._nexting=!0,"function"==typeof n._next?n._next(function(){n._nexting=!1,t.apply(null,arguments)}):void e.nextTick(function(){n._nexting=!1,t()}))},n.prototype.end=function(t){if("function"!=typeof t)throw new Error("end() requires a callback argument");return this._ended?t(new Error("end() already called on iterator")):(this._ended=!0,"function"==typeof this._end?this._end(t):void e.nextTick(t))},t.exports=n}).call(this,e(55))},{55:55}],11:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e,this.status="new"}var o=e(14),a=e(10),s=e(9);i.prototype.open=function(e,t){var n=this,i=this.status;if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");"object"!=typeof e&&(e={}),e.createIfMissing=0!=e.createIfMissing,e.errorIfExists=!!e.errorIfExists,"function"==typeof this._open?(this.status="opening",this._open(e,function(e){return e?(n.status=i,t(e)):(n.status="open",void t())})):(this.status="open",r.nextTick(t))},i.prototype.close=function(e){var t=this,n=this.status;if("function"!=typeof e)throw new Error("close() requires a callback argument");"function"==typeof this._close?(this.status="closing",this._close(function(r){return r?(t.status=n,e(r)):(t.status="closed",void e())})):(this.status="closed",r.nextTick(e))},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),t.asBuffer=0!=t.asBuffer,"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKey(e,"key",this._isBuffer))?i(o):(this._isBuffer(e)||(e=String(e)),null==t||this._isBuffer(t)||r.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKey(e,"key",this._isBuffer))?n(i):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"==typeof e&&(n=e),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));t&&"object"==typeof t||(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKey(i.type,"type",this._isBuffer))return n(o);if(o=this._checkKey(i.key,"key",this._isBuffer))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||(t=String(t)),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.keys=0!=e.keys,e.values=0!=e.values,e.limit="limit"in e?e.limit:-1,e.keyAsBuffer=0!=e.keyAsBuffer,e.valueAsBuffer=0!=e.valueAsBuffer,e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._checkKey=function(e,t){if(null===e||void 0===e)return new Error(t+" cannot be `null` or `undefined`");if(this._isBuffer(e)){if(0===e.length)return new Error(t+" cannot be an empty Buffer")}else if(""===String(e))return new Error(t+" cannot be an empty String")},t.exports=i}).call(this,{isBuffer:e(24)},e(55))},{10:10,14:14,24:24,55:55,9:9}],12:[function(e,t,n){n.AbstractLevelDOWN=e(11),n.AbstractIterator=e(10),n.AbstractChainedBatch=e(9),n.isLevelDOWN=e(13)},{10:10,11:11,13:13,9:9}],13:[function(e,t,n){function r(e){return e&&"object"==typeof e?Object.keys(i.prototype).filter(function(e){return"_"!=e[0]&&"approximateSize"!=e}).every(function(t){return"function"==typeof e[t]}):!1}var i=e(11);t.exports=r},{11:11}],14:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}],15:[function(e,t,n){"use strict";function r(e){if(this._capacity=a(e),this._length=0,this._front=0,this._makeCapacity(),s(e)){for(var t=e.length,n=0;t>n;++n)this[n]=e[n];this._length=t}}function i(e,t,n,r,i){for(var o=0;i>o;++o)n[o+r]=e[o+t]}function o(e){return e>>>=0,e-=1,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,e+1}function a(e){if("number"!=typeof e){if(!s(e))return 16;e=e.length}return o(Math.min(Math.max(16,e),1073741824))}r.prototype.toArray=function(){for(var e=this._length,t=new Array(e),n=this._front,r=this._capacity,i=0;e>i;++i)t[i]=this[n+i&r-1];return t},r.prototype.push=function(e){var t=arguments.length,n=this._length;if(t>1){var r=this._capacity;if(n+t>r){for(var i=0;t>i;++i){this._checkCapacity(n+1);var o=this._front+n&this._capacity-1;this[o]=arguments[i],n++,this._length=n}return n}for(var o=this._front,i=0;t>i;++i)this[o+n&r-1]=arguments[i],o++;return this._length=n+t,n+t}if(0===t)return n;this._checkCapacity(n+1);var i=this._front+n&this._capacity-1;return this[i]=e,this._length=n+1,n+1},r.prototype.pop=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1,n=this[t];return this[t]=void 0,this._length=e-1,n}},r.prototype.shift=function(){var e=this._length;if(0!==e){var t=this._front,n=this[t];return this[t]=void 0,this._front=t+1&this._capacity-1,this._length=e-1,n}},r.prototype.unshift=function(e){var t=this._length,n=arguments.length;if(n>1){var r=this._capacity;if(t+n>r){for(var i=n-1;i>=0;i--){this._checkCapacity(t+1);var r=this._capacity,o=(this._front-1&r-1^r)-r;this[o]=arguments[i],t++,this._length=t,this._front=o}return t}for(var a=this._front,i=n-1;i>=0;i--){var o=(a-1&r-1^r)-r;this[o]=arguments[i],a=o}return this._front=a,this._length=t+n,t+n}if(0===n)return t;this._checkCapacity(t+1);var r=this._capacity,i=(this._front-1&r-1^r)-r;return this[i]=e,this._length=t+1,this._front=i,t+1},r.prototype.peekBack=function(){var e=this._length;if(0!==e){var t=this._front+e-1&this._capacity-1;return this[t]}},r.prototype.peekFront=function(){return 0!==this._length?this[this._front]:void 0},r.prototype.get=function(e){var t=e;if(t===(0|t)){var n=this._length;if(0>t&&(t+=n),!(0>t||t>=n))return this[this._front+t&this._capacity-1]}},r.prototype.isEmpty=function(){return 0===this._length},r.prototype.clear=function(){this._length=0,this._front=0,this._makeCapacity()},r.prototype.toString=function(){return this.toArray().toString()},r.prototype.valueOf=r.prototype.toString,r.prototype.removeFront=r.prototype.shift,r.prototype.removeBack=r.prototype.pop,r.prototype.insertFront=r.prototype.unshift,r.prototype.insertBack=r.prototype.push,r.prototype.enqueue=r.prototype.push,r.prototype.dequeue=r.prototype.shift,r.prototype.toJSON=r.prototype.toArray,Object.defineProperty(r.prototype,"length",{get:function(){return this._length},set:function(){throw new RangeError("")}}),r.prototype._makeCapacity=function(){
+for(var e=this._capacity,t=0;e>t;++t)this[t]=void 0},r.prototype._checkCapacity=function(e){this._capacity<e&&this._resizeTo(a(1.5*this._capacity+16))},r.prototype._resizeTo=function(e){var t=this._front,n=this._capacity,r=new Array(n),o=this._length;if(i(this,0,r,0,n),this._capacity=e,this._makeCapacity(),this._front=0,n>=t+o)i(r,t,this,0,o);else{var a=o-(t+o&n-1);i(r,t,this,0,a),i(r,0,this,a,o-a)}};var s=Array.isArray;t.exports=r},{}],16:[function(e,t,n){function r(e,t,n){a(this,{type:e,name:e,cause:"string"!=typeof t?t:n,message:t&&"string"!=typeof t?t.message:t},"ewr")}function i(e,t){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee),r.call(this,"CustomError",e,t)}function o(e,t,n){var o=function(n,i){r.call(this,t,n,i),"FilesystemError"==t&&(this.code=this.cause.code,this.path=this.cause.path,this.errno=this.cause.errno,this.message=(e.errno[this.cause.errno]?e.errno[this.cause.errno].description:this.cause.message)+(this.cause.path?" ["+this.cause.path+"]":"")),Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,arguments.callee)};return o.prototype=n?new n:new i,o}var a=e(18);i.prototype=new Error,t.exports=function(e){var t=function(t,n){return o(e,t,n)};return{CustomError:i,FilesystemError:t("FilesystemError"),createError:t}}},{18:18}],17:[function(e,t,n){var r=t.exports.all=[{errno:-2,code:"ENOENT",description:"no such file or directory"},{errno:-1,code:"UNKNOWN",description:"unknown error"},{errno:0,code:"OK",description:"success"},{errno:1,code:"EOF",description:"end of file"},{errno:2,code:"EADDRINFO",description:"getaddrinfo error"},{errno:3,code:"EACCES",description:"permission denied"},{errno:4,code:"EAGAIN",description:"resource temporarily unavailable"},{errno:5,code:"EADDRINUSE",description:"address already in use"},{errno:6,code:"EADDRNOTAVAIL",description:"address not available"},{errno:7,code:"EAFNOSUPPORT",description:"address family not supported"},{errno:8,code:"EALREADY",description:"connection already in progress"},{errno:9,code:"EBADF",description:"bad file descriptor"},{errno:10,code:"EBUSY",description:"resource busy or locked"},{errno:11,code:"ECONNABORTED",description:"software caused connection abort"},{errno:12,code:"ECONNREFUSED",description:"connection refused"},{errno:13,code:"ECONNRESET",description:"connection reset by peer"},{errno:14,code:"EDESTADDRREQ",description:"destination address required"},{errno:15,code:"EFAULT",description:"bad address in system call argument"},{errno:16,code:"EHOSTUNREACH",description:"host is unreachable"},{errno:17,code:"EINTR",description:"interrupted system call"},{errno:18,code:"EINVAL",description:"invalid argument"},{errno:19,code:"EISCONN",description:"socket is already connected"},{errno:20,code:"EMFILE",description:"too many open files"},{errno:21,code:"EMSGSIZE",description:"message too long"},{errno:22,code:"ENETDOWN",description:"network is down"},{errno:23,code:"ENETUNREACH",description:"network is unreachable"},{errno:24,code:"ENFILE",description:"file table overflow"},{errno:25,code:"ENOBUFS",description:"no buffer space available"},{errno:26,code:"ENOMEM",description:"not enough memory"},{errno:27,code:"ENOTDIR",description:"not a directory"},{errno:28,code:"EISDIR",description:"illegal operation on a directory"},{errno:29,code:"ENONET",description:"machine is not on the network"},{errno:31,code:"ENOTCONN",description:"socket is not connected"},{errno:32,code:"ENOTSOCK",description:"socket operation on non-socket"},{errno:33,code:"ENOTSUP",description:"operation not supported on socket"},{errno:34,code:"ENOENT",description:"no such file or directory"},{errno:35,code:"ENOSYS",description:"function not implemented"},{errno:36,code:"EPIPE",description:"broken pipe"},{errno:37,code:"EPROTO",description:"protocol error"},{errno:38,code:"EPROTONOSUPPORT",description:"protocol not supported"},{errno:39,code:"EPROTOTYPE",description:"protocol wrong type for socket"},{errno:40,code:"ETIMEDOUT",description:"connection timed out"},{errno:41,code:"ECHARSET",description:"invalid Unicode character"},{errno:42,code:"EAIFAMNOSUPPORT",description:"address family for hostname not supported"},{errno:44,code:"EAISERVICE",description:"servname not supported for ai_socktype"},{errno:45,code:"EAISOCKTYPE",description:"ai_socktype not supported"},{errno:46,code:"ESHUTDOWN",description:"cannot send after transport endpoint shutdown"},{errno:47,code:"EEXIST",description:"file already exists"},{errno:48,code:"ESRCH",description:"no such process"},{errno:49,code:"ENAMETOOLONG",description:"name too long"},{errno:50,code:"EPERM",description:"operation not permitted"},{errno:51,code:"ELOOP",description:"too many symbolic links encountered"},{errno:52,code:"EXDEV",description:"cross-device link not permitted"},{errno:53,code:"ENOTEMPTY",description:"directory not empty"},{errno:54,code:"ENOSPC",description:"no space left on device"},{errno:55,code:"EIO",description:"i/o error"},{errno:56,code:"EROFS",description:"read-only file system"},{errno:57,code:"ENODEV",description:"no such device"},{errno:58,code:"ESPIPE",description:"invalid seek"},{errno:59,code:"ECANCELED",description:"operation canceled"}];t.exports.errno={},t.exports.code={},r.forEach(function(e){t.exports.errno[e.errno]=e,t.exports.code[e.code]=e}),t.exports.custom=e(16)(t.exports),t.exports.create=t.exports.custom.createError},{16:16}],18:[function(e,t,n){!function(e,n,r){"undefined"!=typeof t&&t.exports?t.exports=r():n[e]=r()}("prr",this,function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e},t=function(e,t){var n="object"==typeof t,r=!n&&"string"==typeof t,i=function(e){return n?!!t[e]:r?t.indexOf(e[0])>-1:!1};return{enumerable:i("enumerable"),configurable:i("configurable"),writable:i("writable"),value:e}},n=function(n,r,i,o){var a;if(o=t(i,o),"object"==typeof r){for(a in r)Object.hasOwnProperty.call(r,a)&&(o.value=r[a],e(n,a,o));return n}return e(n,r,o)};return n})},{}],19:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function o(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,o,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(a(n))for(o=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,u=0;r>u;u++)c[u].apply(this,o);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,a(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,o,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],o=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(s=o;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],20:[function(e,t,n){"use strict";function r(e,t,n,r,i,o){this._color=e,this.key=t,this.value=n,this.left=r,this.right=i,this._count=o}function i(e){return new r(e._color,e.key,e.value,e.left,e.right,e._count)}function o(e,t){return new r(e,t.key,t.value,t.left,t.right,t._count)}function a(e){e._count=1+(e.left?e.left._count:0)+(e.right?e.right._count:0)}function s(e,t){this._compare=e,this.root=t}function u(e,t){if(t.left){var n=u(e,t.left);if(n)return n}var n=e(t.key,t.value);return n?n:t.right?u(e,t.right):void 0}function c(e,t,n,r){var i=t(e,r.key);if(0>=i){if(r.left){var o=c(e,t,n,r.left);if(o)return o}var o=n(r.key,r.value);if(o)return o}return r.right?c(e,t,n,r.right):void 0}function f(e,t,n,r,i){var o,a=n(e,i.key),s=n(t,i.key);if(0>=a){if(i.left&&(o=f(e,t,n,r,i.left)))return o;if(s>0&&(o=r(i.key,i.value)))return o}return s>0&&i.right?f(e,t,n,r,i.right):void 0}function l(e,t){this.tree=e,this._stack=t}function h(e,t){e.key=t.key,e.value=t.value,e.left=t.left,e.right=t.right,e._color=t._color,e._count=t._count}function d(e){for(var t,n,r,s,u=e.length-1;u>=0;--u){if(t=e[u],0===u)return void(t._color=y);if(n=e[u-1],n.left===t){if(r=n.right,r.right&&r.right._color===v){if(r=n.right=i(r),s=r.right=i(r.right),n.right=r.left,r.left=n,r.right=s,r._color=n._color,t._color=y,n._color=y,s._color=y,a(n),a(r),u>1){var c=e[u-2];c.left===n?c.left=r:c.right=r}return void(e[u-1]=r)}if(r.left&&r.left._color===v){if(r=n.right=i(r),s=r.left=i(r.left),n.right=s.left,r.left=s.right,s.left=n,s.right=r,s._color=n._color,n._color=y,r._color=y,t._color=y,a(n),a(r),a(s),u>1){var c=e[u-2];c.left===n?c.left=s:c.right=s}return void(e[u-1]=s)}if(r._color===y){if(n._color===v)return n._color=y,void(n.right=o(v,r));n.right=o(v,r);continue}if(r=i(r),n.right=r.left,r.left=n,r._color=n._color,n._color=v,a(n),a(r),u>1){var c=e[u-2];c.left===n?c.left=r:c.right=r}e[u-1]=r,e[u]=n,u+1<e.length?e[u+1]=t:e.push(t),u+=2}else{if(r=n.left,r.left&&r.left._color===v){if(r=n.left=i(r),s=r.left=i(r.left),n.left=r.right,r.right=n,r.left=s,r._color=n._color,t._color=y,n._color=y,s._color=y,a(n),a(r),u>1){var c=e[u-2];c.right===n?c.right=r:c.left=r}return void(e[u-1]=r)}if(r.right&&r.right._color===v){if(r=n.left=i(r),s=r.right=i(r.right),n.left=s.right,r.right=s.left,s.right=n,s.left=r,s._color=n._color,n._color=y,r._color=y,t._color=y,a(n),a(r),a(s),u>1){var c=e[u-2];c.right===n?c.right=s:c.left=s}return void(e[u-1]=s)}if(r._color===y){if(n._color===v)return n._color=y,void(n.left=o(v,r));n.left=o(v,r);continue}if(r=i(r),n.left=r.right,r.right=n,r._color=n._color,n._color=v,a(n),a(r),u>1){var c=e[u-2];c.right===n?c.right=r:c.left=r}e[u-1]=r,e[u]=n,u+1<e.length?e[u+1]=t:e.push(t),u+=2}}}function p(e,t){return t>e?-1:e>t?1:0}function g(e){return new s(e||p,null)}t.exports=g;var v=0,y=1,_=s.prototype;Object.defineProperty(_,"keys",{get:function(){var e=[];return this.forEach(function(t,n){e.push(t)}),e}}),Object.defineProperty(_,"values",{get:function(){var e=[];return this.forEach(function(t,n){e.push(n)}),e}}),Object.defineProperty(_,"length",{get:function(){return this.root?this.root._count:0}}),_.insert=function(e,t){for(var n=this._compare,i=this.root,u=[],c=[];i;){var f=n(e,i.key);u.push(i),c.push(f),i=0>=f?i.left:i.right}u.push(new r(v,e,t,null,null,1));for(var l=u.length-2;l>=0;--l){var i=u[l];c[l]<=0?u[l]=new r(i._color,i.key,i.value,u[l+1],i.right,i._count+1):u[l]=new r(i._color,i.key,i.value,i.left,u[l+1],i._count+1)}for(var l=u.length-1;l>1;--l){var h=u[l-1],i=u[l];if(h._color===y||i._color===y)break;var d=u[l-2];if(d.left===h)if(h.left===i){var p=d.right;if(!p||p._color!==v){if(d._color=v,d.left=h.right,h._color=y,h.right=d,u[l-2]=h,u[l-1]=i,a(d),a(h),l>=3){var g=u[l-3];g.left===d?g.left=h:g.right=h}break}h._color=y,d.right=o(y,p),d._color=v,l-=1}else{var p=d.right;if(!p||p._color!==v){if(h.right=i.left,d._color=v,d.left=i.right,i._color=y,i.left=h,i.right=d,u[l-2]=i,u[l-1]=h,a(d),a(h),a(i),l>=3){var g=u[l-3];g.left===d?g.left=i:g.right=i}break}h._color=y,d.right=o(y,p),d._color=v,l-=1}else if(h.right===i){var p=d.left;if(!p||p._color!==v){if(d._color=v,d.right=h.left,h._color=y,h.left=d,u[l-2]=h,u[l-1]=i,a(d),a(h),l>=3){var g=u[l-3];g.right===d?g.right=h:g.left=h}break}h._color=y,d.left=o(y,p),d._color=v,l-=1}else{var p=d.left;if(!p||p._color!==v){if(h.left=i.right,d._color=v,d.right=i.left,i._color=y,i.right=h,i.left=d,u[l-2]=i,u[l-1]=h,a(d),a(h),a(i),l>=3){var g=u[l-3];g.right===d?g.right=i:g.left=i}break}h._color=y,d.left=o(y,p),d._color=v,l-=1}}return u[0]._color=y,new s(n,u[0])},_.forEach=function(e,t,n){if(this.root)switch(arguments.length){case 1:return u(e,this.root);case 2:return c(t,this._compare,e,this.root);case 3:if(this._compare(t,n)>=0)return;return f(t,n,this._compare,e,this.root)}},Object.defineProperty(_,"begin",{get:function(){for(var e=[],t=this.root;t;)e.push(t),t=t.left;return new l(this,e)}}),Object.defineProperty(_,"end",{get:function(){for(var e=[],t=this.root;t;)e.push(t),t=t.right;return new l(this,e)}}),_.at=function(e){if(0>e)return new l(this,[]);for(var t=this.root,n=[];;){if(n.push(t),t.left){if(e<t.left._count){t=t.left;continue}e-=t.left._count}if(!e)return new l(this,n);if(e-=1,!t.right)break;if(e>=t.right._count)break;t=t.right}return new l(this,[])},_.ge=function(e){for(var t=this._compare,n=this.root,r=[],i=0;n;){var o=t(e,n.key);r.push(n),0>=o&&(i=r.length),n=0>=o?n.left:n.right}return r.length=i,new l(this,r)},_.gt=function(e){for(var t=this._compare,n=this.root,r=[],i=0;n;){var o=t(e,n.key);r.push(n),0>o&&(i=r.length),n=0>o?n.left:n.right}return r.length=i,new l(this,r)},_.lt=function(e){for(var t=this._compare,n=this.root,r=[],i=0;n;){var o=t(e,n.key);r.push(n),o>0&&(i=r.length),n=0>=o?n.left:n.right}return r.length=i,new l(this,r)},_.le=function(e){for(var t=this._compare,n=this.root,r=[],i=0;n;){var o=t(e,n.key);r.push(n),o>=0&&(i=r.length),n=0>o?n.left:n.right}return r.length=i,new l(this,r)},_.find=function(e){for(var t=this._compare,n=this.root,r=[];n;){var i=t(e,n.key);if(r.push(n),0===i)return new l(this,r);n=0>=i?n.left:n.right}return new l(this,[])},_.remove=function(e){var t=this.find(e);return t?t.remove():this},_.get=function(e){for(var t=this._compare,n=this.root;n;){var r=t(e,n.key);if(0===r)return n.value;n=0>=r?n.left:n.right}};var b=l.prototype;Object.defineProperty(b,"valid",{get:function(){return this._stack.length>0}}),Object.defineProperty(b,"node",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1]:null},enumerable:!0}),b.clone=function(){return new l(this.tree,this._stack.slice())},b.remove=function(){var e=this._stack;if(0===e.length)return this.tree;var t=new Array(e.length),n=e[e.length-1];t[t.length-1]=new r(n._color,n.key,n.value,n.left,n.right,n._count);for(var i=e.length-2;i>=0;--i){var n=e[i];n.left===e[i+1]?t[i]=new r(n._color,n.key,n.value,t[i+1],n.right,n._count):t[i]=new r(n._color,n.key,n.value,n.left,t[i+1],n._count)}if(n=t[t.length-1],n.left&&n.right){var o=t.length;for(n=n.left;n.right;)t.push(n),n=n.right;var a=t[o-1];t.push(new r(n._color,a.key,a.value,n.left,n.right,n._count)),t[o-1].key=n.key,t[o-1].value=n.value;for(var i=t.length-2;i>=o;--i)n=t[i],t[i]=new r(n._color,n.key,n.value,n.left,t[i+1],n._count);t[o-1].left=t[o]}if(n=t[t.length-1],n._color===v){var u=t[t.length-2];u.left===n?u.left=null:u.right===n&&(u.right=null),t.pop();for(var i=0;i<t.length;++i)t[i]._count--;return new s(this.tree._compare,t[0])}if(n.left||n.right){n.left?h(n,n.left):n.right&&h(n,n.right),n._color=y;for(var i=0;i<t.length-1;++i)t[i]._count--;return new s(this.tree._compare,t[0])}if(1===t.length)return new s(this.tree._compare,null);for(var i=0;i<t.length;++i)t[i]._count--;var c=t[t.length-2];return d(t),c.left===n?c.left=null:c.right=null,new s(this.tree._compare,t[0])},Object.defineProperty(b,"key",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1].key:void 0},enumerable:!0}),Object.defineProperty(b,"value",{get:function(){return this._stack.length>0?this._stack[this._stack.length-1].value:void 0},enumerable:!0}),Object.defineProperty(b,"index",{get:function(){var e=0,t=this._stack;if(0===t.length){var n=this.tree.root;return n?n._count:0}t[t.length-1].left&&(e=t[t.length-1].left._count);for(var r=t.length-2;r>=0;--r)t[r+1]===t[r].right&&(++e,t[r].left&&(e+=t[r].left._count));return e},enumerable:!0}),b.next=function(){var e=this._stack;if(0!==e.length){var t=e[e.length-1];if(t.right)for(t=t.right;t;)e.push(t),t=t.left;else for(e.pop();e.length>0&&e[e.length-1].right===t;)t=e[e.length-1],e.pop()}},Object.defineProperty(b,"hasNext",{get:function(){var e=this._stack;if(0===e.length)return!1;if(e[e.length-1].right)return!0;for(var t=e.length-1;t>0;--t)if(e[t-1].left===e[t])return!0;return!1}}),b.update=function(e){var t=this._stack;if(0===t.length)throw new Error("Can't update empty node!");var n=new Array(t.length),i=t[t.length-1];n[n.length-1]=new r(i._color,i.key,e,i.left,i.right,i._count);for(var o=t.length-2;o>=0;--o)i=t[o],i.left===t[o+1]?n[o]=new r(i._color,i.key,i.value,n[o+1],i.right,i._count):n[o]=new r(i._color,i.key,i.value,i.left,n[o+1],i._count);return new s(this.tree._compare,n[0])},b.prev=function(){var e=this._stack;if(0!==e.length){var t=e[e.length-1];if(t.left)for(t=t.left;t;)e.push(t),t=t.right;else for(e.pop();e.length>0&&e[e.length-1].left===t;)t=e[e.length-1],e.pop()}},Object.defineProperty(b,"hasPrev",{get:function(){var e=this._stack;if(0===e.length)return!1;if(e[e.length-1].left)return!0;for(var t=e.length-1;t>0;--t)if(e[t-1].right===e[t])return!0;return!1}})},{}],21:[function(e,t,n){n.read=function(e,t,n,r,i){var o,a,s=8*i-r-1,u=(1<<s)-1,c=u>>1,f=-7,l=n?i-1:0,h=n?-1:1,d=e[t+l];for(l+=h,o=d&(1<<-f)-1,d>>=-f,f+=s;f>0;o=256*o+e[t+l],l+=h,f-=8);for(a=o&(1<<-f)-1,o>>=-f,f+=r;f>0;a=256*a+e[t+l],l+=h,f-=8);if(0===o)o=1-c;else{if(o===u)return a?NaN:(d?-1:1)*(1/0);a+=Math.pow(2,r),o-=c}return(d?-1:1)*a*Math.pow(2,o-r)},n.write=function(e,t,n,r,i,o){var a,s,u,c=8*o-i-1,f=(1<<c)-1,l=f>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,g=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=f):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),t+=a+l>=1?h/u:h*Math.pow(2,1-l),t*u>=2&&(a++,u/=2),a+l>=f?(s=0,a=f):a+l>=1?(s=(t*u-1)*Math.pow(2,i),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,i),a=0));i>=8;e[n+d]=255&s,d+=p,s/=256,i-=8);for(a=a<<i|s,c+=i;c>0;e[n+d]=255&a,d+=p,a/=256,c-=8);e[n+d-p]|=128*g}},{}],22:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||i()}var i,o=e.MutationObserver||e.WebKitMutationObserver;if(o){var a=0,s=new o(n),u=e.document.createTextNode("");s.observe(u,{characterData:!0}),i=function(){u.data=a=++a%2}}else if(e.setImmediate||"undefined"==typeof e.MessageChannel)i="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var c=new e.MessageChannel;c.port1.onmessage=n,i=function(){c.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],23:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],24:[function(e,t,n){t.exports=function(e){return!(null==e||!(e._isBuffer||e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)))}},{}],25:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],26:[function(e,t,n){(function(e){e("object"==typeof n?n:this)}).call(this,function(e){var t=Array.prototype.slice,n=Array.prototype.forEach,r=function(e){if("object"!=typeof e)throw e+" is not an object";var i=t.call(arguments,1);return n.call(i,function(t){if(t)for(var n in t)"object"==typeof t[n]&&e[n]?r.call(e,e[n],t[n]):e[n]=t[n]}),e};e.extend=r})},{}],27:[function(e,t,n){function r(e){this.opts=e||{},this.encodings=i}var i=e(28);t.exports=r,r.prototype._encoding=function(e){return"string"==typeof e&&(e=i[e]),e||(e=i.id),e},r.prototype._keyEncoding=function(e,t){return this._encoding(t&&t.keyEncoding||e&&e.keyEncoding||this.opts.keyEncoding)},r.prototype._valueEncoding=function(e,t){return this._encoding(t&&(t.valueEncoding||t.encoding)||e&&(e.valueEncoding||e.encoding)||this.opts.valueEncoding||this.opts.encoding)},r.prototype.encodeKey=function(e,t,n){return this._keyEncoding(t,n).encode(e)},r.prototype.encodeValue=function(e,t,n){return this._valueEncoding(t,n).encode(e)},r.prototype.decodeKey=function(e,t){return this._keyEncoding(t).decode(e)},r.prototype.decodeValue=function(e,t){return this._valueEncoding(t).decode(e)},r.prototype.encodeBatch=function(e,t){var n=this;return e.map(function(e){var r={type:e.type,key:n.encodeKey(e.key,t,e)};return n.keyAsBuffer(t,e)&&(r.keyEncoding="binary"),e.prefix&&(r.prefix=e.prefix),"value"in e&&(r.value=n.encodeValue(e.value,t,e),n.valueAsBuffer(t,e)&&(r.valueEncoding="binary")),r})};var o=["lt","gt","lte","gte","start","end"];r.prototype.encodeLtgt=function(e){var t=this,n={};return Object.keys(e).forEach(function(r){n[r]=o.indexOf(r)>-1?t.encodeKey(e[r],e):e[r]}),n},r.prototype.createStreamDecoder=function(e){var t=this;return e.keys&&e.values?function(n,r){return{key:t.decodeKey(n,e),value:t.decodeValue(r,e)}}:e.keys?function(n){return t.decodeKey(n,e)}:e.values?function(n,r){return t.decodeValue(r,e)}:function(){}},r.prototype.keyAsBuffer=function(e){return this._keyEncoding(e).buffer},r.prototype.valueAsBuffer=function(e){return this._valueEncoding(e).buffer}},{28:28}],28:[function(e,t,n){(function(e){function t(e){return e}function r(t){return void 0===t||null===t||e.isBuffer(t)}n.utf8=n["utf-8"]={encode:function(e){return r(e)?e:String(e)},decode:t,buffer:!1,type:"utf8"},n.json={encode:JSON.stringify,decode:JSON.parse,buffer:!1,type:"json"},n.binary={encode:function(t){return r(t)?t:new e(t)},decode:t,buffer:!0,type:"binary"},n.id={encode:function(e){return e},decode:function(e){return e},buffer:!1,type:"id"};var i=["hex","ascii","base64","ucs2","ucs-2","utf16le","utf-16le"];i.forEach(function(t){n[t]={encode:function(n){return r(n)?n:new e(n,t)},decode:function(e){return e.toString(t)},buffer:!0,type:t}})}).call(this,e(5).Buffer)},{5:5}],29:[function(e,t,n){var r=e(17).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{17:17}],30:[function(e,t,n){function r(e,t){return this instanceof r?(o.call(this,a(t,{objectMode:!0})),this._iterator=e,this._destroyed=!1,this._decoder=null,t&&t.decoder&&(this._decoder=t.decoder),void this.on("end",this._cleanup.bind(this))):new r(e,t)}var i=e(23),o=e(37).Readable,a=e(38),s=e(29).EncodingError;t.exports=r,i(r,o),r.prototype._read=function(){var e=this;this._destroyed||this._iterator.next(function(t,n,r){if(!e._destroyed){if(t)return e.emit("error",t);if(void 0===n&&void 0===r)e.push(null);else{if(!e._decoder)return e.push({key:n,value:r});try{var r=e._decoder(n,r)}catch(t){return e.emit("error",new s(t)),void e.push(null)}e.push(r)}}})},r.prototype.destroy=r.prototype._cleanup=function(){var e=this;this._destroyed||(this._destroyed=!0,this._iterator.end(function(t){return t?e.emit("error",t):void e.emit("close")}))}},{23:23,29:29,37:37,38:38}],31:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],32:[function(e,t,n){(function(n){function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||n.nextTick(this.end.bind(this))}function o(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}t.exports=r;var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},s=e(6);s.inherits=e(23);var u=e(34),c=e(36);s.inherits(r,u),o(a(c.prototype),function(e){r.prototype[e]||(r.prototype[e]=c.prototype[e])})}).call(this,e(55))},{23:23,34:34,36:36,55:55,6:6}],33:[function(e,t,n){function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(35),o=e(6);o.inherits=e(23),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{23:23,35:35,6:6}],34:[function(e,t,n){(function(n){function r(t,n){var r=e(32);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(69).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(t){e(32);return this instanceof i?(this._readableState=new r(t,this),this.readable=!0,void B.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(R.isNullOrUndefined(n))t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),i||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e)),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=j)e=j;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:isNaN(e)||R.isNull(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||R.isString(t)||R.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(M("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){M("emit readable"),e.emit("readable"),_(e)}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(M("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;M("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&x.listenerCount(e,"data")&&(t.flowing=!0,_(e))}}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,n.nextTick(function(){y(e,t)}))}function y(e,t){t.resumeScheduled=!1,e.emit("resume"),_(e),t.flowing&&!t.reading&&e.read(0)}function _(e){var t=e._readableState;if(M("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function b(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(31),S=e(5).Buffer;i.ReadableState=r;var x=e(19).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(58),R=e(6);R.inherits=e(23);var A,M=e(4);M=M&&M.debuglog?M.debuglog("stream"):function(){},R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return R.isString(e)&&!n.objectMode&&(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){return A||(A=e(69).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t,this};var j=8388608;i.prototype.read=function(e){M("read",e);var t=this._readableState,n=e;if((!R.isNumber(e)||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return M("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?m(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&m(this),null;var r=t.needReadable;M("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,M("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,M("reading or ended",r)),r&&(M("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?b(e,t):null,R.isNull(i)&&(t.needReadable=!0,e=0),t.length-=e,
+0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&m(this),R.isNull(i)||this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){M("onunpipe"),e===l&&o()}function i(){M("onend"),e.end()}function o(){M("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){M("ondata");var n=e.write(t);!1===n&&(M("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++,l.pause())}function s(t){M("onerror",t),f(),e.removeListener("error",s),0===x.listenerCount(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){M("onfinish"),e.removeListener("close",u),f()}function f(){M("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,M("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?n.nextTick(p):l.once("end",p),e.on("unpipe",r);var v=g(l);return e.on("drain",v),l.on("data",a),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(M("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var r=B.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&this.readable){var i=this._readableState;if(!i.readableListening)if(i.readableListening=!0,i.emittedReadable=!1,i.needReadable=!0,i.reading)i.length&&l(this,i);else{var o=this;n.nextTick(function(){M("readable nexttick read 0"),o.read(0)})}}return r},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(M("resume"),e.flowing=!0,e.reading||(M("resume read 0"),this.read(0)),v(this,e)),this},i.prototype.pause=function(){return M("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(M("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(M("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(M("wrapped data"),t.decoder&&(i=t.decoder.write(i)),i&&(t.objectMode||i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)R.isFunction(e[i])&&R.isUndefined(this[i])&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){M("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=b}).call(this,e(55))},{19:19,23:23,31:31,32:32,4:4,5:5,55:55,58:58,6:6,69:69}],35:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,u.isNullOrUndefined(n)||e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(e,this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("prefinish",function(){u.isFunction(this._flush)?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(32),u=e(6);u.inherits=e(23),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;u.isNull(t.writechunk)||!t.writecb||t.transforming?t.needTransform=!0:(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform))}},{23:23,32:32,6:6}],36:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(t,n){var r=e(32);t=t||{};var i=t.highWaterMark,o=t.objectMode?16:16384;this.highWaterMark=i||0===i?i:o,this.objectMode=!!t.objectMode,n instanceof r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1}function o(t){var n=e(32);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void k.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!(E.isBuffer(r)||E.isString(r)||E.isNullOrUndefined(r)||t.objectMode)){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return!e.objectMode&&e.decodeStrings!==!1&&E.isString(t)&&(t=new w(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),E.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing||t.corked?t.buffer.push(new r(n,i,o)):f(e,t,!1,a,n,i,o),s}function f(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){t.pendingcb--,o(i)}):(t.pendingcb--,o(i)),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.corked||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),t.pendingcb--,r(),b(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){if(t.bufferProcessing=!0,e._writev&&t.buffer.length>1){for(var n=[],r=0;r<t.buffer.length;r++)n.push(t.buffer[r].callback);t.pendingcb++,f(e,t,!0,t.length,t.buffer,"",function(e){for(var r=0;r<n.length;r++)t.pendingcb--,n[r](e)}),t.buffer=[]}else{for(var r=0;r<t.buffer.length;r++){var i=t.buffer[r],o=i.chunk,a=i.encoding,s=i.callback,u=t.objectMode?1:o.length;if(f(e,t,!1,u,o,a,s),t.writing){r++;break}}r<t.buffer.length?t.buffer=t.buffer.slice(r):t.buffer.length=0}t.bufferProcessing=!1}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function _(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function b(e,t){var n=y(e,t);return n&&(0===t.pendingcb?(_(e,t),t.finished=!0,e.emit("finish")):_(e,t)),n}function m(e,t,r){t.ending=!0,b(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var w=e(5).Buffer;o.WritableState=i;var E=e(6);E.inherits=e(23);var k=e(58);E.inherits(o,k),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return E.isFunction(t)&&(n=t,t=null),E.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),E.isFunction(n)||(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(r.pendingcb++,i=c(this,r,e,t,n)),i},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.buffer.length||v(this,e))},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;E.isFunction(e)?(n=e,e=null,t=null):E.isFunction(t)&&(n=t,t=null),E.isNullOrUndefined(e)||this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||m(this,r,n)}}).call(this,e(55))},{23:23,32:32,5:5,55:55,58:58,6:6}],37:[function(e,t,n){(function(r){n=t.exports=e(34),n.Stream=e(58),n.Readable=n,n.Writable=e(36),n.Duplex=e(32),n.Transform=e(35),n.PassThrough=e(33),r.browser||"disable"!==r.env.READABLE_STREAM||(t.exports=e(58))}).call(this,e(55))},{32:32,33:33,34:34,35:35,36:36,55:55,58:58}],38:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{14:14}],39:[function(e,t,n){function r(e,t){this._levelup=e,this._codec=t,this.batch=e.db.batch(),this.ops=[],this.length=0}var i=e(41),o=e(29).WriteError,a=i.getOptions,s=i.dispatchError;r.prototype.put=function(e,t,n){n=a(n);var r=this._codec.encodeKey(e,n),i=this._codec.encodeValue(t,n);try{this.batch.put(r,i)}catch(s){throw new o(s)}return this.ops.push({type:"put",key:r,value:i}),this.length++,this},r.prototype.del=function(e,t){t=a(t);var n=this._codec.encodeKey(e,t);try{this.batch.del(n)}catch(r){throw new o(r)}return this.ops.push({type:"del",key:n}),this.length++,this},r.prototype.clear=function(){try{this.batch.clear()}catch(e){throw new o(e)}return this.ops=[],this.length=0,this},r.prototype.write=function(e){var t=this._levelup,n=this.ops;try{this.batch.write(function(r){return r?s(t,new o(r),e):(t.emit("batch",n),void(e&&e()))})}catch(r){throw new o(r)}},t.exports=r},{29:29,41:41}],40:[function(e,t,n){(function(n){function r(e,t){return"function"==typeof e?e:t}function i(e,t,r){if(!(this instanceof i))return new i(e,t,r);var o;if(c.call(this),this.setMaxListeners(1/0),"function"==typeof e?(t="object"==typeof t?t:{},t.db=e,e=null):"object"==typeof e&&"function"==typeof e.db&&(t=e,e=null),"function"==typeof t&&(r=t,t={}),(!t||"function"!=typeof t.db)&&"string"!=typeof e){if(o=new E("Must provide a location for the database"),r)return n.nextTick(function(){r(o)});throw o}t=B(t),this.options=h(R,t),this._codec=new x(this.options),this._status="new",d(this,"location",e,"e"),this.open(r)}function o(e,t,n){return e._isOpening()||e.isOpen()?void 0:(M(e,new _("Database is not open"),n),!0)}function a(e,t,n){M(e,new y(t),n)}function s(e,t,n){M(e,new _(t),n)}function u(e){return function(t,n){A()[e](t,n||function(){})}}var c=e(19).EventEmitter,f=e(93).inherits,l=e(93).deprecate,h=e(42),d=e(56),p=e(8),g=e(30),v=e(29),y=v.WriteError,_=v.ReadError,b=v.NotFoundError,m=v.OpenError,w=v.EncodingError,E=v.InitializationError,k=e(41),S=e(39),x=e(27),B=k.getOptions,R=k.defaultOptions,A=k.getLevelDOWN,M=k.dispatchError;k.isDefined;f(i,c),i.prototype.open=function(e){var t,r,i=this;return this.isOpen()?(e&&n.nextTick(function(){e(null,i)}),this):this._isOpening()?e&&this.once("open",function(){e(null,i)}):(this.emit("opening"),this._status="opening",this.db=new p(this.location),t=this.options.db||A(),r=t(this.location),void r.open(this.options,function(t){return t?M(i,new m(t),e):(i.db.setDb(r),i.db=r,i._status="open",e&&e(null,i),i.emit("open"),i.emit("ready"),void 0)}))},i.prototype.close=function(e){var t=this;if(this.isOpen())this._status="closing",this.db.close(function(){t._status="closed",t.emit("closed"),e&&e.apply(null,arguments)}),this.emit("closing"),this.db=new p(this.location);else{if("closed"==this._status&&e)return n.nextTick(e);"closing"==this._status&&e?this.once("closed",e):this._isOpening()&&this.once("open",function(){t.close(e)})}},i.prototype.isOpen=function(){return"open"==this._status},i.prototype._isOpening=function(){return"opening"==this._status},i.prototype.isClosed=function(){return/^clos/.test(this._status)},i.prototype.get=function(e,t,n){var i,a=this;if(n=r(t,n),!o(this,t,n)){if(null===e||void 0===e||"function"!=typeof n)return s(this,"get() requires key and callback arguments",n);t=k.getOptions(t),i=this._codec.encodeKey(e,t),t.asBuffer=this._codec.valueAsBuffer(t),this.db.get(i,t,function(r,i){if(r)return r=/notfound/i.test(r)||r.notFound?new b("Key not found in database ["+e+"]",r):new _(r),M(a,r,n);if(n){try{i=a._codec.decodeValue(i,t)}catch(o){return n(new w(o))}n(null,i)}})}},i.prototype.put=function(e,t,n,i){var s,u,c=this;return i=r(n,i),null===e||void 0===e?a(this,"put() requires a key argument",i):void(o(this,n,i)||(n=B(n),s=this._codec.encodeKey(e,n),u=this._codec.encodeValue(t,n),this.db.put(s,u,n,function(n){return n?M(c,new y(n),i):(c.emit("put",e,t),void(i&&i()))})))},i.prototype.del=function(e,t,n){var i,s=this;return n=r(t,n),null===e||void 0===e?a(this,"del() requires a key argument",n):void(o(this,t,n)||(t=B(t),i=this._codec.encodeKey(e,t),this.db.del(i,t,function(t){return t?M(s,new y(t),n):(s.emit("del",e),void(n&&n()))})))},i.prototype.batch=function(e,t,n){var i,s=this;return arguments.length?(n=r(t,n),Array.isArray(e)?void(o(this,t,n)||(t=B(t),i=s._codec.encodeBatch(e,t),i=i.map(function(e){return e.type||void 0===e.key||void 0===e.value||(e.type="put"),e}),this.db.batch(i,t,function(t){return t?M(s,new y(t),n):(s.emit("batch",e),void(n&&n()))}))):a(this,"batch() requires an array argument",n)):new S(this,this._codec)},i.prototype.approximateSize=l(function(e,t,n,i){var o,a,u=this;return i=r(n,i),n=B(n),null===e||void 0===e||null===t||void 0===t||"function"!=typeof i?s(this,"approximateSize() requires start, end and callback arguments",i):(o=this._codec.encodeKey(e,n),a=this._codec.encodeKey(t,n),void this.db.approximateSize(o,a,function(e,t){return e?M(u,new m(e),i):void(i&&i(null,t))}))},"db.approximateSize() is deprecated. Use db.db.approximateSize() instead"),i.prototype.readStream=i.prototype.createReadStream=function(e){return e=h({keys:!0,values:!0},this.options,e),e.keyEncoding=e.keyEncoding,e.valueEncoding=e.valueEncoding,e=this._codec.encodeLtgt(e),e.keyAsBuffer=this._codec.keyAsBuffer(e),e.valueAsBuffer=this._codec.valueAsBuffer(e),"number"!=typeof e.limit&&(e.limit=-1),new g(this.db.iterator(e),h(e,{decoder:this._codec.createStreamDecoder(e)}))},i.prototype.keyStream=i.prototype.createKeyStream=function(e){return this.createReadStream(h(e,{keys:!0,values:!1}))},i.prototype.valueStream=i.prototype.createValueStream=function(e){return this.createReadStream(h(e,{keys:!1,values:!0}))},i.prototype.toString=function(){return"LevelUP"},t.exports=i,t.exports.errors=e(29),t.exports.destroy=l(u("destroy"),"levelup.destroy() is deprecated. Use leveldown.destroy() instead"),t.exports.repair=l(u("repair"),"levelup.repair() is deprecated. Use leveldown.repair() instead")}).call(this,e(55))},{19:19,27:27,29:29,30:30,39:39,41:41,42:42,55:55,56:56,8:8,93:93}],41:[function(e,t,n){function r(e){return"string"==typeof e&&(e={valueEncoding:e}),"object"!=typeof e&&(e={}),e}function i(){if(u)return u;var t,n=e(43).devDependencies.leveldown;try{t=e(4).version}catch(r){throw o(r)}if(!e(4).satisfies(t,n))throw new c("Installed version of LevelDOWN ("+t+") does not match required version ("+n+")");try{return u=e(4)}catch(r){throw o(r)}}function o(e){var t="Failed to require LevelDOWN (%s). Try `npm install leveldown` if it's missing";return new c(f(t,e.message))}function a(e,t,n){"function"==typeof n?n(t):e.emit("error",t)}function s(e){return"undefined"!=typeof e}var u,c=(e(42),e(29).LevelUPError),f=e(93).format,l={createIfMissing:!0,errorIfExists:!1,keyEncoding:"utf8",valueEncoding:"utf8",compression:!0};t.exports={defaultOptions:l,getOptions:r,getLevelDOWN:i,dispatchError:a,isDefined:s}},{29:29,4:4,42:42,43:43,93:93}],42:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{14:14}],43:[function(e,t,n){t.exports={_args:[["levelup@1.3.1","/Users/nolan/workspace/pouchdb"]],_from:"levelup@1.3.1",_id:"levelup@1.3.1",_inCache:!0,_installable:!0,_location:"/levelup",_nodeVersion:"4.2.2",_npmUser:{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},_npmVersion:"3.5.0",_phantomChildren:{},_requested:{name:"levelup",raw:"levelup@1.3.1",rawSpec:"1.3.1",scope:null,spec:"1.3.1",type:"version"},_requiredBy:["/","/pouchdb"],_resolved:"http://127.0.0.1:5080/tarballs/levelup/1.3.1.tgz",_shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",_shrinkwrap:null,_spec:"levelup@1.3.1",_where:"/Users/nolan/workspace/pouchdb",browser:{leveldown:!1,"leveldown/package":!1,semver:!1},bugs:{url:"https://github.com/level/levelup/issues"},contributors:[{email:"r@va.gg",name:"Rod Vagg",url:"https://github.com/rvagg"},{email:"john@chesl.es",name:"John Chesley",url:"https://github.com/chesles/"},{email:"raynos2@gmail.com",name:"Jake Verbaten",url:"https://github.com/raynos"},{email:"dominic.tarr@gmail.com",name:"Dominic Tarr",url:"https://github.com/dominictarr"},{email:"max@maxogden.com",name:"Max Ogden",url:"https://github.com/maxogden"},{email:"ralphtheninja@riseup.net",name:"Lars-Magnus Skog",url:"https://github.com/ralphtheninja"},{email:"david.bjorklund@gmail.com",name:"David Björklund",url:"https://github.com/kesla"},{email:"julian@juliangruber.com",name:"Julian Gruber",url:"https://github.com/juliangruber"},{email:"paolo@async.ly",name:"Paolo Fragomeni",url:"https://github.com/hij1nx"},{email:"anton.whalley@nearform.com",name:"Anton Whalley",url:"https://github.com/No9"},{email:"matteo.collina@gmail.com",name:"Matteo Collina",url:"https://github.com/mcollina"},{email:"pedro.teixeira@gmail.com",name:"Pedro Teixeira",url:"https://github.com/pgte"},{email:"mail@substack.net",name:"James Halliday",url:"https://github.com/substack"},{email:"jcrugzz@gmail.com",name:"Jarrett Cruger",url:"https://github.com/jcrugzz"}],dependencies:{"deferred-leveldown":"~1.2.1","level-codec":"~6.1.0","level-errors":"~1.0.3","level-iterator-stream":"~1.3.0",prr:"~1.0.1",semver:"~5.1.0",xtend:"~4.0.0"},description:"Fast & simple storage - a Node.js-style LevelDB wrapper",devDependencies:{async:"~1.5.0",bustermove:"~1.0.0",delayed:"~1.0.1",faucet:"~0.0.1",leveldown:"^1.1.0",memdown:"~1.1.0","msgpack-js":"~0.3.0",referee:"~1.2.0",rimraf:"~2.4.3","slow-stream":"0.0.4",tap:"~2.3.1",tape:"~4.2.1"},directories:{},dist:{shasum:"8030758bb1b1dafdb71bfb55fff0caa2740cb846",tarball:"https://registry.npmjs.org/levelup/-/levelup-1.3.1.tgz"},gitHead:"40bd66872974140c79a74d9411b992ddffa926a4",homepage:"https://github.com/level/levelup",keywords:["leveldb","stream","database","db","store","storage","json"],license:"MIT",main:"lib/levelup.js",maintainers:[{email:"rod@vagg.org",name:"rvagg"},{email:"ralphtheninja@riseup.net",name:"ralphtheninja"},{email:"julian@juliangruber.com",name:"juliangruber"}],name:"levelup",optionalDependencies:{},readme:"ERROR: No README data found!",repository:{type:"git",url:"git+https://github.com/level/levelup.git"},scripts:{test:"tape test/*-test.js | faucet"},version:"1.3.1"}},{}],44:[function(e,t,n){"use strict";function r(){}function i(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=_,this.queue=[],this.outcome=void 0,e!==r&&u(this,e)}function o(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function a(e,t,n){p(function(){var r;try{r=t(n)}catch(i){return g.reject(e,i)}r===e?g.reject(e,new TypeError("Cannot resolve promise with itself")):g.resolve(e,r)})}function s(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}function u(e,t){function n(t){o||(o=!0,g.reject(e,t))}function r(t){o||(o=!0,g.resolve(e,t))}function i(){t(r,n)}var o=!1,a=c(i);"error"===a.status&&n(a.value)}function c(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}function f(e){return e instanceof this?e:g.resolve(new this(r),e)}function l(e){var t=new this(r);return g.reject(t,e)}function h(e){function t(e,t){function r(e){a[t]=e,++s!==i||o||(o=!0,g.resolve(c,a))}n.resolve(e).then(r,function(e){o||(o=!0,g.reject(c,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=new Array(i),s=0,u=-1,c=new this(r);++u<i;)t(e[u],u);return c}function d(e){function t(e){n.resolve(e).then(function(e){o||(o=!0,g.resolve(s,e))},function(e){o||(o=!0,g.reject(s,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var i=e.length,o=!1;if(!i)return this.resolve([]);for(var a=-1,s=new this(r);++a<i;)t(e[a]);return s}var p=e(22),g={},v=["REJECTED"],y=["FULFILLED"],_=["PENDING"];t.exports=n=i,i.prototype["catch"]=function(e){return this.then(null,e)},i.prototype.then=function(e,t){if("function"!=typeof e&&this.state===y||"function"!=typeof t&&this.state===v)return this;var n=new this.constructor(r);if(this.state!==_){var i=this.state===y?e:t;a(n,i,this.outcome)}else this.queue.push(new o(n,e,t));return n},o.prototype.callFulfilled=function(e){g.resolve(this.promise,e)},o.prototype.otherCallFulfilled=function(e){a(this.promise,this.onFulfilled,e)},o.prototype.callRejected=function(e){g.reject(this.promise,e)},o.prototype.otherCallRejected=function(e){a(this.promise,this.onRejected,e)},g.resolve=function(e,t){var n=c(s,t);if("error"===n.status)return g.reject(e,n.value);var r=n.value;if(r)u(e,r);else{e.state=y,e.outcome=t;for(var i=-1,o=e.queue.length;++i<o;)e.queue[i].callFulfilled(t)}return e},g.reject=function(e,t){e.state=v,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},n.resolve=f,n.reject=l,n.all=h,n.race=d},{22:22}],45:[function(e,t,n){(function(e){function t(e){return null!=e&&""!==e}n.compare=function(t,n){if(e.isBuffer(t)){for(var r=Math.min(t.length,n.length),i=0;r>i;i++){var o=t[i]-n[i];if(o)return o}return t.length-n.length}return n>t?-1:t>n?1:0};var r=n.lowerBound=function(e){return t(e.gt)?e.gt:t(e.gte)?e.gte:t(e.min)?e.min:t(e.start)&&!e.reverse?e.start:t(e.end)&&e.reverse?e.end:void 0};n.lowerBoundInclusive=function(e){return!t(e.gt)},n.upperBoundInclusive=function(e){return!t(e.lt)};var i=n.lowerBoundExclusive=function(e){return!!t(e.gt)},o=n.upperBoundExclusive=function(e){return!!t(e.lt)},a=n.upperBound=function(e){return t(e.lt)?e.lt:t(e.lte)?e.lte:t(e.max)?e.max:t(e.start)&&e.reverse?e.start:t(e.end)&&!e.reverse?e.end:void 0};n.contains=function(e,s,u){u=u||n.compare;var c=r(e);if(t(c)){var f=u(s,c);if(0>f||0===f&&i(e))return!1}var l=a(e);if(t(l)){var f=u(s,l);if(f>0||0===f&&o(e))return!1}return!0},n.filter=function(e,t){return function(r){return n.contains(e,r,t)}}}).call(this,{isBuffer:e(24)})},{24:24}],46:[function(e,t,n){(function(n,r,i){function o(e){return"string"==typeof e?"$"+e:JSON.stringify(e)}function a(e){return g.compare(e,this._end)>0}function s(e){return g.compare(e,this._end)>=0}function u(e){return g.compare(e,this._end)<0}function c(e){return g.compare(e,this._end)<=0}function f(e,t){p.call(this,e),this._limit=t.limit,-1===this._limit&&(this._limit=1/0);var n=e._store[e._location];this.keyAsBuffer=t.keyAsBuffer!==!1,this.valueAsBuffer=t.valueAsBuffer!==!1,this._reverse=t.reverse,this._options=t,this._done=0,this._reverse?(this._incr="prev",this._start=g.upperBound(t),this._end=g.lowerBound(t),"undefined"==typeof this._start?this._tree=n.end:g.upperBoundInclusive(t)?this._tree=n.le(this._start):this._tree=n.lt(this._start),this._end&&(g.lowerBoundInclusive(t)?this._test=s:this._test=a)):(this._incr="next",this._start=g.lowerBound(t),this._end=g.upperBound(t),"undefined"==typeof this._start?this._tree=n.begin:g.lowerBoundInclusive(t)?this._tree=n.ge(this._start):this._tree=n.gt(this._start),this._end&&(g.upperBoundInclusive(t)?this._test=c:this._test=u))}function l(e){return this instanceof l?(d.call(this,"string"==typeof e?e:""),this._location=this.location?o(this.location):"_tree",this._store=this.location?_:this,void(this._store[this._location]=this._store[this._location]||y(g.compare))):new l(e)}var h=e(23),d=e(50).AbstractLevelDOWN,p=e(50).AbstractIterator,g=e(45),v=r.setImmediate||n.nextTick,y=e(20),_={};h(f,p),f.prototype._next=function(e){var t,n;return this._done++>=this._limit?v(e):this._tree.valid?(t=this._tree.key,n=this._tree.value,this._test(t)?(this.keyAsBuffer&&(t=new i(t)),this.valueAsBuffer&&(n=new i(n)),this._tree[this._incr](),void v(function(){e(null,t,n)})):v(e)):v(e)},f.prototype._test=function(){return!0},l.clearGlobalStore=function(e){e?Object.keys(_).forEach(function(e){delete _[e]}):_={}},h(l,d),l.prototype._open=function(e,t){var n=this;v(function(){t(null,n)})},l.prototype._put=function(e,t,n,r){"undefined"!=typeof t&&null!==t||(t="");var i=this._store[this._location].find(e);i.valid?this._store[this._location]=i.update(t):this._store[this._location]=this._store[this._location].insert(e,t),v(r)},l.prototype._get=function(e,t,n){var r=this._store[this._location].get(e);if(void 0===r){var o=new Error("NotFound");return v(function(){n(o)})}t.asBuffer===!1||this._isBuffer(r)||(r=new i(String(r))),v(function(){n(null,r)})},l.prototype._del=function(e,t,n){this._store[this._location]=this._store[this._location].remove(e),v(n)},l.prototype._batch=function(e,t,n){for(var r,i,o,a,s=-1,u=e.length,c=this._store[this._location];++s<u;)if(e[s]){if(i=this._isBuffer(e[s].key)?e[s].key:String(e[s].key),r=this._checkKey(i,"key"))return v(function(){n(r)});if(a=c.find(i),"put"===e[s].type){if(o=this._isBuffer(e[s].value)?e[s].value:String(e[s].value),r=this._checkKey(o,"value"))return v(function(){n(r)});c=a.valid?a.update(o):c.insert(i,o)}else c=a.remove()}this._store[this._location]=c,v(n)},l.prototype._iterator=function(e){return new f(this,e)},l.prototype._isBuffer=function(e){return i.isBuffer(e)},l.destroy=function(e,t){var n=o(e);n in _&&delete _[n],v(t)},t.exports=l}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e(5).Buffer)},{20:20,23:23,45:45,5:5,50:50,55:55}],47:[function(e,t,n){(function(e){function n(e){this._db=e,this._operations=[],this._written=!1}n.prototype._serializeKey=function(e){return this._db._serializeKey(e)},n.prototype._serializeValue=function(e){return this._db._serializeValue(e)},n.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},n.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKey(e,"key",this._db._isBuffer);if(n)throw n;return e=this._serializeKey(e),t=this._serializeValue(t),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},n.prototype.del=function(e){this._checkWritten();var t=this._db._checkKey(e,"key",this._db._isBuffer);if(t)throw t;return e=this._serializeKey(e),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},n.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},n.prototype.write=function(t,n){if(this._checkWritten(),"function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("write() requires a callback argument");return"object"!=typeof t&&(t={}),this._written=!0,"function"==typeof this._write?this._write(n):"function"==typeof this._db._batch?this._db._batch(this._operations,t,n):void e.nextTick(n)},t.exports=n}).call(this,e(55))},{55:55}],48:[function(e,t,n){arguments[4][10][0].apply(n,arguments)},{10:10,55:55}],49:[function(e,t,n){(function(n,r){function i(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e,this.status="new"}var o=e(52),a=e(48),s=e(47);i.prototype.open=function(e,t){var n=this,i=this.status;if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");"object"!=typeof e&&(e={}),e.createIfMissing=0!=e.createIfMissing,e.errorIfExists=!!e.errorIfExists,"function"==typeof this._open?(this.status="opening",this._open(e,function(e){return e?(n.status=i,t(e)):(n.status="open",void t())})):(this.status="open",r.nextTick(t))},i.prototype.close=function(e){var t=this,n=this.status;if("function"!=typeof e)throw new Error("close() requires a callback argument");"function"==typeof this._close?(this.status="closing",this._close(function(r){return r?(t.status=n,e(r)):(t.status="closed",void e())})):(this.status="closed",r.nextTick(e))},i.prototype.get=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(i=this._checkKey(e,"key"))?n(i):(e=this._serializeKey(e),"object"!=typeof t&&(t={}),t.asBuffer=0!=t.asBuffer,"function"==typeof this._get?this._get(e,t,n):void r.nextTick(function(){n(new Error("NotFound"))}))},i.prototype.put=function(e,t,n,i){var o;if("function"==typeof n&&(i=n),"function"!=typeof i)throw new Error("put() requires a callback argument");return(o=this._checkKey(e,"key"))?i(o):(e=this._serializeKey(e),t=this._serializeValue(t),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,i):void r.nextTick(i))},i.prototype.del=function(e,t,n){var i;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(i=this._checkKey(e,"key"))?n(i):(e=this._serializeKey(e),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void r.nextTick(n))},i.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"==typeof e&&(n=e),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));t&&"object"==typeof t||(t={});for(var i,o,a=0,s=e.length;s>a;a++)if(i=e[a],"object"==typeof i){if(o=this._checkKey(i.type,"type"))return n(o);if(o=this._checkKey(i.key,"key"))return n(o)}return"function"==typeof this._batch?this._batch(e,t,n):void r.nextTick(n)},i.prototype.approximateSize=function(e,t,n){if(null==e||null==t||"function"==typeof e||"function"==typeof t)throw new Error("approximateSize() requires valid `start`, `end` and `callback` arguments");if("function"!=typeof n)throw new Error("approximateSize() requires a callback argument");return e=this._serializeKey(e),t=this._serializeKey(t),"function"==typeof this._approximateSize?this._approximateSize(e,t,n):void r.nextTick(function(){n(null,0)})},i.prototype._setupIteratorOptions=function(e){var t=this;return e=o(e),["start","end","gt","gte","lt","lte"].forEach(function(n){e[n]&&t._isBuffer(e[n])&&0===e[n].length&&delete e[n]}),e.reverse=!!e.reverse,e.keys=0!=e.keys,e.values=0!=e.values,e.limit="limit"in e?e.limit:-1,e.keyAsBuffer=0!=e.keyAsBuffer,e.valueAsBuffer=0!=e.valueAsBuffer,
+e},i.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),e=this._setupIteratorOptions(e),"function"==typeof this._iterator?this._iterator(e):new a(this)},i.prototype._chainedBatch=function(){return new s(this)},i.prototype._isBuffer=function(e){return n.isBuffer(e)},i.prototype._serializeKey=function(e){return this._isBuffer(e)?e:String(e)},i.prototype._serializeValue=function(e){return this._isBuffer(e)||r.browser?e:String(e)},i.prototype._checkKey=function(e,t){return null===e||void 0===e?new Error(t+" cannot be `null` or `undefined`"):this._isBuffer(e)&&0===e.length?new Error(t+" cannot be an empty Buffer"):""===String(e)?new Error(t+" cannot be an empty String"):void 0},t.exports=i}).call(this,{isBuffer:e(24)},e(55))},{24:24,47:47,48:48,52:52,55:55}],50:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{12:12,47:47,48:48,49:49,51:51}],51:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{13:13,49:49}],52:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{14:14}],53:[function(e,t,n){"use strict";function r(){this.store={}}function i(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=i,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){for(var t=Object.keys(this.store),n=0,r=t.length;r>n;n++){var i=t[n],o=this.store[i];i=this.unmangle(i),e(o,i)}},i.prototype.add=function(e){return this.store.set(e,!0)},i.prototype.has=function(e){return this.store.has(e)},i.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],54:[function(e,t,n){(function(e){"use strict";function n(t){for(var n=new Array(arguments.length-1),r=0;r<n.length;)n[r++]=arguments[r];e.nextTick(function(){t.apply(null,n)})}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e(55))},{55:55}],55:[function(e,t,n){function r(){f=!1,s.length?c=s.concat(c):l=-1,c.length&&i()}function i(){if(!f){var e=setTimeout(r);f=!0;for(var t=c.length;t;){for(s=c,c=[];++l<t;)s&&s[l].run();l=-1,t=c.length}s=null,f=!1,clearTimeout(e)}}function o(e,t){this.fun=e,this.array=t}function a(){}var s,u=t.exports={},c=[],f=!1,l=-1;u.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new o(e,t)),1!==c.length||f||setTimeout(i,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},u.title="browser",u.browser=!0,u.env={},u.argv=[],u.version="",u.versions={},u.on=a,u.addListener=a,u.once=a,u.off=a,u.removeListener=a,u.removeAllListeners=a,u.emit=a,u.binding=function(e){throw new Error("process.binding is not supported")},u.cwd=function(){return"/"},u.chdir=function(e){throw new Error("process.chdir is not supported")},u.umask=function(){return 0}},{}],56:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{18:18}],57:[function(e,t,n){!function(e){if("object"==typeof n)t.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;try{r=window}catch(i){r=self}r.SparkMD5=e()}}(function(e){"use strict";function t(e,t,n,r,i,o){return t=b(b(t,e),b(r,o)),b(t<<i|t>>>32-i,n)}function n(e,n,r,i,o,a,s){return t(n&r|~n&i,e,n,o,a,s)}function r(e,n,r,i,o,a,s){return t(n&i|r&~i,e,n,o,a,s)}function i(e,n,r,i,o,a,s){return t(n^r^i,e,n,o,a,s)}function o(e,n,r,i,o,a,s){return t(r^(n|~i),e,n,o,a,s)}function a(e,t){var a=e[0],s=e[1],u=e[2],c=e[3];a=n(a,s,u,c,t[0],7,-680876936),c=n(c,a,s,u,t[1],12,-389564586),u=n(u,c,a,s,t[2],17,606105819),s=n(s,u,c,a,t[3],22,-1044525330),a=n(a,s,u,c,t[4],7,-176418897),c=n(c,a,s,u,t[5],12,1200080426),u=n(u,c,a,s,t[6],17,-1473231341),s=n(s,u,c,a,t[7],22,-45705983),a=n(a,s,u,c,t[8],7,1770035416),c=n(c,a,s,u,t[9],12,-1958414417),u=n(u,c,a,s,t[10],17,-42063),s=n(s,u,c,a,t[11],22,-1990404162),a=n(a,s,u,c,t[12],7,1804603682),c=n(c,a,s,u,t[13],12,-40341101),u=n(u,c,a,s,t[14],17,-1502002290),s=n(s,u,c,a,t[15],22,1236535329),a=r(a,s,u,c,t[1],5,-165796510),c=r(c,a,s,u,t[6],9,-1069501632),u=r(u,c,a,s,t[11],14,643717713),s=r(s,u,c,a,t[0],20,-373897302),a=r(a,s,u,c,t[5],5,-701558691),c=r(c,a,s,u,t[10],9,38016083),u=r(u,c,a,s,t[15],14,-660478335),s=r(s,u,c,a,t[4],20,-405537848),a=r(a,s,u,c,t[9],5,568446438),c=r(c,a,s,u,t[14],9,-1019803690),u=r(u,c,a,s,t[3],14,-187363961),s=r(s,u,c,a,t[8],20,1163531501),a=r(a,s,u,c,t[13],5,-1444681467),c=r(c,a,s,u,t[2],9,-51403784),u=r(u,c,a,s,t[7],14,1735328473),s=r(s,u,c,a,t[12],20,-1926607734),a=i(a,s,u,c,t[5],4,-378558),c=i(c,a,s,u,t[8],11,-2022574463),u=i(u,c,a,s,t[11],16,1839030562),s=i(s,u,c,a,t[14],23,-35309556),a=i(a,s,u,c,t[1],4,-1530992060),c=i(c,a,s,u,t[4],11,1272893353),u=i(u,c,a,s,t[7],16,-155497632),s=i(s,u,c,a,t[10],23,-1094730640),a=i(a,s,u,c,t[13],4,681279174),c=i(c,a,s,u,t[0],11,-358537222),u=i(u,c,a,s,t[3],16,-722521979),s=i(s,u,c,a,t[6],23,76029189),a=i(a,s,u,c,t[9],4,-640364487),c=i(c,a,s,u,t[12],11,-421815835),u=i(u,c,a,s,t[15],16,530742520),s=i(s,u,c,a,t[2],23,-995338651),a=o(a,s,u,c,t[0],6,-198630844),c=o(c,a,s,u,t[7],10,1126891415),u=o(u,c,a,s,t[14],15,-1416354905),s=o(s,u,c,a,t[5],21,-57434055),a=o(a,s,u,c,t[12],6,1700485571),c=o(c,a,s,u,t[3],10,-1894986606),u=o(u,c,a,s,t[10],15,-1051523),s=o(s,u,c,a,t[1],21,-2054922799),a=o(a,s,u,c,t[8],6,1873313359),c=o(c,a,s,u,t[15],10,-30611744),u=o(u,c,a,s,t[6],15,-1560198380),s=o(s,u,c,a,t[13],21,1309151649),a=o(a,s,u,c,t[4],6,-145523070),c=o(c,a,s,u,t[11],10,-1120210379),u=o(u,c,a,s,t[2],15,718787259),s=o(s,u,c,a,t[9],21,-343485551),e[0]=b(a,e[0]),e[1]=b(s,e[1]),e[2]=b(u,e[2]),e[3]=b(c,e[3])}function s(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function u(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function c(e){var t,n,r,i,o,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,s(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),u=parseInt(i[1],16)||0,r[14]=o,r[15]=u,a(f,r),f}function f(e){var t,n,r,i,o,s,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return i=8*c,i=i.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),s=parseInt(i[1],16)||0,r[14]=o,r[15]=s,a(f,r),f}function l(e){var t,n="";for(t=0;4>t;t+=1)n+=m[e>>8*t+4&15]+m[e>>8*t&15];return n}function h(e){var t;for(t=0;t<e.length;t+=1)e[t]=l(e[t]);return e.join("")}function d(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function p(e,t){var n,r=e.length,i=new ArrayBuffer(r),o=new Uint8Array(i);for(n=0;r>n;n+=1)o[n]=e.charCodeAt(n);return t?o:i}function g(e){return String.fromCharCode.apply(null,new Uint8Array(e))}function v(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}function y(e){var t,n=[],r=e.length;for(t=0;r-1>t;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function _(){this.reset()}var b=function(e,t){return e+t&4294967295},m=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==h(c("hello"))&&(b=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function t(e,t){return e=0|e||0,0>e?Math.max(e+t,0):Math.min(e,t)}ArrayBuffer.prototype.slice=function(n,r){var i,o,a,s,u=this.byteLength,c=t(n,u),f=u;return r!==e&&(f=t(r,u)),c>f?new ArrayBuffer(0):(i=f-c,o=new ArrayBuffer(i),a=new Uint8Array(o),s=new Uint8Array(this,c,i),a.set(s),o)}}(),_.prototype.append=function(e){return this.appendBinary(d(e)),this},_.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._hash,s(this._buff.substring(t-64,t)));return this._buff=this._buff.substring(t-64),this},_.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},_.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},_.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},_.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},_.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},_.prototype._finish=function(e,t){var n,r,i,o=t;if(e[o>>2]|=128<<(o%4<<3),o>55)for(a(this._hash,e),o=0;16>o;o+=1)e[o]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),i=parseInt(n[1],16)||0,e[14]=r,e[15]=i,a(this._hash,e)},_.hash=function(e,t){return _.hashBinary(d(e),t)},_.hashBinary=function(e,t){var n=c(e),r=h(n);return t?y(r):r},_.ArrayBuffer=function(){this.reset()},_.ArrayBuffer.prototype.append=function(e){var t,n=v(this._buff.buffer,e,!0),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._hash,u(n.subarray(t-64,t)));return this._buff=r>t-64?new Uint8Array(n.buffer.slice(t-64)):new Uint8Array(0),this},_.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;i>t;t+=1)o[t>>2]|=r[t]<<(t%4<<3);return this._finish(o,i),n=h(this._hash),e&&(n=y(n)),this.reset(),n},_.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},_.ArrayBuffer.prototype.getState=function(){var e=_.prototype.getState.call(this);return e.buff=g(e.buff),e},_.ArrayBuffer.prototype.setState=function(e){return e.buff=p(e.buff,!0),_.prototype.setState.call(this,e)},_.ArrayBuffer.prototype.destroy=_.prototype.destroy,_.ArrayBuffer.prototype._finish=_.prototype._finish,_.ArrayBuffer.hash=function(e,t){var n=f(new Uint8Array(e)),r=h(n);return t?y(r):r},_})},{}],58:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e(19).EventEmitter,o=e(23);o(r,i),r.Readable=e(66),r.Writable=e(68),r.Duplex=e(59),r.Transform=e(67),r.PassThrough=e(65),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&c.pause&&c.pause()}function r(){c.readable&&c.resume&&c.resume()}function o(){f||(f=!0,e.end())}function a(){f||(f=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(u(),0===i.listenerCount(this,"error"))throw e}function u(){c.removeListener("data",n),e.removeListener("drain",r),c.removeListener("end",o),c.removeListener("close",a),c.removeListener("error",s),e.removeListener("error",s),c.removeListener("end",u),c.removeListener("close",u),e.removeListener("close",u)}var c=this;c.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(c.on("end",o),c.on("close",a));var f=!1;return c.on("error",s),e.on("error",s),c.on("end",u),c.on("close",u),e.on("close",u),e.emit("pipe",c),e}},{19:19,23:23,59:59,65:65,66:66,67:67,68:68}],59:[function(e,t,n){t.exports=e(60)},{60:60}],60:[function(e,t,n){"use strict";function r(e){return this instanceof r?(c.call(this,e),f.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(o,this)}function o(e){e.end()}var a=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e(54),u=e(6);u.inherits=e(23);var c=e(62),f=e(64);u.inherits(r,c);for(var l=a(f.prototype),h=0;h<l.length;h++){var d=l[h];r.prototype[d]||(r.prototype[d]=f.prototype[d])}},{23:23,54:54,6:6,62:62,64:64}],61:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e(63),o=e(6);o.inherits=e(23),o.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{23:23,6:6,63:63}],62:[function(e,t,n){(function(n){"use strict";function r(t,n){C=C||e(60),t=t||{},this.objectMode=!!t.objectMode,n instanceof C&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(T||(T=e(69).StringDecoder),this.decoder=new T(t.encoding),this.encoding=t.encoding)}function i(t){return C=C||e(60),this instanceof i?(this._readableState=new r(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void A.call(this)):new i(t)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n)t.reading=!1,f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e))),d(e,t)}else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){return e>=I?e=I:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return R.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(L("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?x(h,e):h(e))}function h(e){L("emit readable"),e.emit("readable"),b(e)}function d(e,t){t.readingMore||(t.readingMore=!0,x(p,e,t))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(L("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;L("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&M(e,"data")&&(t.flowing=!0,b(e))}}function v(e){L("readable nexttick read 0"),e.read(0)}function y(e,t){t.resumeScheduled||(t.resumeScheduled=!0,x(_,e,t))}function _(e,t){t.reading||(L("resume read 0"),e.read(0)),t.resumeScheduled=!1,e.emit("resume"),b(e),t.flowing&&!t.reading&&e.read(0)}function b(e){var t=e._readableState;if(L("flow",t.flowing),t.flowing)do var n=e.read();while(null!==n&&t.flowing)}function m(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):1===r.length?r[0]:R.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new R(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function w(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,x(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function k(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function S(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var x=e(54),B=e(25),R=e(5).Buffer;i.ReadableState=r;var A,M=(e(19),function(e,t){return e.listeners(t).length});!function(){try{A=e("stream")}catch(t){}finally{A||(A=e(19).EventEmitter)}}();var R=e(5).Buffer,j=e(6);j.inherits=e(23);var O=e(4),L=void 0;L=O&&O.debuglog?O.debuglog("stream"):function(){};var T;j.inherits(i,A);var C,C;i.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new R(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.isPaused=function(){return this._readableState.flowing===!1},i.prototype.setEncoding=function(t){return T||(T=e(69).StringDecoder),this._readableState.decoder=new T(t),this._readableState.encoding=t,this};var I=8388608;i.prototype.read=function(e){L("read",e);var t=this._readableState,n=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return L("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?w(this):l(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&w(this),null;var r=t.needReadable;L("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,L("length less than watermark",r)),(t.ended||t.reading)&&(r=!1,L("reading or ended",r)),r&&(L("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=u(n,t));var i;return i=e>0?m(e,t):null,null===i&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&w(this),null!==i&&this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){L("onunpipe"),e===l&&o()}function i(){L("onend"),e.end()}function o(){L("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",v),e.removeListener("error",s),e.removeListener("unpipe",r),l.removeListener("end",i),l.removeListener("end",o),l.removeListener("data",a),y=!0,!h.awaitDrain||e._writableState&&!e._writableState.needDrain||v()}function a(t){L("ondata");var n=e.write(t);!1===n&&(1!==h.pipesCount||h.pipes[0]!==e||1!==l.listenerCount("data")||y||(L("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++),l.pause())}function s(t){L("onerror",t),f(),e.removeListener("error",s),0===M(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),f()}function c(){L("onfinish"),e.removeListener("close",u),f()}function f(){L("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,L("pipe count=%d opts=%j",h.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;h.endEmitted?x(p):l.once("end",p),e.on("unpipe",r);var v=g(l);e.on("drain",v);var y=!1;return l.on("data",a),e._events&&e._events.error?B(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",u),e.once("finish",c),e.emit("pipe",l),h.flowing||(L("pipe resume"),l.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var o=S(t.pipes,e);return-1===o?this:(t.pipes.splice(o,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=A.prototype.on.call(this,e,t);if("data"===e&&!1!==this._readableState.flowing&&this.resume(),"readable"===e&&!this._readableState.endEmitted){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):x(v,this))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){var e=this._readableState;return e.flowing||(L("resume"),e.flowing=!0,y(this,e)),this},i.prototype.pause=function(){return L("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(L("pause"),this._readableState.flowing=!1,this.emit("pause")),this},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(L("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(L("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return k(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){L("wrapped _read",t),n&&(n=!1,e.resume())},r},i._fromList=m}).call(this,e(55))},{19:19,23:23,25:25,4:4,5:5,54:54,55:55,6:6,60:60,69:69}],63:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(60),u=e(6);u.inherits=e(23),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{23:23,6:6,60:60}],64:[function(e,t,n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){M=M||e(60),t=t||{},this.objectMode=!!t.objectMode,n instanceof M&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return M=M||e(60),this instanceof a||this instanceof M?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=_(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function _(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=_(t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(54),S=k,x=e(5).Buffer;a.WritableState=o;var B=e(6);B.inherits=e(23);var R,A={deprecate:e(91)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(19).EventEmitter)}}();var x=e(5).Buffer;B.inherits(a,R);var M;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var M;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}},{19:19,23:23,5:5,54:54,6:6,60:60,91:91}],65:[function(e,t,n){t.exports=e(61)},{61:61}],66:[function(e,t,n){var r=function(){try{return e("stream")}catch(t){}}();n=t.exports=e(62),n.Stream=r||n,n.Readable=n,n.Writable=e(64),n.Duplex=e(60),n.Transform=e(63),n.PassThrough=e(61)},{58:58,60:60,61:61,62:62,63:63,64:64}],67:[function(e,t,n){t.exports=e(63)},{63:63}],68:[function(e,t,n){t.exports=e(64)},{64:64}],69:[function(e,t,n){function r(e){if(e&&!u(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function o(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function a(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e(5).Buffer,u=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},c=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=o;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=a;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};c.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&56319>=r)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&56319>=r){var o=this.surrogateSize;return this.charLength+=o,this.charReceived+=o,this.charBuffer.copy(this.charBuffer,o,0,o),e.copy(this.charBuffer,0,0,o),t.substring(0,i)}return t},c.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(2>=t&&n>>4==14){this.charLength=3;
+break}if(3>=t&&n>>3==30){this.charLength=4;break}}this.charReceived=t},c.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{5:5}],70:[function(e,t,n){t.exports={encode:function(e){return"ÿ"+e[0]+"ÿ"+e[1]},decode:function(e){var t=e.toString(),n=t.indexOf("ÿ",1);return[t.substring(1,n),t.substring(n+1)]},lowerBound:"\x00",upperBound:"ÿ"}},{}],71:[function(e,t,n){var r=e(17).create,i=r("LevelUPError"),o=r("NotFoundError",i);o.prototype.notFound=!0,o.prototype.status=404,t.exports={LevelUPError:i,InitializationError:r("InitializationError",i),OpenError:r("OpenError",i),ReadError:r("ReadError",i),WriteError:r("WriteError",i),NotFoundError:o,EncodingError:r("EncodingError",i)}},{17:17}],72:[function(e,t,n){var r=e(73),i=e(75),o=e(27),a=new o,s=e(74),u=e(70);t.exports=function(e){return i(r(e,u,a),[],s,e.options)}},{27:27,70:70,73:73,74:74,75:75}],73:[function(e,t,n){function r(e){return"function"==typeof e}function i(e){return null==e?e:r(e.prefix)?e.prefix():e}function o(e){var t={};for(var n in e)t[n]=e[n];return t}var a=e(77);t.exports=function(e,t,n,s){function u(e,r,i,o){return t.encode([e,n.encodeKey(r,i,o)])}function c(e,t){return t&&t.options&&(e.keyEncoding=e.keyEncoding||t.options.keyEncoding,e.valueEncoding=e.valueEncoding||t.options.valueEncoding),e}function f(){for(h=!0;l.length;)l.shift()()}var l=[],h=!1;return r(e.isOpen)&&e.isOpen()?h=!0:e.open(f),{apply:function(t,r,o){for(var a=0;a<t.length;a++){var s=t[a];c(s,s.prefix),s.prefix=i(s.prefix)}if(r=r||{},"object"!=typeof r)throw new Error("opts must be object, was:"+r);"function"==typeof r&&(o=r,r={}),t.length?(e.db||e).batch(t.map(function(e){return{key:u(e.prefix,e.key,r,e),value:"del"!==e.type?n.encodeValue(e.value,r,e):void 0,type:e.type||(void 0===e.value?"del":"put")}}),r,function(e){return e?o(e):void o()}):o()},get:function(t,r,i,o){return i.asBuffer=n.valueAsBuffer(i),(e.db||e).get(u(r,t,i),i,function(e,t){e?o(e):o(null,n.decodeValue(t,i))})},createDecoder:function(e){return function(r,i){return{key:n.decodeKey(t.decode(r)[1],e),value:n.decodeValue(i,e)}}},isOpen:function(){return e.db&&r(e.db.isOpen)?e.db.isOpen():e.isOpen()},isClosed:function(){return e.db&&r(e.db.isClosed)?e.db.isClosed():e.isClosed()},close:function(t){return e.close(t)},iterator:function(r,i){function s(e){return u(d,e,f,{})}function c(e){return{next:function(t){return e.next(t)},end:function(t){e.end(t)}}}var f=o(r||{}),d=r.prefix||[];return a.toLtgt(r,f,s,t.lowerBound,t.upperBound),f.prefix=null,f.keyAsBuffer=f.valueAsBuffer=!1,"number"!=typeof f.limit&&(f.limit=-1),f.keyAsBuffer=t.buffer,f.valueAsBuffer=n.valueAsBuffer(f),h?c((e.db||e).iterator(f)):void l.push(function(){i(null,c((e.db||e).iterator(f)))})}}}},{77:77}],74:[function(e,t,n){function r(e,t){return this instanceof r?(i.call(this,{objectMode:!0,highWaterMark:e.highWaterMark}),this._waiting=!1,this._options=e,void(this._makeData=t)):new r(e,t)}var i=e(83).Readable,o=e(23),a=e(71).EncodingError;o(r,i),r.prototype.setIterator=function(e){return this._iterator=e,this._destroyed?e.end(function(){}):this._waiting?(this._waiting=!1,this._read()):this},r.prototype._read=function(){var e=this;if(!e._destroyed)return e._iterator?void e._iterator.next(function(t,n,r){if(t||void 0===n&&void 0===r)return t||e._destroyed||e.push(null),e._cleanup(t);try{r=e._makeData(n,r)}catch(i){return e._cleanup(new a(i))}e._destroyed||e.push(r)}):this._waiting=!0},r.prototype._cleanup=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;e&&t.emit("error",e),t._iterator?t._iterator.end(function(){t._iterator=null,t.emit("close")}):t.emit("close")}},r.prototype.destroy=function(){this._cleanup()},r.prototype.toString=function(){return"LevelUP.ReadStream"},t.exports=r},{23:23,71:71,83:83}],75:[function(e,t,n){(function(n){var r=e(19).EventEmitter,i=e(71),o="6.5.4",a=t.exports=function(e,t,s,u){function c(e){e&&l.emit("error",e)}function f(e){var t={};if(u)for(var n in u)void 0!=u[n]&&(t[n]=u[n]);if(e)for(var n in e)void 0!=e[n]&&(t[n]=e[n]);return t}var l=new r;return l.sublevels={},l.options=u,l.version=o,l.methods={},t=t||[],l.put=function(n,r,i,o){"function"==typeof i&&(o=i,i={}),o||(o=c),e.apply([{key:n,value:r,prefix:t.slice(),type:"put"}],f(i),function(e){return e||(l.emit("put",n,r),o(null)),e?o(e):void 0})},l.prefix=function(){return t.slice()},l.del=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),e.apply([{key:n,prefix:t.slice(),type:"del"}],f(r),function(e){return e||(l.emit("del",n),i(null)),e?i(e):void 0})},l.batch=function(n,r,i){"function"==typeof r&&(i=r,r={}),i||(i=c),n=n.map(function(e){return{key:e.key,value:e.value,prefix:e.prefix||t,keyEncoding:e.keyEncoding,valueEncoding:e.valueEncoding,type:e.type}}),e.apply(n,f(r),function(e){return e||(l.emit("batch",n),i(null)),e?i(e):void 0})},l.get=function(n,r,o){"function"==typeof r&&(o=r,r={}),e.get(n,t,f(r),function(e,t){e?o(new i.NotFoundError("Key not found in database",e)):o(null,t)})},l.clone=function(n){return a(e,t,s,f(n))},l.sublevel=function(n,r){return l.sublevels[n]=l.sublevels[n]||a(e,t.concat(n),s,f(r))},l.readStream=l.createReadStream=function(n){n=f(n),n.prefix=t;var r,i=e.iterator(n,function(e,t){r.setIterator(t)});return r=s(n,e.createDecoder(n)),i&&r.setIterator(i),r},l.valueStream=l.createValueStream=function(e){return e=e||{},e.values=!0,e.keys=!1,l.createReadStream(e)},l.keyStream=l.createKeyStream=function(e){return e=e||{},e.values=!1,e.keys=!0,l.createReadStream(e)},l.close=function(r){r=r||function(){},t.length?n.nextTick(r):e.close(r)},l.isOpen=e.isOpen,l.isClosed=e.isClosed,l}}).call(this,e(55))},{19:19,55:55,71:71}],76:[function(e,t,n){arguments[4][31][0].apply(n,arguments)},{31:31}],77:[function(e,t,n){(function(e){function t(e,t){return Object.hasOwnProperty.call(e,t)}function r(e){return void 0!==e&&""!==e}function t(e,t){return Object.hasOwnProperty.call(e,t)}function i(e,t){return Object.hasOwnProperty.call(e,t)&&t}function o(e){return e}n.compare=function(t,n){if(e.isBuffer(t)){for(var r=Math.min(t.length,n.length),i=0;r>i;i++){var o=t[i]-n[i];if(o)return o}return t.length-n.length}return n>t?-1:t>n?1:0};var a=n.lowerBoundKey=function(e){return i(e,"gt")||i(e,"gte")||i(e,"min")||(e.reverse?i(e,"end"):i(e,"start"))||void 0},s=n.lowerBound=function(e){var t=a(e);return t&&e[t]};n.lowerBoundInclusive=function(e){return!t(e,"gt")},n.upperBoundInclusive=function(e){return!t(e,"lt")&&e.minEx};var u=n.lowerBoundExclusive=function(e){return!(!t(e,"gt")&&!e.minEx)},c=n.upperBoundExclusive=function(e){return!!t(e,"lt")},f=n.upperBoundKey=function(e){return i(e,"lt")||i(e,"lte")||i(e,"max")||(e.reverse?i(e,"start"):i(e,"end"))||void 0},l=n.upperBound=function(e){var t=f(e);return t&&e[t]};n.toLtgt=function(e,r,i,a,s){r=r||{},i=i||o;var u=arguments.length>3,c=n.lowerBoundKey(e),f=n.upperBoundKey(e);return c?"gt"===c?r.gt=i(e.gt,!1):r.gte=i(e[c],!1):u&&(r.gte=i(a,!1)),f?"lt"===f?r.lt=i(e.lt,!0):r.lte=i(e[f],!0):u&&(r.lte=i(s,!0)),null!=e.reverse&&(r.reverse=!!e.reverse),t(r,"max")&&delete r.max,t(r,"min")&&delete r.min,t(r,"start")&&delete r.start,t(r,"end")&&delete r.end,r},n.contains=function(e,t,i){i=i||n.compare;var o=s(e);if(r(o)){var a=i(t,o);if(0>a||0===a&&u(e))return!1}var f=l(e);if(r(f)){var a=i(t,f);if(a>0||0===a&&c(e))return!1}return!0},n.filter=function(e,t){return function(r){return n.contains(e,r,t)}}}).call(this,{isBuffer:e(24)})},{24:24}],78:[function(e,t,n){arguments[4][32][0].apply(n,arguments)},{23:23,32:32,55:55,6:6,80:80,82:82}],79:[function(e,t,n){arguments[4][33][0].apply(n,arguments)},{23:23,33:33,6:6,81:81}],80:[function(e,t,n){(function(n){function r(t,n){t=t||{};var r=t.highWaterMark;this.highWaterMark=r||0===r?r:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!t.objectMode,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(A||(A=e(69).StringDecoder),this.decoder=new A(t.encoding),this.encoding=t.encoding)}function i(e){return this instanceof i?(this._readableState=new r(e,this),this.readable=!0,void B.call(this)):new i(e)}function o(e,t,n,r,i){var o=c(t,n);if(o)e.emit("error",o);else if(null===n||void 0===n)t.reading=!1,t.ended||f(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&i){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||i||r||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&l(e),d(e,t);else i||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function s(e){if(e>=M)e=M;else{e--;for(var t=1;32>t;t<<=1)e|=e>>t;e++}return e}function u(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:null===e||isNaN(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:0>=e?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return S.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?l(e):m(e)}function l(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?n.nextTick(function(){h(e)}):h(e))}function h(e){e.emit("readable")}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&v(e)}}function v(e){function t(e,t,i){var o=e.write(n);!1===o&&r.awaitDrain++}var n,r=e._readableState;for(r.awaitDrain=0;r.pipesCount&&null!==(n=e.read());)if(1===r.pipesCount?t(r.pipes,0,null):w(r.pipes,t),e.emit("data",n),r.awaitDrain>0)return;return 0===r.pipesCount?(r.flowing=!1,void(x.listenerCount(e,"data")>0&&_(e))):void(r.ranOut=!0)}function y(){this._readableState.ranOut&&(this._readableState.ranOut=!1,v(this))}function _(e,t){var r=e._readableState;if(r.flowing)throw new Error("Cannot switch to old mode now.");var i=t||!1,o=!1;e.readable=!0,e.pipe=B.prototype.pipe,e.on=e.addListener=B.prototype.on,e.on("readable",function(){o=!0;for(var t;!i&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)}),e.pause=function(){i=!0,this.emit("pause")},e.resume=function(){i=!1,o?n.nextTick(function(){e.emit("readable")}):this.read(0),this.emit("resume")},e.emit("readable")}function b(e,t){var n,r=t.buffer,i=t.length,o=!!t.decoder,a=!!t.objectMode;if(0===r.length)return null;if(0===i)n=null;else if(a)n=r.shift();else if(!e||e>=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e<r[0].length){var s=r[0];n=s.slice(0,e),r[0]=s.slice(e)}else if(e===r[0].length)n=r.shift();else{n=o?"":new S(e);for(var u=0,c=0,f=r.length;f>c&&e>u;c++){var s=r[0],l=Math.min(e-u,s.length);o?n+=s.slice(0,l):s.copy(n,u,0,l),l<s.length?r[0]=s.slice(l):r.shift(),u+=l}}return n}function m(e){var t=e._readableState;if(t.length>0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function w(e,t){for(var n=0,r=e.length;r>n;n++)t(e[n],n)}function E(e,t){for(var n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}t.exports=i;var k=e(76),S=e(5).Buffer;i.ReadableState=r;var x=e(19).EventEmitter;x.listenerCount||(x.listenerCount=function(e,t){return e.listeners(t).length});var B=e(58),R=e(6);R.inherits=e(23);var A;R.inherits(i,B),i.prototype.push=function(e,t){var n=this._readableState;return"string"!=typeof e||n.objectMode||(t=t||n.defaultEncoding,t!==n.encoding&&(e=new S(e,t),t="")),o(this,n,e,t,!1)},i.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},i.prototype.setEncoding=function(t){A||(A=e(69).StringDecoder),this._readableState.decoder=new A(t),this._readableState.encoding=t};var M=8388608;i.prototype.read=function(e){var t=this._readableState;t.calledRead=!0;var n,r=e;if(("number"!=typeof e||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return l(this),null;if(e=u(e,t),0===e&&t.ended)return n=null,t.length>0&&t.decoder&&(n=b(e,t),t.length-=n.length),0===t.length&&m(this),n;var i=t.needReadable;return t.length-e<=t.highWaterMark&&(i=!0),(t.ended||t.reading)&&(i=!1),i&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),i&&!t.reading&&(e=u(r,t)),n=e>0?b(e,t):null,null===n&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&m(this),n},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){e===f&&o()}function i(){e.end()}function o(){e.removeListener("close",s),e.removeListener("finish",u),e.removeListener("drain",p),e.removeListener("error",a),e.removeListener("unpipe",r),f.removeListener("end",i),f.removeListener("end",o),e._writableState&&!e._writableState.needDrain||p()}function a(t){c(),e.removeListener("error",a),0===x.listenerCount(e,"error")&&e.emit("error",t)}function s(){e.removeListener("finish",u),c()}function u(){e.removeListener("close",s),c()}function c(){f.unpipe(e)}var f=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=e;break;case 1:l.pipes=[l.pipes,e];break;default:l.pipes.push(e)}l.pipesCount+=1;var h=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,d=h?i:o;l.endEmitted?n.nextTick(d):f.once("end",d),e.on("unpipe",r);var p=g(f);return e.on("drain",p),e._events&&e._events.error?k(e._events.error)?e._events.error.unshift(a):e._events.error=[a,e._events.error]:e.on("error",a),e.once("close",s),e.once("finish",u),e.emit("pipe",f),l.flowing||(this.on("readable",y),l.flowing=!0,n.nextTick(function(){v(f)})),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",y),t.flowing=!1;for(var i=0;r>i;i++)n[i].emit("unpipe",this);return this}var i=E(t.pipes,e);return-1===i?this:(t.pipes.splice(i,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},i.prototype.on=function(e,t){var n=B.prototype.on.call(this,e,t);if("data"!==e||this._readableState.flowing||_(this),"readable"===e&&this.readable){var r=this._readableState;r.readableListening||(r.readableListening=!0,r.emittedReadable=!1,r.needReadable=!0,r.reading?r.length&&l(this,r):this.read(0))}return n},i.prototype.addListener=i.prototype.on,i.prototype.resume=function(){_(this),this.read(0),this.emit("resume")},i.prototype.pause=function(){_(this,!0),this.emit("pause")},i.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var o=r.push(i);o||(n=!0,e.pause())}});for(var i in e)"function"==typeof e[i]&&"undefined"==typeof this[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var o=["error","close","destroy","pause","resume"];return w(o,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){n&&(n=!1,e.resume())},r},i._fromList=b}).call(this,e(55))},{19:19,23:23,5:5,55:55,58:58,6:6,69:69,76:76}],81:[function(e,t,n){function r(e,t){this.afterTransform=function(e,n){return i(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i&&i(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.length<o.highWaterMark)&&e._read(o.highWaterMark)}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e);var t=(this._transformState=new r(e,this),this);this._readableState.needReadable=!0,this._readableState.sync=!1,this.once("finish",function(){"function"==typeof this._flush?this._flush(function(e){a(t,e)}):a(t)})}function a(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=(e._readableState,e._transformState);if(n.length)throw new Error("calling transform done when ws.length != 0");if(r.transforming)throw new Error("calling transform done when still transforming");return e.push(null)}t.exports=o;var s=e(78),u=e(6);u.inherits=e(23),u.inherits(o,s),o.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},o.prototype._transform=function(e,t,n){throw new Error("not implemented")},o.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},o.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{23:23,6:6,78:78}],82:[function(e,t,n){(function(n){function r(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function i(e,t){e=e||{};var n=e.highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var r=e.decodeStrings===!1;this.decodeStrings=!r,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(t,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.errorEmitted=!1}function o(t){var n=e(78);return this instanceof o||this instanceof n?(this._writableState=new i(t,this),this.writable=!0,void E.call(this)):new o(t)}function a(e,t,r){var i=new Error("write after end");e.emit("error",i),n.nextTick(function(){r(i)})}function s(e,t,r,i){var o=!0;if(!m.isBuffer(r)&&"string"!=typeof r&&null!==r&&void 0!==r&&!t.objectMode){var a=new TypeError("Invalid non-string/buffer chunk");e.emit("error",a),n.nextTick(function(){i(a)}),o=!1}return o}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new m(t,n)),t}function c(e,t,n,i,o){n=u(t,n,i),m.isBuffer(n)&&(i="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;return s||(t.needDrain=!0),t.writing?t.buffer.push(new r(n,i,o)):f(e,t,a,n,i,o),s}function f(e,t,n,r,i,o){t.writelen=n,t.writecb=o,t.writing=!0,t.sync=!0,e._write(r,i,t.onwrite),t.sync=!1}function l(e,t,r,i,o){r?n.nextTick(function(){o(i)}):o(i),e._writableState.errorEmitted=!0,e.emit("error",i)}function h(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var r=e._writableState,i=r.sync,o=r.writecb;if(h(r),t)l(e,r,i,t,o);else{var a=y(e,r);a||r.bufferProcessing||!r.buffer.length||v(e,r),i?n.nextTick(function(){p(e,r,a,o)}):p(e,r,a,o)}}function p(e,t,n,r){n||g(e,t),r(),n&&_(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function v(e,t){t.bufferProcessing=!0;for(var n=0;n<t.buffer.length;n++){var r=t.buffer[n],i=r.chunk,o=r.encoding,a=r.callback,s=t.objectMode?1:i.length;if(f(e,t,s,i,o,a),t.writing){n++;break}}t.bufferProcessing=!1,n<t.buffer.length?t.buffer=t.buffer.slice(n):t.buffer.length=0}function y(e,t){return t.ending&&0===t.length&&!t.finished&&!t.writing}function _(e,t){var n=y(e,t);return n&&(t.finished=!0,e.emit("finish")),n}function b(e,t,r){t.ending=!0,_(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r)),t.ended=!0}t.exports=o;var m=e(5).Buffer;o.WritableState=i;var w=e(6);w.inherits=e(23);var E=e(58);w.inherits(o,E),o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},o.prototype.write=function(e,t,n){var r=this._writableState,i=!1;return"function"==typeof t&&(n=t,t=null),m.isBuffer(e)?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=function(){}),r.ended?a(this,r,n):s(this,r,e,n)&&(i=c(this,r,e,t,n)),i},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),"undefined"!=typeof e&&null!==e&&this.write(e,t),r.ending||r.finished||b(this,r,n)}}).call(this,e(55))},{23:23,5:5,55:55,58:58,6:6,78:78}],83:[function(e,t,n){var r=e(58);n=t.exports=e(80),n.Stream=r,n.Readable=n,n.Writable=e(82),n.Duplex=e(78),n.Transform=e(81),n.PassThrough=e(79)},{58:58,78:78,79:79,80:80,81:81,82:82}],84:[function(e,t,n){arguments[4][60][0].apply(n,arguments)},{23:23,54:54,6:6,60:60,85:85,87:87}],85:[function(e,t,n){arguments[4][62][0].apply(n,arguments)},{19:19,23:23,25:25,4:4,5:5,54:54,55:55,6:6,62:62,69:69,84:84}],86:[function(e,t,n){arguments[4][63][0].apply(n,arguments)},{23:23,6:6,63:63,84:84}],87:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function o(t,n){M=M||e(84),t=t||{},this.objectMode=!!t.objectMode,n instanceof M&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){p(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new E(this),this.corkedRequestsFree.next=new E(this)}function a(t){return M=M||e(84),this instanceof a||this instanceof M?(this._writableState=new o(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void R.call(this)):new a(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),k(t,n)}function u(e,t,n,r){var i=!0;if(!x.isBuffer(n)&&"string"!=typeof n&&null!==n&&void 0!==n&&!t.objectMode){var o=new TypeError("Invalid non-string/buffer chunk");e.emit("error",o),k(r,o),i=!1}return i}function c(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=new x(t,n)),t}function f(e,t,n,r,o){n=c(t,n,r),x.isBuffer(n)&&(r="buffer");var a=t.objectMode?1:n.length;t.length+=a;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var u=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,o),u?u.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else l(e,t,!1,a,n,r,o);return s}function l(e,t,n,r,i,o,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?k(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function d(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function p(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(d(n),t)h(e,n,r,t,i);else{var o=_(n);o||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(g,e,n,o,i):g(e,n,o,i)}}function g(e,t,n,r){n||v(e,t),t.pendingcb--,r(),m(e,t)}function v(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),o=t.corkedRequestsFree;o.entry=n;for(var a=0;n;)i[a]=n,n=n.next,a+=1;l(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,t.corkedRequestsFree=o.next,o.next=null}else{for(;n;){var s=n.chunk,u=n.encoding,c=n.callback,f=t.objectMode?1:s.length;if(l(e,t,!1,f,s,u,c),n=n.next,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function _(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function m(e,t){var n=_(t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function w(e,t,n){t.ending=!0,m(e,t),n&&(t.finished?k(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function E(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=a;var k=e(54),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:k,x=e(5).Buffer;a.WritableState=o;var B=e(6);B.inherits=e(23);var R,A={deprecate:e(91)};!function(){try{R=e("stream")}catch(t){}finally{R||(R=e(19).EventEmitter)}}();var x=e(5).Buffer;B.inherits(a,R);var M;o.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(o.prototype,"buffer",{get:A.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var M;a.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe. Not readable."))},a.prototype.write=function(e,t,n){var i=this._writableState,o=!1;return"function"==typeof t&&(n=t,t=null),x.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):u(this,i,e,n)&&(i.pendingcb++,o=f(this,i,e,t,n)),o},a.prototype.cork=function(){var e=this._writableState;e.corked++},a.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},a.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e},a.prototype._write=function(e,t,n){n(new Error("not implemented"))},a.prototype._writev=null,a.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||w(this,r,n)}}).call(this,e(55))},{19:19,23:23,5:5,54:54,55:55,6:6,84:84,91:91}],88:[function(e,t,n){arguments[4][67][0].apply(n,arguments)},{67:67,86:86}],89:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{14:14}],90:[function(e,t,n){(function(n){function r(e){a.call(this,e),this._destroyed=!1}function i(e,t,n){n(null,e)}function o(e){return function(t,n,r){return"function"==typeof t&&(r=n,n=t,t={}),"function"!=typeof n&&(n=i),"function"!=typeof r&&(r=null),e(t,n,r)}}var a=e(88),s=e(93).inherits,u=e(89);s(r,a),r.prototype.destroy=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;n.nextTick(function(){e&&t.emit("error",e),t.emit("close")})}},t.exports=o(function(e,t,n){var i=new r(e);return i._transform=t,n&&(i._flush=n),i}),t.exports.ctor=o(function(e,t,n){function i(t){return this instanceof i?(this.options=u(e,t),void r.call(this,this.options)):new i(t)}return s(i,r),i.prototype._transform=t,n&&(i.prototype._flush=n),i}),t.exports.obj=o(function(e,t,n){var i=new r(u({objectMode:!0,highWaterMark:16},e));return i._transform=t,n&&(i._flush=n),i})}).call(this,e(55))},{55:55,88:88,89:89,93:93}],91:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null==r?!1:"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],92:[function(e,t,n){t.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},{}],93:[function(e,t,n){(function(t,r){function i(e,t){var r={seen:[],stylize:a};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),g(t)?r.showHidden=t:t&&n._extend(r,t),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,e,r.depth)}function o(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function u(e,t,r){if(e.customInspect&&t&&B(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return b(i)||(i=u(e,i,r)),i}var o=c(e,t);if(o)return o;var a=Object.keys(t),g=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(t)),x(t)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(t);if(0===a.length){if(B(t)){var v=t.name?": "+t.name:"";return e.stylize("[Function"+v+"]","special")}if(E(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(S(t))return e.stylize(Date.prototype.toString.call(t),"date");if(x(t))return f(t)}var y="",_=!1,m=["{","}"];if(p(t)&&(_=!0,m=["[","]"]),B(t)){var w=t.name?": "+t.name:"";y=" [Function"+w+"]"}if(E(t)&&(y=" "+RegExp.prototype.toString.call(t)),S(t)&&(y=" "+Date.prototype.toUTCString.call(t)),x(t)&&(y=" "+f(t)),0===a.length&&(!_||0==t.length))return m[0]+y+m[1];if(0>r)return E(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var k;return k=_?l(e,t,r,g,a):a.map(function(n){return h(e,t,r,g,n,_)}),e.seen.pop(),d(k,y,m)}function c(e,t){if(w(t))return e.stylize("undefined","undefined");if(b(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return _(t)?e.stylize(""+t,"number"):g(t)?e.stylize(""+t,"boolean"):v(t)?e.stylize("null","null"):void 0}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function l(e,t,n,r,i){for(var o=[],a=0,s=t.length;s>a;++a)O(t,String(a))?o.push(h(e,t,n,r,String(a),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(h(e,t,n,r,i,!0))}),o}function h(e,t,n,r,i,o){var a,s,c;if(c=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},c.get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),O(r,i)||(a="["+i+"]"),s||(e.seen.indexOf(c.value)<0?(s=v(n)?u(e,c.value,null):u(e,c.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return"  "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return"   "+e}).join("\n"))):s=e.stylize("[Circular]","special")),w(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),
+a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function d(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n  ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function p(e){return Array.isArray(e)}function g(e){return"boolean"==typeof e}function v(e){return null===e}function y(e){return null==e}function _(e){return"number"==typeof e}function b(e){return"string"==typeof e}function m(e){return"symbol"==typeof e}function w(e){return void 0===e}function E(e){return k(e)&&"[object RegExp]"===A(e)}function k(e){return"object"==typeof e&&null!==e}function S(e){return k(e)&&"[object Date]"===A(e)}function x(e){return k(e)&&("[object Error]"===A(e)||e instanceof Error)}function B(e){return"function"==typeof e}function R(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function A(e){return Object.prototype.toString.call(e)}function M(e){return 10>e?"0"+e.toString(10):e.toString(10)}function j(){var e=new Date,t=[M(e.getHours()),M(e.getMinutes()),M(e.getSeconds())].join(":");return[e.getDate(),I[e.getMonth()],t].join(" ")}function O(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var L=/%[sdj%]/g;n.format=function(e){if(!b(e)){for(var t=[],n=0;n<arguments.length;n++)t.push(i(arguments[n]));return t.join(" ")}for(var n=1,r=arguments,o=r.length,a=String(e).replace(L,function(e){if("%%"===e)return"%";if(n>=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])a+=v(s)||!k(s)?" "+s:" "+i(s);return a},n.deprecate=function(e,i){function o(){if(!a){if(t.throwDeprecation)throw new Error(i);t.traceDeprecation?console.trace(i):console.error(i),a=!0}return e.apply(this,arguments)}if(w(r.process))return function(){return n.deprecate(e,i).apply(this,arguments)};if(t.noDeprecation===!0)return e;var a=!1;return o};var T,C={};n.debuglog=function(e){if(w(T)&&(T=t.env.NODE_DEBUG||""),e=e.toUpperCase(),!C[e])if(new RegExp("\\b"+e+"\\b","i").test(T)){var r=t.pid;C[e]=function(){var t=n.format.apply(n,arguments);console.error("%s %d: %s",e,r,t)}}else C[e]=function(){};return C[e]},n.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=p,n.isBoolean=g,n.isNull=v,n.isNullOrUndefined=y,n.isNumber=_,n.isString=b,n.isSymbol=m,n.isUndefined=w,n.isRegExp=E,n.isObject=k,n.isDate=S,n.isError=x,n.isFunction=B,n.isPrimitive=R,n.isBuffer=e(92);var I=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",j(),n.format.apply(n,arguments))},n.inherits=e(23),n._extend=function(e,t){if(!t||!k(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(this,e(55),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{23:23,55:55,92:92}],94:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var i=r.element,o=r.index;if(Array.isArray(i))i.push(e);else if(o===t.length-2){var a=t.pop();i[a]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,i,o,a,s,u,c,f,l,h,d="";n=t.pop();)if(r=n.obj,i=n.prefix||"",o=n.val||"",d+=i,o)d+=o;else if("object"!=typeof r)d+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)d+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),a=r.length-1;a>=0;a--)s=0===a?"":",",t.push({obj:r[a],prefix:s});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),a=u.length-1;a>=0;a--)f=u[a],l=r[f],h=a>0?",":"",h+=JSON.stringify(f)+":",t.push({obj:l,prefix:h});t.push({val:"{"})}return d},n.parse=function(e){for(var t,n,i,o,a,s,u,c,f,l=[],h=[],d=0;;)if(t=e[d++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":d+=3,r(null,l,h);break;case"t":d+=3,r(!0,l,h);break;case"f":d+=4,r(!1,l,h);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",d--;;){if(i=e[d++],!/[\d\.\-e\+]/.test(i)){d--;break}n+=i}r(parseFloat(n),l,h);break;case'"':for(o="",a=void 0,s=0;;){if(u=e[d++],'"'===u&&("\\"!==a||s%2!==1))break;o+=u,a=u,"\\"===a?s++:s=0}r(JSON.parse('"'+o+'"'),l,h);break;case"[":c={element:[],index:l.length},l.push(c.element),h.push(c);break;case"{":f={element:{},index:l.length},l.push(f.element),h.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,h)}}},{}]},{},[1]);
diff --git a/dist/pouchdb.min.js b/dist/pouchdb.min.js
new file mode 100644
index 0000000..7852501
--- /dev/null
+++ b/dist/pouchdb.min.js
@@ -0,0 +1,11 @@
+// PouchDB 5.3.2
+// 
+// (c) 2012-2016 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.PouchDB=e()}}(function(){var e;return function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[a]={exports:{}};e[a][0].call(f.exports,function(t){var n=e[a][1][t];return o(n?n:t)},f,f.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],2:[function(e,t,n){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function o(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var o=0,i=0;return e[0].replace(/%[a-z%]/g,function(e){"%%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r),e}function i(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(t){}}function s(){var e;try{e=n.storage.debug}catch(t){}return e}function u(){try{return window.localStorage}catch(e){}}n=t.exports=e(3),n.log=i,n.formatArgs=o,n.save=a,n.load=s,n.useColors=r,n.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){return JSON.stringify(e)},n.enable(s())},{3:3}],3:[function(e,t,n){function r(){return n.colors[f++%n.colors.length]}function o(e){function t(){}function o(){var e=o,t=+new Date,i=t-(c||t);e.diff=i,e.prev=c,e.curr=t,c=t,null==e.useColors&&(e.useColors=n.useColors()),null==e.color&&e.useColors&&(e.color=r());var a=Array.prototype.slice.call(arguments);a[0]=n.coerce(a[0]),"string"!=typeof a[0]&&(a=["%o"].concat(a));var s=0;a[0]=a[0].replace(/%([a-z%])/g,function(t,r){if("%%"===t)return t;s++;var o=n.formatters[r];if("function"==typeof o){var i=a[s];t=o.call(e,i),a.splice(s,1),s--}return t}),"function"==typeof n.formatArgs&&(a=n.formatArgs.apply(e,a));var u=o.log||n.log||console.log.bind(console);u.apply(e,a)}t.enabled=!1,o.enabled=!0;var i=n.enabled(e)?o:t;return i.namespace=e,i}function i(e){n.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;r>o;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function a(){n.enable("")}function s(e){var t,r;for(t=0,r=n.skips.length;r>t;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;r>t;t++)if(n.names[t].test(e))return!0;return!1}function u(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o,n.coerce=u,n.disable=a,n.enable=i,n.enabled=s,n.humanize=e(9),n.names=[],n.skips=[],n.formatters={};var c,f=0},{9:9}],4:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function o(e){return"function"==typeof e}function i(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!i(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,i,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],s(n))return!1;if(o(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:i=Array.prototype.slice.call(arguments,1),n.apply(this,i)}else if(a(n))for(i=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,u=0;r>u;u++)c[u].apply(this,i);return!0},r.prototype.addListener=function(e,t){var n;if(!o(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,o(t.listener)?t.listener:t),this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,a(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!o(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,i,s;if(!o(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],i=n.length,r=-1,n===t||o(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(s=i;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],o(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?o(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(o(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],5:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||o()}var o,i=e.MutationObserver||e.WebKitMutationObserver;if(i){var a=0,s=new i(n),u=e.document.createTextNode("");s.observe(u,{characterData:!0}),o=function(){u.data=a=++a%2}}else if(e.setImmediate||"undefined"==typeof e.MessageChannel)o="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var c=new e.MessageChannel;c.port1.onmessage=n,o=function(){c.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],6:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],7:[function(e,t,n){(function(e){e("object"==typeof n?n:this)}).call(this,function(e){var t=Array.prototype.slice,n=Array.prototype.forEach,r=function(e){if("object"!=typeof e)throw e+" is not an object";var o=t.call(arguments,1);return n.call(o,function(t){if(t)for(var n in t)"object"==typeof t[n]&&e[n]?r.call(e,e[n],t[n]):e[n]=t[n]}),e};e.extend=r})},{}],8:[function(e,t,n){"use strict";function r(){}function o(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=m,this.queue=[],this.outcome=void 0,e!==r&&u(this,e)}function i(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function a(e,t,n){p(function(){var r;try{r=t(n)}catch(o){return v.reject(e,o)}r===e?v.reject(e,new TypeError("Cannot resolve promise with itself")):v.resolve(e,r)})}function s(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}function u(e,t){function n(t){i||(i=!0,v.reject(e,t))}function r(t){i||(i=!0,v.resolve(e,t))}function o(){t(r,n)}var i=!1,a=c(o);"error"===a.status&&n(a.value)}function c(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}function f(e){return e instanceof this?e:v.resolve(new this(r),e)}function l(e){var t=new this(r);return v.reject(t,e)}function d(e){function t(e,t){function r(e){a[t]=e,++s!==o||i||(i=!0,v.resolve(c,a))}n.resolve(e).then(r,function(e){i||(i=!0,v.reject(c,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var o=e.length,i=!1;if(!o)return this.resolve([]);for(var a=new Array(o),s=0,u=-1,c=new this(r);++u<o;)t(e[u],u);return c}function h(e){function t(e){n.resolve(e).then(function(e){i||(i=!0,v.resolve(s,e))},function(e){i||(i=!0,v.reject(s,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var o=e.length,i=!1;if(!o)return this.resolve([]);for(var a=-1,s=new this(r);++a<o;)t(e[a]);return s}var p=e(5),v={},y=["REJECTED"],_=["FULFILLED"],m=["PENDING"];t.exports=n=o,o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,t){if("function"!=typeof e&&this.state===_||"function"!=typeof t&&this.state===y)return this;var n=new this.constructor(r);if(this.state!==m){var o=this.state===_?e:t;a(n,o,this.outcome)}else this.queue.push(new i(n,e,t));return n},i.prototype.callFulfilled=function(e){v.resolve(this.promise,e)},i.prototype.otherCallFulfilled=function(e){a(this.promise,this.onFulfilled,e)},i.prototype.callRejected=function(e){v.reject(this.promise,e)},i.prototype.otherCallRejected=function(e){a(this.promise,this.onRejected,e)},v.resolve=function(e,t){var n=c(s,t);if("error"===n.status)return v.reject(e,n.value);var r=n.value;if(r)u(e,r);else{e.state=_,e.outcome=t;for(var o=-1,i=e.queue.length;++o<i;)e.queue[o].callFulfilled(t)}return e},v.reject=function(e,t){e.state=y,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},n.resolve=f,n.reject=l,n.all=d,n.race=h},{5:5}],9:[function(e,t,n){function r(e){if(e=""+e,!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*l;case"days":case"day":case"d":return n*f;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*u;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}}}function o(e){return e>=f?Math.round(e/f)+"d":e>=c?Math.round(e/c)+"h":e>=u?Math.round(e/u)+"m":e>=s?Math.round(e/s)+"s":e+"ms"}function i(e){return a(e,f,"day")||a(e,c,"hour")||a(e,u,"minute")||a(e,s,"second")||e+" ms"}function a(e,t,n){return t>e?void 0:1.5*t>e?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var s=1e3,u=60*s,c=60*u,f=24*c,l=365.25*f;t.exports=function(e,t){return t=t||{},"string"==typeof e?r(e):t["long"]?i(e):o(e)}},{}],10:[function(e,t,n){"use strict";function r(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return f(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),r=t?e:Object.keys(e),o=-1,i=r.length,a="";if(t)for(;++o<i;)a+=n.toIndexableString(r[o]);else for(;++o<i;){var s=r[o];a+=n.toIndexableString(s)+n.toIndexableString(e[s])}return a}return""}function o(e,t){var n,r=t,o="1"===e[t];if(o)n=0,t++;else{var i="0"===e[t];t++;var a="",s=e.substring(t,t+d),u=parseInt(s,10)+l;for(i&&(u=-u),t+=d;;){var c=e[t];if("\x00"===c)break;a+=c,t++}a=a.split("."),n=1===a.length?parseInt(a,10):parseFloat(a[0]+"."+a[1]),i&&(n-=10),0!==u&&(n=parseFloat(n+"e"+u))}return{num:n,length:t-r}}function i(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(n);else if(i===e.length-2){var a=e.pop();o[a]=n}else e.push(n)}}function a(e,t){for(var r=Math.min(e.length,t.length),o=0;r>o;o++){var i=n.collate(e[o],t[o]);if(0!==i)return i}return e.length===t.length?0:e.length>t.length?1:-1}function s(e,t){return e===t?0:e>t?1:-1}function u(e,t){for(var r=Object.keys(e),o=Object.keys(t),i=Math.min(r.length,o.length),a=0;i>a;a++){var s=n.collate(r[a],o[a]);if(0!==s)return s;if(s=n.collate(e[r[a]],t[o[a]]),0!==s)return s}return r.length===o.length?0:r.length>o.length?1:-1}function c(e){var t=["boolean","number","string","object"],n=t.indexOf(typeof e);return~n?null===e?1:Array.isArray(e)?5:3>n?n+2:n+3:Array.isArray(e)?5:void 0}function f(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=0>e,o=r?"0":"2",i=(r?-n:n)-l,a=p.padLeft(i.toString(),"0",d);o+=h+a;var s=Math.abs(parseFloat(t[0]));r&&(s=10-s);var u=s.toFixed(20);return u=u.replace(/\.?0+$/,""),o+=h+u}var l=-324,d=3,h="",p=e(11);n.collate=function(e,t){if(e===t)return 0;e=n.normalizeKey(e),t=n.normalizeKey(t);var r=c(e),o=c(t);if(r-o!==0)return r-o;if(null===e)return 0;switch(typeof e){case"number":return e-t;case"boolean":return e===t?0:t>e?-1:1;case"string":return s(e,t)}return Array.isArray(e)?a(e,t):u(e,t)},n.normalizeKey=function(e){switch(typeof e){case"undefined":return null;case"number":return e===1/0||e===-(1/0)||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var r=e.length;e=new Array(r);for(var o=0;r>o;o++)e[o]=n.normalizeKey(t[o])}else{if(e instanceof Date)return e.toJSON();if(null!==e){e={};for(var i in t)if(t.hasOwnProperty(i)){var a=t[i];"undefined"!=typeof a&&(e[i]=n.normalizeKey(a))}}}}return e},n.toIndexableString=function(e){var t="\x00";return e=n.normalizeKey(e),c(e)+h+r(e)+t},n.parseIndexableString=function(e){for(var t=[],n=[],r=0;;){var a=e[r++];if("\x00"!==a)switch(a){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var s=o(e,r);t.push(s.num),r+=s.length;break;case"4":for(var u="";;){var c=e[r];if("\x00"===c)break;u+=c,r++}u=u.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(u);break;case"5":var f={element:[],index:t.length};t.push(f.element),n.push(f);break;case"6":var l={element:{},index:t.length};t.push(l.element),n.push(l);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+a)}else{if(1===t.length)return t.pop();i(t,n)}}}},{11:11}],11:[function(e,t,n){"use strict";function r(e,t,n){for(var r="",o=n-e.length;r.length<o;)r+=t;return r}n.padLeft=function(e,t,n){var o=r(e,t,n);return o+e},n.padRight=function(e,t,n){var o=r(e,t,n);return e+o},n.stringLexCompare=function(e,t){var n,r=e.length,o=t.length;for(n=0;r>n;n++){if(n===o)return 1;var i=e.charAt(n),a=t.charAt(n);if(i!==a)return a>i?-1:1}return o>r?-1:0},n.intToDecimalForm=function(e){var t=0>e,n="";do{var r=t?-Math.ceil(e%10):Math.floor(e%10);n=r+n,e=t?Math.ceil(e/10):Math.floor(e/10)}while(e);return t&&"0"!==n&&(n="-"+n),n}},{}],12:[function(e,t,n){"use strict";function r(){this.store={}}function o(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=o,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){for(var t=Object.keys(this.store),n=0,r=t.length;r>n;n++){var o=t[n],i=this.store[o];o=this.unmangle(o),e(i,o)}},o.prototype.add=function(e){return this.store.set(e,!0)},o.prototype.has=function(e){return this.store.has(e)},o.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],13:[function(e,t,n){function r(){f=!1,s.length?c=s.concat(c):l=-1,c.length&&o()}function o(){if(!f){var e=setTimeout(r);f=!0;for(var t=c.length;t;){for(s=c,c=[];++l<t;)s&&s[l].run();l=-1,t=c.length}s=null,f=!1,clearTimeout(e)}}function i(e,t){this.fun=e,this.array=t}function a(){}var s,u=t.exports={},c=[],f=!1,l=-1;u.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new i(e,t)),1!==c.length||f||setTimeout(o,0)},i.prototype.run=function(){this.fun.apply(null,this.array)},u.title="browser",u.browser=!0,u.env={},u.argv=[],u.version="",u.versions={},u.on=a,u.addListener=a,u.once=a,u.off=a,u.removeListener=a,u.removeAllListeners=a,u.emit=a,u.binding=function(e){throw new Error("process.binding is not supported")},u.cwd=function(){return"/"},u.chdir=function(e){throw new Error("process.chdir is not supported")},u.umask=function(){return 0}},{}],14:[function(e,t,n){(function(){var e={}.hasOwnProperty,n=[].slice;t.exports=function(t,r){var o,i,a,s;i=[],s=[];for(o in r)e.call(r,o)&&(a=r[o],"this"!==o&&(i.push(o),s.push(a)));return Function.apply(null,n.call(i).concat([t])).apply(r["this"],s)}}).call(this)},{}],15:[function(t,n,r){!function(t){if("object"==typeof r)n.exports=t();else if("function"==typeof e&&e.amd)e(t);else{var o;try{o=window}catch(i){o=self}o.SparkMD5=t()}}(function(e){"use strict";function t(e,t,n,r,o,i){return t=g(g(t,e),g(r,i)),g(t<<o|t>>>32-o,n)}function n(e,n,r,o,i,a,s){return t(n&r|~n&o,e,n,i,a,s)}function r(e,n,r,o,i,a,s){return t(n&o|r&~o,e,n,i,a,s)}function o(e,n,r,o,i,a,s){return t(n^r^o,e,n,i,a,s)}function i(e,n,r,o,i,a,s){return t(r^(n|~o),e,n,i,a,s)}function a(e,t){var a=e[0],s=e[1],u=e[2],c=e[3];a=n(a,s,u,c,t[0],7,-680876936),c=n(c,a,s,u,t[1],12,-389564586),u=n(u,c,a,s,t[2],17,606105819),s=n(s,u,c,a,t[3],22,-1044525330),a=n(a,s,u,c,t[4],7,-176418897),c=n(c,a,s,u,t[5],12,1200080426),u=n(u,c,a,s,t[6],17,-1473231341),s=n(s,u,c,a,t[7],22,-45705983),a=n(a,s,u,c,t[8],7,1770035416),c=n(c,a,s,u,t[9],12,-1958414417),u=n(u,c,a,s,t[10],17,-42063),s=n(s,u,c,a,t[11],22,-1990404162),a=n(a,s,u,c,t[12],7,1804603682),c=n(c,a,s,u,t[13],12,-40341101),u=n(u,c,a,s,t[14],17,-1502002290),s=n(s,u,c,a,t[15],22,1236535329),a=r(a,s,u,c,t[1],5,-165796510),c=r(c,a,s,u,t[6],9,-1069501632),u=r(u,c,a,s,t[11],14,643717713),s=r(s,u,c,a,t[0],20,-373897302),a=r(a,s,u,c,t[5],5,-701558691),c=r(c,a,s,u,t[10],9,38016083),u=r(u,c,a,s,t[15],14,-660478335),s=r(s,u,c,a,t[4],20,-405537848),a=r(a,s,u,c,t[9],5,568446438),c=r(c,a,s,u,t[14],9,-1019803690),u=r(u,c,a,s,t[3],14,-187363961),s=r(s,u,c,a,t[8],20,1163531501),a=r(a,s,u,c,t[13],5,-1444681467),c=r(c,a,s,u,t[2],9,-51403784),u=r(u,c,a,s,t[7],14,1735328473),s=r(s,u,c,a,t[12],20,-1926607734),a=o(a,s,u,c,t[5],4,-378558),c=o(c,a,s,u,t[8],11,-2022574463),u=o(u,c,a,s,t[11],16,1839030562),s=o(s,u,c,a,t[14],23,-35309556),a=o(a,s,u,c,t[1],4,-1530992060),c=o(c,a,s,u,t[4],11,1272893353),u=o(u,c,a,s,t[7],16,-155497632),s=o(s,u,c,a,t[10],23,-1094730640),a=o(a,s,u,c,t[13],4,681279174),c=o(c,a,s,u,t[0],11,-358537222),u=o(u,c,a,s,t[3],16,-722521979),s=o(s,u,c,a,t[6],23,76029189),a=o(a,s,u,c,t[9],4,-640364487),c=o(c,a,s,u,t[12],11,-421815835),u=o(u,c,a,s,t[15],16,530742520),s=o(s,u,c,a,t[2],23,-995338651),a=i(a,s,u,c,t[0],6,-198630844),c=i(c,a,s,u,t[7],10,1126891415),u=i(u,c,a,s,t[14],15,-1416354905),s=i(s,u,c,a,t[5],21,-57434055),a=i(a,s,u,c,t[12],6,1700485571),c=i(c,a,s,u,t[3],10,-1894986606),u=i(u,c,a,s,t[10],15,-1051523),s=i(s,u,c,a,t[1],21,-2054922799),a=i(a,s,u,c,t[8],6,1873313359),c=i(c,a,s,u,t[15],10,-30611744),u=i(u,c,a,s,t[6],15,-1560198380),s=i(s,u,c,a,t[13],21,1309151649),a=i(a,s,u,c,t[4],6,-145523070),c=i(c,a,s,u,t[11],10,-1120210379),u=i(u,c,a,s,t[2],15,718787259),s=i(s,u,c,a,t[9],21,-343485551),e[0]=g(a,e[0]),e[1]=g(s,e[1]),e[2]=g(u,e[2]),e[3]=g(c,e[3])}function s(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function u(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function c(e){var t,n,r,o,i,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,s(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),u=parseInt(o[1],16)||0,r[14]=i,r[15]=u,a(f,r),f}function f(e){var t,n,r,o,i,s,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),s=parseInt(o[1],16)||0,r[14]=i,r[15]=s,a(f,r),f}function l(e){var t,n="";for(t=0;4>t;t+=1)n+=b[e>>8*t+4&15]+b[e>>8*t&15];return n}function d(e){var t;for(t=0;t<e.length;t+=1)e[t]=l(e[t]);return e.join("")}function h(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function p(e,t){var n,r=e.length,o=new ArrayBuffer(r),i=new Uint8Array(o);for(n=0;r>n;n+=1)i[n]=e.charCodeAt(n);return t?i:o}function v(e){return String.fromCharCode.apply(null,new Uint8Array(e))}function y(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}function _(e){var t,n=[],r=e.length;for(t=0;r-1>t;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function m(){this.reset()}var g=function(e,t){return e+t&4294967295},b=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==d(c("hello"))&&(g=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function t(e,t){return e=0|e||0,0>e?Math.max(e+t,0):Math.min(e,t)}ArrayBuffer.prototype.slice=function(n,r){var o,i,a,s,u=this.byteLength,c=t(n,u),f=u;return r!==e&&(f=t(r,u)),c>f?new ArrayBuffer(0):(o=f-c,i=new ArrayBuffer(o),a=new Uint8Array(i),s=new Uint8Array(this,c,o),a.set(s),i)}}(),m.prototype.append=function(e){return this.appendBinary(h(e)),this},m.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._hash,s(this._buff.substring(t-64,t)));return this._buff=this._buff.substring(t-64),this},m.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(i,o),n=d(this._hash),e&&(n=_(n)),this.reset(),n},m.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},m.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},m.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},m.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},m.prototype._finish=function(e,t){var n,r,o,i=t;if(e[i>>2]|=128<<(i%4<<3),i>55)for(a(this._hash,e),i=0;16>i;i+=1)e[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),o=parseInt(n[1],16)||0,e[14]=r,e[15]=o,a(this._hash,e)},m.hash=function(e,t){return m.hashBinary(h(e),t)},m.hashBinary=function(e,t){var n=c(e),r=d(n);return t?_(r):r},m.ArrayBuffer=function(){this.reset()},m.ArrayBuffer.prototype.append=function(e){var t,n=y(this._buff.buffer,e,!0),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._hash,u(n.subarray(t-64,t)));return this._buff=r>t-64?new Uint8Array(n.buffer.slice(t-64)):new Uint8Array(0),this},m.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r[t]<<(t%4<<3);return this._finish(i,o),n=d(this._hash),e&&(n=_(n)),this.reset(),n},m.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},m.ArrayBuffer.prototype.getState=function(){var e=m.prototype.getState.call(this);return e.buff=v(e.buff),e},m.ArrayBuffer.prototype.setState=function(e){return e.buff=p(e.buff,!0),m.prototype.setState.call(this,e)},m.ArrayBuffer.prototype.destroy=m.prototype.destroy,m.ArrayBuffer.prototype._finish=m.prototype._finish,m.ArrayBuffer.hash=function(e,t){var n=f(new Uint8Array(e)),r=d(n);return t?_(r):r},m})},{}],16:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(e);else if(i===t.length-2){var a=t.pop();o[a]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,o,i,a,s,u,c,f,l,d,h="";n=t.pop();)if(r=n.obj,o=n.prefix||"",i=n.val||"",h+=o,i)h+=i;else if("object"!=typeof r)h+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)h+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),a=r.length-1;a>=0;a--)s=0===a?"":",",t.push({obj:r[a],prefix:s});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),a=u.length-1;a>=0;a--)f=u[a],l=r[f],d=a>0?",":"",d+=JSON.stringify(f)+":",t.push({obj:l,prefix:d});t.push({val:"{"})}return h},n.parse=function(e){for(var t,n,o,i,a,s,u,c,f,l=[],d=[],h=0;;)if(t=e[h++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":h+=3,r(null,l,d);break;case"t":h+=3,r(!0,l,d);break;case"f":h+=4,r(!1,l,d);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",h--;;){if(o=e[h++],!/[\d\.\-e\+]/.test(o)){h--;break}n+=o}r(parseFloat(n),l,d);break;case'"':for(i="",a=void 0,s=0;;){if(u=e[h++],'"'===u&&("\\"!==a||s%2!==1))break;i+=u,a=u,"\\"===a?s++:s=0}r(JSON.parse('"'+i+'"'),l,d);break;case"[":c={element:[],index:l.length},l.push(c.element),d.push(c);break;case"{":f={element:{},index:l.length},l.push(f.element),d.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,d)}}},{}],17:[function(e,t,n){(function(n,r){"use strict";function o(e){return e&&"object"==typeof e&&"default"in e?e["default"]:e}function i(e,t){for(var n={},r=0,o=t.length;o>r;r++){var i=t[r];i in e&&(n[i]=e[i])}return n}function a(e){return e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}function s(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}function u(e){if(e instanceof ArrayBuffer)return s(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}function c(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;r>n;n++)t[n]=c(e[n]);return t}if(e instanceof Date)return e.toISOString();if(a(e))return u(e);t={};for(n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var o=c(e[n]);"undefined"!=typeof o&&(t[n]=o)}return t}function f(e){var t=!1;return rr(function(n){if(t)throw new Error("once called more than once");t=!0,e.apply(this,n)})}function l(e){return rr(function(t){t=c(t);var r,o=this,i="function"==typeof t[t.length-1]?t.pop():!1;i&&(r=function(e,t){n.nextTick(function(){i(e,t)})});var a=new fr(function(n,r){var i;try{var a=f(function(e,t){e?r(e):n(t)});t.push(a),i=e.apply(o,t),i&&"function"==typeof i.then&&n(i)}catch(s){r(s)}});return r&&a.then(function(e){r(null,e)},r),a})}function d(e,t){function n(e,t,n){if(lr.enabled){for(var r=[e._db_name,t],o=0;o<n.length-1;o++)r.push(n[o]);lr.apply(null,r);var i=n[n.length-1];n[n.length-1]=function(n,r){var o=[e._db_name,t];o=o.concat(n?["error",n]:["success",r]),lr.apply(null,o),i(n,r)}}}return l(rr(function(r){if(this._closed)return fr.reject(new Error("database is closed"));if(this._destroyed)return fr.reject(new Error("database is destroyed"));var o=this;return n(o,e,r),this.taskqueue.isReady?t.apply(this,r):new fr(function(t,n){o.taskqueue.addTask(function(i){i?n(i):t(o[e].apply(o,r))})})}))}function h(e,t,n){return new fr(function(r,o){e.get(t,function(i,a){if(i){if(404!==i.status)return o(i);a={}}var s=a._rev,u=n(a);return u?(u._id=t,u._rev=s,void r(p(e,u,n))):r({updated:!1,rev:s})})})}function p(e,t,n){return e.put(t).then(function(e){return{updated:!0,rev:e.rev}},function(r){if(409!==r.status)throw r;return h(e,t._id,n)})}function v(e){for(var t,n,r,o,i=e.rev_tree.slice();o=i.pop();){var a=o.ids,s=a[2],u=o.pos;if(s.length)for(var c=0,f=s.length;f>c;c++)i.push({pos:u+1,ids:s[c]});else{var l=!!a[1].deleted,d=a[0];t&&!(r!==l?r:n!==u?u>n:d>t)||(t=d,n=u,r=l)}}return n+"-"+t}function y(e){return e.ids}function _(e,t){t||(t=v(e));for(var n,r=t.substring(t.indexOf("-")+1),o=e.rev_tree.map(y);n=o.pop();){if(n[0]===r)return!!n[1].deleted;o=o.concat(n[2])}}function m(e){return ir("return "+e+";",{})}function g(e){return new Function("doc",["var emitted = false;","var emit = function (a, b) {","  emitted = true;","};","var view = "+e+";","view(doc);","if (emitted) {","  return true;","}"].join("\n"))}function b(e){if(!e)return null;var t=e.split("/");return 2===t.length?t:1===t.length?[e,e]:null}function w(e){var t=b(e);return t?t.join("/"):null}function E(e,t){for(var n,r=e.slice();n=r.pop();)for(var o=n.pos,i=n.ids,a=i[2],s=t(0===a.length,o,i[0],n.ctx,i[1]),u=0,c=a.length;c>u;u++)r.push({pos:o+1,ids:a[u],ctx:s})}function S(e,t){return e.pos-t.pos}function k(e){var t=[];E(e,function(e,n,r,o,i){e&&t.push({rev:n+"-"+r,pos:n,opts:i})}),t.sort(S).reverse();for(var n=0,r=t.length;r>n;n++)delete t[n].pos;return t}function q(e){for(var t=v(e),n=k(e.rev_tree),r=[],o=0,i=n.length;i>o;o++){var a=n[o];a.rev===t||a.opts.deleted||r.push(a.rev)}return r}function x(e){Error.call(this,e.reason),this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}function A(e,t,n){function r(t){for(var r in e)"function"!=typeof e[r]&&(this[r]=e[r]);void 0!==n&&(this.name=n),void 0!==t&&(this.reason=t)}return r.prototype=x.prototype,new r(t)}function T(e){var t,n,r,o,i;return n=e.error===!0&&"string"==typeof e.name?e.name:e.error,i=e.reason,
+r=Br("name",n,i),e.missing||"missing"===i||"deleted"===i||"not_found"===n?r=pr:"doc_validation"===n?(r=kr,o=i):"bad_request"===n&&r.message!==i&&(r=qr),r||(r=Br("status",e.status,i)||br),t=A(r,i,n),o&&(t.message=o),e.id&&(t.id=e.id),e.status&&(t.status=e.status),e.missing&&(t.missing=e.missing),t}function O(e,t,n){function r(){o.cancel()}or.EventEmitter.call(this);var o=this;this.db=e,t=t?c(t):{};var i=t.complete=f(function(t,n){t?o.emit("error",t):o.emit("complete",n),o.removeAllListeners(),e.removeListener("destroyed",r)});n&&(o.on("complete",function(e){n(null,e)}),o.on("error",n)),e.once("destroyed",r),t.onChange=function(e){t.isCancelled||(o.emit("change",e),o.startSeq&&o.startSeq<=e.seq&&(o.startSeq=!1))};var a=new fr(function(e,n){t.complete=function(t,r){t?n(t):e(r)}});o.once("cancel",function(){e.removeListener("destroyed",r),t.complete(null,{status:"cancelled"})}),this.then=a.then.bind(a),this["catch"]=a["catch"].bind(a),this.then(function(e){i(null,e)},i),e.taskqueue.isReady?o.doChanges(t):e.taskqueue.addTask(function(){o.isCancelled?o.emit("cancel"):o.doChanges(t)})}function j(e,t,n){var r=[{rev:e._rev}];"all_docs"===n.style&&(r=k(t.rev_tree).map(function(e){return{rev:e.rev}}));var o={id:t.id,changes:r,doc:e};return _(t,e._rev)&&(o.deleted=!0),n.conflicts&&(o.doc._conflicts=q(t),o.doc._conflicts.length||delete o.doc._conflicts),o}function C(e,t,n){function r(){var e=[];l.forEach(function(t){t.docs.forEach(function(n){e.push({id:t.id,docs:[n]})})}),n(null,{results:e})}function o(){++f===c&&r()}function a(e,t,n){l[e]={id:t,docs:n},o()}var s=Array.isArray(t)?t:t.docs,u={};s.forEach(function(e){e.id in u?u[e.id].push(e):u[e.id]=[e]});var c=Object.keys(u).length,f=0,l=new Array(c);Object.keys(u).forEach(function(n,r){var o=u[n],s=i(o[0],["atts_since","attachments"]);s.open_revs=o.map(function(e){return e.rev}),s.open_revs=s.open_revs.filter(function(e){return e});var c=function(e){return e};0===s.open_revs.length&&(delete s.open_revs,c=function(e){return[{ok:e}]}),["revs","attachments","binary","ajax"].forEach(function(e){e in t&&(s[e]=t[e])}),e.get(n,s,function(e,t){a(r,n,e?[{error:e}]:c(t))})})}function I(e){return/^_local/.test(e)}function L(e){for(var t,n=[],r=e.slice();t=r.pop();){var o=t.pos,i=t.ids,a=i[0],s=i[1],u=i[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:a,opts:s}),c&&n.push({pos:o+1-f.length,ids:f});for(var l=0,d=u.length;d>l;l++)r.push({pos:o+1,ids:u[l],history:f})}return n.reverse()}function R(e){return 0|Math.random()*e}function D(e,t){t=t||Mr.length;var n="",r=-1;if(e){for(;++r<e;)n+=Mr[R(t)];return n}for(;++r<36;)switch(r){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=Mr[3&R(16)|8];break;default:n+=Mr[R(16)]}return n}function N(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function B(e){var t;if(e?"string"!=typeof e?t=A(yr):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=A(mr)):t=A(_r),t)throw t}function M(e){if(!/^\d+\-./.test(e))return A(Ir);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function F(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,o=[r[0],t,[]],i=1,a=r.length;a>i;i++)o=[r[i],{status:"missing"},[o]];return[{pos:n,ids:o}]}function U(e,t){var n,r,o,i={status:"available"};if(e._deleted&&(i.deleted=!0),t)if(e._id||(e._id=D()),r=D(32,16).toLowerCase(),e._rev){if(o=M(e._rev),o.error)return o;e._rev_tree=[{pos:o.prefix,ids:[o.id,{status:"missing"},[[r,i,[]]]]}],n=o.prefix+1}else e._rev_tree=[{pos:1,ids:[r,i,[]]}],n=1;else if(e._revisions&&(e._rev_tree=F(e._revisions,i),n=e._revisions.start,r=e._revisions.ids[0]),!e._rev_tree){if(o=M(e._rev),o.error)return o;n=o.prefix,r=o.id,e._rev_tree=[{pos:n,ids:[r,i,[]]}]}B(e._id),e._rev=n+"-"+r;var a={metadata:{},data:{}};for(var s in e)if(Object.prototype.hasOwnProperty.call(e,s)){var u="_"===s[0];if(u&&!Fr[s]){var c=A(kr,s);throw c.message=kr.message+": "+s,c}u&&!Ur[s]?a.metadata[s.slice(1)]=e[s]:a.data[s]=e[s]}return a}function P(e,t){return t>e?-1:e>t?1:0}function H(e,t){for(var n=0;n<e.length;n++)if(t(e[n],n)===!0)return e[n]}function K(e){return function(t,n){t||n[0]&&n[0].error?e(t||n[0]):e(null,n.length?n[0]:n)}}function W(e){for(var t=0;t<e.length;t++){var n=e[t];if(n._deleted)delete n._attachments;else if(n._attachments)for(var r=Object.keys(n._attachments),o=0;o<r.length;o++){var a=r[o];n._attachments[a]=i(n._attachments[a],["data","digest","content_type","length","revpos","stub"])}}}function J(e,t){var n=P(e._id,t._id);if(0!==n)return n;var r=e._revisions?e._revisions.start:0,o=t._revisions?t._revisions.start:0;return P(r,o)}function V(e){var t={},n=[];return E(e,function(e,r,o,i){var a=r+"-"+o;return e&&(t[a]=0),void 0!==i&&n.push({from:i,to:a}),a}),n.reverse(),n.forEach(function(e){void 0===t[e.from]?t[e.from]=1+t[e.to]:t[e.from]=Math.min(t[e.from],1+t[e.to])}),t}function G(e,t,n){var r="limit"in t?t.keys.slice(t.skip,t.limit+t.skip):t.skip>0?t.keys.slice(t.skip):t.keys;if(t.descending&&r.reverse(),!r.length)return e._allDocs({limit:0},n);var o={offset:t.skip};return fr.all(r.map(function(n){var r=$n.extend({key:n,deleted:"ok"},t);return["limit","skip","keys"].forEach(function(e){delete r[e]}),new fr(function(t,i){e._allDocs(r,function(e,r){return e?i(e):(o.total_rows=r.total_rows,void t(r.rows[0]||{key:n,error:"not_found"}))})})})).then(function(e){return o.rows=e,o})}function X(e){var t=e._compactionQueue[0],r=t.opts,o=t.callback;e.get("_local/compaction")["catch"](function(){return!1}).then(function(t){t&&t.last_seq&&(r.last_seq=t.last_seq),e._compact(r,function(t,r){t?o(t):o(null,r),n.nextTick(function(){e._compactionQueue.shift(),e._compactionQueue.length&&X(e)})})})}function z(e){return"_"===e.charAt(0)?e+"is not a valid attachment name, attachment names cannot start with '_'":!1}function Q(e,t,n,r){t.seq=t.seq||0;var o={doc_ids:["_design/"+n],limit:1,since:t.seq};e.changes(o).then(function(e){var n=e.results&&e.results.length&&e.results[0].seq;n&&n>t.seq&&(t.seq=n,delete t.promise),r()})["catch"](r)}function $(e,t,n){e._ddocCache=e._ddocCache||{},e._ddocCache[t]=e._ddocCache[t]||{};var r=e._ddocCache[t];Q(e,r,t,function(o){return o?n(o):(r.promise||(r.promise=new fr(function(n,r){e._get("_design/"+t,{},function(e,t){if(e)return r(e);var o={};["views","filters"].forEach(function(e){o[e]=t.doc[e]}),n(o)})})),void r.promise.then(function(e){n(null,e)})["catch"](n))})}function Y(e,t,n,r,o){$(e,t,function(e,t){if(e)return o(e);var i=t[n]&&t[n][r];return i?void o(null,i):o(A(pr))})}function Z(){or.EventEmitter.call(this)}function ee(){this.isReady=!1,this.failed=!1,this.queue=[]}function te(e){e&&r.debug&&console.error(e)}function ne(e,t){function n(){i.emit("destroyed",o)}function r(){e.removeListener("destroyed",n),e.emit("destroyed",e)}var o=t.originalName,i=e.constructor,a=i._destructionListeners;e.once("destroyed",n),a.has(o)||a.set(o,[]),a.get(o).push(r)}function re(e,t,n){if(!(this instanceof re))return new re(e,t,n);var r=this;"function"!=typeof t&&"undefined"!=typeof t||(n=t,t={}),e&&"object"==typeof e&&(t=e,e=void 0),"undefined"==typeof n&&(n=te),e=e||t.name,t=c(t),delete t.name,this.__opts=t;var o=n;r.auto_compaction=t.auto_compaction,r.prefix=re.prefix,Z.call(r),r.taskqueue=new ee;var i=new fr(function(o,i){n=function(e,t){return e?i(e):(delete t.then,void o(t))},t=c(t);var a,s,u=t.name||e;return function(){try{if("string"!=typeof u)throw s=new Error("Missing/invalid DB name"),s.code=400,s;if(a=re.parseAdapter(u,t),t.originalName=u,t.name=a.name,t.prefix&&"http"!==a.adapter&&"https"!==a.adapter&&(t.name=t.prefix+t.name),t.adapter=t.adapter||a.adapter,r._adapter=t.adapter,Zn("pouchdb:adapter")("Picked adapter: "+t.adapter),r._db_name=u,!re.adapters[t.adapter])throw s=new Error("Adapter is missing"),s.code=404,s;if(!re.adapters[t.adapter].valid())throw s=new Error("Invalid Adapter"),s.code=404,s}catch(e){r.taskqueue.fail(e)}}(),s?i(s):(r.adapter=t.adapter,r.replicate={},r.replicate.from=function(e,t,n){return r.constructor.replicate(e,r,t,n)},r.replicate.to=function(e,t,n){return r.constructor.replicate(r,e,t,n)},r.sync=function(e,t,n){return r.constructor.sync(r,e,t,n)},r.replicate.sync=r.sync,void re.adapters[t.adapter].call(r,t,function(e){return e?(r.taskqueue.fail(e),void n(e)):(ne(r,t),r.emit("created",r),re.emit("created",t.originalName),r.taskqueue.ready(r),void n(null,r))}))});i.then(function(e){o(null,e)},o),r.then=i.then.bind(i),r["catch"]=i["catch"].bind(i)}function oe(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function ie(){return Pr}function ae(e){Object.keys(or.EventEmitter.prototype).forEach(function(t){"function"==typeof or.EventEmitter.prototype[t]&&(e[t]=Kr[t].bind(Kr))});var t=e._destructionListeners=new nr.Map;e.on("destroyed",function(e){t.has(e)&&(t.get(e).forEach(function(e){e()}),t["delete"](e))})}function se(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(n){if("TypeError"!==n.name)throw n;for(var r="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,o=new r,i=0;i<e.length;i+=1)o.append(e[i]);return o.getBlob(t.type)}}function ue(e,t){if("undefined"==typeof FileReader)return t((new FileReaderSync).readAsArrayBuffer(e));var n=new FileReader;n.onloadend=function(e){var n=e.target.result||new ArrayBuffer(0);t(n)},n.readAsArrayBuffer(e)}function ce(){for(var e={},t=new fr(function(t,n){e.resolve=t,e.reject=n}),n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.promise=t,fr.resolve().then(function(){return fetch.apply(null,n)}).then(function(t){e.resolve(t)})["catch"](function(t){e.reject(t)}),e}function fe(e,t){var n,r,o,i=new Headers,a={method:e.method,credentials:"include",headers:i};return e.json&&(i.set("Accept","application/json"),i.set("Content-Type",e.headers["Content-Type"]||"application/json")),e.body&&e.body instanceof Blob?ue(e.body,function(e){a.body=e}):e.body&&e.processData&&"string"!=typeof e.body?a.body=JSON.stringify(e.body):"body"in e?a.body=e.body:a.body=null,Object.keys(e.headers).forEach(function(t){e.headers.hasOwnProperty(t)&&i.set(t,e.headers[t])}),n=ce(e.url,a),e.timeout>0&&(r=setTimeout(function(){n.reject(new Error("Load timeout for resource: "+e.url))},e.timeout)),n.promise.then(function(t){return o={statusCode:t.status},e.timeout>0&&clearTimeout(r),o.statusCode>=200&&o.statusCode<300?e.binary?t.blob():t.text():t.json()}).then(function(e){o.statusCode>=200&&o.statusCode<300?t(null,o,e):t(e,o)})["catch"](function(e){t(e,o)}),{abort:n.reject}}function le(e,t){var n,r,o=!1,i=function(){n.abort()},a=function(){o=!0,n.abort()};n=e.xhr?new e.xhr:new XMLHttpRequest;try{n.open(e.method,e.url)}catch(s){t(s,{statusCode:413})}n.withCredentials="withCredentials"in e?e.withCredentials:!0,"GET"===e.method?delete e.headers["Content-Type"]:e.json&&(e.headers.Accept="application/json",e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json",e.body&&e.processData&&"string"!=typeof e.body&&(e.body=JSON.stringify(e.body))),e.binary&&(n.responseType="arraybuffer"),"body"in e||(e.body=null);for(var u in e.headers)e.headers.hasOwnProperty(u)&&n.setRequestHeader(u,e.headers[u]);return e.timeout>0&&(r=setTimeout(a,e.timeout),n.onprogress=function(){clearTimeout(r),4!==n.readyState&&(r=setTimeout(a,e.timeout))},"undefined"!=typeof n.upload&&(n.upload.onprogress=n.onprogress)),n.onreadystatechange=function(){if(4===n.readyState){var r={statusCode:n.status};if(n.status>=200&&n.status<300){var i;i=e.binary?se([n.response||""],{type:n.getResponseHeader("Content-Type")}):n.responseText,t(null,r,i)}else{var a={};if(o)a=new Error("ETIMEDOUT"),r.statusCode=400;else try{a=JSON.parse(n.response)}catch(s){}t(a,r)}}},e.body&&e.body instanceof Blob?ue(e.body,function(e){n.send(e)}):n.send(e.body),{abort:i}}function de(){try{return new XMLHttpRequest,!0}catch(e){return!1}}function he(e,t){return Wr||e.xhr?le(e,t):fe(e,t)}function pe(){return""}function ve(e,t){function n(t,n,r){if(!e.binary&&e.json&&"string"==typeof t)try{t=JSON.parse(t)}catch(o){return r(o)}Array.isArray(t)&&(t=t.map(function(e){return e.error||e.missing?T(e):e})),e.binary&&Jr(t,n),r(null,t,n)}function r(e,t){var n,r;if(e.code&&e.status){var o=new Error(e.message||e.code);return o.status=e.status,t(o)}if(e.message&&"ETIMEDOUT"===e.message)return t(e);try{n=JSON.parse(e.responseText),r=T(n)}catch(i){r=T(e)}t(r)}e=c(e);var o={method:"GET",headers:{},json:!0,processData:!0,timeout:1e4,cache:!1};return e=$n.extend(o,e),e.json&&(e.binary||(e.headers.Accept="application/json"),e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json"),e.binary&&(e.encoding=null,e.json=!1),e.processData||(e.json=!1),he(e,function(o,i,a){if(o)return o.status=i?i.statusCode:400,r(o,t);var s,u=i.headers&&i.headers["content-type"],c=a||pe();if(!e.binary&&(e.json||!e.processData)&&"object"!=typeof c&&(/json/.test(u)||/^[\s]*\{/.test(c)&&/\}[\s]*$/.test(c)))try{c=JSON.parse(c.toString())}catch(f){}i.statusCode>=200&&i.statusCode<300?n(c,i,t):(s=T(c),s.status=i.statusCode,t(s))})}function ye(e,t){var n=navigator&&navigator.userAgent?navigator.userAgent.toLowerCase():"",r=-1!==n.indexOf("safari")&&-1===n.indexOf("chrome"),o=-1!==n.indexOf("msie"),i=-1!==n.indexOf("edge"),a=r||(o||i)&&"GET"===e.method,s="cache"in e?e.cache:!0,u=/^blob:/.test(e.url);if(!u&&(a||!s)){var c=-1!==e.url.indexOf("?");e.url+=(c?"&":"?")+"_nonce="+Date.now()}return ve(e,t)}function _e(e){for(var t=zr.exec(e),n={},r=14;r--;){var o=Vr[r],i=t[r]||"",a=-1!==["user","password"].indexOf(o);n[o]=a?decodeURIComponent(i):i}return n[Gr]={},n[Vr[12]].replace(Xr,function(e,t,r){t&&(n[Gr][t]=r)}),n}function me(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),o=0;t>o;o++)r[o]=e.charCodeAt(o);return n}function ge(e,t){return se([me(e)],{type:t})}function be(e,t,n){try{return!e(t,n)}catch(r){var o="Filter function threw: "+r.toString();return A(qr,o)}}function we(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){r.doc||(r.doc={});var o=n&&be(e.filter,r.doc,t);if("object"==typeof o)return o;if(o)return!1;if(e.include_docs){if(!e.attachments)for(var i in r.doc._attachments)r.doc._attachments.hasOwnProperty(i)&&(r.doc._attachments[i].stub=!0)}else delete r.doc;return!0}}function Ee(e,t){"console"in r&&"info"in console&&console.info("The above "+e+" is totally normal. "+t)}function Se(e,t,n,r,o){return e.get(t)["catch"](function(n){if(404===n.status)return"http"===e.type()&&Ee(404,"PouchDB is just checking if a remote checkpoint exists."),{session_id:r,_id:t,history:[],replicator:no,version:to};throw n}).then(function(i){return o.cancelled?void 0:(i.history=(i.history||[]).filter(function(e){return e.session_id!==r}),i.history.unshift({last_seq:n,session_id:r}),i.history=i.history.slice(0,ro),i.version=to,i.replicator=no,i.session_id=r,i.last_seq=n,e.put(i)["catch"](function(i){if(409===i.status)return Se(e,t,n,r,o);throw i}))})}function ke(e,t,n,r){this.src=e,this.target=t,this.id=n,this.returnValue=r}function qe(e,t){if(e.session_id===t.session_id)return{last_seq:e.last_seq,history:e.history||[]};var n=e.history||[],r=t.history||[];return xe(n,r)}function xe(e,t){var n=e[0],r=e.slice(1),o=t[0],i=t.slice(1);if(!n||0===t.length)return{last_seq:oo,history:[]};var a=n.session_id;if(Ae(a,t))return{last_seq:n.last_seq,history:e};var s=o.session_id;return Ae(s,r)?{last_seq:o.last_seq,history:i}:xe(r,i)}function Ae(e,t){var n=t[0],r=t.slice(1);return e&&0!==t.length?e===n.session_id?!0:Ae(e,r):!1}function Te(e){return"number"==typeof e.status&&4===Math.floor(e.status/100)}function Oe(e,t){e=parseInt(e,10)||0,t=parseInt(t,10),t!==t||e>=t?t=(e||1)<<1:t+=1;var n=Math.random(),r=t-e;return~~(r*n+e)}function je(e){var t=0;return e||(t=2e3),Oe(e,t)}function Ce(e,t,n,r){return e.retry===!1?(t.emit("error",n),void t.removeAllListeners()):("function"!=typeof e.back_off_function&&(e.back_off_function=je),t.emit("requestError",n),"active"!==t.state&&"pending"!==t.state||(t.emit("paused",n),t.state="stopped",t.once("active",function(){e.current_back_off=ao})),e.current_back_off=e.current_back_off||ao,e.current_back_off=e.back_off_function(e.current_back_off),void setTimeout(r,e.current_back_off))}function Ie(e){return $r(e)}function Le(e,t,n,r){(n>0||r<t.byteLength)&&(t=new Uint8Array(t,n,Math.min(r,t.byteLength)-n)),e.append(t)}function Re(e,t,n,r){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t)}function De(e){return Object.keys(e).sort(ar.collate).reduce(function(t,n){return t[n]=e[n],t},{})}function Ne(e,t,n){var r=n.doc_ids?n.doc_ids.sort(ar.collate):"",o=n.filter?n.filter.toString():"",i="",a="";return n.filter&&n.query_params&&(i=JSON.stringify(De(n.query_params))),n.filter&&"_view"===n.filter&&(a=n.view.toString()),fr.all([e.id(),t.id()]).then(function(e){var t=e[0]+e[1]+o+a+i+r;return co(t)}).then(function(e){return e=e.replace(/\//g,".").replace(/\+/g,"_"),"_local/"+e})}function Be(e){return/^1-/.test(e)}function Me(e){var t=[];return Object.keys(e).forEach(function(n){var r=e[n].missing;r.forEach(function(e){t.push({id:n,rev:e})})}),{docs:t,revs:!0,attachments:!0,binary:!0}}function Fe(e,t,n){function r(){var r=Me(t);if(r.docs.length)return e.bulkGet(r).then(function(e){if(n.cancelled)throw new Error("cancelled");e.results.forEach(function(e){e.docs.forEach(function(e){e.ok?u.push(e.ok):void 0!==e.error&&(f=!1)})})})}function o(e){return e._attachments&&Object.keys(e._attachments).length>0}function i(r){return e.allDocs({keys:r,include_docs:!0}).then(function(e){if(n.cancelled)throw new Error("cancelled");e.rows.forEach(function(e){!e.deleted&&e.doc&&Be(e.value.rev)&&!o(e.doc)&&(u.push(e.doc),delete t[e.id])})})}function a(){var e=Object.keys(t).filter(function(e){var n=t[e].missing;return 1===n.length&&Be(n[0])});return e.length>0?i(e):void 0}function s(){return{ok:f,docs:u}}t=c(t);var u=[],f=!0;return fr.resolve().then(a).then(r).then(s)}function Ue(e,t,n,r,o){function i(){return S?fr.resolve():Ne(e,t,n).then(function(n){E=n,S=new ke(e,t,E,r)})}function a(){if(B=[],0!==w.docs.length){var e=w.docs;return t.bulkDocs({docs:e,new_edits:!1}).then(function(t){if(r.cancelled)throw p(),new Error("cancelled");var n=[],i={};t.forEach(function(e){e.error&&(o.doc_write_failures++,n.push(e),i[e.id]=e)}),N=N.concat(n),o.docs_written+=w.docs.length-n.length;var a=n.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(e.forEach(function(e){var t=i[e._id];t?r.emit("denied",c(t)):B.push(e)}),a.length>0){var s=new Error("bulkDocs error");throw s.other_errors=n,h("target.bulkDocs failed to write docs",s),new Error("bulkWrite partial failure")}},function(t){throw o.doc_write_failures+=e.length,t})}}function s(){if(w.error)throw new Error("There was a problem getting docs.");o.last_seq=O=w.seq;var e=c(o);return B.length&&(e.docs=B,r.emit("change",e)),x=!0,S.writeCheckpoint(w.seq,M).then(function(){if(x=!1,r.cancelled)throw p(),new Error("cancelled");w=void 0,m()})["catch"](function(e){throw x=!1,h("writeCheckpoint completed with error",e),e})}function u(){var e={};return w.changes.forEach(function(t){"_user/"!==t.id&&(e[t.id]=t.changes.map(function(e){return e.rev}))}),t.revsDiff(e).then(function(e){if(r.cancelled)throw p(),new Error("cancelled");w.diffs=e})}function f(){return Fe(e,w.diffs,r).then(function(e){w.error=!e.ok,e.docs.forEach(function(e){delete w.diffs[e._id],o.docs_read++,w.docs.push(e)})})}function l(){if(!r.cancelled&&!w){if(0===k.length)return void d(!0);w=k.shift(),u().then(f).then(a).then(s).then(l)["catch"](function(e){h("batch processing terminated with error",e)})}}function d(e){return 0===q.changes.length?void(0!==k.length||w||((j&&F.live||A)&&(r.state="pending",r.emit("paused")),A&&p())):void((e||A||q.changes.length>=C)&&(k.push(q),q={seq:0,changes:[],docs:[]},"pending"!==r.state&&"stopped"!==r.state||(r.state="active",r.emit("active")),l()))}function h(e,t){T||(t.message||(t.message=e),o.ok=!1,o.status="aborting",o.errors.push(t),N=N.concat(t),k=[],q={seq:0,changes:[],docs:[]},p())}function p(){if(!(T||r.cancelled&&(o.status="cancelled",x))){o.status=o.status||"complete",o.end_time=new Date,o.last_seq=O,T=!0;var i=N.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(i.length>0){var a=N.pop();N.length>0&&(a.other_errors=N),a.result=o,Ce(n,r,a,function(){Ue(e,t,n,r)})}else o.errors=N,r.emit("complete",o),r.removeAllListeners()}}function v(e){if(r.cancelled)return p();var t=we(n)(e);t&&(q.seq=e.seq,q.changes.push(e),d(F.live))}function y(e){return L=!1,r.cancelled?p():(e.results.length>0?(F.since=e.last_seq,m()):j?(F.live=!0,m()):A=!0,void d(!0))}function _(e){return L=!1,r.cancelled?p():void h("changes rejected",e)}function m(){function t(){i.cancel()}function o(){r.removeListener("cancel",t)}if(!L&&!A&&k.length<I){L=!0,r._changes&&(r.removeListener("cancel",r._abortChanges),r._changes.cancel()),r.once("cancel",t);var i=e.changes(F).on("change",v);i.then(o,o),i.then(y)["catch"](_),n.retry&&(r._changes=i,r._abortChanges=t)}}function g(){i().then(function(){return r.cancelled?void p():S.getCheckpoint().then(function(e){O=e,F={since:O,limit:C,batch_size:C,style:"all_docs",doc_ids:R,return_docs:!0},n.filter&&("string"!=typeof n.filter?F.include_docs=!0:F.filter=n.filter),"heartbeat"in n&&(F.heartbeat=n.heartbeat),"timeout"in n&&(F.timeout=n.timeout),n.query_params&&(F.query_params=n.query_params),n.view&&(F.view=n.view),m()})})["catch"](function(e){h("getCheckpoint rejected with ",e)})}function b(e){throw x=!1,h("writeCheckpoint completed with error",e),e}var w,E,S,k=[],q={seq:0,changes:[],docs:[]},x=!1,A=!1,T=!1,O=0,j=n.continuous||n.live||!1,C=n.batch_size||100,I=n.batches_limit||10,L=!1,R=n.doc_ids,N=[],B=[],M=D();o=o||{ok:!0,start_time:new Date,docs_read:0,docs_written:0,doc_write_failures:0,errors:[]};var F={};return r.ready(e,t),r.cancelled?void p():(r._addedListeners||(r.once("cancel",p),"function"==typeof n.complete&&(r.once("error",n.complete),r.once("complete",function(e){n.complete(null,e)})),r._addedListeners=!0),void("undefined"==typeof n.since?g():i().then(function(){return x=!0,S.writeCheckpoint(n.since,M)}).then(function(){return x=!1,r.cancelled?void p():(O=n.since,void g())})["catch"](b)))}function Pe(){or.EventEmitter.call(this),this.cancelled=!1,this.state="pending";var e=this,t=new fr(function(t,n){e.once("complete",t),e.once("error",n)});e.then=function(e,n){return t.then(e,n)},e["catch"]=function(e){return t["catch"](e)},e["catch"](function(){})}function He(e,t){var n=t.PouchConstructor;return"string"==typeof e?new n(e,t):e}function Ke(e,t,n,r){if("function"==typeof n&&(r=n,n={}),"undefined"==typeof n&&(n={}),n.doc_ids&&!Array.isArray(n.doc_ids))throw A(qr,"`doc_ids` filter parameter is not a list.");n.complete=r,n=c(n),n.continuous=n.continuous||n.live,n.retry="retry"in n?n.retry:!1,n.PouchConstructor=n.PouchConstructor||this;var o=new Pe(n),i=He(e,n),a=He(t,n);return Ue(i,a,n,o),o}function We(e,t,n,r){return"function"==typeof n&&(r=n,n={}),"undefined"==typeof n&&(n={}),n=c(n),n.PouchConstructor=n.PouchConstructor||this,e=fo.toPouch(e,n),t=fo.toPouch(t,n),new Je(e,t,n,r)}function Je(e,t,n,r){function o(e){h.emit("change",{direction:"pull",change:e})}function i(e){h.emit("change",{direction:"push",change:e})}function a(e){h.emit("denied",{direction:"push",doc:e})}function s(e){h.emit("denied",{direction:"pull",doc:e})}function u(){h.pushPaused=!0,h.pullPaused&&h.emit("paused")}function c(){h.pullPaused=!0,h.pushPaused&&h.emit("paused")}function f(){h.pushPaused=!1,h.pullPaused&&h.emit("active",{direction:"push"})}function l(){h.pullPaused=!1,h.pushPaused&&h.emit("active",{direction:"pull"})}function d(e){return function(t,n){var r="change"===t&&(n===o||n===i),d="denied"===t&&(n===s||n===a),p="paused"===t&&(n===c||n===u),v="active"===t&&(n===l||n===f);(r||d||p||v)&&(t in y||(y[t]={}),y[t][e]=!0,2===Object.keys(y[t]).length&&h.removeAllListeners(t))}}var h=this;this.canceled=!1;var p=n.push?$n.extend({},n,n.push):n,v=n.pull?$n.extend({},n,n.pull):n;this.push=lo(e,t,p),this.pull=lo(t,e,v),this.pushPaused=!0,this.pullPaused=!0;var y={};n.live&&(this.push.on("complete",h.pull.cancel.bind(h.pull)),this.pull.on("complete",h.push.cancel.bind(h.push))),this.on("newListener",function(e){"change"===e?(h.pull.on("change",o),h.push.on("change",i)):"denied"===e?(h.pull.on("denied",s),h.push.on("denied",a)):"active"===e?(h.pull.on("active",l),h.push.on("active",f)):"paused"===e&&(h.pull.on("paused",c),h.push.on("paused",u))}),this.on("removeListener",function(e){"change"===e?(h.pull.removeListener("change",o),h.push.removeListener("change",i)):"denied"===e?(h.pull.removeListener("denied",s),h.push.removeListener("denied",a)):"active"===e?(h.pull.removeListener("active",l),h.push.removeListener("active",f)):"paused"===e&&(h.pull.removeListener("paused",c),h.push.removeListener("paused",u))}),this.pull.on("removeListener",d("pull")),this.push.on("removeListener",d("push"));var _=fr.all([this.push,this.pull]).then(function(e){var t={push:e[0],pull:e[1]};return h.emit("complete",t),r&&r(null,t),h.removeAllListeners(),t},function(e){if(h.cancel(),r?r(e):h.emit("error",e),h.removeAllListeners(),r)throw e});this.then=function(e,t){return _.then(e,t)},this["catch"]=function(e){return _["catch"](e)}}function Ve(e,t){return ge(Qr(e),t)}function Ge(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,o=0;r>o;o++)t+=String.fromCharCode(n[o]);return t}function Xe(e,t){if("undefined"==typeof FileReader)return t(Ge((new FileReaderSync).readAsArrayBuffer(e)));var n=new FileReader,r="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";return r?t(n):void t(Ge(n))},r?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}function ze(e){return new fr(function(t){Xe(e,function(e){t($r(e))})})}function Qe(e){for(var t=[],n=0,r=e.length;r>n;n++)t=t.concat(e[n]);return t}function $e(e){var t=e.doc&&e.doc._attachments;t&&Object.keys(t).forEach(function(e){var n=t[e];n.data=Ve(n.data,n.content_type)})}function Ye(e){return/^_design/.test(e)?"_design/"+encodeURIComponent(e.slice(8)):/^_local/.test(e)?"_local/"+encodeURIComponent(e.slice(7)):encodeURIComponent(e)}function Ze(e){return e._attachments&&Object.keys(e._attachments)?fr.all(Object.keys(e._attachments).map(function(t){var n=e._attachments[t];return n.data&&"string"!=typeof n.data?ze(n.data).then(function(e){n.data=e}):void 0})):fr.resolve()}function et(e){var t=_e(e);(t.user||t.password)&&(t.auth={username:t.user,password:t.password});var n=t.path.replace(/(^\/|\/$)/g,"").split("/");return t.db=n.pop(),-1===t.db.indexOf("%")&&(t.db=encodeURIComponent(t.db)),t.path=n.join("/"),t}function tt(e,t){return nt(e,e.db+"/"+t)}function nt(e,t){var n=e.path?"/":"";return e.protocol+"://"+e.host+(e.port?":"+e.port:"")+"/"+e.path+n+t}function rt(e){return"?"+Object.keys(e).map(function(t){return t+"="+encodeURIComponent(e[t])}).join("&")}function ot(e,t){function n(e,t,n){var r=e.ajax||{},o=$n.extend(c(p),r,t);return _o(o.method+" "+o.url),Zr.ajax(o,n)}function r(e,t){return new fr(function(r,o){n(e,t,function(e,t){return e?o(e):void r(t)})})}function o(e,t){return d(e,rr(function(e){a().then(function(){return t.apply(this,e)})["catch"](function(t){var n=e.pop();n(t)})}))}function a(){if(e.skipSetup||e.skip_setup)return fr.resolve();if(m)return m;var t={method:"GET",url:h};return m=r({},t)["catch"](function(e){return e&&e.status&&404===e.status?(Ee(404,"PouchDB is just detecting if the remote exists."),r({},{method:"PUT",url:h})):fr.reject(e)})["catch"](function(e){return e&&e.status&&412===e.status?!0:fr.reject(e)}),m["catch"](function(){m=null}),m}function s(e){return e.split("/").map(encodeURIComponent).join("/")}var u=this,f=et;e.getHost&&(f=e.getHost);var l=f(e.name,e),h=tt(l,"");e=c(e);var p=e.ajax||{};if(u.getUrl=function(){return h},u.getHeaders=function(){return p.headers||{}},e.auth||l.auth){var v=e.auth||l.auth,y=v.username+":"+v.password,_=$r(unescape(encodeURIComponent(y)));p.headers=p.headers||{},p.headers.Authorization="Basic "+_}var m;setTimeout(function(){t(null,u)}),u.type=function(){return"http"},u.id=o("id",function(e){n({},{method:"GET",url:nt(l,"")},function(t,n){var r=n&&n.uuid?n.uuid+l.db:tt(l,"");e(null,r)})}),u.request=o("request",function(e,t){e.url=tt(l,e.url),n({},e,t)}),u.compact=o("compact",function(e,t){"function"==typeof e&&(t=e,e={}),e=c(e),n(e,{url:tt(l,"_compact"),method:"POST"},function(){function n(){u.info(function(r,o){o&&!o.compact_running?t(null,{ok:!0}):setTimeout(n,e.interval||200)})}n()})}),u.bulkGet=d("bulkGet",function(e,t){function r(t){var r={};e.revs&&(r.revs=!0),e.attachments&&(r.attachments=!0),n({},{url:tt(l,"_bulk_get"+rt(r)),method:"POST",body:{docs:e.docs}},t)}function o(){function n(e){return function(n,r){u[e]=r.results,++s===o&&t(null,{results:Qe(u)})}}for(var r=po,o=Math.ceil(e.docs.length/r),s=0,u=new Array(o),c=0;o>c;c++){var f=i(e,["revs","attachments"]);f.ajax=p,f.docs=e.docs.slice(c*r,Math.min(e.docs.length,(c+1)*r)),C(a,f,n(c))}}var a=this,s=nt(l,""),u=vo[s];"boolean"!=typeof u?r(function(e,n){if(e){var r=Math.floor(e.status/100);4===r||5===r?(vo[s]=!1,Ee(e.status,"PouchDB is just detecting if the remote supports the _bulk_get API."),o()):t(e)}else vo[s]=!0,t(null,n)}):u?r(t):o()}),u._info=function(e){a().then(function(){n({},{method:"GET",url:tt(l,"")},function(t,n){return t?e(t):(n.host=tt(l,""),void e(null,n))})})["catch"](e)},u.get=o("get",function(e,t,n){function o(e){var n=e._attachments,o=n&&Object.keys(n);return n&&o.length?fr.all(o.map(function(o){var i=n[o],a=Ye(e._id)+"/"+s(o)+"?rev="+e._rev;return r(t,{method:"GET",url:tt(l,a),binary:!0}).then(function(e){return t.binary?e:ze(e)}).then(function(e){delete i.stub,delete i.length,i.data=e})})):void 0}function i(e){return Array.isArray(e)?fr.all(e.map(function(e){return e.ok?o(e.ok):void 0})):o(e)}"function"==typeof t&&(n=t,t={}),t=c(t);var a={};t.revs&&(a.revs=!0),t.revs_info&&(a.revs_info=!0),t.open_revs&&("all"!==t.open_revs&&(t.open_revs=JSON.stringify(t.open_revs)),a.open_revs=t.open_revs),t.rev&&(a.rev=t.rev),t.conflicts&&(a.conflicts=t.conflicts),e=Ye(e);var u={method:"GET",url:tt(l,e+rt(a))};r(t,u).then(function(e){return fr.resolve().then(function(){return t.attachments?i(e):void 0}).then(function(){n(null,e)})})["catch"](n)}),u.remove=o("remove",function(e,t,r,o){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof r&&(o=r,r={})):(i=e,"function"==typeof t?(o=t,r={}):(o=r,r=t));var a=i._rev||r.rev;n(r,{method:"DELETE",url:tt(l,Ye(i._id))+"?rev="+a},o)}),u.getAttachment=o("getAttachment",function(e,t,r,o){"function"==typeof r&&(o=r,r={});var i=r.rev?"?rev="+r.rev:"",a=tt(l,Ye(e))+"/"+s(t)+i;n(r,{method:"GET",url:a,binary:!0},o)}),u.removeAttachment=o("removeAttachment",function(e,t,r,o){var i=tt(l,Ye(e)+"/"+s(t))+"?rev="+r;n({},{method:"DELETE",url:i},o)}),u.putAttachment=o("putAttachment",function(e,t,r,o,i,a){"function"==typeof i&&(a=i,i=o,o=r,r=null);var u=Ye(e)+"/"+s(t),c=tt(l,u);if(r&&(c+="?rev="+r),"string"==typeof o){var f;try{f=Qr(o)}catch(d){return a(A(wr,"Attachment is not a valid base64 string"))}o=f?ge(f,i):""}var h={headers:{"Content-Type":i},method:"PUT",url:c,processData:!1,body:o,timeout:p.timeout||6e4};n({},h,a)}),u._bulkDocs=function(e,t,r){e.new_edits=t.new_edits,a().then(function(){return fr.all(e.docs.map(Ze))}).then(function(){n(t,{method:"POST",url:tt(l,"_bulk_docs"),body:e},function(e,t){return e?r(e):(t.forEach(function(e){e.ok=!0}),void r(null,t))})})["catch"](r)},u.allDocs=o("allDocs",function(e,t){"function"==typeof e&&(t=e,e={}),e=c(e);var n,o={},i="GET";e.conflicts&&(o.conflicts=!0),e.descending&&(o.descending=!0),e.include_docs&&(o.include_docs=!0),e.attachments&&(o.attachments=!0),e.key&&(o.key=JSON.stringify(e.key)),e.start_key&&(e.startkey=e.start_key),e.startkey&&(o.startkey=JSON.stringify(e.startkey)),e.end_key&&(e.endkey=e.end_key),e.endkey&&(o.endkey=JSON.stringify(e.endkey)),"undefined"!=typeof e.inclusive_end&&(o.inclusive_end=!!e.inclusive_end),
+"undefined"!=typeof e.limit&&(o.limit=e.limit),"undefined"!=typeof e.skip&&(o.skip=e.skip);var a=rt(o);if("undefined"!=typeof e.keys){var s="keys="+encodeURIComponent(JSON.stringify(e.keys));s.length+a.length+1<=yo?a+="&"+s:(i="POST",n={keys:e.keys})}r(e,{method:i,url:tt(l,"_all_docs"+a),body:n}).then(function(n){e.include_docs&&e.attachments&&e.binary&&n.rows.forEach($e),t(null,n)})["catch"](t)}),u._changes=function(e){var t="batch_size"in e?e.batch_size:ho;e=c(e),e.timeout="timeout"in e?e.timeout:"timeout"in p?p.timeout:3e4;var r,o=e.timeout?{timeout:e.timeout-5e3}:{},i="undefined"!=typeof e.limit?e.limit:!1;r="return_docs"in e?e.return_docs:"returnDocs"in e?e.returnDocs:!0;var s=i;if(e.style&&(o.style=e.style),(e.include_docs||e.filter&&"function"==typeof e.filter)&&(o.include_docs=!0),e.attachments&&(o.attachments=!0),e.continuous&&(o.feed="longpoll"),e.conflicts&&(o.conflicts=!0),e.descending&&(o.descending=!0),"heartbeat"in e?e.heartbeat&&(o.heartbeat=e.heartbeat):o.heartbeat=1e4,e.filter&&"string"==typeof e.filter&&(o.filter=e.filter,"_view"===e.filter&&e.view&&"string"==typeof e.view&&(o.view=e.view)),e.query_params&&"object"==typeof e.query_params)for(var u in e.query_params)e.query_params.hasOwnProperty(u)&&(o[u]=e.query_params[u]);var f,d="GET";if(e.doc_ids){o.filter="_doc_ids";var h=JSON.stringify(e.doc_ids);h.length<yo?o.doc_ids=h:(d="POST",f={doc_ids:e.doc_ids})}var v,y,_=function(r,u){if(!e.aborted){o.since=r,"object"==typeof o.since&&(o.since=JSON.stringify(o.since)),e.descending?i&&(o.limit=s):o.limit=!i||s>t?t:s;var c={method:d,url:tt(l,"_changes"+rt(o)),timeout:e.timeout,body:f};y=r,e.aborted||a().then(function(){v=n(e,c,u)})["catch"](u)}},m={results:[]},g=function(n,o){if(!e.aborted){var a=0;if(o&&o.results){a=o.results.length,m.last_seq=o.last_seq;var u={};u.query=e.query_params,o.results=o.results.filter(function(t){s--;var n=we(e)(t);return n&&(e.include_docs&&e.attachments&&e.binary&&$e(t),r&&m.results.push(t),e.onChange(t)),n})}else if(n)return e.aborted=!0,void e.complete(n);o&&o.last_seq&&(y=o.last_seq);var c=i&&0>=s||o&&t>a||e.descending;(!e.continuous||i&&0>=s)&&c?e.complete(null,m):setTimeout(function(){_(y,g)},0)}};return _(e.since||0,g),{cancel:function(){e.aborted=!0,v&&v.abort()}}},u.revsDiff=o("revsDiff",function(e,t,r){"function"==typeof t&&(r=t,t={}),n(t,{method:"POST",url:tt(l,"_revs_diff"),body:e},r)}),u._close=function(e){e()},u._destroy=function(t,r){n(t,{url:tt(l,""),method:"DELETE"},function(t,n){return t&&t.status&&404!==t.status?r(t):(u.emit("destroyed"),u.constructor.emit("destroyed",e.name),void r(null,n))})}}function it(){this.promise=new fr(function(e){e()})}function at(e){return ur.hash(e)}function st(e){var t=e.db,n=e.viewName,r=e.map,o=e.reduce,i=e.temporary,a=r.toString()+(o&&o.toString())+"undefined";if(!i&&t._cachedViews){var s=t._cachedViews[a];if(s)return fr.resolve(s)}return t.info().then(function(e){function s(e){e.views=e.views||{};var t=n;-1===t.indexOf("/")&&(t=n+"/"+n);var r=e.views[t]=e.views[t]||{};if(!r[u])return r[u]=!0,e}var u=e.db_name+"-mrview-"+(i?"temp":at(a));return h(t,"_local/mrviews",s).then(function(){return t.registerDependentDatabase(u).then(function(e){var n=e.db;n.auto_compaction=!0;var s={name:u,db:n,sourceDB:t,adapter:t.adapter,mapFun:r,reduceFun:o};return s.db.get("_local/lastSeq")["catch"](function(e){if(404!==e.status)throw e}).then(function(e){return s.seq=e?e.seq:0,i||(t._cachedViews=t._cachedViews||{},t._cachedViews[a]=s,s.db.once("destroyed",function(){delete t._cachedViews[a]})),s})})})})}function ut(e,t,n,r,o,i){return ir("return ("+e.replace(/;\s*$/,"")+");",{emit:t,sum:n,log:r,isArray:o,toJSON:i})}function ct(e){return-1===e.indexOf("/")?[e,e]:e.split("/")}function ft(e){return 1===e.length&&/^1-/.test(e[0].rev)}function lt(e,t){try{e.emit("error",t)}catch(n){console.error("The user's map/reduce function threw an uncaught error.\nYou can debug this error by doing:\nmyDatabase.on('error', function (err) { debugger; });\nPlease double-check your map/reduce function."),console.error(t)}}function dt(e,t,n){try{return{output:t.apply(null,n)}}catch(r){return lt(e,r),{error:r}}}function ht(e,t){var n=qo(e.key,t.key);return 0!==n?n:qo(e.value,t.value)}function pt(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):n>0?e.slice(n):e}function vt(e){var t=e.value,n=t&&"object"==typeof t&&t._id||e.id;return n}function yt(e){e.rows.forEach(function(e){var t=e.doc&&e.doc._attachments;t&&Object.keys(t).forEach(function(e){var n=t[e];t[e].data=Ve(n.data,n.content_type)})})}function _t(e){return function(t){return e.include_docs&&e.attachments&&e.binary&&yt(t),t}}function mt(e){var t="builtin "+e+" function requires map values to be numbers or number arrays";return new Pt(t)}function gt(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];if("number"!=typeof o){if(!Array.isArray(o))throw mt("_sum");t="number"==typeof t?[t]:t;for(var i=0,a=o.length;a>i;i++){var s=o[i];if("number"!=typeof s)throw mt("_sum");"undefined"==typeof t[i]?t.push(s):t[i]+=s}}else"number"==typeof t?t+=o:t[0]+=o}return t}function bt(e,t,n,r){var o=t[e];"undefined"!=typeof o&&(r&&(o=encodeURIComponent(JSON.stringify(o))),n.push(e+"="+o))}function wt(e){if("undefined"!=typeof e){var t=Number(e);return isNaN(t)||t!==parseInt(e,10)?e:t}}function Et(e){return e.group_level=wt(e.group_level),e.limit=wt(e.limit),e.skip=wt(e.skip),e}function St(e){if(e){if("number"!=typeof e)return new Ut('Invalid value for integer: "'+e+'"');if(0>e)return new Ut('Invalid value for positive integer: "'+e+'"')}}function kt(e,t){var n=e.descending?"endkey":"startkey",r=e.descending?"startkey":"endkey";if("undefined"!=typeof e[n]&&"undefined"!=typeof e[r]&&qo(e[n],e[r])>0)throw new Ut("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(t.reduce&&e.reduce!==!1){if(e.include_docs)throw new Ut("{include_docs:true} is invalid for reduce");if(e.keys&&e.keys.length>1&&!e.group&&!e.group_level)throw new Ut("Multi-key fetches for reduce views must use {group: true}")}["group_level","limit","skip"].forEach(function(t){var n=St(e[t]);if(n)throw n})}function qt(e,t,n){var r,o=[],i="GET";if(bt("reduce",n,o),bt("include_docs",n,o),bt("attachments",n,o),bt("limit",n,o),bt("descending",n,o),bt("group",n,o),bt("group_level",n,o),bt("skip",n,o),bt("stale",n,o),bt("conflicts",n,o),bt("startkey",n,o,!0),bt("start_key",n,o,!0),bt("endkey",n,o,!0),bt("end_key",n,o,!0),bt("inclusive_end",n,o),bt("key",n,o,!0),o=o.join("&"),o=""===o?"":"?"+o,"undefined"!=typeof n.keys){var a=2e3,s="keys="+encodeURIComponent(JSON.stringify(n.keys));s.length+o.length+1<=a?o+=("?"===o[0]?"&":"?")+s:(i="POST","string"==typeof t?r={keys:n.keys}:t.keys=n.keys)}if("string"==typeof t){var u=ct(t);return e.request({method:i,url:"_design/"+u[0]+"/_view/"+u[1]+o,body:r}).then(_t(n))}return r=r||{},Object.keys(t).forEach(function(e){Array.isArray(t[e])?r[e]=t[e]:r[e]=t[e].toString()}),e.request({method:"POST",url:"_temp_view"+o,body:r}).then(_t(n))}function xt(e,t,n){return new fr(function(r,o){e._query(t,n,function(e,t){return e?o(e):void r(t)})})}function At(e){return new fr(function(t,n){e._viewCleanup(function(e,r){return e?n(e):void t(r)})})}function Tt(e){return function(t){if(404===t.status)return e;throw t}}function Ot(e,t,n){function r(){return ft(f)?fr.resolve(s):t.db.get(a)["catch"](Tt(s))}function o(e){return e.keys.length?t.db.allDocs({keys:e.keys,include_docs:!0}):fr.resolve({rows:[]})}function i(e,t){for(var n=[],r={},o=0,i=t.rows.length;i>o;o++){var a=t.rows[o],s=a.doc;if(s&&(n.push(s),r[s._id]=!0,s._deleted=!c[s._id],!s._deleted)){var u=c[s._id];"value"in u&&(s.value=u.value)}}var f=Object.keys(c);return f.forEach(function(e){if(!r[e]){var t={_id:e},o=c[e];"value"in o&&(t.value=o.value),n.push(t)}}),e.keys=Co(f.concat(e.keys)),n.push(e),n}var a="_local/doc_"+e,s={_id:a,keys:[]},u=n[e],c=u.indexableKeysToKeyValues,f=u.changes;return r().then(function(e){return o(e).then(function(t){return i(e,t)})})}function jt(e,t,n){var r="_local/lastSeq";return e.db.get(r)["catch"](Tt({_id:r,seq:0})).then(function(r){var o=Object.keys(t);return fr.all(o.map(function(n){return Ot(n,e,t)})).then(function(t){var o=Qe(t);return r.seq=n,o.push(r),e.db.bulkDocs({docs:o})})})}function Ct(e){var t="string"==typeof e?e:e.name,n=Ro[t];return n||(n=Ro[t]=new it),n}function It(e){return jo(Ct(e),function(){return Lt(e)})()}function Lt(e){function t(e,t){var n={id:o._id,key:Ao(e)};"undefined"!=typeof t&&null!==t&&(n.value=Ao(t)),r.push(n)}function n(t,n){return function(){return jt(e,t,n)}}var r,o,i;if("function"==typeof e.mapFun&&2===e.mapFun.length){var a=e.mapFun;i=function(e){return a(e,t)}}else i=ut(e.mapFun.toString(),t,gt,mo,Array.isArray,JSON.parse);var s=e.seq||0,u=new it;return new fr(function(t,a){function c(){u.finish().then(function(){e.seq=s,t()})}function f(){function t(e){a(e)}e.sourceDB.changes({conflicts:!0,include_docs:!0,style:"all_docs",since:s,limit:No}).on("complete",function(t){var a=t.results;if(!a.length)return c();for(var l={},d=0,h=a.length;h>d;d++){var p=a[d];if("_"!==p.doc._id[0]){r=[],o=p.doc,o._deleted||dt(e.sourceDB,i,[o]),r.sort(ht);for(var v,y={},_=0,m=r.length;m>_;_++){var g=r[_],b=[g.key,g.id];0===qo(g.key,v)&&b.push(_);var w=xo(b);y[w]=g,v=g.key}l[p.doc._id]={indexableKeysToKeyValues:y,changes:p.changes}}s=p.seq}return u.add(n(l,s)),a.length<No?c():f()}).on("error",t)}f()})}function Rt(e,t,n){0===n.group_level&&delete n.group_level;var r,o=n.group||n.group_level;r=Bo[e.reduceFun]?Bo[e.reduceFun]:ut(e.reduceFun.toString(),null,gt,mo,Array.isArray,JSON.parse);var i=[],a=isNaN(n.group_level)?Number.POSITIVE_INFINITY:n.group_level;t.forEach(function(e){var t=i[i.length-1],n=o?e.key:null;return o&&Array.isArray(n)&&(n=n.slice(0,a)),t&&0===qo(t.groupKey,n)?(t.keys.push([e.key,e.id]),void t.values.push(e.value)):void i.push({keys:[[e.key,e.id]],values:[e.value],groupKey:n})}),t=[];for(var s=0,u=i.length;u>s;s++){var c=i[s],f=dt(e.sourceDB,r,[c.keys,c.values,!1]);if(f.error&&f.error instanceof Pt)throw f.error;t.push({value:f.error?null:f.output,key:c.groupKey})}return{rows:pt(t,n.limit,n.skip)}}function Dt(e,t){return jo(Ct(e),function(){return Nt(e,t)})()}function Nt(e,t){function n(t){return t.include_docs=!0,e.db.allDocs(t).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(n>t||t>n))return e.doc.value}var r=To(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function r(n){var r;if(r=i?Rt(e,n,t):{total_rows:o,offset:a,rows:n},t.include_docs){var s=Co(n.map(vt));return e.sourceDB.allDocs({keys:s,include_docs:!0,conflicts:t.conflicts,attachments:t.attachments,binary:t.binary}).then(function(e){var t={};return e.rows.forEach(function(e){e.doc&&(t["$"+e.id]=e.doc)}),n.forEach(function(e){var n=vt(e),r=t["$"+n];r&&(e.doc=r)}),r})}return r}var o,i=e.reduceFun&&t.reduce!==!1,a=t.skip||0;if("undefined"==typeof t.keys||t.keys.length||(t.limit=0,delete t.keys),"undefined"!=typeof t.keys){var s=t.keys,u=s.map(function(e){var t={startkey:xo([e]),endkey:xo([e,{}])};return n(t)});return fr.all(u).then(Qe).then(r)}var c={descending:t.descending};if(t.start_key&&(t.startkey=t.start_key),t.end_key&&(t.endkey=t.end_key),"undefined"!=typeof t.startkey&&(c.startkey=xo(t.descending?[t.startkey,{}]:[t.startkey])),"undefined"!=typeof t.endkey){var f=t.inclusive_end!==!1;t.descending&&(f=!f),c.endkey=xo(f?[t.endkey,{}]:[t.endkey])}if("undefined"!=typeof t.key){var l=xo([t.key]),d=xo([t.key,{}]);c.descending?(c.endkey=l,c.startkey=d):(c.startkey=l,c.endkey=d)}return i||("number"==typeof t.limit&&(c.limit=t.limit),c.skip=a),n(c).then(r)}function Bt(e){return e.request({method:"POST",url:"_view_cleanup"})}function Mt(e){return e.get("_local/mrviews").then(function(t){var n={};Object.keys(t.views).forEach(function(e){var t=ct(e),r="_design/"+t[0],o=t[1];n[r]=n[r]||{},n[r][o]=!0});var r={keys:Object.keys(n),include_docs:!0};return e.allDocs(r).then(function(r){var o={};r.rows.forEach(function(e){var r=e.key.substring(8);Object.keys(n[e.key]).forEach(function(n){var i=r+"/"+n;t.views[i]||(i=n);var a=Object.keys(t.views[i]),s=e.doc&&e.doc.views&&e.doc.views[n];a.forEach(function(e){o[e]=o[e]||s})})});var i=Object.keys(o).filter(function(e){return!o[e]}),a=i.map(function(t){return jo(Ct(t),function(){return new e.constructor(t,e.__opts).destroy()})()});return fr.all(a).then(function(){return{ok:!0}})})},Tt({ok:!0}))}function Ft(e,t,r){if("http"===e.type())return qt(e,t,r);if("function"==typeof e._query)return xt(e,t,r);if("string"!=typeof t){kt(r,t);var o={db:e,viewName:"temp_view/temp_view",map:t.map,reduce:t.reduce,temporary:!0};return Do.add(function(){return st(o).then(function(e){function t(){return e.db.destroy()}return Io(It(e).then(function(){return Dt(e,r)}),t)})}),Do.finish()}var i=t,a=ct(i),s=a[0],u=a[1];return e.getView(s,u).then(function(t){kt(r,t);var o={db:e,viewName:i,map:t.map,reduce:t.reduce};return st(o).then(function(e){return"ok"===r.stale||"update_after"===r.stale?("update_after"===r.stale&&n.nextTick(function(){It(e)}),Dt(e,r)):It(e).then(function(){return Dt(e,r)})})})}function Ut(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,Ut)}catch(t){}}function Pt(e){this.status=500,this.name="invalid_value",this.message=e,this.error=!0;try{Error.captureStackTrace(this,Pt)}catch(t){}}function Ht(e){return $r(Ge(e))}function Kt(e,t,n){function r(e){try{return Qr(e)}catch(t){var n=A(wr,"Attachment is not a valid base64 string");return{error:n}}}function o(e,n){if(e.stub)return n();if("string"==typeof e.data){var o=r(e.data);if(o.error)return n(o.error);e.length=o.length,"blob"===t?e.data=ge(o,e.content_type):"base64"===t?e.data=$r(o):e.data=o,co(o).then(function(t){e.digest="md5-"+t,n()})}else ue(e.data,function(r){"binary"===t?e.data=Ge(r):"base64"===t&&(e.data=Ht(r)),co(r).then(function(t){e.digest="md5-"+t,e.length=r.byteLength,n()})})}function i(){s++,e.length===s&&(a?n(a):n())}if(!e.length)return n();var a,s=0;e.forEach(function(e){function t(e){a=e,r++,r===n.length&&i()}var n=e.data&&e.data._attachments?Object.keys(e.data._attachments):[],r=0;if(!n.length)return i();for(var s in e.data._attachments)e.data._attachments.hasOwnProperty(s)&&o(e.data._attachments[s],t)})}function Wt(e,t){return e.pos-t.pos}function Jt(e,t,n){for(var r,o=0,i=e.length;i>o;)r=o+i>>>1,n(e[r],t)<0?o=r+1:i=r;return o}function Vt(e,t,n){var r=Jt(e,t,n);e.splice(r,0,t)}function Gt(e,t){for(var n,r,o=t,i=e.length;i>o;o++){var a=e[o],s=[a.id,a.opts,[]];r?(r[2].push(s),r=s):n=r=s}return n}function Xt(e,t){return e[0]<t[0]?-1:1}function zt(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var o=n.pop(),i=o.tree1,a=o.tree2;(i[1].status||a[1].status)&&(i[1].status="available"===i[1].status||"available"===a[1].status?"available":"missing");for(var s=0;s<a[2].length;s++)if(i[2][0]){for(var u=!1,c=0;c<i[2].length;c++)i[2][c][0]===a[2][s][0]&&(n.push({tree1:i[2][c],tree2:a[2][s]}),u=!0);u||(r="new_branch",Vt(i[2],a[2][s],Xt))}else r="new_leaf",i[2][0]=a[2][s]}return{conflicts:r,tree:e}}function Qt(e,t,n){var r,o=[],i=!1,a=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var s=0,u=e.length;u>s;s++){var c=e[s];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=zt(c.ids,t.ids),o.push({pos:c.pos,ids:r.tree}),i=i||r.conflicts,a=!0;else if(n!==!0){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,d=l.pos-f.pos,h=[],p=[];for(p.push({ids:f.ids,diff:d,parent:null,parentIdx:null});p.length>0;){var v=p.pop();if(0!==v.diff)for(var y=v.ids[2],_=0,m=y.length;m>_;_++)p.push({ids:y[_],diff:v.diff-1,parent:v.ids,parentIdx:_});else v.ids[0]===l.ids[0]&&h.push(v)}var g=h[0];g?(r=zt(g.ids,l.ids),g.parent[2][g.parentIdx]=r.tree,o.push({pos:f.pos,ids:f.ids}),i=i||r.conflicts,a=!0):o.push(c)}else o.push(c)}return a||o.push(t),o.sort(Wt),{tree:o,conflicts:i||"internal_node"}}function $t(e,t){for(var n,r=L(e),o={},i=0,a=r.length;a>i;i++){for(var s=r[i],u=s.ids,c=Math.max(0,u.length-t),f={pos:s.pos+c,ids:Gt(u,c)},l=0;c>l;l++){var d=s.pos+l+"-"+u[l].id;o[d]=!0}n=n?Qt(n,f,!0).tree:[f]}return E(n,function(e,t,n){delete o[t+"-"+n]}),{tree:n,revs:Object.keys(o)}}function Yt(e,t,n){var r=Qt(e,t),o=$t(r.tree,n);return{tree:o.tree,stemmedRevs:o.revs,conflicts:r.conflicts}}function Zt(e,t){for(var n,r=e.slice(),o=t.split("-"),i=parseInt(o[0],10),a=o[1];n=r.pop();){if(n.pos===i&&n.ids[0]===a)return!0;for(var s=n.ids[2],u=0,c=s.length;c>u;u++)r.push({pos:n.pos+1,ids:s[u]})}return!1}function en(e,t,n,r,o,i,a,s){if(Zt(t.rev_tree,n.metadata.rev))return r[o]=n,i();var u=t.winningRev||v(t),c="deleted"in t?t.deleted:_(t,u),f="deleted"in n.metadata?n.metadata.deleted:_(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&s&&l){var d=n.data;d._rev=u,d._id=n.metadata.id,n=U(d,s)}var h=Yt(t.rev_tree,n.metadata.rev_tree[0],e),p=s&&(c&&f||!c&&"new_leaf"!==h.conflicts||c&&!f&&"new_branch"===h.conflicts);if(p){var y=A(vr);return r[o]=y,i()}var m=n.metadata.rev;n.metadata.rev_tree=h.tree,n.stemmedRevs=h.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var g,b=v(n.metadata),w=_(n.metadata,b),E=c===w?0:w>c?-1:1;g=m===b?w:_(n.metadata,m),a(n,b,w,g,!0,E,o,i)}function tn(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}function nn(e,t,n,r,o,i,a,s,u){function c(e,t,n){var r=v(e.metadata),o=_(e.metadata,r);if("was_delete"in s&&o)return i[t]=A(pr,"deleted"),n();var u=l&&tn(e);if(u){var c=A(vr);return i[t]=c,n()}var f=o?0:1;a(e,r,o,o,!1,f,t,n)}function f(){++h===p&&u&&u()}e=e||1e3;var l=s.new_edits,d=new nr.Map,h=0,p=t.length;t.forEach(function(e,t){if(e._id&&I(e._id)){var r=e._deleted?"_removeLocal":"_putLocal";return void n[r](e,{ctx:o},function(e,n){i[t]=e||n,f()})}var a=e.metadata.id;d.has(a)?(p--,d.get(a).push([e,t])):d.set(a,[[e,t]])}),d.forEach(function(t,n){function o(){++u<t.length?s():f()}function s(){var s=t[u],f=s[0],d=s[1];if(r.has(n))en(e,r.get(n),f,i,d,o,a,l);else{var h=Yt([],f.metadata.rev_tree[0],e);f.metadata.rev_tree=h.tree,f.stemmedRevs=h.stemmedRevs||[],c(f,d,o)}}var u=0;s()})}function rn(e){var t=[];return E(e.rev_tree,function(e,n,r,o,i){"available"!==i.status||e||(t.push(n+"-"+r),i.status="missing")}),t}function on(e){try{return JSON.parse(e)}catch(t){return cr.parse(e)}}function an(e){return e.length<5e4?JSON.parse(e):on(e)}function sn(e){try{return JSON.stringify(e)}catch(t){return cr.stringify(e)}}function un(e,t,n,r){try{e.apply(t,n)}catch(o){r.emit("error",o)}}function cn(e){if(!zo.running&&zo.queue.length){zo.running=!0;var t=zo.queue.shift();t.action(function(r,o){un(t.callback,this,[r,o],e),zo.running=!1,n.nextTick(function(){cn(e)})})}}function fn(e){return function(t){var n="unknown_error";t.target&&t.target.error&&(n=t.target.error.name||t.target.error.message),e(A(Tr,n,t.type))}}function ln(e,t,n){return{data:sn(e),winningRev:t,deletedOrLocal:n?"1":"0",seq:e.seq,id:e.id}}function dn(e){if(!e)return null;var t=an(e.data);return t.winningRev=e.winningRev,t.deleted="1"===e.deletedOrLocal,t.seq=e.seq,t}function hn(e){if(!e)return e;var t=e._doc_id_rev.lastIndexOf(":");return e._id=e._doc_id_rev.substring(0,t-1),e._rev=e._doc_id_rev.substring(t+1),delete e._doc_id_rev,e}function pn(e,t,n,r){n?r(e?"string"!=typeof e?e:Ve(e,t):se([""],{type:t})):e?"string"!=typeof e?Xe(e,function(e){r($r(e))}):r(e):r("")}function vn(e,t,n,r){function o(){++s===a.length&&r&&r()}function i(e,t){var r=e._attachments[t],i=r.digest,a=n.objectStore(Wo).get(i);a.onsuccess=function(e){r.body=e.target.result.body,o()}}var a=Object.keys(e._attachments||{});if(!a.length)return r&&r();var s=0;a.forEach(function(n){t.attachments&&t.include_docs?i(e,n):(e._attachments[n].stub=!0,o())})}function yn(e,t){return fr.all(e.map(function(e){if(e.doc&&e.doc._attachments){var n=Object.keys(e.doc._attachments);return fr.all(n.map(function(n){var r=e.doc._attachments[n];if("body"in r){var o=r.body,a=r.content_type;return new fr(function(s){pn(o,a,t,function(t){e.doc._attachments[n]=$n.extend(i(r,["digest","content_type"]),{data:t}),s()})})}}))}}))}function _n(e,t,n){function r(){c--,c||o()}function o(){i.length&&i.forEach(function(e){var t=u.index("digestSeq").count(IDBKeyRange.bound(e+"::",e+"::ï¿¿",!1,!1));t.onsuccess=function(t){var n=t.target.result;n||s["delete"](e)}})}var i=[],a=n.objectStore(Ko),s=n.objectStore(Wo),u=n.objectStore(Jo),c=e.length;e.forEach(function(e){var n=a.index("_doc_id_rev"),o=t+"::"+e;n.getKey(o).onsuccess=function(e){var t=e.target.result;if("number"!=typeof t)return r();a["delete"](t);var n=u.index("seq").openCursor(IDBKeyRange.only(t));n.onsuccess=function(e){var t=e.target.result;if(t){var n=t.value.digestSeq.split("::")[0];i.push(n),u["delete"](t.primaryKey),t["continue"]()}else r()}}})}function mn(e,t,n){try{return{txn:e.transaction(t,n)}}catch(r){return{error:r}}}function gn(e,t,n,r,o,i,a){function s(){var e=[Ho,Ko,Wo,Go,Jo],t=mn(o,e,"readwrite");return t.error?a(t.error):(g=t.txn,g.onabort=fn(a),g.ontimeout=fn(a),g.oncomplete=f,b=g.objectStore(Ho),w=g.objectStore(Ko),E=g.objectStore(Wo),S=g.objectStore(Jo),void d(function(e){return e?(R=!0,a(e)):void c()}))}function u(){nn(e.revs_limit,q,r,L,g,C,h,n)}function c(){function e(){++n===q.length&&u()}function t(t){var n=dn(t.target.result);n&&L.set(n.id,n),e()}if(q.length)for(var n=0,r=0,o=q.length;o>r;r++){var i=q[r];if(i._id&&I(i._id))e();else{var a=b.get(i.metadata.id);a.onsuccess=t}}}function f(){R||(i.notify(r._meta.name),r._meta.docCount+=x,a(null,C))}function l(e,t){var n=E.get(e);n.onsuccess=function(n){if(n.target.result)t();else{var r=A(Rr,"unknown stub attachment with digest "+e);r.status=412,t(r)}}}function d(e){function t(){++o===n.length&&e(r)}var n=[];if(q.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){l(e,function(e){e&&!r&&(r=e),t()})})}function h(e,t,n,r,o,i,a,s){x+=i,e.metadata.winningRev=t,e.metadata.deleted=n;var u=e.data;u._id=e.metadata.id,u._rev=e.metadata.rev,r&&(u._deleted=!0);var c=u._attachments&&Object.keys(u._attachments).length;return c?y(e,t,n,o,a,s):void v(e,t,n,o,a,s)}function p(e){var t=rn(e.metadata);_n(t,e.metadata.id,g)}function v(e,t,n,o,i,a){function s(i){o&&r.auto_compaction?p(e):e.stemmedRevs.length&&_n(e.stemmedRevs,e.metadata.id,g),l.seq=i.target.result,delete l.rev;var a=ln(l,t,n),s=b.put(a);s.onsuccess=c}function u(e){e.preventDefault(),e.stopPropagation();var t=w.index("_doc_id_rev"),n=t.getKey(f._doc_id_rev);n.onsuccess=function(e){var t=w.put(f,e.target.result);t.onsuccess=s}}function c(){C[i]={ok:!0,id:l.id,rev:t},L.set(e.metadata.id,e.metadata),_(e,l.seq,a)}var f=e.data,l=e.metadata;f._doc_id_rev=l.id+"::"+l.rev,delete f._id,delete f._rev;var d=w.put(f);d.onsuccess=s,d.onerror=u}function y(e,t,n,r,o,i){function a(){c===f.length&&v(e,t,n,r,o,i)}function s(){c++,a()}var u=e.data,c=0,f=Object.keys(u._attachments);f.forEach(function(n){var r=e.data._attachments[n];if(r.stub)c++,a();else{var o=r.data;delete r.data,r.revpos=parseInt(t,10);var i=r.digest;m(i,o,s)}})}function _(e,t,n){function r(){++i===a.length&&n()}function o(n){var o=e.data._attachments[n].digest,i=S.put({seq:t,digestSeq:o+"::"+t});i.onsuccess=r,i.onerror=function(e){e.preventDefault(),e.stopPropagation(),r()}}var i=0,a=Object.keys(e.data._attachments||{});if(!a.length)return n();for(var s=0;s<a.length;s++)o(a[s])}function m(e,t,n){var r=E.count(e);r.onsuccess=function(r){var o=r.target.result;if(o)return n();var i={digest:e,body:t},a=E.put(i);a.onsuccess=n}}for(var g,b,w,E,S,k,q=t.docs,x=0,T=0,O=q.length;O>T;T++){var j=q[T];j._id&&I(j._id)||(j=q[T]=U(j,n.new_edits),j.error&&!k&&(k=j))}if(k)return a(k);var C=new Array(q.length),L=new nr.Map,R=!1,D=r._meta.blobSupport?"blob":"base64";Kt(q,D,function(e){return e?a(e):void s()})}function bn(e,t,n,r,o){try{if(e&&t)return o?IDBKeyRange.bound(t,e,!n,!1):IDBKeyRange.bound(e,t,!1,!n);if(e)return o?IDBKeyRange.upperBound(e):IDBKeyRange.lowerBound(e);if(t)return o?IDBKeyRange.lowerBound(t,!n):IDBKeyRange.upperBound(t,!n);if(r)return IDBKeyRange.only(r)}catch(i){return{error:i}}return null}function wn(e,t,n,r){return"DataError"===n.name&&0===n.code?r(null,{total_rows:e._meta.docCount,offset:t.skip,rows:[]}):void r(A(Tr,n.name,n.message))}function En(e,t,n,r){function o(e,r){function o(t,n,r){var o=t.id+"::"+r;S.get(o).onsuccess=function(r){n.doc=hn(r.target.result),e.conflicts&&(n.doc._conflicts=q(t)),vn(n.doc,e,g)}}function i(t,n,r){var i={id:r.id,key:r.id,value:{rev:n}},a=r.deleted;if("ok"===e.deleted)k.push(i),a?(i.value.deleted=!0,i.doc=null):e.include_docs&&o(r,i,n);else if(!a&&d--<=0&&(k.push(i),e.include_docs&&o(r,i,n),0===--h))return;t["continue"]()}function a(e){x=t._meta.docCount;var n=e.target.result;if(n){var r=dn(n.value),o=r.winningRev;i(n,o,r)}}function s(){r(null,{total_rows:x,offset:e.skip,rows:k})}function u(){e.attachments?yn(k,e.binary).then(s):s()}var c="startkey"in e?e.startkey:!1,f="endkey"in e?e.endkey:!1,l="key"in e?e.key:!1,d=e.skip||0,h="number"==typeof e.limit?e.limit:-1,p=e.inclusive_end!==!1,v="descending"in e&&e.descending?"prev":null,y=bn(c,f,p,l,v);if(y&&y.error)return wn(t,e,y.error,r);var _=[Ho,Ko];e.attachments&&_.push(Wo);var m=mn(n,_,"readonly");if(m.error)return r(m.error);var g=m.txn,b=g.objectStore(Ho),w=g.objectStore(Ko),E=v?b.openCursor(y,v):b.openCursor(y),S=w.index("_doc_id_rev"),k=[],x=0;g.oncomplete=u,E.onsuccess=a}function i(e,n){return 0===e.limit?n(null,{total_rows:t._meta.docCount,offset:e.skip,rows:[]}):void o(e,n)}i(e,r)}function Sn(e){return new fr(function(t){var n=se([""]);e.objectStore(Xo).put(n,"key"),e.onabort=function(e){e.preventDefault(),e.stopPropagation(),t(!1)},e.oncomplete=function(){var e=navigator.userAgent.match(/Chrome\/(\d+)/),n=navigator.userAgent.match(/Edge\//);t(n||!e||parseInt(e[1],10)>=43)}})["catch"](function(){return!1})}function kn(e){oe()?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):ie()&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}function qn(){or.EventEmitter.call(this),this._listeners={},kn(this)}function xn(e,t){var n=this;zo.queue.push({action:function(t){An(n,e,t)},callback:t}),cn(n.constructor)}function An(e,t,r){function o(e){var t=e.createObjectStore(Ho,{keyPath:"id"});e.createObjectStore(Ko,{autoIncrement:!0}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0}),e.createObjectStore(Wo,{keyPath:"digest"}),e.createObjectStore(Vo,{keyPath:"id",autoIncrement:!1}),e.createObjectStore(Xo),t.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),e.createObjectStore(Go,{keyPath:"_id"});var n=e.createObjectStore(Jo,{autoIncrement:!0});n.createIndex("seq","seq"),n.createIndex("digestSeq","digestSeq",{unique:!0})}function i(e,t){var n=e.objectStore(Ho);n.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),n.openCursor().onsuccess=function(e){var r=e.target.result;if(r){var o=r.value,i=_(o);o.deletedOrLocal=i?"1":"0",n.put(o),r["continue"]()}else t()}}function a(e){e.createObjectStore(Go,{keyPath:"_id"}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0})}function s(e,t){var n=e.objectStore(Go),r=e.objectStore(Ho),o=e.objectStore(Ko),i=r.openCursor();i.onsuccess=function(e){var i=e.target.result;if(i){var a=i.value,s=a.id,u=I(s),c=v(a);if(u){var f=s+"::"+c,l=s+"::",d=s+"::~",h=o.index("_doc_id_rev"),p=IDBKeyRange.bound(l,d,!1,!1),y=h.openCursor(p);y.onsuccess=function(e){if(y=e.target.result){var t=y.value;t._doc_id_rev===f&&n.put(t),o["delete"](y.primaryKey),y["continue"]()}else r["delete"](i.primaryKey),i["continue"]()}}else i["continue"]()}else t&&t()}}function u(e){var t=e.createObjectStore(Jo,{autoIncrement:!0});t.createIndex("seq","seq"),t.createIndex("digestSeq","digestSeq",{unique:!0})}function f(e,t){var n=e.objectStore(Ko),r=e.objectStore(Wo),o=e.objectStore(Jo),i=r.count();i.onsuccess=function(e){var r=e.target.result;return r?void(n.openCursor().onsuccess=function(e){var n=e.target.result;if(!n)return t();for(var r=n.value,i=n.primaryKey,a=Object.keys(r._attachments||{}),s={},u=0;u<a.length;u++){var c=r._attachments[a[u]];s[c.digest]=!0}var f=Object.keys(s);for(u=0;u<f.length;u++){var l=f[u];o.put({seq:i,digestSeq:l+"::"+i})}n["continue"]()}):t()}}function d(e){function t(e){return e.data?dn(e):(e.deleted="1"===e.deletedOrLocal,e)}var n=e.objectStore(Ko),r=e.objectStore(Ho),o=r.openCursor();o.onsuccess=function(e){function o(){var e=s.id+"::",t=s.id+"::ï¿¿",r=n.index("_doc_id_rev").openCursor(IDBKeyRange.bound(e,t)),o=0;r.onsuccess=function(e){var t=e.target.result;if(!t)return s.seq=o,i();var n=t.primaryKey;n>o&&(o=n),t["continue"]()}}function i(){var e=ln(s,s.winningRev,s.deleted),t=r.put(e);t.onsuccess=function(){a["continue"]()}}var a=e.target.result;if(a){var s=t(a.value);return s.winningRev=s.winningRev||v(s),s.seq?i():void o()}}}var h=t.name,p=null;e._meta=null,e.type=function(){return"idb"},e._id=l(function(t){t(null,e._meta.instanceId)}),e._bulkDocs=function(n,r,o){gn(t,n,r,e,p,Yo,o)},e._get=function(e,t,n){function r(){n(a,{doc:o,metadata:i,ctx:s})}var o,i,a,s=t.ctx;if(!s){var u=mn(p,[Ho,Ko,Wo],"readonly");if(u.error)return n(u.error);s=u.txn}s.objectStore(Ho).get(e).onsuccess=function(e){if(i=dn(e.target.result),!i)return a=A(pr,"missing"),r();if(_(i)&&!t.rev)return a=A(pr,"deleted"),r();var n=s.objectStore(Ko),u=t.rev||i.winningRev,c=i.id+"::"+u;n.index("_doc_id_rev").get(c).onsuccess=function(e){return o=e.target.result,o&&(o=hn(o)),o?void r():(a=A(pr,"missing"),r())}}},e._getAttachment=function(e,t,n){var r;if(t.ctx)r=t.ctx;else{var o=mn(p,[Ho,Ko,Wo],"readonly");if(o.error)return n(o.error);r=o.txn}var i=e.digest,a=e.content_type;r.objectStore(Wo).get(i).onsuccess=function(e){var r=e.target.result.body;pn(r,a,t.binary,function(e){n(null,e)})}},e._info=function(t){if(null===p||!$o.has(h)){var n=new Error("db isn't open");return n.id="idbNull",t(n)}var r,o,i=mn(p,[Ko],"readonly");if(i.error)return t(i.error);var a=i.txn,s=a.objectStore(Ko).openCursor(null,"prev");s.onsuccess=function(t){var n=t.target.result;r=n?n.key:0,o=e._meta.docCount},a.oncomplete=function(){t(null,{doc_count:o,update_seq:r,idb_attachment_format:e._meta.blobSupport?"binary":"base64"})}},e._allDocs=function(t,n){En(t,e,p,n)},e._changes=function(t){function n(e){function n(){return c.seq!==a?e["continue"]():(u=a,c.winningRev===i._rev?o(i):void r())}function r(){var e=i._id+"::"+c.winningRev,t=_.get(e);t.onsuccess=function(e){o(hn(e.target.result))}}function o(n){var r=t.processChange(n,c,t);r.seq=c.seq;var o=b(r);return"object"==typeof o?t.complete(o):(o&&(g++,l&&m.push(r),t.attachments&&t.include_docs?vn(n,t,d,function(){yn([r],t.binary).then(function(){t.onChange(r)})}):t.onChange(r)),void(g!==f&&e["continue"]()))}var i=hn(e.value),a=e.key;if(s&&!s.has(i._id))return e["continue"]();var c;return(c=w.get(i._id))?n():void(y.get(i._id).onsuccess=function(e){c=dn(e.target.result),w.set(i._id,c),n()})}function r(e){var t=e.target.result;t&&n(t)}function o(){var e=[Ho,Ko];t.attachments&&e.push(Wo);var n=mn(p,e,"readonly");if(n.error)return t.complete(n.error);d=n.txn,d.onabort=fn(t.complete),d.oncomplete=i,v=d.objectStore(Ko),y=d.objectStore(Ho),_=v.index("_doc_id_rev");var o;o=t.descending?v.openCursor(null,"prev"):v.openCursor(IDBKeyRange.lowerBound(t.since,!0)),o.onsuccess=r}function i(){function e(){t.complete(null,{results:m,last_seq:u})}!t.continuous&&t.attachments?yn(m).then(e):e()}if(t=c(t),t.continuous){var a=h+":"+D();return Yo.addListener(h,a,e,t),Yo.notify(h),{cancel:function(){Yo.removeListener(h,a)}}}var s=t.doc_ids&&new nr.Set(t.doc_ids);t.since=t.since||0;var u=t.since,f="limit"in t?t.limit:-1;0===f&&(f=1);var l;l="return_docs"in t?t.return_docs:"returnDocs"in t?t.returnDocs:!0;var d,v,y,_,m=[],g=0,b=we(t),w=new nr.Map;o()},e._close=function(e){return null===p?e(A(gr)):(p.close(),$o["delete"](h),
+p=null,void e())},e._getRevisionTree=function(e,t){var n=mn(p,[Ho],"readonly");if(n.error)return t(n.error);var r=n.txn,o=r.objectStore(Ho).get(e);o.onsuccess=function(e){var n=dn(e.target.result);n?t(null,n.rev_tree):t(A(pr))}},e._doCompaction=function(e,t,n){var r=[Ho,Ko,Wo,Jo],o=mn(p,r,"readwrite");if(o.error)return n(o.error);var i=o.txn,a=i.objectStore(Ho);a.get(e).onsuccess=function(n){var r=dn(n.target.result);E(r.rev_tree,function(e,n,r,o,i){var a=n+"-"+r;-1!==t.indexOf(a)&&(i.status="missing")}),_n(t,e,i);var o=r.winningRev,a=r.deleted;i.objectStore(Ho).put(ln(r,o,a))},i.onabort=fn(n),i.oncomplete=function(){n()}},e._getLocal=function(e,t){var n=mn(p,[Go],"readonly");if(n.error)return t(n.error);var r=n.txn,o=r.objectStore(Go).get(e);o.onerror=fn(t),o.onsuccess=function(e){var n=e.target.result;n?(delete n._doc_id_rev,t(null,n)):t(A(pr))}},e._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),delete e._revisions;var r=e._rev,o=e._id;r?e._rev="0-"+(parseInt(r.split("-")[1],10)+1):e._rev="0-1";var i,a=t.ctx;if(!a){var s=mn(p,[Go],"readwrite");if(s.error)return n(s.error);a=s.txn,a.onerror=fn(n),a.oncomplete=function(){i&&n(null,i)}}var u,c=a.objectStore(Go);r?(u=c.get(o),u.onsuccess=function(o){var a=o.target.result;if(a&&a._rev===r){var s=c.put(e);s.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)}}else n(A(vr))}):(u=c.add(e),u.onerror=function(e){n(A(vr)),e.preventDefault(),e.stopPropagation()},u.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)})},e._removeLocal=function(e,t,n){"function"==typeof t&&(n=t,t={});var r=t.ctx;if(!r){var o=mn(p,[Go],"readwrite");if(o.error)return n(o.error);r=o.txn,r.oncomplete=function(){i&&n(null,i)}}var i,a=e._id,s=r.objectStore(Go),u=s.get(a);u.onerror=fn(n),u.onsuccess=function(r){var o=r.target.result;o&&o._rev===e._rev?(s["delete"](a),i={ok:!0,id:a,rev:"0-0"},t.ctx&&n(null,i)):n(A(pr))}},e._destroy=function(e,t){Yo.removeAllListeners(h);var n=Zo.get(h);n&&n.result&&(n.result.close(),$o["delete"](h));var r=indexedDB.deleteDatabase(h);r.onsuccess=function(){Zo["delete"](h),ie()&&h in localStorage&&delete localStorage[h],t(null,{ok:!0})},r.onerror=fn(t)};var y=$o.get(h);if(y)return p=y.idb,e._meta=y.global,void n.nextTick(function(){r(null,e)});var m;m=t.storage?Tn(h,t.storage):indexedDB.open(h,Po),Zo.set(h,m),m.onupgradeneeded=function(e){function t(){var e=c[l-1];l++,e&&e(r,t)}var n=e.target.result;if(e.oldVersion<1)return o(n);var r=e.currentTarget.transaction;e.oldVersion<3&&a(n),e.oldVersion<4&&u(n);var c=[i,s,f,d],l=e.oldVersion;t()},m.onsuccess=function(t){p=t.target.result,p.onversionchange=function(){p.close(),$o["delete"](h)},p.onabort=function(e){console.error("Database has a global failure",e.target.error),p.close(),$o["delete"](h)};var n=p.transaction([Vo,Xo,Ho],"readwrite"),o=n.objectStore(Vo).get(Vo),i=null,a=null,s=null;o.onsuccess=function(t){var o=function(){null!==i&&null!==a&&null!==s&&(e._meta={name:h,instanceId:s,blobSupport:i,docCount:a},$o.set(h,{idb:p,global:e._meta}),r(null,e))},u=t.target.result||{id:Vo};h+"_id"in u?(s=u[h+"_id"],o()):(s=D(),u[h+"_id"]=s,n.objectStore(Vo).put(u).onsuccess=function(){o()}),Qo||(Qo=Sn(n)),Qo.then(function(e){i=e,o()});var c=n.objectStore(Ho).index("deletedOrLocal");c.count(IDBKeyRange.only("0")).onsuccess=function(e){a=e.target.result,o()}}},m.onerror=function(){var e="Failed to open indexedDB, are you in private browsing mode?";console.error(e),r(A(Tr,e))}}function Tn(e,t){try{return indexedDB.open(e,{version:Po,storage:t})}catch(n){return indexedDB.open(e,Po)}}function On(e){return decodeURIComponent(window.escape(e))}function jn(e){return 65>e?e-48:e-55}function Cn(e,t,n){for(var r="";n>t;)r+=String.fromCharCode(jn(e.charCodeAt(t++))<<4|jn(e.charCodeAt(t++)));return r}function In(e,t,n){for(var r="";n>t;)r+=String.fromCharCode(jn(e.charCodeAt(t+2))<<12|jn(e.charCodeAt(t+3))<<8|jn(e.charCodeAt(t))<<4|jn(e.charCodeAt(t+1))),t+=4;return r}function Ln(e,t){return"UTF-8"===t?On(Cn(e,0,e.length)):In(e,0,e.length)}function Rn(e){return"'"+e+"'"}function Dn(){return"undefined"!=typeof sqlitePlugin?sqlitePlugin.openDatabase.bind(sqlitePlugin):"undefined"!=typeof openDatabase?function(e){return openDatabase(e.name,e.version,e.description,e.size)}:void 0}function Nn(){return"undefined"!=typeof openDatabase||"undefined"!=typeof SQLitePlugin}function Bn(e){return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"")}function Mn(e){return e.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,"")}function Fn(e){return delete e._id,delete e._rev,JSON.stringify(e)}function Un(e,t,n){return e=JSON.parse(e),e._id=t,e._rev=n,e}function Pn(e){for(var t="(";e--;)t+="?",e&&(t+=",");return t+")"}function Hn(e,t,n,r,o){return"SELECT "+e+" FROM "+("string"==typeof t?t:t.join(" JOIN "))+(n?" ON "+n:"")+(r?" WHERE "+("string"==typeof r?r:r.join(" AND ")):"")+(o?" ORDER BY "+o:"")}function Kn(e,t,n){function r(){++i===e.length&&o()}function o(){if(a.length){var e="SELECT DISTINCT digest AS digest FROM "+ai+" WHERE seq IN "+Pn(a.length);n.executeSql(e,a,function(e,t){for(var n=[],r=0;r<t.rows.length;r++)n.push(t.rows.item(r).digest);if(n.length){var o="DELETE FROM "+ai+" WHERE seq IN ("+a.map(function(){return"?"}).join(",")+")";e.executeSql(o,a,function(e){var t="SELECT digest FROM "+ai+" WHERE digest IN ("+n.map(function(){return"?"}).join(",")+")";e.executeSql(t,n,function(e,t){for(var r=new nr.Set,o=0;o<t.rows.length;o++)r.add(t.rows.item(o).digest);n.forEach(function(t){r.has(t)||(e.executeSql("DELETE FROM "+ai+" WHERE digest=?",[t]),e.executeSql("DELETE FROM "+ri+" WHERE digest=?",[t]))})})})}})}}if(e.length){var i=0,a=[];e.forEach(function(e){var o="SELECT seq FROM "+ni+" WHERE doc_id=? AND rev=?";n.executeSql(o,[t,e],function(e,t){if(!t.rows.length)return r();var n=t.rows.item(0).seq;a.push(n),e.executeSql("DELETE FROM "+ni+" WHERE seq=?",[n],r)})})}}function Wn(e){return function(t){console.error("WebSQL threw an error",t);var n=t&&t.constructor.toString().match(/function ([^\(]+)/),r=n&&n[1]||t.type,o=t.target||t.message;e(A(Or,o,r))}}function Jn(e){if("size"in e)return 1e6*e.size;var t="undefined"!=typeof navigator&&/Android/.test(navigator.userAgent);return t?5e6:1}function Vn(e,t){try{return{db:e(t)}}catch(n){return{error:n}}}function Gn(e){var t=si.get(e.name);if(!t){var n=Dn();t=Vn(n,e),si.set(e.name,t),t.db&&(t.db._sqlitePlugin="undefined"!=typeof sqlitePlugin)}return t}function Xn(e,t,n,r,o,i,a){function s(){return g?a(g):(i.notify(r._name),r._docCount=-1,void a(null,b))}function u(e,t){var n="SELECT count(*) as cnt FROM "+ri+" WHERE digest=?";m.executeSql(n,[e],function(n,r){if(0===r.rows.item(0).cnt){var o=A(Rr,"unknown stub attachment with digest "+e);t(o)}else t()})}function c(e){function t(){++o===n.length&&e(r)}var n=[];if(y.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){u(e,function(e){e&&!r&&(r=e),t()})})}function f(e,t,n,o,i,a,s,u){function c(){function t(e,t){function r(){return++i===a.length&&t(),!1}function o(t){var o="INSERT INTO "+ai+" (digest, seq) VALUES (?,?)",i=[n._attachments[t].digest,e];m.executeSql(o,i,r,r)}var i=0,a=Object.keys(n._attachments||{});if(!a.length)return t();for(var s=0;s<a.length;s++)o(a[s])}var n=e.data,r=o?1:0,i=n._id,a=n._rev,s=Fn(n),u="INSERT INTO "+ni+" (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);",c=[i,a,s,r];m.executeSql(u,c,function(e,n){var r=n.insertId;t(r,function(){d(e,r)})},function(){var e=Hn("seq",ni,null,"doc_id=? AND rev=?");return m.executeSql(e,[i,a],function(e,n){var o=n.rows.item(0).seq,u="UPDATE "+ni+" SET json=?, deleted=? WHERE doc_id=? AND rev=?;",c=[s,r,i,a];e.executeSql(u,c,function(e){t(o,function(){d(e,o)})})}),!1})}function f(e){p||(e?(p=e,u(p)):v===y.length&&c())}function l(e){v++,f(e)}function d(n,o){var a=e.metadata.id;i&&r.auto_compaction?Kn(rn(e.metadata),a,n):e.stemmedRevs.length&&Kn(e.stemmedRevs,a,n),e.metadata.seq=o,delete e.metadata.rev;var c=i?"UPDATE "+ti+" SET json=?, max_seq=?, winningseq=(SELECT seq FROM "+ni+" WHERE doc_id="+ti+".id AND rev=?) WHERE id=?":"INSERT INTO "+ti+" (id, winningseq, max_seq, json) VALUES (?,?,?,?);",f=sn(e.metadata),l=i?[f,o,t,a]:[a,o,o,f];n.executeSql(c,l,function(){b[s]={ok:!0,id:e.metadata.id,rev:t},w.set(a,e.metadata),u()})}var p=null,v=0;e.data._id=e.metadata.id,e.data._rev=e.metadata.rev;var y=Object.keys(e.data._attachments||{});o&&(e.data._deleted=!0),y.forEach(function(n){var r=e.data._attachments[n];if(r.stub)v++,f();else{var o=r.data;delete r.data,r.revpos=parseInt(t,10);var i=r.digest;h(i,o,l)}}),y.length||c()}function l(){nn(e.revs_limit,y,r,w,m,b,f,n)}function d(e){function t(){++n===y.length&&e()}if(!y.length)return e();var n=0;y.forEach(function(e){if(e._id&&I(e._id))return t();var n=e.metadata.id;m.executeSql("SELECT json FROM "+ti+" WHERE id = ?",[n],function(e,r){if(r.rows.length){var o=an(r.rows.item(0).json);w.set(n,o)}t()})})}function h(e,t,n){var r="SELECT digest FROM "+ri+" WHERE digest=?";m.executeSql(r,[e],function(o,i){return i.rows.length?n():(r="INSERT INTO "+ri+" (digest, body, escaped) VALUES (?,?,1)",void o.executeSql(r,[e,Bn(t)],function(){n()},function(){return n(),!1}))})}var p=n.new_edits,v=t.docs,y=v.map(function(e){if(e._id&&I(e._id))return e;var t=U(e,p);return t}),_=y.filter(function(e){return e.error});if(_.length)return a(_[0]);var m,g,b=new Array(y.length),w=new nr.Map;Kt(y,"binary",function(e){return e?a(e):void o.transaction(function(e){m=e,c(function(e){e?g=e:d(l)})},Wn(a),s)})}function zn(e,t,n,r,o){function a(){++c===u.length&&o&&o()}function s(e,o){var s=e._attachments[o],u={binary:t.binary,ctx:r};n._getAttachment(s,u,function(t,n){e._attachments[o]=$n.extend(i(s,["digest","content_type"]),{data:n}),a()})}var u=Object.keys(e._attachments||{});if(!u.length)return o&&o();var c=0;u.forEach(function(n){t.attachments&&t.include_docs?s(e,n):(e._attachments[n].stub=!0,a())})}function Qn(e,t){function n(){ie()&&(window.localStorage["_pouch__websqldb_"+g._name]=!0),t(null,g)}function r(e,t){e.executeSql(di),e.executeSql("ALTER TABLE "+ni+" ADD COLUMN deleted TINYINT(1) DEFAULT 0",[],function(){e.executeSql(fi),e.executeSql("ALTER TABLE "+ti+" ADD COLUMN local TINYINT(1) DEFAULT 0",[],function(){e.executeSql("CREATE INDEX IF NOT EXISTS 'doc-store-local-idx' ON "+ti+" (local, id)");var n="SELECT "+ti+".winningseq AS seq, "+ti+".json AS metadata FROM "+ni+" JOIN "+ti+" ON "+ni+".seq = "+ti+".winningseq";e.executeSql(n,[],function(e,n){for(var r=[],o=[],i=0;i<n.rows.length;i++){var a=n.rows.item(i),s=a.seq,u=JSON.parse(a.metadata);_(u)&&r.push(s),I(u.id)&&o.push(u.id)}e.executeSql("UPDATE "+ti+"SET local = 1 WHERE id IN "+Pn(o.length),o,function(){e.executeSql("UPDATE "+ni+" SET deleted = 1 WHERE seq IN "+Pn(r.length),r,t)})})})})}function o(e,t){var n="CREATE TABLE IF NOT EXISTS "+oi+" (id UNIQUE, rev, json)";e.executeSql(n,[],function(){var n="SELECT "+ti+".id AS id, "+ni+".json AS data FROM "+ni+" JOIN "+ti+" ON "+ni+".seq = "+ti+".winningseq WHERE local = 1";e.executeSql(n,[],function(e,n){function r(){if(!o.length)return t(e);var n=o.shift(),i=JSON.parse(n.data)._rev;e.executeSql("INSERT INTO "+oi+" (id, rev, json) VALUES (?,?,?)",[n.id,i,n.data],function(e){e.executeSql("DELETE FROM "+ti+" WHERE id=?",[n.id],function(e){e.executeSql("DELETE FROM "+ni+" WHERE seq=?",[n.seq],function(){r()})})})}for(var o=[],i=0;i<n.rows.length;i++)o.push(n.rows.item(i));r()})})}function i(e,t){function n(n){function r(){if(!n.length)return t(e);var o=n.shift(),i=Ln(o.hex,m),a=i.lastIndexOf("::"),s=i.substring(0,a),u=i.substring(a+2),c="UPDATE "+ni+" SET doc_id=?, rev=? WHERE doc_id_rev=?";e.executeSql(c,[s,u,i],function(){r()})}r()}var r="ALTER TABLE "+ni+" ADD COLUMN doc_id";e.executeSql(r,[],function(e){var t="ALTER TABLE "+ni+" ADD COLUMN rev";e.executeSql(t,[],function(e){e.executeSql(li,[],function(e){var t="SELECT hex(doc_id_rev) as hex FROM "+ni;e.executeSql(t,[],function(e,t){for(var r=[],o=0;o<t.rows.length;o++)r.push(t.rows.item(o));n(r)})})})})}function a(e,t){function n(e){var n="SELECT COUNT(*) AS cnt FROM "+ri;e.executeSql(n,[],function(e,n){function r(){var n=Hn(yi+", "+ti+".id AS id",[ti,ni],vi,null,ti+".id ");n+=" LIMIT "+a+" OFFSET "+i,i+=a,e.executeSql(n,[],function(e,n){function o(e,t){var n=i[e]=i[e]||[];-1===n.indexOf(t)&&n.push(t)}if(!n.rows.length)return t(e);for(var i={},a=0;a<n.rows.length;a++)for(var s=n.rows.item(a),u=Un(s.data,s.id,s.rev),c=Object.keys(u._attachments||{}),f=0;f<c.length;f++){var l=u._attachments[c[f]];o(l.digest,s.seq)}var d=[];if(Object.keys(i).forEach(function(e){var t=i[e];t.forEach(function(t){d.push([e,t])})}),!d.length)return r();var h=0;d.forEach(function(t){var n="INSERT INTO "+ai+" (digest, seq) VALUES (?,?)";e.executeSql(n,t,function(){++h===d.length&&r()})})})}var o=n.rows.item(0).cnt;if(!o)return t(e);var i=0,a=10;r()})}var r="CREATE TABLE IF NOT EXISTS "+ai+" (digest, seq INTEGER)";e.executeSql(r,[],function(e){e.executeSql(pi,[],function(e){e.executeSql(hi,[],n)})})}function s(e,t){var n="ALTER TABLE "+ri+" ADD COLUMN escaped TINYINT(1) DEFAULT 0";e.executeSql(n,[],t)}function u(e,t){var n="ALTER TABLE "+ti+" ADD COLUMN max_seq INTEGER";e.executeSql(n,[],function(e){var n="UPDATE "+ti+" SET max_seq=(SELECT MAX(seq) FROM "+ni+" WHERE doc_id=id)";e.executeSql(n,[],function(e){var n="CREATE UNIQUE INDEX IF NOT EXISTS 'doc-max-seq-idx' ON "+ti+" (max_seq)";e.executeSql(n,[],t)})})}function f(e,t){e.executeSql('SELECT HEX("a") AS hex',[],function(e,n){var r=n.rows.item(0).hex;m=2===r.length?"UTF-8":"UTF-16",t()})}function d(){for(;S.length>0;){var e=S.pop();e(null,b)}}function h(e,t){if(0===t){var n="CREATE TABLE IF NOT EXISTS "+ii+" (dbid, db_version INTEGER)",c="CREATE TABLE IF NOT EXISTS "+ri+" (digest UNIQUE, escaped TINYINT(1), body BLOB)",f="CREATE TABLE IF NOT EXISTS "+ai+" (digest, seq INTEGER)",l="CREATE TABLE IF NOT EXISTS "+ti+" (id unique, json, winningseq, max_seq INTEGER UNIQUE)",h="CREATE TABLE IF NOT EXISTS "+ni+" (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, json, deleted TINYINT(1), doc_id, rev)",p="CREATE TABLE IF NOT EXISTS "+oi+" (id UNIQUE, rev, json)";e.executeSql(c),e.executeSql(p),e.executeSql(f,[],function(){e.executeSql(hi),e.executeSql(pi)}),e.executeSql(l,[],function(){e.executeSql(di),e.executeSql(h,[],function(){e.executeSql(fi),e.executeSql(li),e.executeSql(n,[],function(){var t="INSERT INTO "+ii+" (db_version, dbid) VALUES (?,?)";b=D();var n=[ei,b];e.executeSql(t,n,function(){d()})})})})}else{var v=function(){var n=ei>t;n&&e.executeSql("UPDATE "+ii+" SET db_version = "+ei);var r="SELECT dbid FROM "+ii;e.executeSql(r,[],function(e,t){b=t.rows.item(0).dbid,d()})},y=[r,o,i,a,s,u,v],_=t,m=function(e){y[_-1](e,m),_++};m(e)}}function p(){T.transaction(function(e){f(e,function(){v(e)})},Wn(t),n)}function v(e){var t="SELECT sql FROM sqlite_master WHERE tbl_name = "+ii;e.executeSql(t,[],function(e,t){t.rows.length?/db_version/.test(t.rows.item(0).sql)?e.executeSql("SELECT db_version FROM "+ii,[],function(e,t){var n=t.rows.item(0).db_version;h(e,n)}):e.executeSql("ALTER TABLE "+ii+" ADD COLUMN db_version INTEGER",[],function(){h(e,1)}):h(e,0)})}function y(e,t){if(-1!==g._docCount)return t(g._docCount);var n=Hn("COUNT("+ti+".id) AS 'num'",[ti,ni],vi,ni+".deleted=0");e.executeSql(n,[],function(e,n){g._docCount=n.rows.item(0).num,t(g._docCount)})}var m,g=this,b=null,w=Jn(e),S=[];g._docCount=-1,g._name=e.name;var k=$n.extend({},e,{size:w,version:ci}),x=Gn(k);if(x.error)return Wn(t)(x.error);var T=x.db;"function"!=typeof T.readTransaction&&(T.readTransaction=T.transaction),p(),g.type=function(){return"websql"},g._id=l(function(e){e(null,b)}),g._info=function(e){T.readTransaction(function(t){y(t,function(n){var r="SELECT MAX(seq) AS seq FROM "+ni;t.executeSql(r,[],function(t,r){var o=r.rows.item(0).seq||0;e(null,{doc_count:n,update_seq:o,sqlite_plugin:T._sqlitePlugin,websql_encoding:m})})})},Wn(e))},g._bulkDocs=function(t,n,r){Xn(e,t,n,g,T,ui,r)},g._get=function(e,t,n){function r(){n(a,{doc:o,metadata:i,ctx:s})}var o,i,a,s=t.ctx;if(!s)return T.readTransaction(function(r){g._get(e,$n.extend({ctx:r},t),n)});var u,c;t.rev?(u=Hn(yi,[ti,ni],ti+".id="+ni+".doc_id",[ni+".doc_id=?",ni+".rev=?"]),c=[e,t.rev]):(u=Hn(yi,[ti,ni],vi,ti+".id=?"),c=[e]),s.executeSql(u,c,function(e,n){if(!n.rows.length)return a=A(pr,"missing"),r();var s=n.rows.item(0);return i=an(s.metadata),s.deleted&&!t.rev?(a=A(pr,"deleted"),r()):(o=Un(s.data,i.id,s.rev),void r())})},g._allDocs=function(e,t){var n,r=[],o="startkey"in e?e.startkey:!1,i="endkey"in e?e.endkey:!1,a="key"in e?e.key:!1,s="descending"in e?e.descending:!1,u="limit"in e?e.limit:-1,c="skip"in e?e.skip:0,f=e.inclusive_end!==!1,l=[],d=[];if(a!==!1)d.push(ti+".id = ?"),l.push(a);else if(o!==!1||i!==!1){if(o!==!1&&(d.push(ti+".id "+(s?"<=":">=")+" ?"),l.push(o)),i!==!1){var h=s?">":"<";f&&(h+="="),d.push(ti+".id "+h+" ?"),l.push(i)}a!==!1&&(d.push(ti+".id = ?"),l.push(a))}"ok"!==e.deleted&&d.push(ni+".deleted = 0"),T.readTransaction(function(t){y(t,function(o){if(n=o,0!==u){var i=Hn(yi,[ti,ni],vi,d,ti+".id "+(s?"DESC":"ASC"));i+=" LIMIT "+u+" OFFSET "+c,t.executeSql(i,l,function(t,n){for(var o=0,i=n.rows.length;i>o;o++){var a=n.rows.item(o),s=an(a.metadata),u=s.id,c=Un(a.data,u,a.rev),f=c._rev,l={id:u,key:u,value:{rev:f}};if(e.include_docs&&(l.doc=c,l.doc._rev=f,e.conflicts&&(l.doc._conflicts=q(s)),zn(l.doc,e,g,t)),a.deleted){if("ok"!==e.deleted)continue;l.value.deleted=!0,l.doc=null}r.push(l)}})}})},Wn(t),function(){t(null,{total_rows:n,offset:e.skip,rows:r})})},g._changes=function(e){function t(){var t=ti+".json AS metadata, "+ti+".max_seq AS maxSeq, "+ni+".json AS winningDoc, "+ni+".rev AS winningRev ",n=ti+" JOIN "+ni,u=ti+".id="+ni+".doc_id AND "+ti+".winningseq="+ni+".seq",c=["maxSeq > ?"],f=[e.since];e.doc_ids&&(c.push(ti+".id IN "+Pn(e.doc_ids.length)),f=f.concat(e.doc_ids));var l="maxSeq "+(r?"DESC":"ASC"),d=Hn(t,n,u,c,l),h=we(e);e.view||e.filter||(d+=" LIMIT "+o);var p=e.since||0;T.readTransaction(function(t){t.executeSql(d,f,function(t,n){function r(t){return function(){e.onChange(t)}}for(var u=0,c=n.rows.length;c>u;u++){var f=n.rows.item(u),l=an(f.metadata);p=f.maxSeq;var d=Un(f.winningDoc,l.id,f.winningRev),v=e.processChange(d,l,e);v.seq=f.maxSeq;var y=h(v);if("object"==typeof y)return e.complete(y);if(y&&(s++,i&&a.push(v),e.attachments&&e.include_docs?zn(d,e,g,t,r(v)):r(v)()),s===o)break}})},Wn(e.complete),function(){e.continuous||e.complete(null,{results:a,last_seq:p})})}if(e=c(e),e.continuous){var n=g._name+":"+D();return ui.addListener(g._name,n,g,e),ui.notify(g._name),{cancel:function(){ui.removeListener(g._name,n)}}}var r=e.descending;e.since=e.since&&!r?e.since:0;var o="limit"in e?e.limit:-1;0===o&&(o=1);var i;i="return_docs"in e?e.return_docs:"returnDocs"in e?e.returnDocs:!0;var a=[],s=0;t()},g._close=function(e){e()},g._getAttachment=function(e,t,n){var r,o=t.ctx,i=e.digest,a=e.content_type,s="SELECT escaped, CASE WHEN escaped = 1 THEN body ELSE HEX(body) END AS body FROM "+ri+" WHERE digest=?";o.executeSql(s,[i],function(e,o){var i=o.rows.item(0),s=i.escaped?Mn(i.body):Ln(i.body,m);r=t.binary?ge(s,a):$r(s),n(null,r)})},g._getRevisionTree=function(e,t){T.readTransaction(function(n){var r="SELECT json AS metadata FROM "+ti+" WHERE id = ?";n.executeSql(r,[e],function(e,n){if(n.rows.length){var r=an(n.rows.item(0).metadata);t(null,r.rev_tree)}else t(A(pr))})})},g._doCompaction=function(e,t,n){return t.length?void T.transaction(function(n){var r="SELECT json AS metadata FROM "+ti+" WHERE id = ?";n.executeSql(r,[e],function(n,r){var o=an(r.rows.item(0).metadata);E(o.rev_tree,function(e,n,r,o,i){var a=n+"-"+r;-1!==t.indexOf(a)&&(i.status="missing")});var i="UPDATE "+ti+" SET json = ? WHERE id = ?";n.executeSql(i,[sn(o),e])}),Kn(t,e,n)},Wn(n),function(){n()}):n()},g._getLocal=function(e,t){T.readTransaction(function(n){var r="SELECT json, rev FROM "+oi+" WHERE id=?";n.executeSql(r,[e],function(n,r){if(r.rows.length){var o=r.rows.item(0),i=Un(o.json,e,o.rev);t(null,i)}else t(A(pr))})})},g._putLocal=function(e,t,n){function r(e){var r,c;i?(r="UPDATE "+oi+" SET rev=?, json=? WHERE id=? AND rev=?",c=[o,u,a,i]):(r="INSERT INTO "+oi+" (id, rev, json) VALUES (?,?,?)",c=[a,o,u]),e.executeSql(r,c,function(e,r){r.rowsAffected?(s={ok:!0,id:a,rev:o},t.ctx&&n(null,s)):n(A(vr))},function(){return n(A(vr)),!1})}"function"==typeof t&&(n=t,t={}),delete e._revisions;var o,i=e._rev,a=e._id;o=i?e._rev="0-"+(parseInt(i.split("-")[1],10)+1):e._rev="0-1";var s,u=Fn(e);t.ctx?r(t.ctx):T.transaction(r,Wn(n),function(){s&&n(null,s)})},g._removeLocal=function(e,t,n){function r(r){var i="DELETE FROM "+oi+" WHERE id=? AND rev=?",a=[e._id,e._rev];r.executeSql(i,a,function(r,i){return i.rowsAffected?(o={ok:!0,id:e._id,rev:"0-0"},void(t.ctx&&n(null,o))):n(A(pr))})}"function"==typeof t&&(n=t,t={});var o;t.ctx?r(t.ctx):T.transaction(r,Wn(n),function(){o&&n(null,o)})},g._destroy=function(e,t){ui.removeAllListeners(g._name),T.transaction(function(e){var t=[ti,ni,ri,ii,oi,ai];t.forEach(function(t){e.executeSql("DROP TABLE IF EXISTS "+t,[])})},Wn(t),function(){ie()&&(delete window.localStorage["_pouch__websqldb_"+g._name],delete window.localStorage[g._name]),t(null,{ok:!0})})}}var $n=e(7),Yn=o($n),Zn=o(e(2)),er=o(e(6)),tr=o(e(8)),nr=e(12),rr=o(e(1)),or=e(4),ir=o(e(14)),ar=e(10),sr=o(ar),ur=o(e(15)),cr=o(e(16)),fr="function"==typeof Promise?Promise:tr,lr=Zn("pouchdb:api");er(x,Error),x.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};var dr=new x({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),hr=new x({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),pr=new x({status:404,error:"not_found",reason:"missing"}),vr=new x({status:409,error:"conflict",reason:"Document update conflict"}),yr=new x({status:400,error:"invalid_id",reason:"_id field must contain a string"}),_r=new x({status:412,error:"missing_id",reason:"_id is required for puts"}),mr=new x({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),gr=new x({status:412,error:"precondition_failed",reason:"Database not open"}),br=new x({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),wr=new x({status:500,error:"badarg",reason:"Some query argument is invalid"}),Er=new x({status:400,error:"invalid_request",reason:"Request was invalid"}),Sr=new x({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),kr=new x({status:500,error:"doc_validation",reason:"Bad special document member"}),qr=new x({status:400,error:"bad_request",reason:"Something wrong with the request"}),xr=new x({status:400,error:"bad_request",reason:"Document must be a JSON object"}),Ar=new x({status:404,error:"not_found",reason:"Database not found"}),Tr=new x({status:500,error:"indexed_db_went_bad",reason:"unknown"}),Or=new x({status:500,error:"web_sql_went_bad",reason:"unknown"}),jr=new x({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),Cr=new x({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),Ir=new x({status:400,error:"bad_request",reason:"Invalid rev format"}),Lr=new x({status:412,error:"file_exists",reason:"The database could not be created, the file already exists."}),Rr=new x({status:412,error:"missing_stub"}),Dr=new x({status:413,error:"invalid_url",reason:"Provided URL is invalid"}),Nr={UNAUTHORIZED:dr,MISSING_BULK_DOCS:hr,MISSING_DOC:pr,REV_CONFLICT:vr,INVALID_ID:yr,MISSING_ID:_r,RESERVED_ID:mr,NOT_OPEN:gr,UNKNOWN_ERROR:br,BAD_ARG:wr,INVALID_REQUEST:Er,QUERY_PARSE_ERROR:Sr,DOC_VALIDATION:kr,BAD_REQUEST:qr,NOT_AN_OBJECT:xr,DB_MISSING:Ar,WSQ_ERROR:Or,LDB_ERROR:jr,FORBIDDEN:Cr,INVALID_REV:Ir,FILE_EXISTS:Lr,MISSING_STUB:Rr,IDB_ERROR:Tr,INVALID_URL:Dr},Br=function(e,t,n){var r=Object.keys(Nr).filter(function(n){var r=Nr[n];return"function"!=typeof r&&r[e]===t}),o=n&&r.filter(function(e){var t=Nr[e];return t.message===n})[0]||r[0];return o?Nr[o]:null};er(O,or.EventEmitter),O.prototype.cancel=function(){this.isCancelled=!0,this.db.taskqueue.isReady&&this.emit("cancel")},O.prototype.doChanges=function(e){var t=this,n=e.complete;if(e=c(e),"live"in e&&!("continuous"in e)&&(e.continuous=e.live),e.processChange=j,"latest"===e.since&&(e.since="now"),e.since||(e.since=0),"now"===e.since)return void this.db.info().then(function(r){return t.isCancelled?void n(null,{status:"cancelled"}):(e.since=r.update_seq,void t.doChanges(e))},n);if(e.continuous&&"now"!==e.since&&this.db.info().then(function(e){t.startSeq=e.update_seq},function(e){if("idbNull"!==e.id)throw e}),e.filter&&"string"==typeof e.filter&&("_view"===e.filter?e.view=w(e.view):e.filter=w(e.filter),"http"!==this.db.type()&&!e.doc_ids))return this.filterChanges(e);"descending"in e||(e.descending=!1),e.limit=0===e.limit?1:e.limit,e.complete=n;var r=this.db._changes(e);if(r&&"function"==typeof r.cancel){var o=t.cancel;t.cancel=rr(function(e){r.cancel(),o.apply(this,e)})}},O.prototype.filterChanges=function(e){var t=this,n=e.complete;if("_view"===e.filter){if(!e.view||"string"!=typeof e.view){var r=A(qr,"`view` filter parameter not found or invalid.");return n(r)}var o=b(e.view);this.db.getView(o[0],o[1],function(r,o){return t.isCancelled?n(null,{status:"cancelled"}):r?n(T(r)):o.map?(e.filter=g(o.map),void t.doChanges(e)):n(A(pr))})}else{var i=b(e.filter);if(!i)return t.doChanges(e);this.db.getFilter(i[0],i[1],function(r,o){return t.isCancelled?n(null,{status:"cancelled"}):r?n(T(r)):(e.filter=m(o),void t.doChanges(e))})}};var Mr="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),Fr=N(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"]),Ur=N(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]);er(Z,or.EventEmitter),Z.prototype.post=d("post",function(e,t,n){return"function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e)?n(A(xr)):void this.bulkDocs({docs:[e]},t,K(n))}),Z.prototype.put=d("put",rr(function(e){var t,n,r,o,i=e.shift(),a="_id"in i;if("object"!=typeof i||Array.isArray(i))return(o=e.pop())(A(xr));for(;;)if(t=e.shift(),n=typeof t,"string"!==n||a?"string"!==n||!a||"_rev"in i?"object"===n?r=t:"function"===n&&(o=t):i._rev=t:(i._id=t,a=!0),!e.length)break;return r=r||{},B(i._id),I(i._id)&&"function"==typeof this._putLocal?i._deleted?this._removeLocal(i,o):this._putLocal(i,o):void this.bulkDocs({docs:[i]},r,K(o))})),Z.prototype.putAttachment=d("putAttachment",function(e,t,n,r,o){function i(e){var n="_rev"in e?parseInt(e._rev,10):0;return e._attachments=e._attachments||{},e._attachments[t]={content_type:o,data:r,revpos:++n},a.put(e)}var a=this;return"function"==typeof o&&(o=r,r=n,n=null),"undefined"==typeof o&&(o=r,r=n,n=null),a.get(e).then(function(e){if(e._rev!==n)throw A(vr);return i(e)},function(t){if(t.reason===pr.message)return i({_id:e});throw t})}),Z.prototype.removeAttachment=d("removeAttachment",function(e,t,n,r){var o=this;o.get(e,function(e,i){return e?void r(e):i._rev!==n?void r(A(vr)):i._attachments?(delete i._attachments[t],0===Object.keys(i._attachments).length&&delete i._attachments,void o.put(i,r)):r()})}),Z.prototype.remove=d("remove",function(e,t,n,r){var o;"string"==typeof t?(o={_id:e,_rev:t},"function"==typeof n&&(r=n,n={})):(o=e,"function"==typeof t?(r=t,n={}):(r=n,n=t)),n=n||{},n.was_delete=!0;var i={_id:o._id,_rev:o._rev||n.rev};return i._deleted=!0,I(i._id)&&"function"==typeof this._removeLocal?this._removeLocal(o,r):void this.bulkDocs({docs:[i]},n,K(r))}),Z.prototype.revsDiff=d("revsDiff",function(e,t,n){function r(e,t){s.has(e)||s.set(e,{missing:[]}),s.get(e).missing.push(t)}function o(t,n){var o=e[t].slice(0);E(n,function(e,n,i,a,s){var u=n+"-"+i,c=o.indexOf(u);-1!==c&&(o.splice(c,1),"available"!==s.status&&r(t,u))}),o.forEach(function(e){r(t,e)})}"function"==typeof t&&(n=t,t={});var i=Object.keys(e);if(!i.length)return n(null,{});var a=0,s=new nr.Map;i.map(function(t){this._getRevisionTree(t,function(r,u){if(r&&404===r.status&&"missing"===r.message)s.set(t,{missing:e[t]});else{if(r)return n(r);o(t,u)}if(++a===i.length){var c={};return s.forEach(function(e,t){c[t]=e}),n(null,c)}})},this)}),Z.prototype.bulkGet=d("bulkGet",function(e,t){C(this,e,t)}),Z.prototype.compactDocument=d("compactDocument",function(e,t,n){var r=this;this._getRevisionTree(e,function(o,i){if(o)return n(o);var a=V(i),s=[],u=[];Object.keys(a).forEach(function(e){a[e]>t&&s.push(e)}),E(i,function(e,t,n,r,o){var i=t+"-"+n;"available"===o.status&&-1!==s.indexOf(i)&&u.push(i)}),r._doCompaction(e,u,n)})}),Z.prototype.compact=d("compact",function(e,t){"function"==typeof e&&(t=e,e={});var n=this;e=e||{},n._compactionQueue=n._compactionQueue||[],n._compactionQueue.push({opts:e,callback:t}),1===n._compactionQueue.length&&X(n)}),Z.prototype._compact=function(e,t){function n(e){a.push(o.compactDocument(e.id,0))}function r(e){var n=e.last_seq;fr.all(a).then(function(){return h(o,"_local/compaction",function(e){return!e.last_seq||e.last_seq<n?(e.last_seq=n,e):!1})}).then(function(){t(null,{ok:!0})})["catch"](t)}var o=this,i={return_docs:!1,last_seq:e.last_seq||0},a=[];o.changes(i).on("change",n).on("complete",r).on("error",t)},Z.prototype.get=d("get",function(e,t,n){function r(){var r=[],a=o.length;return a?void o.forEach(function(o){i.get(e,{rev:o,revs:t.revs,attachments:t.attachments},function(e,t){e?r.push({missing:o}):r.push({ok:t}),a--,a||n(null,r)})}):n(null,r)}if("function"==typeof t&&(n=t,t={}),"string"!=typeof e)return n(A(yr));if(I(e)&&"function"==typeof this._getLocal)return this._getLocal(e,n);var o=[],i=this;if(!t.open_revs)return this._get(e,t,function(e,r){if(e)return n(e);var o=r.doc,a=r.metadata,s=r.ctx;if(t.conflicts){var u=q(a);u.length&&(o._conflicts=u)}if(_(a,o._rev)&&(o._deleted=!0),t.revs||t.revs_info){var c=L(a.rev_tree),f=H(c,function(e){return-1!==e.ids.map(function(e){return e.id}).indexOf(o._rev.split("-")[1])}),l=f.ids.map(function(e){return e.id}).indexOf(o._rev.split("-")[1])+1,d=f.ids.length-l;if(f.ids.splice(l,d),f.ids.reverse(),t.revs&&(o._revisions={start:f.pos+f.ids.length-1,ids:f.ids.map(function(e){return e.id})}),t.revs_info){var h=f.pos+f.ids.length;o._revs_info=f.ids.map(function(e){return h--,{rev:h+"-"+e.id,status:e.opts.status}})}}if(t.attachments&&o._attachments){var p=o._attachments,v=Object.keys(p).length;if(0===v)return n(null,o);Object.keys(p).forEach(function(e){this._getAttachment(p[e],{binary:t.binary,ctx:s},function(t,r){var i=o._attachments[e];i.data=r,delete i.stub,delete i.length,--v||n(null,o)})},i)}else{if(o._attachments)for(var y in o._attachments)o._attachments.hasOwnProperty(y)&&(o._attachments[y].stub=!0);n(null,o)}});if("all"===t.open_revs)this._getRevisionTree(e,function(e,t){return e?n(e):(o=k(t).map(function(e){return e.rev}),void r())});else{if(!Array.isArray(t.open_revs))return n(A(br,"function_clause"));o=t.open_revs;for(var a=0;a<o.length;a++){var s=o[a];if("string"!=typeof s||!/^\d+-/.test(s))return n(A(Ir))}r()}}),Z.prototype.getView=d("getView",function(e,t,n){Y(this,e,"views",t,n)}),Z.prototype.getFilter=d("getFilter",function(e,t,n){Y(this,e,"filters",t,n)}),Z.prototype.getAttachment=d("getAttachment",function(e,t,n,r){var o=this;n instanceof Function&&(r=n,n={}),this._get(e,n,function(e,i){return e?r(e):i.doc._attachments&&i.doc._attachments[t]?(n.ctx=i.ctx,n.binary=!0,o._getAttachment(i.doc._attachments[t],n,r),void 0):r(A(pr))})}),Z.prototype.allDocs=d("allDocs",function(e,t){if("function"==typeof e&&(t=e,e={}),e.skip="undefined"!=typeof e.skip?e.skip:0,e.start_key&&(e.startkey=e.start_key),e.end_key&&(e.endkey=e.end_key),
+"keys"in e){if(!Array.isArray(e.keys))return t(new TypeError("options.keys must be an array"));var n=["startkey","endkey","key"].filter(function(t){return t in e})[0];if(n)return void t(A(Sr,"Query parameter `"+n+"` is not compatible with multi-get"));if("http"!==this.type())return G(this,e,t)}return this._allDocs(e,t)}),Z.prototype.changes=function(e,t){return"function"==typeof e&&(t=e,e={}),new O(this,e,t)},Z.prototype.close=d("close",function(e){return this._closed=!0,this._close(e)}),Z.prototype.info=d("info",function(e){var t=this;this._info(function(n,r){return n?e(n):(r.db_name=r.db_name||t._db_name,r.auto_compaction=!(!t.auto_compaction||"http"===t.type()),r.adapter=t.type(),void e(null,r))})}),Z.prototype.id=d("id",function(e){return this._id(e)}),Z.prototype.type=function(){return"function"==typeof this._type?this._type():this.adapter},Z.prototype.bulkDocs=d("bulkDocs",function(e,t,n){if("function"==typeof t&&(n=t,t={}),t=t||{},Array.isArray(e)&&(e={docs:e}),!e||!e.docs||!Array.isArray(e.docs))return n(A(hr));for(var r=0;r<e.docs.length;++r)if("object"!=typeof e.docs[r]||Array.isArray(e.docs[r]))return n(A(xr));var o;return e.docs.forEach(function(e){e._attachments&&Object.keys(e._attachments).forEach(function(e){o=o||z(e)})}),o?n(A(qr,o)):("new_edits"in t||("new_edits"in e?t.new_edits=e.new_edits:t.new_edits=!0),t.new_edits||"http"===this.type()||e.docs.sort(J),W(e.docs),this._bulkDocs(e,t,function(e,r){return e?n(e):(t.new_edits||(r=r.filter(function(e){return e.error})),void n(null,r))}))}),Z.prototype.registerDependentDatabase=d("registerDependentDatabase",function(e,t){function n(t){return t.dependentDbs=t.dependentDbs||{},t.dependentDbs[e]?!1:(t.dependentDbs[e]=!0,t)}var r=new this.constructor(e,this.__opts);h(this,"_local/_pouch_dependentDbs",n).then(function(){t(null,{db:r})})["catch"](t)}),Z.prototype.destroy=d("destroy",function(e,t){function n(){r._destroy(e,function(e,n){return e?t(e):(r._destroyed=!0,r.emit("destroyed"),void t(null,n||{ok:!0}))})}"function"==typeof e&&(t=e,e={});var r=this,o="use_prefix"in r?r.use_prefix:!0;return"http"===r.type()?n():void r.get("_local/_pouch_dependentDbs",function(e,i){if(e)return 404!==e.status?t(e):n();var a=i.dependentDbs,s=r.constructor,u=Object.keys(a).map(function(e){var t=o?e.replace(new RegExp("^"+s.prefix),""):e;return new s(t,r.__opts).destroy()});fr.all(u).then(n,t)})}),ee.prototype.execute=function(){var e;if(this.failed)for(;e=this.queue.shift();)e(this.failed);else for(;e=this.queue.shift();)e()},ee.prototype.fail=function(e){this.failed=e,this.execute()},ee.prototype.ready=function(e){this.isReady=!0,this.db=e,this.execute()},ee.prototype.addTask=function(e){this.queue.push(e),this.failed&&this.execute()},er(re,Z),re.debug=Zn;var Pr;if(oe())Pr=!1;else try{localStorage.setItem("_pouch_check_localstorage",1),Pr=!!localStorage.getItem("_pouch_check_localstorage")}catch(Hr){Pr=!1}re.adapters={},re.preferredAdapters=[],re.prefix="_pouch_";var Kr=new or.EventEmitter;ae(re),re.parseAdapter=function(e,t){var n,r,o=e.match(/([a-z\-]*):\/\/(.*)/);if(o){if(e=/http(s?)/.test(o[1])?o[1]+"://"+o[2]:o[2],n=o[1],!re.adapters[n].valid())throw"Invalid adapter";return{name:e,adapter:o[1]}}var i="idb"in re.adapters&&"websql"in re.adapters&&ie()&&localStorage["_pouch__websqldb_"+re.prefix+e];if(t.adapter)r=t.adapter;else if("undefined"!=typeof t&&t.db)r="leveldb";else for(var a=0;a<re.preferredAdapters.length;++a)if(r=re.preferredAdapters[a],r in re.adapters){if(i&&"idb"===r){console.log('PouchDB is downgrading "'+e+'" to WebSQL to avoid data loss, because it was already opened with WebSQL.');continue}break}n=re.adapters[r];var s=n&&"use_prefix"in n?n.use_prefix:!0;return{name:s?re.prefix+e:e,adapter:r}},re.adapter=function(e,t,n){t.valid()&&(re.adapters[e]=t,n&&re.preferredAdapters.push(e))},re.plugin=function(e){return Object.keys(e).forEach(function(t){re.prototype[t]=e[t]}),re},re.defaults=function(e){function t(n,r,o){return this instanceof t?("function"!=typeof r&&"undefined"!=typeof r||(o=r,r={}),n&&"object"==typeof n&&(r=n,n=void 0),r=$n.extend({},e,r),void re.call(this,n,r,o)):new t(n,r,o)}return er(t,re),ae(t),t.preferredAdapters=re.preferredAdapters.slice(),Object.keys(re).forEach(function(e){e in t||(t[e]=re[e])}),t};var Wr=de(),Jr=function(){},Vr=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],Gr="queryKey",Xr=/(?:^|&)([^&=]*)=?([^&]*)/g,zr=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Qr=function(e){return atob(e)},$r=function(e){return btoa(e)},Yr=Yn.extend,Zr={ajax:ye,parseUri:_e,uuid:D,Promise:fr,atob:Qr,btoa:$r,binaryStringToBlobOrBuffer:ge,clone:c,extend:Yr,createError:A},eo=sr.collate,to=1,no="pouchdb",ro=5,oo=0;ke.prototype.writeCheckpoint=function(e,t){var n=this;return this.updateTarget(e,t).then(function(){return n.updateSource(e,t)})},ke.prototype.updateTarget=function(e,t){return Se(this.target,this.id,e,t,this.returnValue)},ke.prototype.updateSource=function(e,t){var n=this;return this.readOnlySource?fr.resolve(!0):Se(this.src,this.id,e,t,this.returnValue)["catch"](function(e){if(Te(e))return n.readOnlySource=!0,!0;throw e})};var io={undefined:function(e,t){return 0===eo(e.last_seq,t.last_seq)?t.last_seq:0},1:function(e,t){return qe(t,e).last_seq}};ke.prototype.getCheckpoint=function(){var e=this;return e.target.get(e.id).then(function(t){return e.readOnlySource?fr.resolve(t.last_seq):e.src.get(e.id).then(function(e){if(t.version!==e.version)return oo;var n;return n=t.version?t.version.toString():"undefined",n in io?io[n](t,e):oo},function(n){if(404===n.status&&t.last_seq)return e.src.put({_id:e.id,last_seq:oo}).then(function(){return oo},function(n){return Te(n)?(e.readOnlySource=!0,t.last_seq):oo});throw n})})["catch"](function(e){if(404!==e.status)throw e;return oo})};var ao=0,so=r.setImmediate||r.setTimeout,uo=32768,co=l(function(e,t){function n(){var r=s*i,o=r+i;if(s++,a>s)c(u,e,r,o),so(n);else{c(u,e,r,o);var f=u.end(!0),l=Ie(f);t(null,l),u.destroy()}}var r="string"==typeof e,o=r?e.length:e.byteLength,i=Math.min(uo,o),a=Math.ceil(o/i),s=0,u=r?new ur:new ur.ArrayBuffer,c=r?Re:Le;n()});er(Pe,or.EventEmitter),Pe.prototype.cancel=function(){this.cancelled=!0,this.state="cancelled",this.emit("cancel")},Pe.prototype.ready=function(e,t){function n(){o.cancel()}function r(){e.removeListener("destroyed",n),t.removeListener("destroyed",n)}var o=this;o._readyCalled||(o._readyCalled=!0,e.once("destroyed",n),t.once("destroyed",n),o.once("complete",r))};var fo={replicate:Ke,toPouch:He},lo=fo.replicate;er(Je,or.EventEmitter),Je.prototype.cancel=function(){this.canceled||(this.canceled=!0,this.push.cancel(),this.pull.cancel())};var ho=25,po=50,vo={},yo=1800,_o=Zn("pouchdb:http");ot.valid=function(){return!0},it.prototype.add=function(e){return this.promise=this.promise["catch"](function(){}).then(function(){return e()}),this.promise},it.prototype.finish=function(){return this.promise};var mo,go=function(e,t){return t&&e.then(function(e){n.nextTick(function(){t(null,e)})},function(e){n.nextTick(function(){t(e)})}),e},bo=function(e){return rr(function(t){var n=t.pop(),r=e.apply(this,t);return"function"==typeof n&&go(r,n),r})},wo=function(e,t){return e.then(function(e){return t().then(function(){return e})},function(e){return t().then(function(){throw e})})},Eo=function(e,t){return function(){var n=arguments,r=this;return e.add(function(){return t.apply(r,n)})}},So=function(e){for(var t={},n=0,r=e.length;r>n;n++)t["$"+e[n]]=!0;var o=Object.keys(t),i=new Array(o.length);for(n=0,r=o.length;r>n;n++)i[n]=o[n].substring(1);return i},ko={uniq:So,sequentialize:Eo,fin:wo,callbackify:bo,promisedCallback:go},qo=sr.collate,xo=sr.toIndexableString,Ao=sr.normalizeKey,To=sr.parseIndexableString;mo="undefined"!=typeof console&&"function"==typeof console.log?Function.prototype.bind.call(console.log,console):function(){};var Oo=ko.callbackify,jo=ko.sequentialize,Co=ko.uniq,Io=ko.fin,Lo=ko.promisedCallback,Ro={},Do=new it,No=50,Bo={_sum:function(e,t){return gt(t)},_count:function(e,t){return t.length},_stats:function(e,t){function n(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];t+=o*o}return t}return{sum:gt(t),min:Math.min.apply(null,t),max:Math.max.apply(null,t),count:t.length,sumsqr:n(t)}}},Mo=Oo(function(){var e=this;return e._ddocCache&&delete e._ddocCache,"http"===e.type()?Bt(e):"function"==typeof e._viewCleanup?At(e):Mt(e)}),Fo=function(e,t,n){"function"==typeof t&&(n=t,t={}),t=t?Et(t):{},"function"==typeof e&&(e={map:e});var r=this,o=fr.resolve().then(function(){return Ft(r,e,t)});return Lo(o,n),o};er(Ut,Error),er(Pt,Error);var Uo={query:Fo,viewCleanup:Mo},Po=5,Ho="document-store",Ko="by-sequence",Wo="attach-store",Jo="attach-seq-store",Vo="meta-store",Go="local-store",Xo="detect-blob-support",zo={running:!1,queue:[]};er(qn,or.EventEmitter),qn.prototype.addListener=function(e,t,n,r){function o(){function e(){s=!1}if(a._listeners[t]){if(s)return void(s="waiting");s=!0;var u=i(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary"]);n.changes(u).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===s&&setTimeout(function(){o()},0),s=!1}).on("error",e)}}if(!this._listeners[t]){var a=this,s=!1;this._listeners[t]=o,this.on(e,o)}},qn.prototype.removeListener=function(e,t){t in this._listeners&&or.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t])},qn.prototype.notifyLocalWindows=function(e){oe()?chrome.storage.local.set({dbName:e}):ie()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},qn.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var Qo,$o=new nr.Map,Yo=new qn,Zo=new nr.Map;xn.valid=function(){var e="undefined"!=typeof openDatabase&&/(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent)&&!/BlackBerry/.test(navigator.platform);return!e&&"undefined"!=typeof indexedDB&&"undefined"!=typeof IDBKeyRange};var ei=7,ti=Rn("document-store"),ni=Rn("by-sequence"),ri=Rn("attach-store"),oi=Rn("local-store"),ii=Rn("metadata-store"),ai=Rn("attach-seq-store"),si=new nr.Map,ui=new qn,ci=1,fi="CREATE INDEX IF NOT EXISTS 'by-seq-deleted-idx' ON "+ni+" (seq, deleted)",li="CREATE UNIQUE INDEX IF NOT EXISTS 'by-seq-doc-id-rev' ON "+ni+" (doc_id, rev)",di="CREATE INDEX IF NOT EXISTS 'doc-winningseq-idx' ON "+ti+" (winningseq)",hi="CREATE INDEX IF NOT EXISTS 'attach-seq-seq-idx' ON "+ai+" (seq)",pi="CREATE UNIQUE INDEX IF NOT EXISTS 'attach-seq-digest-idx' ON "+ai+" (digest, seq)",vi=ni+".seq = "+ti+".winningseq",yi=ni+".seq AS seq, "+ni+".deleted AS deleted, "+ni+".json AS data, "+ni+".rev AS rev, "+ti+".json AS metadata";Qn.use_prefix=!("undefined"!=typeof n&&!n.browser),Qn.valid=Nn;var _i={idb:xn,websql:Qn};re.ajax=ye,re.utils=Zr,re.Errors=Nr,re.replicate=fo.replicate,re.sync=We,re.version="5.3.2",re.adapter("http",ot),re.adapter("https",ot),re.plugin(Uo),Object.keys(_i).forEach(function(e){re.adapter(e,_i[e],!0)}),t.exports=re}).call(this,e(13),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1,10:10,12:12,13:13,14:14,15:15,16:16,2:2,4:4,6:6,7:7,8:8}]},{},[17])(17)});
diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
index 4d11d17..0000000
--- a/docs/_config.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: PouchDB
-description: PouchDB, the JavaScript Database that Syncs!
-url: http://pouchdb.com
-highlighter: pygments
-markdown: redcarpet
-baseurl:
-version: 5.3.2
-paginate: 5
-paginate_path: "blog/page:num"
-github:
-  repository_url: https://github.com/pouchdb/pouchdb
-collections:
-  guides:
-    output: true
diff --git a/docs/_data/authors.yml b/docs/_data/authors.yml
deleted file mode 100644
index b94d146..0000000
--- a/docs/_data/authors.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-- name: Nick Colley
-  twitter: nickcolley
-  github: nickcolley
-  www: http://nickcolley.co.uk
-  gravatar: d83613912d1a2511a784b99c703bdcf6
-  
-- name: Nolan Lawson
-  twitter: nolanlawson
-  github: nolanlawson
-  www: http://nolanlawson.com
-  gravatar: c436dec61b906e27c963518d0ef1d972
-    
-- name: Dale Harvey
-  twitter: daleharvey
-  github: daleharvey
-  www: http://arandomurl.com
-  gravatar: 030451d8cfc268d666bae9a7fe8d10ec
-
-- name: Calvin Metcalf
-  twitter: CWMma
-  github: calvinmetcalf
-  www: http://calvinmetcalf.com/
-  gravatar: e8153037a068f1c32e546f82729a64a5
-
-- name: Giovanni Ornaghi
-  twitter: sphaso
-  github: sphaso
-  www: https://it.linkedin.com/in/giovanniornaghi
-  gravatar: da853b1ad9ebe5e1c3ab5b340bb63b70
diff --git a/docs/_guides/async-code.md b/docs/_guides/async-code.md
deleted file mode 100644
index f6f6ce9..0000000
--- a/docs/_guides/async-code.md
+++ /dev/null
@@ -1,228 +0,0 @@
----
-index: 6
-layout: guide
-title: Asynchronous code
-sidebar: guides_nav.html
----
-
-PouchDB provides a fully **asynchronous** API. This ensures that when you talk to PouchDB, the UI doesn't stutter, because the DOM is not being blocked by database operations.
-
-However, working with asynchronous code can be very complex, especially if you're only accustomed to synchronous APIs. So it's worth going over some of the basics.
-
-{% include anchor.html title="I promise to call you back..." hash="i-promise-to-call-you-back" %}
-
-To make things as flexible as possible for PouchDB users, the API is provided in both **callback** format and **promise** format.
-
-The **callback** format looks like this:
-
-```js
-db.get('mittens', function (error, doc) {
-  if (error) {
-    // oh noes! we got an error
-  } else {
-    // okay, doc contains our document
-  }
-});
-```
-
-The **promise** format looks like this:
-
-```js
-db.get('mittens').then(function (doc) {
-  // okay, doc contains our document
-}).catch(function (err) {
-  // oh noes! we got an error
-});
-```
-
-Basically, if you include a callback as the last argument in a function, then PouchDB assumes you want the callback style. Otherwise it assumes you want the promise style.
-
-{% include anchor.html title="Let's talk about promises" hash="lets-talk-about-promises" %}
-
-For this guide, we will use the **promise** format for a few reasons:
-
-1. Callbacks easily lead to spaghetti code, or to the [pyramid of doom](https://medium.com/@wavded/managing-node-js-callback-hell-1fe03ba8baf).
-2. Promises generally lead to better code organization, although they do have a steep learning curve.
-
-If you already understand promises, you can [skip to the next section](updating-deleting.html).
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-
-**What about async/await?**  Async functions are an experimental ES7 syntax that enhances promise-based APIs by adding
-the `async` and `await` keywords. For more information about `async`/`await`, read [our introductory blog post](http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html).
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-{% include anchor.html title="Understanding promises" hash="understanding-promises" %}
-
-If you have the time, you are strongly encouraged to watch [this 50-minute video: "Redemption from Callback Hell"](http://youtu.be/hf1T_AONQJU). The rest of this chapter basically summarizes that video.
-
-The best way to think of promises is that they bring keywords like `return` and `try/catch` to asynchronous code.
-
-Synchronous code:
-
-```js
-function returnSomething() {
-  try {
-    doSomething();
-    doSomethingElse();
-    return true;
-  } catch (err) {
-    console.log(err);
-  }
-}
-```
-
-Asynchronous code:
-
-```js
-function returnSomething() {
-  return doSomething().then(function () {
-    return doSomethingElse();
-  }).then(function () {
-    return true;
-  }).catch(function (err) {
-    console.log(err);
-  });
-}
-```
-
-{% include anchor.html title="Use `catch()` to catch errors" hash="use-catch-to catch errors" %}
-
-The big advantage of working with Promises in asynchronous code is that you can always attach a `catch` function to the end of a big promise chain, and any errors that occur along the way will show up at the end.
-
-This avoids endless `if (err) {}` checking in the callback world:
-
-```js
-doSomething(function (err, result) {
-  if (err) {
-    // handle error
-  }
-  doSomethingElse(function (err, result) {
-    if (err) {
-      // handle error again...
-    }
-    doSomethingYetAgain(function (err, result) {
-      if (err) {
-        // seriously? okay, handle error again...
-      }
-    });
-  });
-});
-```
-
-Instead, in the promise world, you can have a long chain of asynchronous operations with a single `catch` at the end. To use PouchDB as an example:
-
-```js
-db.put({_id: 'charlie', age: 21}).then(function () {
-  return db.get('charlie');
-}).then(function (charlie) {
-  // increment Charlie's age
-  charlie.age++;
-  return db.put(charlie);
-}).then(function () {
-  return db.get('charlie');
-}).then(function (charlie) {
-  // increment Charlie's age again
-  charlie.age++;
-  return db.put(charlie);
-}).then(function () {
-  return db.get('charlie');
-}).then(function (charlie) {
-  console.log(charlie);
-}).catch(function (err) {
-  console.log(err);
-});
-```
-
-You should see:
-
-```js
-{"age":23,"_id":"charlie","_rev":"3-e794618b4e39ed566cc68b56f5426e8e"}
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/612f95cbbb69eaafc2d5)** of this code.
-
-In this example, we put/get a document 3 times in a row. At the very end, there is a `catch()` statement to catch any errors along the way.
-
-What kind of errors might we run into? Well, let's imagine that we accidentally misspell the id `'charlie'` at some point. In this case, we will gracefully catch the error.  Here's another **[live example](http://bl.ocks.org/nolanlawson/0f1c815cb5fe74cff5fc)**.
-
-You should see:
-
-```js
-{"status":404,"name":"not_found","message":"missing"}
-```
-
-This is really nice! No matter where the misspelling is, the error can be handled within a single function. That's much nicer than having to do `if (err){}` an endless number of times!
-
-{% include anchor.html title="An alternate way of catching errors" hash="an-alternate-way-of-catching-errors" %}
-
-If you've been doing promises for awhile, you might have seen this instead:
-
-```js
-db.get('charlie').then(function (charlie) {
-  // we got the charlie doc
-}, function (err) {
-  // we got an error
-})
-```
-
-This is equivalent to:
-
-```js
-db.get('charlie').then(function (charlie) {
-  // we got the charlie doc
-}).catch(function (err) {
-  // we got an error
-})
-```
-
-The `catch()` method is just syntactic sugar. You can use either format.
-
-{% include anchor.html title="Promises 101" hash="promises-101" %}
-
-The `then()` method takes a function. What can you do within this function? Three things:
-
-* Return another promise
-* Throw an error
-* Return a non-promise object (or `undefined`)
-
-Another way to think of it is this:
-
-```js
-db.get('charlie').then(function (charlie) {
-  // Within this function, you can do
-  // try/catch/return like you normally would,
-  // and it will be handled asynchronously!
-}).then(function (result) {
-  // If the previous function returned something
-  // (or returned undefined), it will show up here
-  // as "result".
-}).catch(function (err) {
-  // If the previous function threw an error,
-  // it will show up here as "err".
-});
-```
-
-{% include anchor.html title="Promises in PouchDB" hash="promises-in-pouchdb" %}
-
-Promises are supported natively in [some browsers](http://caniuse.com/#feat=promises). But since they're not universally supported, PouchDB uses [lie](https://github.com/calvinmetcalf/lie) in browsers and Node.js when they are not supported.
-
-You are free to integrate any Promise library you like with PouchDB, as long as it is compliant with [the Promises A+ spec](http://promisesaplus.com/). Some libraries that fit the bill:
-
-<ul>
-<li><a href="https://github.com/petkaantonov/bluebird">bluebird</a></li>
-<li><a href="https://github.com/calvinmetcalf/lie">lie</a></li>
-<li><a href="https://github.com/kriskowal/q">Q</a></li>
-<li><a href="https://github.com/tildeio/rsvp.js">RSVP</a></li>
-<li><a href="https://github.com/then/promise">then/promise</a></li>
-<li><a href="https://github.com/cujojs/when">when</a></li>
-</ul>
-
-If you use one of these libraries, then you will have access to some advanced Promise features. Read that library's documentation for details.
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you have a grasp on promises, let's learn about updating and deleting documents.
diff --git a/docs/_guides/attachments.md b/docs/_guides/attachments.md
deleted file mode 100644
index 695b873..0000000
--- a/docs/_guides/attachments.md
+++ /dev/null
@@ -1,305 +0,0 @@
----
-index: 9
-layout: guide
-title: Working with attachments
-sidebar: guides_nav.html
----
-
-Attachments are where PouchDB can get really fun.
-
-The big difference between storage engines like WebSQL/IndexedDB and the older localStorage API is that you can stuff [a lot more data](http://www.html5rocks.com/en/tutorials/offline/quota-research/) in it.
-
-PouchDB attachments allow you to use that to full advantage to store images, MP3s, zip files, or whatever you want.
-
-{% include anchor.html title="How attachments are stored" hash="how-attachments-are-stored" %}
-
-As their name implies, attachments are *attached* to documents. You can work with attachments either in base64-encoded format, or as a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
-
-For example, here is a very simple document with a plain text attachment, stored as base64.
-
-```js
-db.put({
-  _id: 'mydoc',
-  _attachments: {
-    'myattachment.txt': {
-      content_type: 'text/plain',
-      data: 'aGVsbG8gd29ybGQ='
-    }
-  }
-});
-```
-
-Our document has the usual `_id` field, but it also has a special `_attachments` field that holds the attachments. Documents can have as many attachments as you want.
-
-{% include alert/start.html variant="info" %}
-
-When you create an attachment, you need to specify its <code>content_type</code>, otherwise known as the <a href='https://en.wikipedia.org/wiki/MIME'>MIME type</a>. Common MIME types include <code>'text/plain'</code> for plain text, <code>'image/png'</code> for PNG images, and <code>'image/jpeg'</code> for JPG images.
-
-{% include alert/end.html %}
-
-As it turns out, `'aGVsbG8gd29ybGQ='` is just the string `'hello world'` encoded in base64. You can use the `atob()` and `btoa()` methods in your browser to verify.
-
-```js
-btoa('hello world')      // "aGVsbG8gd29ybGQ="
-atob('aGVsbG8gd29ybGQ=') // "hello world"
-```
-
-Let's see what happens after we store this document. If you try to `get()` it normally, you may be surprised to see that the attachment data itself isn't returned:
-
-```js
-db.get('mydoc').then(function (doc) {
-  console.log(doc);
-});
-```
-
-The returned document will look like this:
-
-```js
-{
-  "_attachments": {
-    "myattachment.txt": {
-      "content_type": "text/plain",
-      "digest": "md5-XrY7u+Ae7tCTyyK7j1rNww==",
-      "stub": true
-    }
-  },
-  "_id": "mydoc",
-  "_rev": "1-e8a84187bb4e671f27ec11bdf7320aaa"
-}
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/0a4b1267d3a5b5edd7b1)** of this code.
-
-By default, PouchDB will only give you an attachment **stub**, which contains a `digest`, i.e. the [md5sum](http://en.wikipedia.org/wiki/Md5sum) of the binary attachment.
-
-To get the full attachments when using `get()` or `allDocs()`, you need to specify `{attachments: true}`:
-
-```js
-db.get('mydoc', {attachments: true}).then(function (doc) {
-  console.log(doc);
-});
-```
-
-Then you'll get back the full attachment, base64-encoded:
-
-```js
-{
-  "_attachments": {
-    "myattachment.txt": {
-      "content_type": "text/plain",
-      "digest": "md5-XrY7u+Ae7tCTyyK7j1rNww==",
-      "data": "aGVsbG8gd29ybGQ="
-    }
-  },
-  "_id": "mydoc",
-  "_rev": "1-e8a84187bb4e671f27ec11bdf7320aaa"
-}
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/b6d6164035f1fa0d38a8)** of this code.
-
-{% include anchor.html title="Image attachments" hash="image-attachments" %}
-
-Plaintext is cool and all, but you know what would be *really* awesome? Storing images.
-
-So let's do it! In this example, we'll put a document with a small icon attachment, represented as a base64-encoded string. Then we'll fetch it and display the icon as a normal `<img>` tag:
-
-```js
-db.put({
-  _id: 'meowth',
-  _attachments: {
-    'meowth.png': {
-      content_type: 'image/png',
-      data: 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAkCAIAAAB0Xu9BAAAABGdBTUEAALGPC/xhBQAAAuNJREFUWEetmD1WHDEQhDdxRMYlnBFyBIccgdQhKVcgJeQMpE5JSTd2uqnvIGpVUqmm9TPrffD0eLMzUn+qVnXPwiFd/PP6eLh47v7EaazbmxsOxjhTT88z9hV7GoNF1cUCvN7TTPv/gf/+uQPm862MWTL6fff4HfDx4S79/oVAlAUwqOmYR0rnazuFnhfOy/ErMKkcBFOr1vOjUi2MFn4nuMil6OPh5eGANLhW3y6u3aH7ijEDCxgCvzFmimvc95TekZLyMSeJC68Bkw0kqUy1K87FlpGZqsGFCyqEtQNDdFUtFctTiuhnPKNysid/WFEFLE2O102XJdEE+8IgeuGsjeJyGHm/xHvQ3JtKVsGGp85g9rK6xMHtvHO9+WACYjk5vkVM6XQ6OZubCJvTfPicYPeHO2AKFl5NuF5UK1VDUbeLxh2BcRGKTQE3irHm3+vPj6cfCod50Eqv5QxtwBQUGhZhbrGVuRia1B4MNp6edwBxld2sl1splfHCwfsvCZfrCQyWmX10djjOlWJSSy3VQlS6LmfrgNvaieRWx1LZ6s9co+P0DLsy3OdLU3lWRclQsVcHJBcUQ0k9/WVVrmpRzYQzpgAdQcAXxZzUnFX3proannrYH+Vq6KkLi+UkarH09mC8YPr2RMWOlEqFkQClsykGEv7CqCUbXcG8+SaGvJ4a8d4y6epND+pEhxoN0vWUu5ntXlFb5/JT7JfJJqoTdy9u9qc7ax3xJRHqJLADWEl23cFWl4K9fvoaCJ2BHpmJ3s3z+O0U/DmzdMjB9alWZtg4e3yxzPa7lUR7nkvxLHO9+tvJX3mtSDpwX8GajB283I8R8a7D2MhUZr1iNWdny256yYLd52DwRYBtRMvE7rsmtxIUE+zLKQCDO4jlxB6CZ8M17GhuY+XTE8vNhQiIiSE82ZsGwk1pht4ZSpT0YVpon6EvevOXXH8JxVR78QzNuamupW/7UB7wO/+7sG5V4ekXb4cL5Lyv+4IAAAAASUVORK5CYII='
-    }
-  }
-}).then(function () {
-  return db.getAttachment('meowth', 'meowth.png');
-}).then(function (blob) {
-  var url = URL.createObjectURL(blob);
-  var img = document.createElement('img');
-  img.src = url;
-  document.body.appendChild(img);
-}).catch(function (err) {
-  console.log(err);
-});
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/2a5f98a66c9fe3ae3532)** of this code.
-
-You should be unsurprised to see a cat smiling back at you. If the kitten theme bothers you, then you haven't been on the Internet very long.
-
-How does this code work? First off, we are making use of the `URL.createObjectURL()` method, which is a standard HTML5 method that converts a `Blob` to a URL that we can easily use as the `src` of an `img`.
-
-Second off, we are using the `getAttachment()` API, which returns a `Blob` rather than a base64-encoded string. To be clear: we can always convert between base64 and `Blob`s, but in this case, `getAttachment()` is just more convenient.
-
-
-{% include anchor.html title="Directly storing binary data" hash="directly-storing-binary-data" %}
-
-Up to now, we've been supplying our attachments as base64-encoded strings. But we can also create the Blobs ourselves and store those directly in PouchDB.
-
-Another shortcut we can use is the `putAttachment()` API, which simply modifies the existing document to hold a new attachment. Or, if the document does not exist, it will create an empty one.
-
-{% include alert/start.html variant="info" %}
-
-In <strong>Node.js</strong>, PouchDB uses <a href='http://nodejs.org/api/buffer.html'>Buffers</a> instead of Blobs. Otherwise, the same rules apply.
-
-{% include alert/end.html %}
-
-For instance, we can read the image data from an `<img>` tag using a `canvas` element, and then directly write that Blob to PouchDB:
-
-```js
-function convertImgToBlob(img, callback) {
-   var canvas = document.createElement('canvas');
-   var context = canvas.getContext('2d');
-   context.drawImage(img, 0, 0);
-
-    // Warning: toBlob() isn't supported by every browser.
-    // You may want to use blob-util.
-   canvas.toBlob(callback, 'image/png');
-}
-
-var catImage = document.getElementById('cat');
-convertImgToBlob(catImage, function (blob) {
-  db.putAttachment('meowth', 'meowth.png', blob, 'image/png').then(function () {
-    return db.get('meowth', {attachments: true});
-  }).then(function (doc) {
-    console.log(doc);
-  });
-});
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/edaf09b84185418a55d9)** of this code.
-
-This stores exactly the same image content as in the other example, which you can confirm by checking the base64-encoded output.
-
-{% include alert/start.html variant="warning" %}
-
-Blobs can be tricky to work with, especially when it comes to cross-browser support.
-You may find <a href='https://github.com/nolanlawson/blob-util'>blob-util</a> to be a useful
-addition to the attachment API. For instance, it has an
-<code>imgSrcToBlob()</code> method that will work cross-browser.
-
-{% include alert/end.html %}
-
-{% include anchor.html title="Allow the user to store an attachment" hash="allow-the-user-to-store-an-attachment" %}
-
-You can also upload a file with the HTML5 `File` API and store it directly in the database, because the data you get from the `<input type="file">` element is already a `Blob`.
-(See: [Blob API](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [File API](https://developer.mozilla.org/en-US/docs/Web/API/File), which inherits properties from the `Blob` Interface.)
-
-Here is an example of allowing a user to choose a file from their filesystem:
-
-```html
-<input type="file">
-```
-
-And then "uploading" that file directly into PouchDB:
-
-```js
-var input = document.querySelector('input');
-input.addEventListener('change', function () {
-  var file = input.files[0]; // file is a Blob
-
-  db.put({
-    _id: 'mydoc',
-    _attachments: {
-      filename: {
-        type: file.type,
-        data: file
-      }
-    }
-  }).catch(function (err) {
-    console.log(err);
-  });
-});
-```
-
-You can see **[a live example](http://bl.ocks.org/ntwcklng/f57b03c15e91c25e2cb5)** of this code.
-
-Select a file and you will see the stored file, `size`, and `type`, which are valid `Blob` properties. If you choose an image, it will also show the image!
-
-{% include anchor.html title="Base64 vs Blobs/Buffers" hash="base64-vs-blobs-buffers" %}
-
-Whether you supply attachments as base64-encoded strings or as Blobs/Buffers, PouchDB will try to store them in [the most efficient way](/faq.html#data_types).
-
-So when you insert your attachments, either format is acceptable. For instance, you can put Blobs/Buffers using `put()`:
-
-```js
-db.put({
-  _id: 'mydoc',
-  _attachments: {
-    'myattachment.txt': {
-      content_type: 'text/plain',
-      data: myBlob
-    }
-  }
-});
-```
-
-And you can also pass base64-encoded strings to `putAttachment()`:
-
-```js
-db.putAttachment('mydoc', 'myattachment.png', myBase64String, 'image/png');
-```
-
-You can also insert multiple attachments at once using `put()`:
-
-```js
-db.put({
-  _id: 'mydoc',
-  _attachments: {
-    'myattachment1.txt': {
-      content_type: 'text/plain',
-      data: myBlob1
-    },
-    'myattachment2.txt': {
-      content_type: 'text/plain',
-      data: myBlob2
-    },
-    'myattachment3.txt': {
-      content_type: 'text/plain',
-      data: myBlob3
-    },
-    // etc.
-  }
-});
-```
-
-The `bulkDocs()` and `post()` APIs also accept attachments in either format.
-
-When you fetch attachments, however, `getAttachment()` will always return Blobs/Buffers.
-
-The other "read" APIs, such as `get()`, `allDocs()`, `changes()`, and `query()` have an `{attachments: true}` option that returns the attachments base64-encoded strings. If you add `{binary: true}`, though, they will return Blobs/Buffers.
-
-{% include anchor.html title="Blob types" hash="blob-types" %}
-
-Blobs have their own `type`, but there is also a `content_type` that you specify when you store it in PouchDB:
-
-```js
-var myBlob = new Blob(['I am plain text!'], {type: 'text/plain'});
-console.log(myBlob.type); // 'text/plain'
-
-db.put({
-  _id: 'mydoc',
-  _attachments: {
-    'myattachment.txt': {
-      content_type: 'text/plain',
-      data: myBlob
-    }
-  }
-});
-```
-
-The reason for this redundancy is 1) Buffers in Node do not have a `type`, and 2) the CouchDB attachment format requires it.
-
-So for best results, you should ensure that your Blobs have the same type as the one reported to PouchDB. Otherwise you may see inconsistent behavior (e.g. in IndexedDB, where the Blob is stored as-is on compatible browsers).
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [putAttachment()](/api.html#save_attachment)
-* [getAttachment()](/api.html#get_attachment)
-* [removeAttachment()](/api.html#delete_attachment)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you can attach cat pictures to all your documents (and why wouldn't you?), let's talk about replication.
diff --git a/docs/_guides/bulk-operations.md b/docs/_guides/bulk-operations.md
deleted file mode 100644
index 127b101..0000000
--- a/docs/_guides/bulk-operations.md
+++ /dev/null
@@ -1,132 +0,0 @@
----
-index: 8
-layout: guide
-title: Bulk operations
-sidebar: guides_nav.html
----
-
-You can `get()`, `put()`, and `remove()` single documents to your heart's content, but a database isn't a database unless it can handle many operations at once!
-
-PouchDB provides two methods for bulk operations - `bulkDocs()` for bulk writes, and `allDocs()` for bulk reads.
-
-{% include anchor.html title="Use `bulkDocs()` to write many docs" hash="use-bulkdocs-to-write-many-docs" %}
-
-The `bulkDocs()` API is very simple.  It just takes a list of documents that you want to `put()` into the database:
-
-```js
-db.bulkDocs([
-  {
-    _id: 'mittens',
-    occupation: 'kitten',
-    cuteness: 9.0
-  },
-  {
-    _id: 'katie',
-    occupation: 'kitten',
-    cuteness: 7.0
-  },
-  {
-    _id: 'felix',
-    occupation: 'kitten',
-    cuteness: 8.0
-  }
-]);
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/038a45134341f3b7235b)** of this code.
-
-This code is equivalent to `put()`ing each document separately:
-
-```js
-db.put({
-    _id: 'mittens',
-    occupation: 'kitten',
-    cuteness: 9.0
-}).then(function () {
-  return db.put({
-    _id: 'katie',
-    occupation: 'kitten',
-    cuteness: 7.0
-  });
-}).then(function () {
-  return db.put({
-    _id: 'felix',
-    occupation: 'kitten',
-    cuteness: 8.0
-  });
-});
-```
-
-{% include anchor.html title="Why bulk up with `bulkDocs()`?" hash="why-bulk-up-with-bulkdocs" %}
-
-Bulk operations tend to be faster than individual operations, because they can be combined into a single transaction (in a local IndexedDB/WebSQL) or a single HTTP request (in a remote CouchDB).
-
-You can also update or delete multiple documents this way. You just need to include the `_rev` and `_deleted` values as previously discussed. The same rules as for `put()` apply to each individual document.
-
-{% include alert/start.html variant="warning" %}
-
-Neither <code>bulkDocs()</code> nor <code>allDocs()</code> constitutes a transaction in the traditional sense. That means that, if a single <code>put()</code> fails, you should not assume that the others will fail.
-<p/>
-<p/>
-By design, CouchDB and PouchDB do not support transactions. A document is the smallest unit of operations.
-{% include alert/end.html %}
-
-{% include anchor.html title="Use `allDocs()` to read many docs" hash="use-alldocs-to-read-many-docs" %}
-
-Likewise, `allDocs()` is a method that allows you to read many documents at once.
-
-Most crucially, when you read from `allDocs()`, the documents are returned *sorted by order of `_id`*.  This makes the `_id` a very powerful field that you can use for more than just uniquely identifying your documents.
-
-For instance, if you refer back to [the live example](http://bl.ocks.org/nolanlawson/038a45134341f3b7235b) above, you'll notice that the kittens are sorted by their name, because their names are used as their `_id`s.
-
-Another common way to take advantage of this is to use `new Date().toJSON()` as your document `_id`s. In this way, all your documents will be sorted by date.
-
-For instance, let's save three kittens with three different dates, and then fetch them sorted by date:
-
-```js
-db.put({
-    _id: new Date().toJSON(),
-    name: 'Mittens',
-    occupation: 'kitten',
-    cuteness: 9.0
-}).then(function () {
-  return db.put({
-    _id: new Date().toJSON(),
-    name: 'Katie',
-    occupation: 'kitten',
-    cuteness: 7.0
-  });
-}).then(function () {
-  return db.put({
-    _id: new Date().toJSON(),
-    name: 'Felix',
-    occupation: 'kitten',
-    cuteness: 8.0
-  });
-}).then(function () {
-  return db.allDocs({include_docs: true});
-}).then(function (response) {
-  console.log(response);
-}).catch(function (err) {
-  console.log(err);
-});
-```
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/8f58dbc360348a4c95f6)** to confirm that the kittens are sorted by the order they were put into the database.
-
-{% include anchor.html title="Please use `allDocs()`. Seriously." hash="please-use-alldocs" %}
-
-`allDocs()` is the unsung star of the PouchDB world. It not only returns documents in order &ndash; it also allows you to reverse the order, filter by `_id`, slice and dice using "greater than" and "less than" operations on the `_id`, and much more.
-
-Far too many developers overlook this valuable API, because they misunderstand it. When a developer says "my PouchDB app is slow!", it is usually because they are using the slow `query()` API when they should be using the fast `allDocs()` API.
-
-For details on how to effectively use `allDocs()`, you are strongly recommended to read ["Pagination strategies with PouchDB"](http://pouchdb.com/2014/04/14/pagination-strategies-with-pouchdb.html). For 99% of your applications, you should be able to use `allDocs()` for all the pagination/sorting/searching functionality that you need.
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [bulkDocs()](/api.html#batch_create)
-* [allDocs()](/api.html#batch_fetch)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you've fallen helplessly in love with `bulkDocs()` and `allDocs()`, let's turn our wandering gaze to attachments.
diff --git a/docs/_guides/changes.md b/docs/_guides/changes.md
deleted file mode 100644
index 14ab96e..0000000
--- a/docs/_guides/changes.md
+++ /dev/null
@@ -1,142 +0,0 @@
----
-index: 12
-layout: guide
-title: Changes feed
-sidebar: guides_nav.html
----
-
-One of the brilliant things about CouchDB replication is that it makes it easy to learn about changes made to the database over time. CouchDB allows you to easily answer questions like:
-
-* What changes occurred to the database since a given time?
-* What changes occurred to this document?
-* What did this database look like a few days ago?
-
-For all of these and related questions, there's the `changes()` API.
-
-{% include anchor.html title="Basic changes usage" hash="basic-changes-usage" %}
-
-If you want to simply fetch all changes since the beginning of time, you can do:
-
-```js
-db.changes({
-  since: 0,
-  include_docs: true
-}).then(function (changes) {
-
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/7c32861af5d31a8fac4a)** of this code.
-
-Then you will have a list of all changes made to the database, in the order that they were made.
-
-One thing you will notice about the changes feed is that it actually omits non-leaf revisions to documents. For instance, in the live example, we skip from `seq` 1 immediately to `seq` 3.
-
-This is by design &ndash; the changes feed only tells us about leaf revisions. However, the order of those leaf revisions is determined by the order they were put in the database. So you may notice that `'firstDoc'` still appears before `'secondDoc'`, which appears before `'thirdDoc'`.
-
-Also notice the the option `{include_docs: true}`. By default, the documents themselves are not included in the changes feed; only the `id`s, `rev`s, and whether or not they were `deleted`. With `{include_docs: true}`, however, each non-deleted change will have a `doc` property containing the new or modified document.
-
-{% include anchor.html title="Changes pagination" hash="changes-pagination" %}
-
-If you expect this to be a very large number of changes, you can also use the `limit` option to do pagination:
-
-```js
-var pageSize = 10;
-var lastSeq = 0;
-function fetchNextPage() {
-  return db.changes({
-    since: lastSeq,
-    limit: pageSize
-  }).then(function (changes) {
-    if (changes.results.length < pageSize) {
-      // done!
-    } else {
-      lastSeq = changes.last_seq;
-      return fetchNextPage();
-    }
-  });
-}
-
-fetchNextPage().catch(function (err) {
-  // handle errors
-});
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/dcdeae555b31c2a6d332)** of this code.
-
-{% include anchor.html title="`seq` versus `_rev`" hash="seq-versus-rev" %}
-
-The changes feed lists each change with a corresponding `seq` integer. `seq` always starts with 0, and beyond that it increases monotonically. (In Cloudant, these are strings rather than integers.)
-
-`seq` can be thought of as a version number for the entire database. Basically it answers the question of "How many total changes have been made to all documents in this database?" This sets it apart from the revision hash `_rev`, which marks the changes made to a single document.
-
-However, the `seq` between two databases is not guaranteed to be kept in sync. CouchDB and PouchDB have slightly different ways of increasing their `seq` values, so really `seq` is only meaningful within a single database.
-
-{% include anchor.html title="Live changes feed" hash="live-changes-feed" %}
-
-Just like replication, you can also listen to a live changes feed. The way this works is very similar to the replication API:
-
-```js
-db.changes({
-  since: 'now'
-}).on('change', function (change) {
-  // received a change
-}).on('error', function (err) {
-  // handle errors
-});
-```
-
-In the above example, we've also taken advantage of the quasi-magical `'now'` option for `since`, which will give us all changes from the moment we start listening.
-
-This can be very useful for scenarios where you want to update the UI whenever something in the database changes, such as for a real-time chat application.
-
-{% include anchor.html title="Understanding changes" hash="understanding-changes" %}
-
-There are two types of changes:
-
-* Added or modified documents
-* Deleted documents
-
-To distinguish between the two types in a live `changes()` listener,
-you can use the following code:
-
-```js
-db.changes({
-  since: 'now',
-  live: true,
-  include_docs: true
-}).on('change', function (change) {
-  // change.id contains the doc id, change.doc contains the doc
-  if (change.deleted) {
-    // document was deleted
-  } else {
-    // document was added/modified
-  }
-}).on('error', function (err) {
-  // handle errors
-});
-```
-
-You can see a [live example](http://bl.ocks.org/nolanlawson/fa42662cdfeeaa7b78fc) of this code.
-
-Notice that `change.doc` contains the document (unless it's deleted), because we used `{include_docs: true}`.
-
-Also notice that new documents always have revisions starting with the string `'1-'`. Subsequent revisions start with `'2-'`, `'3-'`, `'4-'`, etc.
-
-{% include alert/start.html variant="info" %}
-
-<p><strong>How can I distinguish between added and modified documents?</strong> Checking if the revision starts with <code>'1-'</code> is a pretty good trick. However, this will not work for databases that are replication targets, because replication only sends the latest versions of documents. This means that the <code>'1-'</code> revision may get skipped entirely, and the local database will only receive the 2nd, 3rd or 4th (etc.) revision. Conflicting revisions will also appear in the changes feed.</p>
-
-<p>So the short answer is that you cannot. If you are trying to mirror changes in a non-Pouch structure (e.g. a list of DOM elements), then the best solution is to search all the DOM elements to see if the document already exists, or to re-run <code>allDocs()</code> for every change.</p>
-
-{% include alert/end.html %}
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [changes()](/api.html#changes)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that we know how to hook our data spigot to the changes feed, let's look into using the very powerful `query()` API.
diff --git a/docs/_guides/compact-and-destroy.md b/docs/_guides/compact-and-destroy.md
deleted file mode 100644
index 9dce70d..0000000
--- a/docs/_guides/compact-and-destroy.md
+++ /dev/null
@@ -1,97 +0,0 @@
----
-index: 14
-layout: guide
-title: Compacting and destroying
-sidebar: guides_nav.html
----
-
-By default, PouchDB and CouchDB are designed to store all document revisions forever. This is very similar to how Git works, and it helps ensure that two databases can consistently replicate with each other.
-
-However, if you allow your database to grow without bounds, it can end up taking up much more space than you need. This can especially be a problem in [browsers with storage quotas](/faq.html#data_limits).
-
-To mitigate this problem, PouchDB offers two recourses: compaction and destruction.
-
-{% include anchor.html title="Compacting a database" hash="compacting-a-database" %}
-
-When you compact a database, you tell PouchDB to optimize its current storage usage. CouchDB will do the same thing:
-
-```js
-return db.compact().then(function (info) {
-  // compaction complete
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-From the API perspective, nothing should be different about the database after compaction, *except* that non-leaf revisions will no longer be available.
-
-```js
-db.put({_id: 'foo', version: 1}).then(function () {
-  return db.get('foo');
-}).then(function (doc) {
-  doc.version = 2;
-  return db.put(doc);
-}).then(function () { )
-  return db.compact();
-}).then(function () {
-  // DANGER!
-  // From now on, revision 1 is no longer available.
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/ff6eb521793e3a199864)** of this code.
-
-Compaction is a great feature, but it may not be what you desire if you want to retain a document's history from the beginning of time.
-
-However, if that's not a concern, then compaction is a harmless operation. In fact, since leaf revisions are retained, this means that you can still do [conflict resolution](/guides/conflicts.html) after compaction!
-
-{% include anchor.html title="Auto-compaction" hash="auto-compaction" %}
-
-If you really want to go all-in on compaction, then you can even put your database in `auto_compaction` mode. This means that it will automatically perform a `compact()` operation after every write.
-
-```js
-var db = new PouchDB('mydb', {auto_compaction: true});
-db.put({_id: 'foo', version: 1}).then(function () {
-  return db.get('foo');
-}).then(function (doc) {
-  doc.version = 2;
-  return db.put(doc);
-}).then(function () {
-  // Revision 1 is already unavailable!
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/b88f46d7cbaef8d93cba)** of this code.
-
-This feature is only available in local databases, not remote ones. On remote databases, the `auto_compaction` option will do nothing.
-
-{% include anchor.html title="Destroying a database" hash="destroying-a–database" %}
-
-We all love our databases, but sometimes good things must come to an end, and you need to snub out a database completely.
-
-So if you want to give your database to a nice farm family upstate, then the `destroy()` API is for you. It's very simple:
-
-```js
-new PouchDB('mydb').destroy().then(function () {
-  // database destroyed
-}).catch(function (err) {
-  // error occurred
-})
-```
-
-Note that destroying a database does not mean that replicated databases will also be destroyed. Destruction has nothing to do with the normal `put()`/`remove()` operations on documents, so it has no impact on replication.
-
-Also note that in Web SQL, the database will not really be destroyed &ndash; it will just have its tables dropped. This is because Web SQL does not support true database deletion.
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [compact()](/api.html#compaction)
-* [destroy()](/api.html#delete_database)
-
-{% include anchor.html title="Next" hash="next" %}
-
-To wrap up, let's look at a special class of documents in PouchDB &ndash; local docs.
diff --git a/docs/_guides/conflicts.md b/docs/_guides/conflicts.md
deleted file mode 100644
index ffb29eb..0000000
--- a/docs/_guides/conflicts.md
+++ /dev/null
@@ -1,168 +0,0 @@
----
-index: 11
-layout: guide
-title: Conflicts
-sidebar: guides_nav.html
----
-
-Conflicts are an unavoidable reality when dealing with distributed systems. And make no mistake: client-server *is* a distributed system.
-
-CouchDB and PouchDB differ from many other sync solutions, because they bring the issue of conflicts front-and-center. With PouchDB, conflict resolution is entirely under your control.
-
-{% include alert/start.html variant="info" %}
-
-PouchDB exactly implements CouchDB's replication algorithm, so conflict resolution works the same in both. For the purposes of this article, "CouchDB" and "PouchDB" may be used interchangeably.
-
-{% include alert/end.html %}
-
-{% include anchor.html title="Two types of conflicts" hash="two-types-of-conflicts" %}
-
-In CouchDB, conflicts can occur in two places: immediately, when you try to commit a new revision, or later, when two peers have committed changes to the same document. Let's call these **immediate conflicts** and **eventual conflicts**.
-
-### Immediate conflicts
-
-**Immediate conflicts** can occur with any API that takes a `rev` or a document with `_rev` as input &ndash; `put()`, `post()`, `remove()`, `bulkDocs()`, and `putAttachment()`. They manifest as a `409` (conflict) error:
-
-```js
-var myDoc = {
-  _id: 'someid',
-  _rev: '1-somerev'
-};
-db.put(myDoc).then(function () {
-  // success
-}).catch(function (err) {
-  if (err.status === 409) {
-    // conflict!
-  } else {
-    // some other error
-  }
-});
-```
-
-In your code, *you should always be handling conflicts*. No matter how unlikely it may seem, 409s can and do occur.
-
-For instance, if you are doing live replication, a document may be modified by somebody else while the user is working on it. If the remote changes are replicated to the local database before the user tries to commit their changes, then they will receive the above 409 error.
-
-#### Upsert
-
-In many cases, the most practical solution to the 409 problem is to retry the `put()` until it succeeds. If the user's intended change can be expressed as a **delta** (i.e. a change that doesn't depend on the current revision), then this is very easy to achieve.
-
-Borrowing a phrase from MongoDB, let's call this an **upsert** ("update or insert"), and use the [pouchdb-upsert](https://github.com/pouchdb/pouchdb-upsert) plugin to implement it:
-
-```js
-function myDeltaFunction(doc) {
-  doc.counter = doc.counter || 0;
-  doc.counter++;
-  return doc;
-}
-
-db.upsert('my_id', myDeltaFunction).then(function () {
-  // success!
-}).catch(function (err) {
-  // error (not a 404 or 409)
-});
-```
-
-This `upsert()` function takes a `docId` and `deltaFunction`, where the `deltaFunction` is just a function that takes a document and outputs a new document. (If the document does not exist, then an empty document is provided.)
-
-`pouchdb-upsert` also offers a `putIfNotExists()` function, which will create a document if it doesn't exist already. For more details, see [the plugin's documentation](https://github.com/pouchdb/pouchdb-upsert#readme).
-
-### Eventual conflicts
-
-Now, let's move on to the second type: **eventual conflicts**.
-
-Imagine two PouchDB databases have both gone offline. The two separate users each make modifications to the same document, and then they come back online at a later time.
-
-Both users committed changes to the same version of the document, and their local databases did not throw 409 errors. What happens then?
-
-This is the classic "conflict" scenario, and CouchDB handles it very elegantly. By default, CouchDB will choose an arbitrary winner based on a deterministic algorithm, which means both users will see the same winner once they're back online. However, since the replication history is stored, you can always go back in time to resolve the conflict.
-
-To detect if a document is in conflict, you use the `{conflicts: true}` option when you `get()` it.
-
-```js
-db.get('docid', {conflicts: true}).then(function (doc) {
-  // do something with the doc
-}).catch(function (err) {
-  // handle any errors
-});
-```
-
-If the document has conflicts, then the `doc` will be returned with a `_conflicts` attribute, which may contain the IDs of conflicting revisions.
-
-For instance, imagine the `doc` returned is the following:
-
-```js
-{
-  "_id": "docid",
-  "_rev": "2-x",
-  "_conflicts": ["2-y"]
-}
-```
-
-Here we have two separate revisions (`2-x` and `2-y`) written by two separate databases, and one database's revision (`2-x`) has arbitrarily won.
-
-{% include alert/start.html variant="warning" %}
-{% markdown %}
-
-Normally, `_rev`s look more like `2-c1592ce7b31cc26e91d2f2029c57e621`, i.e. a digit followed by a very long hash. In these examples, `x` and `y` are used in place of the hash, for simplicity's sake.
-
-{% endmarkdown %}
-{% include alert/end.html %}
-
-Notice that the document's current revision starts with `2-`, and the conflicting version also starts with `2-`, indicating that they're both at the same level of the revision tree. (Revision hashes start with `1-`, `2-`, `3-`, etc., which indicates their distance from the first, "root" revision. The root always starts with `1-`.)
-
-Both databases will see the same conflict, assuming replication has completed. In fact, all databases in the network will see the exact same revision history &ndash; much like Git.
-
-To fetch the losing revision, you simply `get()` it using the `rev` option:
-
-```js
-db.get('docid', {rev: '2-y'}).then(function (doc) {
-  // do something with the doc
-}).catch(function (err) {
-  // handle any errors
-});
-```
-
-At this point, you can present both versions to the user, or resolve the conflict automatically using your preferred conflict resolution strategy: last write wins, first write wins, [RCS](https://www.gnu.org/software/rcs/), etc.
-
-To mark a conflict as resolved, all you need to do is `remove()` the unwanted revisions. So for instance, to remove `'2-y'`, you would do:
-
-```js
-db.remove('docid', '2-y').then(function (doc) {
-  // yay, we're done
-}).catch(function (err) {
-  // handle any errors
-});
-```
-
-If you want to resolve the conflict by creating a new revision, you simply `put()` a new document on top of the current winner, and make sure that the losing revision is deleted.
-
-{% include alert/start.html variant="info" %}
-{% markdown %}
-PouchDB deviates from CouchDB's replication algorithm in one small way: revision hashes aren't deterministic. PouchDB is forced to do this, because CouchDB calculates its revision hashes in an Erlang-specific way.
-
-In practice, this just means that PouchDB's replication algorithm is slightly less efficient than CouchDB's, for some very unlikely edge cases. For details, see [this comment](https://github.com/pouchdb/pouchdb/issues/2451#issuecomment-77386826).
-{% endmarkdown %}
-{% include alert/end.html %}
-
-{% include anchor.html title="Accountants don't use erasers" hash="accountants-dont-use-erasers" %}
-
-Another conflict resolution strategy is to design your database so that conflicts are impossible. In practice, this means that you never update or remove existing documents &ndash; you only create new documents.
-
-This strategy has been called the "every doc is a delta" strategy. A classic use-case for this would be a checkbook app, where every document is simply an operation that increases or decreases the account balance:
-
-```js
-{_id: new Date().toJSON(), change: 100} // balance increased by $100
-{_id: new Date().toJSON(), change: -50} // balance decreased by $50
-{_id: new Date().toJSON(), change: 200} // balance increased by $200
-```
-
-In this system, it is impossible for two documents to conflict, because the document `_id`s are just timestamps. Ledger transactions are recorded in the order they were made, and at the end of the day, you only need to do an `allDocs()` or `query()` operation to sum the result.
-
-The wisdom of this strategy can be expressed by the maxim: ["Accountants don't use erasers"](http://blogs.msdn.com/b/pathelland/archive/2007/06/14/accountants-don-t-use-erasers.aspx). Like a diligent accountant, your app can just add new documents when you want to make a change, rather than going back and scrubbing out previous changes.
-
-There is also a PouchDB plugin that implements this strategy: [delta-pouch](https://github.com/redgeoff/delta-pouch).
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that we've settled our conflicts, let's take a look at the changes feed.
diff --git a/docs/_guides/databases.md b/docs/_guides/databases.md
deleted file mode 100644
index 152a972..0000000
--- a/docs/_guides/databases.md
+++ /dev/null
@@ -1,172 +0,0 @@
----
-index: 4
-layout: guide
-title: Working with databases
-sidebar: guides_nav.html
----
-
-PouchDB databases come in two flavors: local and remote.
-
-{% include anchor.html title="Local databases" hash="local–databases" %}
-
-To create a local database, you simply call `new PouchDB` and give it a name:
-
-```js
-var db = new PouchDB('kittens');
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/bddac54b92c2d8d39241)** of this code.
-
-{% include alert/start.html variant="info" %}
-
-<strong>Protip:</strong> whenever you see a live example in this guide, you can download it to follow along at home! For example, to run this example, just enter the following commands in your command prompt:
-<p/>
-<code>
-<br/>git clone https://gist.github.com/bddac54b92c2d8d39241.git kittens
-<br/>cd kittens
-<br/>python -m SimpleHTTPServer # for Python 2
-<br/>python -m http.server      # for Python 3
-</code>
-<p/>
-Now the site is up and running at <a href='http://localhost:8000'>http://localhost:8000</a>. To find the correct <code>gist.github.com</code> URL, just click the "block" number at the top of the page.
-
-{% include alert/end.html %}
-
-{% include anchor.html title="Remote databases" hash="remote-databases" %}
-
-To create a remote database, you call `new PouchDB` and give it a path to a database in CouchDB.
-
-```js
-var db = new PouchDB('http://localhost:5984/kittens');
-```
-
-{% include alert/start.html variant="info" %}
-<strong>note:</strong> The remote database will not be created until you do an API call, e.g.: <code>db.info()</code>. The reason behind that is that the <code>PouchDB</code> constructor is completely
-synchronous, for ease of error handling (i.e. no asynchronous errors).
-{% include alert/end.html %}
-
-The structure of a CouchDB URL is very simple:
-
-```
-http://     localhost:5984     /kittens
-⌞_____⌟     ⌞____________⌟      ⌞_____⌟
-   |              |                |
-Protocol     Where CouchDB       database
-(https if    itself is           name
-Cloudant)    hosted
-
-```
-
-If the remote database doesn't exist, then PouchDB will create it for you.
-
-You can verify that your database is working by visiting the URL  [http://localhost:5984/kittens](http://localhost:5984/kittens).  You should see something like this:
-
-```js
-{"db_name":"kittens","doc_count":0,"doc_del_count":0,"update_seq":0,"purge_seq":0,"compact_running":false,"disk_size":79,"data_size":0,"instance_start_time":"1410722558431975","disk_format_version":6,"committed_update_seq":0}
-```
-
-If instead you see:
-
-```js
-{"error":"not_found","reason":"no_db_file"}
-```
-
-Then check to make sure that your remote CouchDB has started up correctly. Common errors (such as CORS) are [listed here](/errors.html).
-
-{% include anchor.html title="Get basic info about the database" hash="get-basic-info-about-the–database" %}
-
-You can see basic information about the database by using the `info()` method.
-
-```js
-db.info().then(function (info) {
-  console.log(info);
-})
-```
-
-The local database should show something like:
-
-```js
-{"doc_count":0,"update_seq":0,"db_name":"kittens"}
-```
-
-The remote database may have a bit more information:
-
-```js
-{"db_name":"kittens","doc_count":0,"doc_del_count":0,"update_seq":0,"purge_seq":0,"compact_running":false,"disk_size":79,"data_size":0,"instance_start_time":"1410722558431975","disk_format_version":6,"committed_update_seq":0}
-```
-
-The most important bits of information are:
-
-* `doc_count`: the number of undeleted documents in the database
-* `db_name`: the name of the database
-
-{% include anchor.html title="Debugging" hash="debugging" %}
-
-When you create a PouchDB database, there are many ways to debug and inspect it.
-
-### PouchDB Inspector
-
-PouchDB Inspector is an add-on for Chrome and Firefox that allows you to inspect your local databases.
-
-* [Download PouchDB Inspector for Chrome](https://chrome.google.com/webstore/detail/pouchdb-inspector/hbhhpaojmpfimakffndmpmpndcmonkfa)
-* [Download PouchDB Inspector for Firefox](https://addons.mozilla.org/en-US/firefox/addon/pouchdb-inspector/)
-
-{% include img.html src="pouchdb_inspector.png" alt="PouchDB Inspector in Chrome" %}
-
-It provides the full "Fauxton" interface, which is the same interface you will see in CouchDB and PouchDB Server.
-
-### IndexedDB/WebSQL inspectors
-
-You can also use the normal developer tools to see what your database looks like under the hood.
-
-In Chrome, just choose *Overflow icon* &#9776; &#8594; *Tools* &#8594; *Developer Tools*. Then click the *Resources* tab, then *IndexedDB*, and you should see the following:
-
-{% include img.html src="dev_tools.png" alt="Chrome Developer Tools" %}
-
-This is the raw IndexedDB representation of your PouchDB, so it is very fine-grained compared to what PouchDB Inspector shows. However, you may find it useful.
-
-In Safari, your database will be under *Develop* &#8594; *Show Web Inspector* &#8594; *Resources* &#8594; *Databases*.
-
-{% include img.html src="safari_inspector.png" alt="Web Inspector in Safari" %}
-
-### Debug logging
-
-You can also enable debug logging by doing:
-
-```js
-PouchDB.debug.enable('*');
-```
-
-And then disable it by doing:
-
-```js
-PouchDB.debug.disable();
-```
-
-
-{% include anchor.html title="Deleting your local database" hash="deleting-your-local-database" %}
-
-During development, it's often useful to destroy the local database, so you can see what your users will experience when they visit your site for the first time. A page refresh is not enough, because the data will still be there!
-
-In Chrome, you can use the [ClearBrowserData extension](https://chrome.google.com/webstore/detail/clearbrowserdata/apehfighfmpoieeniallefdeibodgmmb), which will add a trashcan icon to your toolbar, which you can click to delete all local data (IndexedDB, WebSQL, LocalStorage, cookies, etc.).
-
-In Firefox, you can use the [Clear Recent History+ add-on](https://addons.mozilla.org/en-US/firefox/addon/clear-recent-history/), so when you right-click a page you can quickly clear all data.
-
-In Safari, you can simply click *Safari* &#8594; *Clear History and Website Data*.
-
-{% include anchor.html title="Differences between the local and remote databases" hash="differences-between-the-local-and-remote-databases" %}
-
-When you create a local PouchDB database, it uses whatever underlying datastore is available - IndexedDB in most browsers, WebSQL in older browsers, and LevelDB in Node.js.
-
-When you create a remote PouchDB database, it communicates directly with the remote database &ndash; CouchDB, Cloudant, Couchbase, etc.
-
-The goal of PouchDB is to allow you to seamlessly communicate with one or the other. You should not notice many differences between the two, except that of course the local one is much faster!
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [new PouchDB() (constructor)](/api.html#create_database)
-* [Debug mode](/api.html#debug_mode)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you've created some databases, let's put some documents in 'em!
diff --git a/docs/_guides/documents.md b/docs/_guides/documents.md
deleted file mode 100644
index e06a66a..0000000
--- a/docs/_guides/documents.md
+++ /dev/null
@@ -1,191 +0,0 @@
----
-index: 5
-layout: guide
-title: Working with documents
-sidebar: guides_nav.html
----
-
-{% include anchor.html title="What's a document?" hash="whats-a–document" %}
-
-PouchDB is a NoSQL database, meaning that you store unstructured *documents* rather than explicitly specifying a schema with rows, tables, and all that jazz.
-
-A document might look like this:
-
-```js
-{
-  "_id": "mittens",
-  "name": "Mittens",
-  "occupation": "kitten",
-  "age": 3,
-  "hobbies": [
-    "playing with balls of yarn",
-    "chasing laser pointers",
-    "lookin' hella cute"
-  ]
-}
-```
-
-If you come from a SQL background, this handy conversion chart may help:
-
-<div class="table-responsive">
-<table class="table">
-<tr>
-  <th>SQL concept</th>
-  <th>PouchDB concept</th>
-</tr>
-<tr>
-  <td>table</td>
-  <td><em>no equivalent</em></td>
-</tr>
-<tr>
-  <td>row</td>
-  <td>document</td>
-</tr>
-
-<tr>
-  <td>column</td>
-  <td>field</td>
-</tr>
-<tr>
-  <td>primary key</td>
-  <td>primary key (<code>_id</code>)</td>
-</tr>
-<tr>
-  <td>index</td>
-  <td>view</td>
-</tr>
-</table>
-</div>
-
-We'll discuss these concepts later on.
-
-{% include anchor.html title="Storing a document" hash="storing-a–document" %}
-
-To store a document, you simply `put` it:
-
-```js
-var doc = {
-  "_id": "mittens",
-  "name": "Mittens",
-  "occupation": "kitten",
-  "age": 3,
-  "hobbies": [
-    "playing with balls of yarn",
-    "chasing laser pointers",
-    "lookin' hella cute"
-  ]
-};
-db.put(doc);
-```
-
-Whenever you `put()` a document, it must have an `_id` field so that you can retrieve it later.
-
-So now let's `get()` the document by using its `_id`:
-
-```js
-db.get('mittens').then(function (doc) {
-  console.log(doc);
-});
-```
-
-You should see:
-
-```js
-{
-  "name": "Mittens",
-  "occupation": "kitten",
-  "age": 3,
-  "hobbies": [
-    "playing with balls of yarn",
-    "chasing laser pointers",
-    "lookin' hella cute"
-  ],
-  "_id": "mittens",
-  "_rev": "1-bea5fa18e06522d12026f4aee6b15ee4"
-}
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/c02bba75247012afb1bf)** of this code.
-
-The document looks exactly the same as when we put it, except... aha! What is this? There is a new field, `_rev`, that contains what looks like garbage. PouchDB gots some 'splainin' to do.
-
-{% include anchor.html title="Understanding revisions (`_rev`)" hash="understanding-revisions-rev" %}
-
-The new field, `_rev` is the *revision marker*. It is a randomly-generated ID that changes whenever a document is created or updated.
-
-Unlike most other databases, whenever you update a document in PouchDB or CouchDB, you must present the *entire document* along with its current *revision marker*.
-
-For instance, to increment Mittens' age to 4, we would do:
-
-```js
-doc.age = 4;
-doc._rev = "1-bea5fa18e06522d12026f4aee6b15ee4";
-db.put(doc);
-```
-
-If you fail to include the correct `_rev`, you will get the following sad error:
-
-```js
-{
-  "status": 409,
-  "name": "conflict",
-  "message": "Document update conflict"
-}
-```
-
-`HTTP 409` is a standard HTTP error message that indicates a conflict.
-
-{% include anchor.html title="Updating documents correctly" hash="updating-documents–correctly" %}
-
-So to update Mittens' age, we will first need to fetch Mittens from the database, to ensure that we have the correct `_rev` before we put them back. We don't need to manually assign the `_rev` value here (like we did above), as it is already in the `doc` we're fetching.
-
-```js
-// fetch mittens
-db.get('mittens').then(function (doc) {
-  // update their age
-  doc.age = 4;
-  // put them back
-  return db.put(doc);
-}).then(function () {
-  // fetch mittens again
-  return db.get('mittens');
-}).then(function (doc) {
-  console.log(doc);
-});
-```
-
-You can see a **[live example](http://bl.ocks.org/nolanlawson/d6daa02ca3875d1222dd)** of this code.
-
-{% include alert/start.html variant="info" %}
-
-Don't worry if the structure of this code seems strange! It's using <strong>promises</strong>, which will be discussed in the next chapter.
-
-{% include alert/end.html %}
-
-Now you should see the following:
-
-```js
-{
-  "name": "Mittens",
-  "occupation": "kitten",
-  "age": 4,
-  "hobbies": [
-    "playing with balls of yarn",
-    "chasing laser pointers",
-    "lookin' hella cute"
-  ],
-  "_id": "mittens",
-  "_rev": "2-3e3fd988b331193beeeea2d4221b57e7"
-}
-```
-
-As you can see, we have successfully updated Mittens' age to 4 (they grow up so fast!), and their revision marker has also changed to `"2-3e3fd988b331193beeeea2d4221b57e7"`. If we wanted to increment their age to 5, we would need to supply this new revision marker.
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [get()](/api.html#fetch_document)
-* [put()](/api.html#create_document)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you understand a bit about how to create and update documents, let's take a small detour to talk about asynchronous code.
diff --git a/docs/_guides/index.md b/docs/_guides/index.md
deleted file mode 100644
index 026c9b2..0000000
--- a/docs/_guides/index.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-index: 1
-layout: guide
-nav: Intro
-title: Introduction to PouchDB
-sidebar: guides_nav.html
----
-
-Welcome to the PouchDB guide! Consider this your starting point for anything and everything related to the world of PouchDB and CouchDB.
-
-For a quicker TodoMVC-based tutorial, you can also check out the ["Getting Started" guide](/getting-started.html).
-
-Feel free to skip ahead using the sidebar at any time.
-
-{% include anchor.html title="What is PouchDB?" hash="what-is-pouchdb" %}
-
-**PouchDB** is a JavaScript implementation of [CouchDB](http://couchdb.com). Its goal is to emulate the CouchDB API with near-perfect fidelity, while running in the browser or in Node.js.
-
-{% include anchor.html title="What is CouchDB?" hash="what-is-couchdb" %}
-
-**CouchDB** is a NoSQL database created in 2005 by Damien Katz, and now maintained by the Apache Software Foundation.  If you are a JavaScript developer, you probably use CouchDB every day, because it's the core technology that powers [npm](https://www.npmjs.org/).
-
-{% include anchor.html title="Couchbase, CouchDB, Couch-what?" hash="couchbase-couchdb-couch-what" %}
-
-Today there are two major database companies that
-can trace their lineage back to CouchDB: [**Couchbase**](http://couchbase.com) and [**Cloudant**](http://cloudant.com). Both of them are separate products compared to CouchDB.
-
-However, all three of these databases share the same **CouchDB sync protocol**. This means that PouchDB can sync with either one of them, and you can always swap out one database for another. You're never locked in.
-
-In a sense, these databases are like competing phone companies, and the CouchDB sync protocol is the underlying telephony infrastructure.
-
-{% include anchor.html title="CouchDB's one-two punch: HTTP and sync" hash="http-and-sync" %}
-
-With so many SQL and NoSQL databases out there &ndash; MongoDB, PostgreSQL, MySQL, etc. &ndash; you may wonder why we chose to implement CouchDB instead of the others.
-
-We have two very good answers to that question: **HTTP** and **sync**.
-
-{% include anchor.html title="HTTP: the little protocol that could" hash="http" %}
-
-When working with databases, we're often accustomed to writing some kind of conversion layer between the database and our client-side applications. This means, however, that we are just translating database queries into RESTful HTTP calls, over and over. For every app we write.
-
-CouchDB throws this out the window by daring us to talk to the database directly, from our client-side apps. And it does so by using HTTP as its primary means of communication. No special protocol, no special drivers: just REST and HTTP. You can communicate with CouchDB entirely through your browser, `curl`, or a REST client like [Postman](https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm).
-
-In this way, CouchDB truly is a "database for the web."
-
-{% include anchor.html title="Sync: CouchDB's killer feature" hash="sync" %}
-
-Another unique feature of CouchDB is that it was designed from the bottom-up to enable easy synchronization between different databases.
-
-For example, if you are worried about latency in your client-side applications, you can simply set up one CouchDB in Europe, another in North America, and another in Asia. After enabling continuous two-way replication between these databases, your clients can simply talk to whichever one is closer.
-
-PouchDB takes this one step further by putting the database inside your browser.
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you understand the basics of the PouchDB/CouchDB universe, let's set up CouchDB!
diff --git a/docs/_guides/local-documents.md b/docs/_guides/local-documents.md
deleted file mode 100644
index f13f191..0000000
--- a/docs/_guides/local-documents.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-index: 15
-layout: guide
-title: Local documents
-sidebar: guides_nav.html
----
-
-"Local" documents are a special class of documents in PouchDB and CouchDB, which are used for storing local metadata about a database. You might never need them in your own app, but sometimes they can come in handy for advanced use cases.
-
-{% include anchor.html title="Local docs in a nutshell" hash="local-docs-in-a-nutshell" %}
-
-Local docs have the following characteristics:
-
-* They don't replicate.
-* They can't contain attachments.
-* They don't appear in `allDocs()`, `changes()`, or `query()`.
-* However, you can modify them with `put()`/`remove()`/`bulkDocs()`, and you can fetch them with `get()`.
-
-So basically, local docs only exist *for that database*, and they don't mix with the "normal" documents.
-
-To create a local doc, you simply use `'_local/'` as the prefix of the `_id`. This is supported in both CouchDB and PouchDB:
-
-```js
-db.put({
-  _id: '_local/foobar',
-  someText: 'yo, this is my local doc!'
-}).then(function () {
-  return db.get('_local/foobar');
-});
-```
-
-{% include anchor.html title="Advantages of local docs" hash="advantages-of-local–docs" %}
-
-Local docs are useful for small bits of configuration or metadata, which you don't necessarily want to replicate, but which you want to keep in the database anyway. Many PouchDB plugins and core components use local docs. For instance, the replication algorithm uses them to store checkpoints, and map/reduce uses them to keep track of what's been `emit`ted.
-
-Local docs also have some good performance characteristics compared to regular docs. They don't have a version history, so only the most recent revision is ever stored in the database. This means that `put()`s and `get()`s are faster for local docs than for regular docs, and that local docs tend to take up less space on disk.  In a sense, they are auto-compacted, although they take up even less space on disk than documents in a compacted database.
-
-Regardless, you need to provide the current `_rev` when you update local docs, just like with regular docs.
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [put()](/api.html#create_document)
-* [get()](/api.html#fetch_document)
-* [remove()](/api.html#delete_document)
diff --git a/docs/_guides/queries.md b/docs/_guides/queries.md
deleted file mode 100644
index 8c54795..0000000
--- a/docs/_guides/queries.md
+++ /dev/null
@@ -1,240 +0,0 @@
----
-index: 13
-layout: guide
-title: Map/reduce queries
-sidebar: guides_nav.html
----
-
-Map/reduce queries, also known as *secondary indexes*, are one of the most powerful features in PouchDB. However, they can be quite tricky to use, so this guide is designed to dispell some of the mysteries around them.
-
-{% include alert/start.html variant="warning" %}
-
-Many developers make the mistake of using the <code>query()</code> API when the more performant <code>allDocs()</code> API would be a better fit.
-<p/>&nbsp;<p/>
-Before you solve a problem with secondary indexes, you should ask yourself: can I solve this with the <em>primary index</em> (<code>_id</code>) instead?
-
-{% include alert/end.html %}
-
-{% include anchor.html title="Mappin' and reducin'" hash="mappin-and-reducin" %}
-
-The PouchDB `query()` API (which corresponds to the `_view` API in CouchDB) has two modes: temporary queries and persistent queries.
-
-### Temporary queries
-
-**Temporary queries** are very slow, and we only recommend them for quick debugging during development. To use a temporary query, you simply pass in a `map` function:
-
-```js
-db.query(function (doc, emit) {
-  emit(doc.name);
-}, {key: 'foo'}).then(function (result) {
-  // found docs with name === 'foo'
-}).catch(function (err) {
-  // handle any errors
-});
-```
-
-In the above example, the `result` object will contain stubs of documents where the `name` attribute is equal to `'foo'`. To include the document in each row of results, use the `include_docs` option.
-
-{% include alert/start.html variant="info" %}
-
-The <code>emit</code> pattern is part of the standard <a href='http://couchdb.readthedocs.org/en/latest/couchapp/views/intro.html'>CouchDB map/reduce API</a>.  What the function basically says is, "for each document, emit <code>doc.name</code> as a key."
-
-{% include alert/end.html %}
-
-### Persistent queries
-
-**Persistent queries** are much faster, and are the intended way to use the `query()` API in your production apps. To use persistent queries, there are two steps.
-
-First, you create a **design document**, which describes the `map` function you would like to use:
-
-```js
-// document that tells PouchDB/CouchDB
-// to build up an index on doc.name
-var ddoc = {
-  _id: '_design/my_index',
-  views: {
-    by_name: {
-      map: function (doc) { emit(doc.name); }.toString()
-    }
-  }
-};
-// save it
-pouch.put(ddoc).then(function () {
-  // success!
-}).catch(function (err) {
-  // some error (maybe a 409, because it already exists?)
-});
-```
-
-{% include alert/start.html variant="info" %}
-
-The <code>.toString()</code> at the end of the map function is necessary to prep the
-object for becoming valid JSON.
-
-{% include alert/end.html %}
-
-Then you actually query it, by using the name you gave the design document when you saved it:
-
-```js
-db.query('my_index/by_name').then(function (res) {
-  // got the query results
-}).catch(function (err) {
-  // some error
-});
-```
-
-Note that, the first time you query, it will be quite slow because the index isn't
-built until you query it. To get around this, you can do an empty query to kick
-off a new build:
-
-```js
-db.query('my_index/by_name', {
-  limit: 0 // don't return any results
-}).then(function (res) {
-  // index was built!
-}).catch(function (err) {
-  // some error
-});
-```
-
-After this, your queries will be much faster.
-
-{% include alert/start.html variant="info"%}
-
-CouchDB builds indexes in exactly the same way as PouchDB. So you may want to familiarize yourself with the <a href='/api.html#query_database'>"stale" option</a> in order to get the best possible performance for your app.
-
-{% include alert/end.html %}
-
-
-{% include anchor.html title="More about map/reduce" hash="more-about-map-reduce" %}
-
-That was a fairly whirlwind tour of the `query()` API, so let's get into more detail about how to write your map/reduce functions.
-
-#### Indexes in SQL databases
-
-Quick refresher on how indexes work: in relational databases like MySQL and PostgreSQL, you can usually query whatever field you want:
-
-```sql
-SELECT * FROM pokemon WHERE name = 'Pikachu';
-```
-
-But if you don't want your performance to be terrible, you first add an index:
-
-```sql
-ALTER TABLE pokemon ADD INDEX myIndex ON (name);
-```
-
-The job of the index is to ensure the field is stored in a B-tree within the database, so your queries run in _O(log(n))_ time instead of _O(n)_ time.
-
-#### Indexes in NoSQL databases
-
-All of the above is also true in document stores like CouchDB and MongoDB, but conceptually it's a little different. By default, documents are assumed to be schemaless blobs with one primary key (called `_id` in both Mongo and Couch), and any other keys need to be specified separately.  The concepts are largely the same; it's mostly just the vocabulary that's different.
-
-In CouchDB, queries are called _map/reduce functions_.  This is because, like most NoSQL databases, CouchDB is designed to scale well across multiple computers, and to perform efficient query operations in parallel. Basically, the idea is that you divide your query into a _map_ function and a _reduce_ function, each of which may be executed in parallel in a multi-node cluster.
-
-#### Map functions
-
-It may sound daunting at first, but in the simplest (and most common) case, you only need the _map_ function.  A basic map function might look like this:
-
-```js
-function myMapFunction(doc) {
-  emit(doc.name);
-}
-```
-
-This is functionally equivalent to the SQL index given above.  What it essentially says is: "for each document in the database, emit its name as a key."
-
-And since it's just JavaScript, you're allowed to get as fancy as you want here:
-
-```js
-function myMapFunction(doc) {
-  if (doc.type === 'pokemon') {
-    if (doc.name === 'Pikachu') {
-      emit('Pika pi!');
-    } else {
-      emit(doc.name);
-    }
-  }
-}
-```
-
-Then you can query it:
-
-```js
-// find pokemon with name === 'Pika pi!'
-pouch.query(myMapFunction, {
-  key          : 'Pika pi!',
-  include_docs : true
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  // handle errors
-});
-
-// find the first 5 pokemon whose name starts with 'P'
-pouch.query(myMapFunction, {
-  startkey     : 'P',
-  endkey       : 'P\uffff',
-  limit        : 5,
-  include_docs : true
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-{% include alert/start.html variant="info"%}
-
-The pagination options for <code>query()</code> &ndash; i.e., <code>startkey</code>/<code>endkey</code>/<code>key</code>/<code>keys</code>/<code>skip</code>/<code>limit</code>/<code>descending</code> &ndash; are exactly the same as with <code>allDocs()</code>. For a guide to pagination, read the <a href="/guides/bulk-operations.html">Bulk operations guide</a> or <a href='http://pouchdb.com/2014/04/14/pagination-strategies-with-pouchdb.html'>Pagination strategies with PouchDB</a>.
-
-{% include alert/end.html %}
-
-#### Reduce functions
-
-As for _reduce_ functions, there are a few handy built-ins that do aggregate operations (`'_sum'`, `'_count'`, and `'_stats'`), and you can typically steer clear of trying to write your own:
-
-```js
-// emit the first letter of each pokemon's name
-var myMapReduceFun = {
-  map: function (doc) {
-    emit(doc.name.charAt(0));
-  },
-  reduce: '_count'
-};
-// count the pokemon whose names start with 'P'
-pouch.query(myMapReduceFun, {
-  key: 'P', reduce: true, group: true
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  // handle errors
-});
-```
-
-If you're adventurous, though, you should check out the [CouchDB documentation](http://couchdb.readthedocs.org/en/latest/couchapp/views/intro.html) or the [PouchDB documentation](http://pouchdb.com/api.html#query_database) for details on reduce functions.
-
-{% include anchor.html title="PouchDB Find" hash="pouchdb-find" %}
-
-The map/reduce API is complex. Part of this problem will be resolved when the more developer-friendly [Cloudant query language](http://docs.cloudant.com/api/cloudant-query.html) is released in CouchDB 2.0, and the equivalent [pouchdb-find plugin](https://github.com/nolanlawson/pouchdb-find) is finished.
-
-{% include alert/start.html variant="warning" %}
-{% markdown %}
-pouchdb-find is in beta, but you may find it is already sufficient for simple queries. Eventually it will replace map/reduce as PouchDB's "flagship" query engine.
-{% endmarkdown %}
-{% include alert/end.html %}
-
-In the meantime, there are a few tricks you can use to avoid unnecessarily complicating your codebase:
-
-1. Avoid the `query()` API altogether if you can. You'd be amazed how much you can do with just `allDocs()`. (In fact, under the hood, the `query()` API is simply implemented on top of `allDocs()`!)
-2. If your data is highly relational, try the [relational-pouch](https://github.com/nolanlawson/relational-pouch) plugin.
-1. Read the [12 tips for better code with PouchDB](/2014/06/17/12-pro-tips-for-better-code-with-pouchdb.html).
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [query()](/api.html#query_database)
-* [viewCleanup()](/api.html#view_cleanup)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that we've learned how to map reduce, map reuse, and map recycle, let's move on to `destroy()` and `compact()`.
diff --git a/docs/_guides/replication.md b/docs/_guides/replication.md
deleted file mode 100644
index a32b9f7..0000000
--- a/docs/_guides/replication.md
+++ /dev/null
@@ -1,194 +0,0 @@
----
-index: 10
-layout: guide
-title: Replication
-sidebar: guides_nav.html
----
-
-PouchDB and CouchDB were designed for one main purpose: **sync**. Jason Smith has [a great quote](http://nodeup.com/thirtyseven) about this:
-
-> The way I like to think about CouchDB is this: CouchDB is bad at everything, *except syncing*. And it turns out that's the most important feature you could ever ask for, for many types of software."
-
-When you first start using CouchDB, you may become frustrated because it doesn't work quite like other databases. Unlike most databases, CouchDB requires you to manage revisions (`_rev`), which can be tedious.
-
-However, CouchDB was designed with sync in mind, and this is exactly what it excels at. Many of the rough edges of the API serve this larger purpose. For instance, managing your document revisions pays off in the future, when you eventually need to start dealing with conflicts.
-
-{% include anchor.html title="CouchDB sync" hash="couchdb-sync" %}
-
-CouchDB sync has a unique design. Rather than relying on a master/slave architecture, CouchDB
-supports a **multi-master** architecture. You can think of this as a system where any node can be written to or read from, and where you don't have to care which one is the "master" and which one is the "slave." In CouchDB's egalitarian world, every citizen is as worthy as another.
-
-<figure>
-  {% include img.html src="offline_replication.gif" alt="Offline replication with CouchDB." %}
-  <figcaption>
-    <p>(Thanks to IBM for the image: http://www.ibm.com/developerworks/library/wa-couchdb/)</p>
-  </figcaption>
-</figure>
-
-When you use PouchDB, CouchDB, and other members of the Couch family, you
-don't have to worry which database is the "single source of truth." They all are. According to the CAP theorem, CouchDB is an AP database, meaning that it's **P**artitioned,
-every node is **A**vailable, and it's only eventually **C**onsistent.
-
-To illustrate, imagine a multi-node architecture with CouchDB servers spread across several continents. As long as you're willing to wait, the data will eventually flow
-from Australia to Europe to North America to wherever. Users around the world running PouchDB in their browsers or [Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios)/[Cloudant Sync](https://github.com/cloudant/CDTDatastore) in their smartphones experience the
-same privileges. The data won't show up instantaneously, but depending on the Internet connection speed, it's usually close enough to real-time.
-
-In cases of conflict, CouchDB will choose an arbitrary winner that every node can agree upon deterministically. However, conflicts are still stored in the **revision tree** (similar to a Git history tree), which means that app developers can either surface the conflicts to the user, or just ignore them.
-
-In this way, CouchDB replication "just works."
-
-{% include anchor.html title="Setting up sync" hash="setting-up-sync" %}
-
-As you already know, you can create either local PouchDBs:
-
-```js
-var localDB = new PouchDB('mylocaldb')
-```
-
-or remote PouchDBs:
-
-```js
-var remoteDB = new PouchDB('http://localhost:5984/myremotedb')
-```
-
-This pattern comes in handy when you want to share data between the two.
-
-The simplest case is **unidirectional replication**, meaning you just want one database to mirror its changes to a second one. Writes to the second database, however, will not propagate back to the master database.
-
-To perform unidirectional replication, you simply do:
-
-```js
-localDB.replicate.to(remoteDB).on('complete', function () {
-  // yay, we're done!
-}).on('error', function (err) {
-  // boo, something went wrong!
-});
-```
-
-Congratulations, all changes from the `localDB` have been replicated to the `remoteDB`.
-
-However, what if you want **bidirectional replication**? (Kinky!) You could do:
-
-```js
-localDB.replicate.to(remoteDB);
-localDB.replicate.from(remoteDB);
-```
-
-However, to make things easier for your poor tired fingers, PouchDB has a shortcut API:
-
-```js
-localDB.sync(remoteDB);
-```
-
-These two code blocks above are equivalent. And the `sync` API supports all the same events as the `replicate` API:
-
-```js
-localDB.sync(remoteDB).on('complete', function () {
-  // yay, we're in sync!
-}).on('error', function (err) {
-  // boo, we hit an error!
-});
-```
-
-{% include anchor.html title="Live replication" hash="live–replication" %}
-
-Live replication (or "continuous" replication) is a separate mode where changes are propagated between the two databases as the changes occur. In other words, normal replication happens once, whereas live replication happens in real time.
-
-To enable live replication, you simply specify `{live: true}`:
-
-```js
-localDB.sync(remoteDB, {
-  live: true
-}).on('change', function (change) {
-  // yo, something changed!
-}).on('error', function (err) {
-  // yo, we got an error! (maybe the user went offline?)
-});
-```
-
-However, there is one gotcha with live replication: what if the user goes offline? In those cases, an error will be thrown and replication will stop.
-
-You can allow PouchDB to automatically handle this error, and retry until the connection is re-established, by using the `retry` option:
-
-```js
-localDB.sync(remoteDB, {
-  live: true,
-  retry: true
-}).on('change', function (change) {
-  // yo, something changed!
-}).on('paused', function (info) {
-  // replication was paused, usually because of a lost connection
-}).on('active', function (info) {
-  // replication was resumed
-}).on('error', function (err) {
-  // totally unhandled error (shouldn't happen)
-});
-```
-
-This is ideal for scenarios where the user may be flitting in and out of connectivity, such as on mobile devices.
-
-{% include anchor.html title="Canceling replication" hash="canceling—replication" %}
-
-Sometimes, you may want to manually cancel replication &ndash; for instance, because the user logged out. You can do so by calling `cancel()` and then waiting for the `'complete'` event:
-
-```js
-var syncHandler = localDB.sync(remoteDB, {
-  live: true,
-  retry: true
-});
-
-syncHandler.on('complete', function (info) {
-  // replication was canceled!
-});
-
-syncHandler.cancel(); // <-- this cancels it
-```
-
-The `replicate` API also supports canceling:
-
-```js
-var replicationHandler = localDB.replicate.to(remoteDB, {
-  live: true,
-  retry: true
-});
-
-replicationHandler.on('complete', function (info) {
-  // replication was canceled!
-});
-
-replicationHandler.cancel(); // <-- this cancels it
-```
-
-{% include anchor.html title="Deleting replicated databases" hash="delete-during-replication" %}
------
-
-One thing to note about replication is that it tracks the data within a database, not the database itself. If you [`destroy()`](/api.html#delete_database) a database that is being replicated to, the next time the replication starts it will transfer all of the data again, recreating the database to the state it was before it was `destroyed`. If you want the data within the database to be deleted you will need to delete via [`remove()`](/api.html#delete_document) or [`bulkDocs()`](/api.html#batch_create). The [pouchdb-erase](https://github.com/marten-de-vries/pouchdb-erase) plugin can help you remove the entire contents of a database.
-
-{% include anchor.html title="Fancy replication" hash="fancy-replication" %}
------
-
-Any PouchDB object can replicate to any other PouchDB object. So for instance, you can replicate two remote databases, or two local databases. You can also replicate from multiple databases into a single one, or from a single database into many others.
-
-This can be very powerful, because it enables lots of fancy scenarios. For example:
-
-1. You have an [in-memory PouchDB](http://pouchdb.com/adapters.html#pouchdb_in_the_browser) that replicates with a local PouchDB, acting as a cache.
-2. You have many remote CouchDB databases that the user may access, and they are all replicated to the same local PouchDB.
-3. You have many local PouchDB databases, which are mirrored to a single remote CouchDB as a backup store.
-
-The only limits are your imagination and your disk space.
-
-{% include alert/start.html variant="warning" %}
-
-When you replicate between two remote databases, the changes flow through PouchDB. If this is not what you want, then you should <code>POST</code> directly to the CouchDB <code>_replicate</code> endpoint, as described in <a href='http://guide.couchdb.org/draft/replication.html'>the CouchDB replication guide</a>.
-
-{% include alert/end.html %}
-
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [replication()](/api.html#replication)
-* [sync()](/api.html#sync)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that we have a grasp on replication, let's talk about an inconvenient fact of life: conflicts.
diff --git a/docs/_guides/setup-couchdb.md b/docs/_guides/setup-couchdb.md
deleted file mode 100644
index 7762fd7..0000000
--- a/docs/_guides/setup-couchdb.md
+++ /dev/null
@@ -1,90 +0,0 @@
----
-index: 2
-layout: guide
-title: Setting up CouchDB
-sidebar: guides_nav.html
----
-
-{% include anchor.html title="CouchDB: PouchDB's older sibling" hash="couchdb-pouchdbs-older-sibling" %}
-
-One of the main benefits of learning PouchDB is that it's exactly the same as CouchDB. In fact, PouchDB is a shameless plagiarist: all of the API methods are the same, with only slight modifications to make it more JavaScript-y.
-
-For instance, in CouchDB you would fetch all documents using:
-
-    /db/_all_docs?include_docs=true
-
-In PouchDB this becomes:
-
-```js
-db.allDocs({include_docs: true})
-```
-
-The APIs are the same, and the semantics are the same.
-
-In the following examples, we will set up CouchDB and talk to it using a tool you're already familiar with: your browser.
-
-{% include anchor.html title="Installing CouchDB" hash="installing-couchdb" %}
-
-If you are on a Debian flavor of Linux (Ubuntu, Mint, etc.), you can install CouchDB with:
-
-```
-$ sudo apt-get install couchdb
-```
-
-On a Mac you can do:
-
-```
-$ brew install couchdb
-```
-
-On Windows, you should install from [the CouchDB web site](https://couchdb.apache.org/#download).
-
-#### A CouchDB alternative: PouchDB Server
-
-If you have trouble installing CouchDB, you can also install PouchDB Server, which is a drop-in replacement for CouchDB that uses PouchDB under the hood:
-
-```
-$ npm install -g pouchdb-server
-$ pouchdb-server --port 5984
-```
-
-PouchDB Server is currently experimental, and we do not recommend it for production environments.
-
-{% include anchor.html title="Verify your installation" hash="verify-your–installation" %}
-
-Once CouchDB is installed, it should be running at `localhost:5984`. To verify, you can open up your terminal and type
-
-```
-$ curl localhost:5984
-```
-
-You should see something like:
-
-```js
-{"couchdb":"Welcome","version":"1.5.1",...}
-```
-
-Next, open up [http://localhost:5984/_utils/fauxton/](http://localhost:5984/_utils/fauxton/) in your browser. (Or [http://localhost:5984/_utils/](http://localhost:5984/_utils/) if you installed PouchDB Server.)
-
-If you see a screen like the following, then you are ready to rock and roll with CouchDB:
-
-
-{% include img.html src="fauxton.png" alt="Fauxton interface" %}
-
-{% include anchor.html title="Set up CORS" hash="set-up-cors" %}
-
-[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) is a web technology that allows web sites to use resources from another domain. You will want to enable this in your CouchDB before continuing, because otherwise PouchDB will not work unless it's served from exactly the same domain as CouchDB.
-
-Enabling CORS is easy. Just install this handy script:
-
-    $ npm install -g add-cors-to-couchdb
-
-And run it:
-
-    $ add-cors-to-couchdb
-
-If you installed PouchDB Server, CORS is enabled by default, and this step is not necessary.
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you have CouchDB installed, let's install PouchDB.
diff --git a/docs/_guides/setup-pouchdb.md b/docs/_guides/setup-pouchdb.md
deleted file mode 100644
index b7c4de1..0000000
--- a/docs/_guides/setup-pouchdb.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-index: 3
-layout: guide
-title: Setting up PouchDB
-sidebar: guides_nav.html
----
-
-
-Installing PouchDB is easy. There are a few different ways to do it:
-
-{% include anchor.html title="Direct download" hash="direct-download" %}
-
-Download the latest **pouchdb-{{site.version}}.min.js** from the big green button above. Then in your `index.html`:
-
-```html
-<script src="pouchdb-{{site.version}}.min.js"></script>
-```
-
-{% include anchor.html title="Bower" hash="bower" %}
-
-Run this on the command line:
-
-```
-$ bower install pouchdb
-```
-
-Then in your `index.html`:
-
-```html
-<script src="bower_components/pouchdb/dist/pouchdb.min.js"></script>
-```
-
-{% include anchor.html title="npm" hash="npm" %}
-
-Run this on the command line:
-
-```
-$ npm install pouchdb
-```
-
-Then in your `index.html`:
-
-```html
-<script src="node_modules/pouchdb/dist/pouchdb.min.js"></script>
-```
-
-{% include anchor.html title="jsdelivr CDN" hash="jsdelivr-cdn" %}
-
-Add this to your `index.html`:
-
-```html
-<script src="//cdn.jsdelivr.net/pouchdb/{{site.version}}/pouchdb.min.js"></script>
-```
-
-{% include anchor.html title="Node.js" hash="nodejs" %}
-
-Run this on the command line:
-
-```
-$ npm install pouchdb
-```
-
-Then in your JavaScript:
-
-```js
-var PouchDB = require('pouchdb');
-```
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that you have PouchDB installed, let's start working with databases.
\ No newline at end of file
diff --git a/docs/_guides/updating-deleting.md b/docs/_guides/updating-deleting.md
deleted file mode 100644
index 26a794e..0000000
--- a/docs/_guides/updating-deleting.md
+++ /dev/null
@@ -1,145 +0,0 @@
----
-index: 7
-layout: guide
-nav: Updating/deleting documents
-title: Updating and deleting documents
-sidebar: guides_nav.html
----
-
-As we saw in the past two chapters, working with PouchDB documents can be tricky, because you have to manage the revision identifier `_rev`.
-
-Now that we understand promises, though, there are few techniques we can use to make our code more elegant and readable.
-
-{% include anchor.html title="Creating a default document" hash="creating-a–default-document" %}
-
-Often in our code, we'll want to `get()` a document, and if it doesn't exist, we want to create some default.
-
-For instance, let's say we have a configuration object. We want to provide some reasonable defaults for our config:
-
-```js
-{
-  _id: 'config',
-  background: 'blue',
-  foreground: 'white',
-  sparkly: 'false'
-}
-```
-
-This is a pretty good default setting! So let's write the code to set it as our default.
-
-Thankfully, promises make this rather easy:
-
-```js
-db.get('config').catch(function (err) {
-  if (err.status === 404) { // not found!
-    return {
-      _id: 'config',
-      background: 'blue',
-      foreground: 'white',
-      sparkly: 'false'
-    };
-  } else { // hm, some other error
-  	throw err;
-  }
-}).then(function (configDoc) {
-  // sweet, here is our configDoc
-}).catch(function (err) {
-  // handle any errors
-});
-```
-
-This code is doing the following:
-
-* Try to `get()` a doc with `_id` equal to `'config'`
-* If it doesn't find it, return the default doc
-* Otherwise, you'll just get back the existing document
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/0a01d466b2d331cf7e25)** of this code.
-
-{% include anchor.html title="Why must we dance this dance?" hash="why-must-we-dance-this-dance" %}
-
-A common question from new PouchDB/CouchDB users is: why do we have to deal with `_rev` at all? Why can't I just `put()` the document without providing a `_rev`?
-
-The answer is: because `_rev`s are what makes sync work so well. PouchDB asks for a little upfront effort with managing document revisions, so that later on, sync is a breeze.
-
-In fact, you are probably already familiar with a system that forces you to go through a similar dance. This system is called [Git](http://www.git-scm.com/).
-
-PouchDB and CouchDB's document revision structure is very similar to Git's. In fact, each document's revision history is stored as a tree (exactly like Git), which allows you to handle conflicts when any two databases get out of sync.
-
-```
-rev 3-a  rev 3-b
-      \___/
-        |
-      rev 2
-        |
-      rev 1
-```
-
-Conflicts will be discussed later in this guide. For now, you can think of revisions as being a single lineage:
-
-```
-      rev 4
-        |
-      rev 3
-        |
-      rev 2
-        |
-      rev 1
-```
-
-{% include anchor.html title="Deleting documents" hash="deleting-documents" %}
-
-When you `remove()` a document, it's not really deleted; it just gets a `_deleted` attribute added to it.
-
-That is, the database saves a tombstone at the end of the revision tree.
-
-```
-{_id: 'foo', _rev: '4-z', _deleted: true}
-            |
-{_id: 'foo', _rev: '3-y'}
-            |
-{_id: 'foo', _rev: '2-x'}
-            |
-{_id: 'foo', _rev: '1-w'}
-```
-
-There are three ways of deleting a document, which are all equivalent:
-
-1) You can call `db.remove(doc)`:
-
-```js
-db.get('mydoc').then(function (doc) {
-  return db.remove(doc);
-});
-```
-
-2) You can call `db.remove(doc._id, doc._rev)`:
-
-```js
-db.get('mydoc').then(function (doc) {
-  return db.remove(doc._id, doc._rev);
-});
-```
-
-3) You can call `db.put(doc)` with `_deleted` set to `true`:
-
-```js
-db.get('mydoc').then(function (doc) {
-  doc._deleted = true;
-  return db.put(doc);
-});
-```
-
-Of course, you will want to add `catch()` to the end of all these, unless you like to live dangerously.
-
-You can see **[a live example](http://bl.ocks.org/nolanlawson/b2049ad69308e92f15bc)** of this code.
-
-{% include anchor.html title="Related API documentation" hash="related-api-documentation" %}
-
-* [get()](/api.html#fetch_document)
-* [put()](/api.html#create_document)
-* [remove()](/api.html#delete_document)
-
-{% include anchor.html title="Next" hash="next" %}
-
-Now that we understand how to update and delete documents, let's do it in bulk.
diff --git a/docs/_includes/alert/end.html b/docs/_includes/alert/end.html
deleted file mode 100644
index e04ad1b..0000000
--- a/docs/_includes/alert/end.html
+++ /dev/null
@@ -1 +0,0 @@
-</div></div>
diff --git a/docs/_includes/alert/start.html b/docs/_includes/alert/start.html
deleted file mode 100644
index 458faa5..0000000
--- a/docs/_includes/alert/start.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% if include.variant == "success" %}
-<div class="alert alert-success">
-{% elsif include.variant == "warning" %}
-<div class="alert alert-warning">
-{% elsif include.variant == "danger" %}
-<div class="alert alert-danger">
-{% else %}
-<div class="alert alert-info">
-{% endif %}
-
-<div class="alert-text">
diff --git a/docs/_includes/anchor.html b/docs/_includes/anchor.html
deleted file mode 100644
index 0f9d34f..0000000
--- a/docs/_includes/anchor.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% if include.class %}
-  {% assign class = include.class %}
-{% else %}
-  {% assign class = 'h2' %}
-{% endif %}
-<div id='{{ include.hash }}'></div>
-<a class='{{ class }} anchor' href='#{{ include.hash }}' name='{{ include.hash }}'>
-{{ include.title }}
-</a>{% if include.edit %}
-<span class="h2">
-<a
-data-toggle="tooltip"
-data-placement="top"
-title="Edit this on Github"
-class="icon-edit"
-href="{{ site.github.repository_url }}/edit/master/docs/_includes/api/{{ include.hash }}.html"
-target="_blank"
-></a>
-</span>
-{% endif %}
diff --git a/docs/_includes/api.html b/docs/_includes/api.html
deleted file mode 100644
index 93c072a..0000000
--- a/docs/_includes/api.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<li><a href="#overview">API overview</a></li>
-<li><a href="#create_database">Create database</a></li>
-<li><a href="#delete_database">Delete database</a></li>
-<li><a href="#create_document">Create/update doc</a></li>
-<li><a href="#fetch_document">Fetch doc</a></li>
-<li><a href="#delete_document">Delete doc</a></li>
-<li><a href="#batch_create">Batch create</a></li>
-<li><a href="#batch_fetch">Batch fetch</a></li>
-<li><a href="#changes">Changes</a></li>
-<li><a href="#replication">Replication</a></li>
-<li><a href="#sync">Sync</a></li>
-<li><a href="#save_attachment">Save attachment</a></li>
-<li><a href="#get_attachment">Get attachment</a></li>
-<li><a href="#delete_attachment">Delete attachment</a></li>
-<li><a href="#query_database">Query database</a></li>
-<li><a href="#view_cleanup">View cleanup</a></li>
-<li><a href="#database_information">Database info</a></li>
-<li><a href="#compaction">Compaction</a></li>
-<li><a href="#revisions_diff">Revision diff</a></li>
-<li><a href="#bulk_get">Bulk get</a></li>
-<li><a href="#events">Events</a></li>
-<li><a href="#defaults">Default settings</a></li>
-<li><a href="#plugins">Plugins</a></li>
-<li><a href="#extras">Extras</a></li>
-<li><a href="#debug_mode">Debug mode</a></li>
diff --git a/docs/_includes/api/batch_create.html b/docs/_includes/api/batch_create.html
deleted file mode 100644
index 902162d..0000000
--- a/docs/_includes/api/batch_create.html
+++ /dev/null
@@ -1,271 +0,0 @@
-{% include anchor.html edit="true" title="Create/update a batch of documents" hash="batch_create" %}
-
-{% highlight js %}
-db.bulkDocs(docs, [options], [callback])
-{% endhighlight %}
-
-Create, update or delete multiple documents. The `docs` argument is an array of documents.
-
-If you omit an `_id` parameter on a given document, the database will create a new document and assign the ID for you. To update a document, you must include both an `_id` parameter and a `_rev` parameter, which should match the ID and revision of the document on which to base your updates. Finally, to delete a document, include a `_deleted` parameter with the value `true`.
-
-#### Example Usage:
-
-Put some new docs, providing the `_id`s:
-
-{% include code/start.html id="bulk_docs_1" type="callback" %}
-{% highlight js %}
-db.bulkDocs([
-  {title : 'Lisa Says', _id: 'doc1'},
-  {title : 'Space Oddity', _id: 'doc2'}
-], function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_1" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.bulkDocs([
-    {title : 'Lisa Says', _id: 'doc1'},
-    {title : 'Space Oddity', _id: 'doc2'}
-  ]);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_1" type="promise" %}
-{% highlight js %}
-db.bulkDocs([
-  {title : 'Lisa Says', _id: 'doc1'},
-  {title : 'Space Oddity', _id: 'doc2'}
-]).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-Post some new docs and auto-generate the `_id`s:
-
-{% include code/start.html id="bulk_docs_2" type="callback" %}
-{% highlight js %}
-db.bulkDocs([
-  {title : 'Lisa Says'},
-  {title : 'Space Oddity'}
-], function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_2" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.bulkDocs([
-    {title : 'Lisa Says'},
-    {title : 'Space Oddity'}
-  ]);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_2" type="promise" %}
-{% highlight js %}
-db.bulkDocs([
-  {title : 'Lisa Says'},
-  {title : 'Space Oddity'}
-]).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-[
-  {
-    "ok": true,
-    "id": "doc1",
-    "rev": "1-84abc2a942007bee7cf55007cba56198"
-  },
-  {
-    "ok": true,
-    "id": "doc2",
-    "rev": "1-7b80fc50b6af7a905f368670429a757e"
-  }
-]
-{% endhighlight %}
-
-The response contains an array of the familiar `ok`/`rev`/`id`
-from the [put()/post() API](#create_document). If there are any errors, they
-will be provided individually like so:
-
-{% highlight js %}
-[
-  { status: 409,
-    name: 'conflict',
-    message: 'Document update conflict',
-    error: true
-  }
-]
-{% endhighlight %}
-
-The results are returned in the same order as the supplied "docs" array.
-
-Note that `bulkDocs()` is not transactional, and that you may get
-back a mixed array of errors/non-errors. In CouchDB/PouchDB, the smallest
-atomic unit is the document.
-
-#### Bulk update/delete:
-
-You can also use `bulkDocs()` to update/delete many documents at once:
-
-{% include code/start.html id="bulk_docs3" type="callback" %}
-{% highlight js %}
-db.bulkDocs([
-  {
-    title  : 'Lisa Says',
-    artist : 'Velvet Underground',
-    _id    : "doc1",
-    _rev   : "1-84abc2a942007bee7cf55007cba56198"
-  },
-  {
-    title  : 'Space Oddity',
-    artist : 'David Bowie',
-    _id    : "doc2",
-    _rev   : "1-7b80fc50b6af7a905f368670429a757e"
-  }
-], function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs3" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.bulkDocs([
-    {
-      title  : 'Lisa Says',
-      artist : 'Velvet Underground',
-      _id    : "doc1",
-      _rev   : "1-84abc2a942007bee7cf55007cba56198"
-    },
-    {
-      title  : 'Space Oddity',
-      artist : 'David Bowie',
-      _id    : "doc2",
-      _rev   : "1-7b80fc50b6af7a905f368670429a757e"
-    }
-  ]);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs3" type="promise" %}
-{% highlight js %}
-db.bulkDocs([
-  {
-    title  : 'Lisa Says',
-    artist : 'Velvet Underground',
-    _id    : "doc1",
-    _rev   : "1-84abc2a942007bee7cf55007cba56198"
-  },
-  {
-    title  : 'Space Oddity',
-    artist : 'David Bowie',
-    _id    : "doc2",
-    _rev   : "1-7b80fc50b6af7a905f368670429a757e"
-  }
-]).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-Or delete them:
-
-{% include code/start.html id="bulk_docs_4" type="callback" %}
-{% highlight js %}
-db.bulkDocs([
-  {
-    title    : 'Lisa Says',
-    _deleted : true,
-    _id      : "doc1",
-    _rev     : "1-84abc2a942007bee7cf55007cba56198"
-  },
-  {
-    title    : 'Space Oddity',
-    _deleted : true,
-    _id      : "doc2",
-    _rev     : "1-7b80fc50b6af7a905f368670429a757e"
-  }
-], function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_4" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.bulkDocs([
-    {
-      title    : 'Lisa Says',
-      _deleted : true,
-      _id      : "doc1",
-      _rev     : "1-84abc2a942007bee7cf55007cba56198"
-    },
-    {
-      title    : 'Space Oddity',
-      _deleted : true,
-      _id      : "doc2",
-      _rev     : "1-7b80fc50b6af7a905f368670429a757e"
-    }
-  ]);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulk_docs_4" type="promise" %}
-{% highlight js %}
-db.bulkDocs([
-  {
-    title    : 'Lisa Says',
-    _deleted : true,
-    _id      : "doc1",
-    _rev     : "1-84abc2a942007bee7cf55007cba56198"
-  },
-  {
-    title    : 'Space Oddity',
-    _deleted : true,
-    _id      : "doc2",
-    _rev     : "1-7b80fc50b6af7a905f368670429a757e"
-  }
-]).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-**Note:** You can also specify a `new_edits` property on the options object that when set to `false` allows you to post [existing documents from other databases](http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Posting_Existing_Revisions). This will not allow you to edit existing local documents and normally only the replication algorithm needs to do this.
diff --git a/docs/_includes/api/batch_fetch.html b/docs/_includes/api/batch_fetch.html
deleted file mode 100644
index 13acb78..0000000
--- a/docs/_includes/api/batch_fetch.html
+++ /dev/null
@@ -1,202 +0,0 @@
-{% include anchor.html edit="true" title="Fetch a batch of documents" hash="batch_fetch" %}
-
-{% highlight js %}
-db.allDocs([options], [callback])
-{% endhighlight %}
-
-Fetch multiple documents, indexed and sorted by the `_id`.  Deleted documents are only included if `options.keys` is specified.
-
-### Options
-
-All options default to `false` unless otherwise specified.
-
-* `options.include_docs`: Include the document itself in each row in the `doc` field. Otherwise by default you only get the `_id` and `_rev` properties.
-    - `options.conflicts`: Include conflict information in the `_conflicts` field of a doc.
-  - `options.attachments`: Include attachment data as base64-encoded string.
-    - `options.binary`: Return attachment data as Blobs/Buffers, instead of as base64-encoded strings.
-* `options.startkey` &amp; `options.endkey`: Get documents with IDs in a certain range (inclusive/inclusive).
-* `options.inclusive_end`: Include documents having an ID equal to the given `options.endkey`. Default: `true`.
-* `options.limit`: Maximum number of documents to return.
-* `options.skip`: Number of docs to skip before returning (warning: poor performance on IndexedDB/LevelDB!).
-* `options.descending`: Reverse the order of the output documents. Note that the order of `startkey` and `endkey` is reversed when `descending`:`true`.
-* `options.key`: Only return documents with IDs matching this string key.
-* `options.keys`: Array of string keys to fetch in a single shot.
-    - Neither `startkey` nor `endkey` can be specified with this option.
-    - The rows are returned in the same order as the supplied `keys` array.
-    - The row for a deleted document will have the revision ID of the deletion, and an extra key `"deleted":true` in the `value` property.
-    - The row for a nonexistent document will just contain an `"error"` property with the value `"not_found"`.
-    - For details, see the [CouchDB query options documentation](http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options).
-
-**Notes:** For pagination, `options.limit` and `options.skip` are also available, but the same performance concerns as in CouchDB apply. Use the [startkey/endkey pattern](http://docs.couchdb.org/en/latest/couchapp/views/pagination.html) instead.
-
-#### Example Usage:
-
-{% include code/start.html id="all_docs" type="callback" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true
-}, function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.allDocs({
-    include_docs: true,
-    attachments: true
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs" type="promise" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-
-{% highlight js %}
-{
-  "offset": 0,
-  "total_rows": 1,
-  "rows": [{
-    "doc": {
-      "_id": "0B3358C1-BA4B-4186-8795-9024203EB7DD",
-      "_rev": "1-5782E71F1E4BF698FA3793D9D5A96393",
-      "title": "Sound and Vision",
-      "_attachments": {
-      	"attachment/its-id": {
-      	  "content_type": "image/jpg",
-      	  "data": "R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==",
-      	  "digest": "md5-57e396baedfe1a034590339082b9abce"
-      	}
-      }
-    },
-   "id": "0B3358C1-BA4B-4186-8795-9024203EB7DD",
-   "key": "0B3358C1-BA4B-4186-8795-9024203EB7DD",
-   "value": {
-    "rev": "1-5782E71F1E4BF698FA3793D9D5A96393"
-   }
- }]
-}
-{% endhighlight %}
-
-In the response, you have three things:
-
-* `total_rows` the total number of non-deleted documents in the database
-* `offset` the `skip` if provided, or in CouchDB the actual offset
-* `rows`: rows containing the documents, or just the `_id`/`_revs` if you didn't set `include_docs` to `true`.
-
-You can use `startkey`/`endkey` to find all docs in a range:
-
-{% include code/start.html id="all_docs_2" type="callback" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true,
-  startkey: 'bar',
-  endkey: 'quux'
-}, function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs_2" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.allDocs({
-    include_docs: true,
-    attachments: true,
-    startkey: 'bar',
-    endkey: 'quux'
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs_2" type="promise" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true,
-  startkey: 'bar',
-  endkey: 'quux'
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-This will return all docs with `_id`s between `'bar'` and `'quux'`.
-
-#### Prefix search
-
-You can do prefix search in `allDocs()` &ndash; i.e. "give me all the documents whose `_id`s start with `'foo'`" &ndash; by using the special high Unicode character `'\uffff'`:
-
-{% include code/start.html id="all_docs_3" type="callback" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true,
-  startkey: 'foo',
-  endkey: 'foo\uffff'
-}, function(err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs_3" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.allDocs({
-    include_docs: true,
-    attachments: true,
-    startkey: 'foo',
-    endkey: 'foo\uffff'
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="all_docs_3" type="promise" %}
-{% highlight js %}
-db.allDocs({
-  include_docs: true,
-  attachments: true,
-  startkey: 'foo',
-  endkey: 'foo\uffff'
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-This works because CouchDB/PouchDB `_id`s are sorted [lexicographically](http://docs.couchdb.org/en/latest/couchapp/views/collation.html).
diff --git a/docs/_includes/api/bulk_get.html b/docs/_includes/api/bulk_get.html
deleted file mode 100644
index cb84b92..0000000
--- a/docs/_includes/api/bulk_get.html
+++ /dev/null
@@ -1,118 +0,0 @@
-{% include anchor.html edit="true" title="Document bulk get" hash="bulk_get" %}
-
-{% highlight js %}
-db.bulkGet(options, [callback])
-{% endhighlight %}
-
-Given a set of document/revision IDs, returns the document bodies (and, optionally, attachment data) for each ID/revision pair specified.
-
-### Options
-
-* `options.docs`: An array of `id` and `rev` pairs representing the revisions to fetch.
-  - `id`: ID of the document to fetch.
-  - `rev`: Revision of the document to fetch. If this is not specified, all available revisions are fetched.
-  - `atts_since`: Optional and supported by the http adapter only. Includes attachments only since specified revisions. Doesn’t includes attachments for specified revisions.
-* `options.revs`: Each returned revision body will include its revision history as a `_revisions` property. Default is `false`.
-* `options.attachments`: Include attachment data in the response. Default is `false`, resulting in only stubs being returned.
-* `options.binary`: Return attachment data as Blobs/Buffers, instead of as base64-encoded strings. Default is `false`.
-
-
-
-#### Example Usage:
-
-{% include code/start.html id="bulkget1" type="callback" %}
-{% highlight js %}
-db.bulkGet({
-  docs: [
-    { id: "existing-doc", rev: "1-b2e54331db828310f3c772d6e042ac9c"},
-    { id: "foo", rev: "2-3a24009a9525bde9e4bfa8a99046b00d"},
-    { id: "bar", rev: "1-3a24009a9525bde9e4bfa8a99046b00d"}
-  ]
-}, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulkget1" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.bulkGet({
-      docs: [
-        { id: "doc-that-exists", rev: "1-967a00dff5e02add41819138abb3284d"},
-        { id: "doc-that-does-not-exist", rev: "1-3a24009a9525bde9e4bfa8a99046b00d"},
-        { id: "doc-that-exists", rev: "1-bad_rev"}
-      ]
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="bulkget1" type="promise" %}
-{% highlight js %}
-db.bulkGet({
-    docs: [
-      { id: "doc-that-exists", rev: "1-967a00dff5e02add41819138abb3284d"},
-      { id: "doc-that-does-not-exist", rev: "1-3a24009a9525bde9e4bfa8a99046b00d"},
-      { id: "doc-that-exists", rev: "1-bad_rev"}
-    ]
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "results": [
-  {
-    "docs": [
-    {
-      "ok": {
-        "_id": "doc-that-exists",
-        "_rev": "1-967a00dff5e02add41819138abb3284d",
-        "_revisions": {
-          "ids": [
-            "967a00dff5e02add41819138abb3284d"
-          ],
-          "start": 1
-        }
-      }
-    }],
-    "id": "doc-that-exists"
-  },
-  {
-    "docs": [
-    {
-      "error": {
-        "error": "not_found",
-        "id": "doc-that-does-not-exist",
-        "reason": "missing",
-        "rev": "undefined"
-      }
-    }],
-    "id": "doc-that-does-not-exist"
-  },
-  {
-    "docs": [
-    {
-      "error": {
-        "error": "not_found",
-        "id": "doc-that-exists",
-        "reason": "missing",
-        "rev": "1-badrev"
-      }
-    }
-    ],
-    "id": "doc-that-exists"
-  }]
-}
-{% endhighlight %}
-
-
diff --git a/docs/_includes/api/changes.html b/docs/_includes/api/changes.html
deleted file mode 100644
index c7d9098..0000000
--- a/docs/_includes/api/changes.html
+++ /dev/null
@@ -1,355 +0,0 @@
-{% include anchor.html edit="true" title="Listen to database changes" hash="changes" %}
-
-{% highlight js %}
-db.changes(options)
-{% endhighlight %}
-
-A list of changes made to documents in the database, in the order they were made.
-It returns an object with the method `cancel()`, which you call if you don't want to listen to new changes anymore.
-
-It is an [event emitter][event emitter] and will emit a `'change'` event on each document change, a `'complete'` event when all the changes have been processed, and an `'error'` event when an error occurs.
-
-### Options
-
-All options default to `false` unless otherwise specified.
-
-* `options.live`: Will emit change events for all future changes until cancelled.
-* `options.include_docs`: Include the associated document with each change.
-  * `options.conflicts`: Include conflicts.
-  * `options.attachments`: Include attachments.
-    - `options.binary`: Return attachment data as Blobs/Buffers, instead of as base64-encoded strings.
-* `options.descending`: Reverse the order of the output documents.
-* `options.since`: Start the results from the change immediately after the given sequence number. You can also pass `'now'` if you want only new changes (when `live` is `true`).
-* `options.limit`: Limit the number of results to this number.
-* `options.timeout`: Request timeout (in milliseconds), use `false` to disable.
-* `options.heartbeat`: For http adapter only, time in milliseconds for server to give a heartbeat to keep long connections open. Defaults to 10000 (10 seconds), use `false` to disable the default.
-
-**Filtering Options:**
-
-* `options.filter`: Reference a filter function from a design document to selectively get updates. To use a view function, pass `_view` here and provide a reference to the view function in `options.view`. See [filtered changes](#filtered-changes) for details.
-* `options.doc_ids`: Only show changes for docs with these ids (array of strings).
-* `options.query_params`: Object containing properties that are passed to the filter function, e.g. `{"foo:"bar"}`, where `"bar"` will be available in the filter function as `params.query.foo`. To access the `params`, define your filter function like `function (doc, params) {/* ... */}`.
-* `options.view`: Specify a view function (e.g. `'design_doc_name/view_name'` or `'view_name'` as shorthand for `'view_name/view_name'`) to act as a filter. Documents counted as "passed" for a view filter if a map function emits at least one record for them. **Note**: `options.filter` must be set to `'_view'` for this option to work.
-
-**Advanced Options:**
-
-* `options.return_docs` (previously `options.returnDocs`): Is available for non-http databases and defaults to `true`. Passing `false` prevents the changes feed from keeping all the documents in memory &ndash; in other words complete always has an empty results array, and the `change` event is the only way to get the event. Useful for large change sets where otherwise you would run out of memory.
-* `options.batch_size`: Only available for http databases, this configures how many changes to fetch at a time. Increasing this can reduce the number of requests made. Default is 25.
-* `options.style`: Specifies how many revisions are returned in the changes array. The default, `'main_only'`, will only return the current "winning" revision; `'all_docs'` will return all leaf revisions (including conflicts and deleted former conflicts). Most likely you won't need this unless you're writing a replicator.
-
-#### Example Usage:
-
-{% highlight js %}
-var changes = db.changes({
-  since: 'now',
-  live: true,
-  include_docs: true
-}).on('change', function(change) {
-  // handle change
-}).on('complete', function(info) {
-  // changes() was canceled
-}).on('error', function (err) {
-  console.log(err);
-});
-
-changes.cancel(); // whenever you want to cancel
-{% endhighlight %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "id":"somestuff",
-  "seq":21,
-  "changes":[{
-    "rev":"1-8e6e4c0beac3ec54b27d1df75c7183a8"
-  }],
-  "doc":{
-    "title":"Ch-Ch-Ch-Ch-Changes",
-    "_id":"someDocId",
-    "_rev":"1-8e6e4c0beac3ec54b27d1df75c7183a8"
-  }
-}
-{% endhighlight %}
-
-#### Change events
-
-* __`change`__ (`info`) - This event fires when a change has been found. `info` will contain details about the change, such as whether it was deleted and what the new `_rev` is. `info.doc` will contain the doc if you set `include_docs` to `true`. See below for an example response.
-* __`complete`__ (`info`) - This event fires when all changes have been read. In live changes, only cancelling the changes should trigger this event. `info.results` will contain the list of changes. See below for an example.
-* __`error`__ (`err`) - This event is fired when the replication is stopped due to an unrecoverable failure.
-
-#### Example response
-
-Example response in the `'change'` listener (using `{include_docs: true}`):
-
-{% highlight js %}
-{ id: 'doc1',
-  changes: [ { rev: '1-9152679630cc461b9477792d93b83eae' } ],
-  doc: {
-    _id: 'doc1',
-    _rev: '1-9152679630cc461b9477792d93b83eae'
-  },
-  seq: 1
-}
-{% endhighlight %}
-
-Example response in the `'change'` listener when a doc was deleted:
-
-{% highlight js %}
-{ id: 'doc2',
-  changes: [ { rev: '2-9b50a4b63008378e8d0718a9ad05c7af' } ],
-  doc: { _id: 'doc2',
-    _rev: '2-9b50a4b63008378e8d0718a9ad05c7af',
-    _deleted: true
-  },
-  deleted: true,
-  seq: 3
-}
-{% endhighlight %}
-
-Example response in the `'complete'` listener:
-
-{% highlight js %}
-{
-  "results": [
-    {
-      "id": "doc1",
-      "changes": [ { "rev": "1-9152679630cc461b9477792d93b83eae" } ],
-      "doc": {
-        "_id": "doc1",
-        "_rev": "1-9152679630cc461b9477792d93b83eae"
-      },
-      "seq": 1
-    },
-    {
-      "id": "doc2",
-      "changes": [ { "rev": "2-9b50a4b63008378e8d0718a9ad05c7af" } ],
-      "doc": {
-        "_id": "doc2",
-        "_rev": "2-9b50a4b63008378e8d0718a9ad05c7af",
-        "_deleted": true
-      },
-      "deleted": true,
-      "seq": 3
-    }
-  ],
-  "last_seq": 3
-}
-{% endhighlight %}
-
-`seq` and `last_seq` correspond to the overall sequence number of the entire database, and it's what is passed in when using `since` (except for the special `'now'`). It is the primary key for the changes feed, and is also used as a checkpointer by the replication algorithm.
-
-#### Single-shot
-
-If you don't specify `{live: true}`, then you can also use `changes()` in the standard
-callback/promise style, and it will be treated as a single-shot request, which
-returns a list of the changes (i.e. what the `'complete'` event emits):
-
-{% include code/start.html id="changes1" type="callback" %}
-{% highlight js %}
-db.changes({
-  limit: 10,
-  since: 0
-}, function (err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="changes1" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.changes({
-    limit: 10,
-    since: 0
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="changes1" type="promise" %}
-{% highlight js %}
-db.changes({
-  limit: 10,
-  since: 0
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-
-{% highlight js %}
-{
-  "results": [{
-    "id": "0B3358C1-BA4B-4186-8795-9024203EB7DD",
-    "seq": 1,
-    "changes": [{
-      "rev": "1-5782E71F1E4BF698FA3793D9D5A96393"
-    }]
-  }, {
-    "id": "mydoc",
-    "seq": 2,
-    "changes": [{
-      "rev": "1-A6157A5EA545C99B00FF904EEF05FD9F"
-    }]
-  }, {
-    "id": "otherdoc",
-    "seq": 3,
-    "changes": [{
-      "rev": "1-3753476B70A49EA4D8C9039E7B04254C"
-    }]
-  }, {
-    "id": "828124B9-3973-4AF3-9DFD-A94CE4544005",
-    "seq": 4,
-    "changes": [{
-      "rev": "1-A8BC08745E62E58830CA066D99E5F457"
-    }]
-  }]
-}
-{% endhighlight %}
-
-When `live` is `false`, the returned object is also an event emitter as well as a promise,
-and will fire the `'complete'` event when the results are ready.
-
-Note that this `'complete'` event only fires when you aren't doing live changes.
-
-#### Filtered changes
-
-As with [replicate()](#replication), you can filter using:
-
-* an ad-hoc `filter` function
-* an array of `doc_ids`
-* a `filter` function inside of a design document
-* a `filter` function inside of a design document, with `query_params`
-* a `view` function inside of a design document
-
-If you are running `changes()` on a remote CouchDB, then the first method will run client-side, whereas the last four will filter on the server side. Therefore the last four should be preferred, especially if the database is large, because you want to send as few documents over the wire as possible.
-
-If you are running `changes()` on a local PouchDB, then obviously all five methods will run client-side. There are also no performance benefits to using any of the five, so can also just filter yourself, in your own `on('change')` handler. These methods are implemented in PouchDB purely for consistency with CouchDB.
-
-The named functions can either be specified with `'designdoc_id/function_name'` or (if both design doc id and function name are equal) as `'fname'` as shorthand for `'fname/fname'`.
-
-#### Filtering examples
-
-In these examples, we'll work with some mammals. Let's imagine our docs are:
-
-{% highlight js %}
-[
-  {_id: 'a', name: 'Kangaroo', type: 'marsupial'},
-  {_id: 'b', name: 'Koala', type: 'marsupial'},
-  {_id: 'c', name: 'Platypus', type: 'monotreme'}
-]
-{% endhighlight %}
-
-Here are 5 examples using the 5 different systems.
-
-**Example 1: Ad-hoc `filter` function**
-
-*Warning*: this runs client-side, if the database is remote.
-
-Filter by `type === 'marsupial'`:
-
-{% highlight js %}
-db.changes({
-  filter: function (doc) {
-    return doc.type === 'marsupial';
-  }
-});
-{% endhighlight %}
-
-**Example 2: Array of `doc_ids`**
-
-Filter documents with `_id`s `['a', 'c']`.
-
-{% highlight js %}
-db.changes({
-  doc_ids: ['a', 'c']
-});
-{% endhighlight %}
-
-**Example 3: `filter` function inside of a design document**
-
-First `put()` a design document:
-
-{% highlight js %}
-{
-  _id: '_design/mydesign',
-  filters: {
-    myfilter: function (doc) {
-      return doc.type === 'marsupial';
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-db.changes({
-  filter: 'mydesign/myfilter'
-});
-{% endhighlight %}
-
-**Example 4: `filter` function inside of a design document, with `query_params`**
-
-This is the most powerful way to filter, because it allows you to pass in arbitrary options to your filter function.
-
-First `put()` a design document:
-
-{% highlight js %}
-{
-  _id: '_design/myfilter',
-  filters: {
-    myfilter: function (doc, req) {
-      return doc.type === req.query.type;
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-db.changes({
-  filter: 'myfilter',
-  query_params: {type: 'marsupial'}
-});
-{% endhighlight %}
-
-Since both the design document and the filter function have the same name, we can shorten the function name to `'myfilter'`.
-
-**Example 5: `view` function inside of a design document**
-
-This doesn't really offer any advantages compared to the previous two methods, unless you are already using a `view` for map/reduce queries, and you want to reuse it.
-
-Any documents that `emit()` anything will be considered to have passed this filter method.
-
-First `put()` a design document:
-
-{% highlight js %}
-{
-  _id: '_design/mydesign',
-  views: {
-    myview: function (doc) {
-      if (doc.type === 'marsupial') {
-        emit(doc._id);
-      }
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-db.changes({
-  filter: '_view',
-  view: 'mydesign/myview'
-});
-{% endhighlight %}
diff --git a/docs/_includes/api/compaction.html b/docs/_includes/api/compaction.html
deleted file mode 100644
index fadbaec..0000000
--- a/docs/_includes/api/compaction.html
+++ /dev/null
@@ -1,49 +0,0 @@
-{% include anchor.html edit="true" title="Compact the database" hash="compaction" %}
-
-{% highlight js %}
-db.compact([options], [callback])
-{% endhighlight %}
-
-Triggers a compaction operation in the local or remote database. This reduces the database's size by removing unused and old data, namely non-leaf revisions and attachments that are no longer referenced by those revisions. Note that this is a separate operation from [`viewCleanup()`](#view_cleanup).
-
-For remote databases, PouchDB checks the compaction status at regular intervals and fires the callback (or resolves the promise) upon completion. Consult the [compaction section of CouchDB's maintenance documentation](http://couchdb.readthedocs.org/en/latest/maintenance/compaction.html) for more details.
-
-Also see [auto-compaction](#create_database), which runs compaction automatically (local databases only).
-
-* `options.interval`: Number of milliseconds to wait before asking again if compaction is already done. Defaults to 200. (Only applies to remote databases.)
-
-#### Example Usage:
-
-{% include code/start.html id="compact" type="callback" %}
-{% highlight js %}
-db.compact(function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="compact" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.compact();
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="compact" type="promise" %}
-{% highlight js %}
-db.compact().then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{ "ok" : "true" }
-{% endhighlight %}
diff --git a/docs/_includes/api/create_database.html b/docs/_includes/api/create_database.html
deleted file mode 100644
index 74092f2..0000000
--- a/docs/_includes/api/create_database.html
+++ /dev/null
@@ -1,94 +0,0 @@
-{% include anchor.html edit="true" title="Create a database" hash="create_database" %}
-
-{% highlight js %}
-new PouchDB([name], [options])
-{% endhighlight %}
-
-This method creates a database or opens an existing one. If you use a URL like `'http://domain.com/dbname'`, then PouchDB will work as a client to an online CouchDB instance.  Otherwise it will create a local database using [whatever backend is present](/adapters.html).
-
-### Options
-
-* `name`: You can omit the `name` argument and specify it via `options` instead. Note that the name is required.
-
-**Options for local databases:**
-
-* `auto_compaction`: This turns on auto compaction, which means `compact()` is called after every change to the database. Defaults to `false`.
-* `adapter`: One of `'idb'`, `'leveldb'`, `'websql'`, or `'http'`. If unspecified, PouchDB will infer this automatically, preferring IndexedDB to WebSQL in browsers that support both (i.e. Chrome, Opera and Android 4.4+).
-* `revs_limit`: Specify how many old revisions we keep track (not a copy) of.
-
-**Options for remote databases:**
-
-* `ajax`: (Remote databases only.) Ajax requester options. For instance, passing in the options `{ajax: {timeout: 10000}}` will allow you to set the max timeout for an HTTP request. These are passed ver batim to [request][] (in Node.js) or  [a request shim](https://github.com/pouchdb/pouchdb/blob/master/lib/deps/request-browser.js) (in the browser), with the exception of:
-* `ajax.cache`: Appends a random string to the end of all HTTP GET requests to avoid them being cached on IE. Set this to `true` to prevent this happening.
-* `ajax.headers`: The `ajax.headers` option allows you to customise headers that are sent to the remote HTTP Server.
-* `auth.username` + `auth.password`: You can specify HTTP auth parameters either by using a database with a name in the form `http://user:pass@host/name` or via the `auth.username` + `auth.password` options.
-* `ajax.withCredentials`: Set to `false` to disable transferring cookies or [HTTP Auth information](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials). Defaults to `true`.
-* `skip_setup`: Initially PouchDB checks if the database exists, and tries to create it, if it does not exist yet. Set this to `true` to skip this setup.
-
-**IndexedDB-only options:**
-
-* `storage`: Specifies whether you want to use `persistent` or `temporary` storage. This non-standard feature has been supported in Firefox since version 26. Find out more about the available storage types, and how Firefox handles client-side data storage, at [Browser storage limits and eviction criteria](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria).
-
-**WebSQL-only options:**
-
-* `size`: Amount in MB to request for storage, which you will need if you are storing >5MB in order to [avoid storage limit errors on iOS/Safari](/errors.html#not_enough_space).
-
-**SQLite Plugin-only options:**
-
-Any options given to the PouchDB constructor will be passed verbatim to the SQLite Plugin.  Older versions of PouchDB supported only the following, which may be of use:
-
-* `location`: Where to store data on iOS, which may affect iTunes/iCloud backup, and thus whether or not your app gets rejected by Apple. See [SQLite Plugin documentation](https://github.com/brodysoft/Cordova-SQLitePlugin/#opening-a-database) and [iOS data storage guidelines](https://developer.apple.com/icloud/documentation/data-storage/index.html).
-* `createFromLocation`: Use a pre-populated database, so you can package it with your app and users don't have to wait for it to load. See the [SQLite Plugin documentation](https://github.com/brodysoft/Cordova-SQLitePlugin/#pre-populated-database).
-* `androidDatabaseImplementation`: `1` to use the new `sqlite4java` implementation, `2` to use the older version based on the native Android APIs. Defaults to `1`. See the [SQLite Plugin documentation](https://github.com/litehelpers/Cordova-sqlite-storage#android-sqlite-implementation).
-
-**Notes:**
-
-1. In IndexedDB and WebSQL, PouchDB will use `_pouch_` to prefix the internal database names. Do not manually create databases with the same prefix.
-2. When acting as a client on Node, any other options given will be passed to [request][].
-3. When using the `'leveldb'` adapter (the default on Node), any other options given will be passed to [levelup][]. The storage layer of leveldb can be replaced by passing a level backend factory (such as [MemDOWN][]) as `options.db`. The rest of the [supported levelup options are documented here][levelup_options].
-
-[request]: https://github.com/mikeal/request
-[levelup]: https://github.com/rvagg/node-levelup
-[MemDOWN]: https://github.com/rvagg/memdown
-[levelup_options]: https://github.com/rvagg/node-levelup/#options
-
-#### Example Usage:
-{% highlight js %}
-var db = new PouchDB('dbname');
-// or
-var db = new PouchDB('http://localhost:5984/dbname');
-{% endhighlight %}
-
-Create a WebSQL-only Pouch (e.g. when using the [SQLite Plugin][] for Cordova/PhoneGap):
-
-[sqlite plugin]: https://github.com/brodysoft/Cordova-SQLitePlugin
-
-{% highlight js %}
-var db = new PouchDB('dbname', {adapter : 'websql'});
-{% endhighlight %}
-
-Create an in-memory Pouch (in Node):
-
-{% highlight js %}
-var db = new PouchDB('dbname', {db : require('memdown')});
-{% endhighlight %}
-
-Create a remote PouchDB with special Ajax options:
-
-{% highlight js %}
-var db = new PouchDB('http://example.com/dbname', {
-  ajax: {
-    cache: false,
-    timeout: 10000,
-    headers: {
-      'X-Some-Special-Header': 'foo'
-    },
-  },
-  auth: {
-    username: 'mysecretusername',
-    password: 'mysecretpassword'
-  }
-});
-{% endhighlight %}
-
-For more info, check out [adapters](/adapters.html).
diff --git a/docs/_includes/api/create_document.html b/docs/_includes/api/create_document.html
deleted file mode 100644
index 207a8c5..0000000
--- a/docs/_includes/api/create_document.html
+++ /dev/null
@@ -1,216 +0,0 @@
-{% include anchor.html edit="true" title="Create/update a document" hash="create_document" %}
-
-### Using db.put()
-{% highlight js %}
-db.put(doc, [docId], [docRev], [options], [callback])
-{% endhighlight %}
-
-Create a new document or update an existing document. If the document already exists, you must specify its revision `_rev`, otherwise a conflict will occur.
-
-There are some [restrictions on valid property names of the documents](http://wiki.apache.org/couchdb/HTTP_Document_API#Special_Fields). If you try to store non-JSON data (for instance `Date` objects) you may see [inconsistent results](http://pouchdb.com/errors.html#could_not_be_cloned).
-
-#### Example Usage:
-
-Create a new doc with an `_id` of `'mydoc'`:
-
-{% include code/start.html id="newDoc" type="callback" %}
-{% highlight js %}
-db.put({
-  _id: 'mydoc',
-  title: 'Heroes'
-}, function(err, response) {
-  if (err) { return console.log(err); }
-  // handle response
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="newDoc" type="async" %}
-{% highlight js %}
-try {
-  var response = await db.put({
-    _id: 'mydoc',
-    title: 'Heroes'
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="newDoc" type="promise" %}
-{% highlight js %}
-db.put({
-  _id: 'mydoc',
-  title: 'Heroes'
-}).then(function (response) {
-  // handle response
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-You can update an existing doc using `_rev`:
-
-{% include code/start.html id="updateDoc" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  db.put({
-    _id: 'mydoc',
-    _rev: doc._rev,
-    title: "Let's Dance"
-  }, function(err, response) {
-    if (err) { return console.log(err); }
-    // handle response
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="updateDoc" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-  var response = await db.put({
-    _id: 'mydoc',
-    _rev: doc._rev,
-    title: "Let's Dance"
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-
-{% include code/start.html id="updateDoc" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function(doc) {
-  return db.put({
-    _id: 'mydoc',
-    _rev: doc._rev,
-    title: "Let's Dance"
-  });
-}).then(function(response) {
-  // handle response
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-Instead of including the `_id` and `_rev` in the document, you can
-also pass them in as options:
-
-{% include code/start.html id="updateDoc2" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  db.put({
-    title: "Sound and Vision"
-  }, 'mydoc', doc._rev, function(err, response) {
-    if (err) { return console.log(err); }
-    // handle response
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="updateDoc2" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-  var response = await db.put({
-    title: "Sound and Vision"
-  }, 'mydoc', doc._rev);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="updateDoc2" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function(doc) {
-  return db.put({
-    title: "Sound and Vision"
-  }, 'mydoc', doc._rev,);
-}).then(function(response) {
-  // handle response
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "ok": true,
-  "id": "mydoc",
-  "rev": "1-A6157A5EA545C99B00FF904EEF05FD9F"
-}
-{% endhighlight %}
-
-The response contains the `id` of the document, the new `rev`, and an `ok` to reassure
-you that everything is okay.
-
-### Using db.post()
-
-{% highlight js %}
-db.post(doc, [options], [callback])
-{% endhighlight %}
-
-Create a new document and let PouchDB auto-generate an `_id` for it.
-
-#### Example Usage:
-
-{% include code/start.html id="post_doc" type="callback" %}
-{% highlight js %}
-db.post({
-  title: 'Ziggy Stardust'
-}, function (err, response) {
-  if (err) { return console.log(err); }
-  // handle response
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="post_doc" type="async" %}
-{% highlight js %}
-try {
-  var response = await db.post({
-    title: 'Ziggy Stardust'
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="post_doc" type="promise" %}
-{% highlight js %}
-db.post({
-  title: 'Ziggy Stardust'
-}).then(function (response) {
-  // handle response
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "ok" : true,
-  "id" : "8A2C3761-FFD5-4770-9B8C-38C33CED300A",
-  "rev" : "1-d3a8e0e5aa7c8fff0c376dac2d8a4007"
-}
-{% endhighlight %}
-
-**Put vs. post**: The basic rule of thumb is: `put()` new documents with an `_id`, `post()` new documents without an `_id`.
-
-You should also prefer `put()` to `post()`, because when you `post()`, you are missing an opportunity to use `allDocs()` to sort documents by `_id` (because your `_id`s are random). For more info, read the [PouchDB pro tips](/2014/06/17/12-pro-tips-for-better-code-with-pouchdb.html).
diff --git a/docs/_includes/api/database_information.html b/docs/_includes/api/database_information.html
deleted file mode 100644
index 52be41d..0000000
--- a/docs/_includes/api/database_information.html
+++ /dev/null
@@ -1,61 +0,0 @@
-{% include anchor.html edit="true" title="Get database information" hash="database_information" %} 
-
-{% highlight js %}
-db.info([callback])
-{% endhighlight %}
-
-Get information about a database.
-
-#### Example Usage:
-
-{% include code/start.html id="dbinfo" type="callback" %}
-{% highlight js %}
-db.info(function(err, info) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="dbinfo" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.info();
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="dbinfo" type="promise" %}
-{% highlight js %}
-db.info().then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "db_name": "test",
-  "doc_count": 4,
-  "update_seq": 5
-}
-{% endhighlight %}
-
-**Response object:**
-
-* `db_name` is the name of the database you gave when you called `new PouchDB()`, and also the unique identifier for the database.
-* `doc_count` is the total number of non-deleted documents in the database.
-* `update_seq` is the sequence number of the database.  It starts at 0 and gets incremented every time a document is added or modified.
-
-There are also some details you can use for debugging. These are unofficial and may change at any time:
-
-* `adapter`: The name of the adapter being used (idb, websql, leveldb, ...).
-* `idb_attachment_format`: (IndexedDB) either `'base64'` or `'binary'`, depending on whether the browser [supports binary blobs](/faq.html#data_types).
-* `sqlite_plugin`: (WebSQL) true if the [SQLite Plugin][] is being used.
-* `websql_encoding`: (WebSQL) either `'UTF-8'` or `'UTF-16'`, depending on the [WebSQL implementation](http://pouchdb.com/faq.html#data_types)
-* `backend_adapter`: (Node.JS) the backend *DOWN adapter being used (MemDOWN, RiakDOWN, ...).
\ No newline at end of file
diff --git a/docs/_includes/api/debug_mode.html b/docs/_includes/api/debug_mode.html
deleted file mode 100644
index ef6c380..0000000
--- a/docs/_includes/api/debug_mode.html
+++ /dev/null
@@ -1,34 +0,0 @@
-{% include anchor.html edit="true" title="Debug mode" hash="debug_mode" %} 
-
-PouchDB uses the [debug](https://www.npmjs.org/package/debug) module for fine-grained debug output.
-
-To enable debug mode, just call:
-
-{% highlight js %}
-PouchDB.debug.enable('*');
-{% endhighlight %}
-
-In your browser console, you should then see something like this:
-
-{% include img.html src="debug_mode.png" alt="Coloured Log Output" %}
-
-In Node.js, you can also set a command-line flag:
-
-{% highlight bash %}
-DEBUG=pouchdb:* node myscript.js
-{% endhighlight %}
-
-You can also enable debugging of specific modules. Currently we only have `pouchb:api` (API-level calls) and `pouchdb:http`  (HTTP requests):
-
-{% highlight js %}
-PouchDB.debug.enable('pouchdb:api'); // or
-PouchDB.debug.enable('pouchdb:http');
-{% endhighlight %}
-
-These settings are saved to the browser's LocalStorage. So to disable them, you must call:
-
-{% highlight js %}
-PouchDB.debug.disable();
-{% endhighlight %}
-
-Your users won't see debug output unless you explicitly call `PouchDB.debug.enable()` within your application code.
\ No newline at end of file
diff --git a/docs/_includes/api/defaults.html b/docs/_includes/api/defaults.html
deleted file mode 100644
index 77318a6..0000000
--- a/docs/_includes/api/defaults.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% include anchor.html edit="true" title="Default settings" hash="defaults" %} 
-
-If you find yourself using the same constructor options repeatedly,
-you can simplify your code with `PouchDB.defaults()`:
-
-{% highlight js %}
-PouchDB.defaults({
-  option1: 'foo',
-  option2: 'value'
-});
-{% endhighlight %}
-
-The returned object is a constructor function that works the same as `PouchDB`, except that whenever you invoke it (e.g. with `new`), the given options will be passed in by default.
-
-#### Example Usage:
-{% highlight js %}
-var MyMemPouch = PouchDB.defaults({
-  db: require('memdown')
-});
-// MemDOWN-backed Pouch (in Node)
-var MyMemPouch = new MyMemPouch('dbname');
-
-var MyPrefixedPouch = PouchDB.defaults({
-  prefix: '/path/to/my/db/'
-});
-// db will be named '/path/to/my/db/dbname', useful for LevelDB
-var myPrefixedPouch = new MyPrefixedPouch('dbname');
-{% endhighlight %}
-
-Note the special constructor option `prefix`, which appends a prefix to the database name
-and can be helpful for URL-based or file-based LevelDOWN path names.
-
-All [constructor options](#create_database) are supported. Default options can still be overriden individually.
-
-
diff --git a/docs/_includes/api/delete_attachment.html b/docs/_includes/api/delete_attachment.html
deleted file mode 100644
index b26781e..0000000
--- a/docs/_includes/api/delete_attachment.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% include anchor.html edit="true" title="Delete an attachment" hash="delete_attachment" %} 
-
-{% highlight js %}
-db.removeAttachment(docId, attachmentId, rev, [callback])
-{% endhighlight %}
-
-Delete an attachment from a doc. You must supply the `rev` of the existing doc.
-
-#### Example Usage:
-
-{% include code/start.html id="delete_att" type="callback" %}
-{% highlight js %}
-var rev = '1-068E73F5B44FEC987B51354DFC772891';
-db.removeAttachment('doc', 'att.txt', rev, function(err, res) {
-  if (err) { return console.log(err); }
-  // handle result                      
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_att" type="async" %}
-{% highlight js %}
-try {
-  var rev = '1-068E73F5B44FEC987B51354DFC772891';
-  var result = await db.removeAttachment('doc', 'att.txt', rev);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_att" type="promise" %}
-{% highlight js %}
-var rev = '1-068E73F5B44FEC987B51354DFC772891';
-db.removeAttachment('doc', 'att.txt', rev).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-
-{% highlight js %}
-{
-  "ok": true,
-  "rev": "2-1F983211AB87EFCCC980974DFC27382F"
-}
-{% endhighlight %}
-
-
diff --git a/docs/_includes/api/delete_database.html b/docs/_includes/api/delete_database.html
deleted file mode 100644
index 0394371..0000000
--- a/docs/_includes/api/delete_database.html
+++ /dev/null
@@ -1,54 +0,0 @@
-{% include anchor.html edit="true" title="Delete a database" hash="delete_database"%}
-
-{% highlight js %}
-db.destroy([options], [callback])
-{% endhighlight %}
-
-Delete the database. Note that this has no impact on other replicated databases.
-
-### Options
-
-* `options.ajax`: (Remote databases only.) Ajax requester options, [as described above](#create_database).
-
-#### Example Usage
-
-{% include code/start.html id="destroy_db" type="callback" %}
-{% highlight js %}
-db.destroy(function (err, response) {
-  if (err) {
-    return console.log(err);
-  } else {
-    // success
-  }
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="destroy_db" type="async" %}
-
-{% highlight js %}
-try {
-  await db.destroy();
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="destroy_db" type="promise" %}
-
-{% highlight js %}
-db.destroy().then(function (response) {
-  // success
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "ok" : true
-}
-{% endhighlight %}
diff --git a/docs/_includes/api/delete_document.html b/docs/_includes/api/delete_document.html
deleted file mode 100644
index ebb5e2b..0000000
--- a/docs/_includes/api/delete_document.html
+++ /dev/null
@@ -1,140 +0,0 @@
-{% include anchor.html edit="true" title="Delete a document" hash="delete_document"%}
-
-{% highlight js %}
-db.remove(doc, [options], [callback])
-{% endhighlight %}
-
-Or:
-
-{% highlight js %}
-db.remove(docId, docRev, [options], [callback])
-{% endhighlight %}
-
-
-Deletes the document. `doc` is required to be a document with at least an `_id` and a `_rev` property. Sending the full document will work as well.
-
-See [filtered replication](http://pouchdb.com/api.html#filtered-replication) for why you might want to use `put()` with `{_deleted: true}` instead.
-
-#### Example Usage:
-
-{% include code/start.html id="delete_doc" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  db.remove(doc, function(err, response) {
-    if (err) { return console.log(err); }
-    // handle response
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-  var response = await db.remove(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function(doc) {
-  return db.remove(doc);
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-
-{% highlight js %}
-{
-  "ok": true,
-  "id": "mydoc",
-  "rev": "2-9AF304BE281790604D1D8A4B0F4C9ADB"
-}
-{% endhighlight %}
-
-You can also delete a document by just providing an `id` and `rev`:
-
-{% include code/start.html id="delete_doc3" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  db.remove(doc._id, doc._rev, function(err, response) {
-    if (err) { return console.log(err); }
-    // handle response
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc3" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-  var response = await db.remove(doc._id, doc._rev);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc3" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function(doc) {
-  return db.remove(doc._id, doc._rev);
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-You can also delete a document by using `put()` with `{_deleted: true}`:
-
-{% include code/start.html id="delete_doc2" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  doc._deleted = true;
-  db.put(doc, function(err, response) {
-    if (err) { return console.log(err); }
-    // handle response
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc2" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-  doc._deleted = true;
-  var result = await db.put(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="delete_doc2" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function(doc) {
-  doc._deleted = true;
-  return db.put(doc);
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
diff --git a/docs/_includes/api/events.html b/docs/_includes/api/events.html
deleted file mode 100644
index 793df31..0000000
--- a/docs/_includes/api/events.html
+++ /dev/null
@@ -1,14 +0,0 @@
-{% include anchor.html edit="true" title="Events" hash="events" %} 
-
-PouchDB is an [event emitter][event emitter] and will emit a `'created'` event when a database is created. A `'destroyed'` event is emitted when a database is destroyed.
-
-{% highlight js %}
-PouchDB.on('created', function (dbName) {
-  // called whenver a db is created.
-});
-PouchDB.on('destroyed', function (dbName) {
-  // called whenver a db is destroyed.
-});
-{% endhighlight %}
-
-
diff --git a/docs/_includes/api/extras.html b/docs/_includes/api/extras.html
deleted file mode 100644
index 50ec3d8..0000000
--- a/docs/_includes/api/extras.html
+++ /dev/null
@@ -1,122 +0,0 @@
-{% include anchor.html edit="true" title="Extras" hash="extras" %}
-
-PouchDB offers some "extra" APIs that are designed for PouchDB plugin authors, or for those who want to use non-standard adapters like in-memory and LocalStorage.
-
-These can be especially useful when you are using [Browserify](http://browserify.org/)/[Webpack](https://github.com/webpack/webpack), because they can reduce your overall code size by deduplicating packages. If you're not using Browserify/Webpack, you can also download them [as standalone scripts](/adapters.html#pouchdb_in_the_browser).
-
-### Browser adapter plugins
-
-These adapters are alternatives to PouchDB's built-in IndexedDB/WebSQL adapters. They fully pass the PouchDB test suite.
-
-#### In-memory adapter
-
-{% highlight js %}
-var PouchDB = require('pouchdb');
-require('pouchdb/extras/memory');
-
-var db = new PouchDB('mydb', {adapter: 'memory'});
-{% endhighlight %}
-
-Fully in-memory PouchDB adapter. Data will not be saved after a browser refresh!
-
-This adapter can be useful for unit tests or for environments that don't support IndexedDB/WebSQL. Based on [MemDOWN](https://github.com/Level/memdown).
-
-You can also download this plugin [as a standalone script](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.memory.js).
-
-{% include alert/start.html variant="warning"%}
-{% markdown %}
-
-If you want to use an in-memory PouchDB in Node.js/io.js, you should [directly require MemDOWN instead](/adapters.html#pouchdb_in_node_js).
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-#### LocalStorage adapter
-
-{% highlight js %}
-var PouchDB = require('pouchdb');
-require('pouchdb/extras/localstorage');
-
-var db = new PouchDB('mydb', {adapter: 'localstorage'});
-{% endhighlight %}
-
-PouchDB adapter using [LocalStorage](http://www.w3.org/TR/webstorage/). Intended for browsers and environments that don't support IndexedDB or WebSQL. Based on [localstorage-down](https://github.com/No9/localstorage-down).
-
-You can also download this plugin [as a standalone script](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.localstorage.js).
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-
-When you include these plugins in your project, they will be automatically picked up as a "third" option when you create a new PouchDB without an adapter specified (e.g. `new PouchDB('mydb')`).
-
-So for instance, if the user loads PouchDB in a browser that does not support WebSQL or IndexedDB, and if you are using the in-memory plugin, then PouchDB will automatically use the memory adapter instead of WebSQL or IndexedDB.
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-#### FruitDOWN adapter
-
-{% highlight js %}
-var PouchDB = require('pouchdb');
-require('pouchdb/extras/fruitdown');
-
-var db = new PouchDB('mydb', {adapter: 'fruitdown'});
-{% endhighlight %}
-
-PouchDB adapter using [FruitDOWN](https://github.com/nolanlawson/fruitdown).
-This is an alternative to the default IndexedDB adapter that ships with PouchDB, which works over all implementations of IndexedDB, including Apple's version.
-
-It is slower and more inefficient than PouchDB's default IndexedDB adapter, but it's handy if you need to use IndexedDB in Safari, iOS, WKWebView, etc.
-
-You can also download this plugin [as a standalone script](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.fruitdown.js).
-
-#### node-websql adapter
-
-{% highlight js %}
-var PouchDB = require('pouchdb');
-require('pouchdb/extras/websql');
-
-var db = new PouchDB('mydatabase.db', {adapter: 'websql'});
-{% endhighlight %}
-
-PouchDB adapter using WebSQL in Node, via [node-websql](https://github.com/nolanlawson/node-websql).
-This allows you to use the efficient WebSQL-based PouchDB directly over SQLite.
-
-Unlike the LocalStorage/memory/FruitDOWN adapters, this adapter is designed only
-to run in Node.js. In the browser, PouchDB already comes with WebSQL support.
-
-### APIs for plugin authors
-
-These APIs are designed for PouchDB plugin authors, who may want to re-use some PouchDB code to avoid duplication.
-
-To use these APIs, you should save PouchDB as a required npm dependency (`npm install --save pouchdb`) and then require them like so:
-
-#### Ajax
-
-{% highlight js %}
-var ajax = require('pouchdb/extras/ajax');
-{% endhighlight %}
-
-The `ajax()` function as used by PouchDB. Essentially a shim in the style of `jQuery.ajax`.
-
-#### Checkpointer
-
-{% highlight js %}
-var Checkpointer = require('pouchdb/extras/checkpointer');
-{% endhighlight %}
-
-The `Checkpointer` function as used by PouchDB's replicator. Writes checkpoints as `_local` docs so that replication can resume where it last left off.
-
-#### Promise
-
-{% highlight js %}
-var Promise = require('pouchdb/extras/promise');
-{% endhighlight %}
-
-The ES6 `Promise` shim as used by PouchDB. Expect this to be `lie` where a global `Promise` does not exist, the global `Promise` is used when supported.
-
-#### Caveats
-
-These APIs are not rigorously documented and may change frequently. Refer to the [source code](https://github.com/pouchdb/pouchdb/tree/master/extras) for the details of the APIs.
-
-If your plugin depends on a particular version of PouchDB, please notify your users. Unless you like to live dangerously, you should also nail down the version of PouchDB you are using in your `package.json`. And if you need any other internal modules, please submit a pull request!
diff --git a/docs/_includes/api/fetch_document.html b/docs/_includes/api/fetch_document.html
deleted file mode 100644
index 45a5b71..0000000
--- a/docs/_includes/api/fetch_document.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-{% include anchor.html edit="true" title="Fetch a document" hash="fetch_document"%}
-
-{% highlight js %}
-db.get(docId, [options], [callback])
-{% endhighlight %}
-
-Retrieves a document, specified by `docId`.
-
-### Options
-
-All options default to `false` unless otherwise specified.
-
-* `options.rev`: Fetch specific revision of a document. Defaults to winning revision (see [the CouchDB guide](http://guide.couchdb.org/draft/conflicts.html)).
-* `options.revs`: Include revision history of the document.
-* `options.revs_info`: Include a list of revisions of the document, and their availability.
-* `options.open_revs`: Fetch all leaf revisions if `open_revs="all"` or fetch all leaf revisions specified in `open_revs` array. Leaves will be returned in the same order as specified in input array.
-* `options.conflicts`: If specified, conflicting leaf revisions will be attached in `_conflicts` array.
-* `options.attachments`: Include attachment data.
-  * `options.binary`: Return attachment data as Blobs/Buffers, instead of as base64-encoded strings.
-* `options.ajax`: An object of options to be sent to the ajax requester. In Node they are sent verbatim to [request][] with the exception of:
-* `options.ajax.cache`: Appends a random string to the end of all HTTP GET requests to avoid them being cached on IE. Set this to `true` to prevent this happening.
-
-#### Example Usage:
-
-{% include code/start.html id="get1" type="callback" %}
-{% highlight js %}
-db.get('mydoc', function(err, doc) {
-  if (err) { return console.log(err); }
-  // handle doc
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get1" type="async" %}
-{% highlight js %}
-try {
-  var doc = await db.get('mydoc');
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get1" type="promise" %}
-{% highlight js %}
-db.get('mydoc').then(function (doc) {
-  // handle doc
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "_id": "mydoc",
-  "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F"
-  "title": "Rock and Roll Heart",
-}
-{% endhighlight %}
-
-The response contains the document as it is stored in the database, along with its
-`_id` and `_rev`.
diff --git a/docs/_includes/api/get_attachment.html b/docs/_includes/api/get_attachment.html
deleted file mode 100644
index fed78a9..0000000
--- a/docs/_includes/api/get_attachment.html
+++ /dev/null
@@ -1,116 +0,0 @@
-{% include anchor.html edit="true" title="Get an attachment" hash="get_attachment" %} 
-
-{% highlight js %}
-db.getAttachment(docId, attachmentId, [options], [callback])
-{% endhighlight %}
-
-Get attachment data.
-
-### Options
-
-* `options.rev`: as with [get()](#fetch_document), you can pass a `rev` in and get back an attachment for the document at that particular revision.
-
-#### Example Usage:
-
-Get an attachment with filename `'att.txt'` from document with ID `'doc'`:
-
-{% include code/start.html id="get_att1" type="callback" %}
-{% highlight js %}
-db.getAttachment('doc', 'att.txt', function(err, blobOrBuffer) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get_att1" type="async" %}
-{% highlight js %}
-try {
-  var blobOrBuffer = await db.getAttachment('doc', 'att.txt');
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get_att1" type="promise" %}
-{% highlight js %}
-db.getAttachment('doc', 'att.txt').then(function (blobOrBuffer) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-Get an attachment with filename `'att.txt'` from document with ID `'doc'`, at
-the revision `'1-abcd'`:
-
-{% include code/start.html id="get_att2" type="callback" %}
-{% highlight js %}
-db.getAttachment('doc', 'att.txt', {rev: '1-abcd'}, function(err, blobOrBuffer) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get_att2" type="async" %}
-{% highlight js %}
-try {
-  var blobOrBuffer = await db.getAttachment('doc', 'att.txt', {rev: '1-abcd'});
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="get_att2" type="promise" %}
-{% highlight js %}
-db.getAttachment('doc', 'att.txt', {rev: '1-abcd'}).then(function (blobOrBuffer) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Response type:
-
-The response will be a `Blob` object in the browser, and a `Buffer` object in Node.js. See [blob-util](https://github.com/nolanlawson/blob-util) for utilities to transform `Blob`s to other formats, such as base64-encoded strings, data URLs, array buffers, etc.
-
-#### Inline base64 attachments
-
-You can specify `{attachments: true}` to most "read" operations, such as `get()`, `allDocs()`, `changes()`, and `query()`. The attachment data will then be included inlined in the resulting doc(s). However, it will always be supplied as base64. For example:
-
-{% highlight js %}
-{
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "digest": "d5ccfd24a8748bed4e2c9a279a2b6089",
-      "data": "SXMgdGhlcmUgbGlmZSBvbiBNYXJzPw=="
-    }
-  },
-  "_id": "mydoc",
-  "_rev": "1-e147d9ec9c85139dfe7e93bc17148d1a"
-}
-{% endhighlight %}
-
-For such APIs, when you don't specify `{attachments: true}`, you will instead get metadata about the attachments. For example:
-
-{% highlight js %}
-{
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "digest": "d5ccfd24a8748bed4e2c9a279a2b6089",
-      "stub": true
-    }
-  },
-  "_id": "mydoc",
-  "_rev": "1-e147d9ec9c85139dfe7e93bc17148d1a"
-}
-{% endhighlight %}
-
-This "summary" operation may be faster in some cases, because the attachment itself does not need to be read from disk.
\ No newline at end of file
diff --git a/docs/_includes/api/overview.html b/docs/_includes/api/overview.html
deleted file mode 100644
index f2a3f80..0000000
--- a/docs/_includes/api/overview.html
+++ /dev/null
@@ -1,67 +0,0 @@
-{% include anchor.html edit="true" title="API overview" hash="overview" %}
-
-PouchDB has an asynchronous API, supporting [callbacks](http://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks), [promises][promise], and
-[async functions](https://jakearchibald.com/2014/es7-async-functions/). For beginners, we recommend promises, although you are free to use whatever format you prefer. If you are unsure, check out our [guide to asynchronous code](/guides/async-code.html).
-
-Most of the API is exposed as:
-
-{% highlight js %}
-db.doSomething(args..., [options], [callback])
-{% endhighlight %}
-
-&hellip; where both the `options` and `callback` are optional.
-
-### Callbacks
-
-Callbacks use the standard Node.js idiom of:
-
-{% highlight js %}
-function(error, result) { /* ... */ }
-{% endhighlight %}
-
-&hellip; where the `error` will be undefined if there's no error.
-
-### Promises
-
-If you don't specify a `callback`, then the API returns a [promise][]. In [supported browsers](http://caniuse.com/#feat=promises) or Node.js, native promises are used, falling back to the minimal library [lie][] as needed.
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-
-**Using Ionic/Angular?**  You can wrap PouchDB promises in [`$q.when()`](https://docs.angularjs.org/api/ng/service/$q#when). This will notify Angular to update the UI when the PouchDB promise has resolved.
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-To use a custom promise implementation with PouchDB, you must redefine a global `Promise` object before loading PouchDB:
-
-{% highlight html %}
-<script>window.Promise = MyCustomPromiseLibrary;</script>
-<script src="path/to/pouchdb.js"></script>
-{% endhighlight %}
-
-### Async functions
-
-If you are using a transpiler like [Babel](http://babeljs.io/), you can enable [async functions](https://github.com/tc39/ecmascript-asyncawait), which are an experimental API tentatively slated for release in ES7 (ES2016). This allows you to use the `async`/`await` keywords when consuming promise-based APIs like PouchDB's.
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-
-**How to configure Babel?** To use async functions, you will need the [syntax-async-functions plugin](http://babeljs.io/docs/plugins/syntax-async-functions/), as well as the [transform-regenerator plugin](https://babeljs.io/docs/plugins/transform-regenerator/) or [Kneden](https://github.com/marten-de-vries/kneden) (which is experimental as of this writing). For a full working example, see [async-functions-with-regenerator](https://github.com/nolanlawson/async-functions-with-regenerator).
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-Note that the samples for `async`/`await` in the API documentation assume that your code is inside an async function. So for instance:
-
-{% highlight js %}
-async function myFunction() {
-  // your code goes in here
-}
-{% endhighlight %}
-
-Any `await` not inside of an async function is a syntax error. For more information about `async`/`await`, read [our introductory blog post](http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html).
-
-[promise]: https://www.promisejs.org/
-[lie]: https://github.com/calvinmetcalf/lie
-[event emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter
diff --git a/docs/_includes/api/plugins.html b/docs/_includes/api/plugins.html
deleted file mode 100644
index 8a9684f..0000000
--- a/docs/_includes/api/plugins.html
+++ /dev/null
@@ -1,93 +0,0 @@
-{% include anchor.html edit="true" title="Plugins" hash="plugins" %} 
-
-Writing a plugin is easy! The API is:
-
-{% highlight js %}
-PouchDB.plugin({
-  methodName: myFunction
-});
-{% endhighlight %}
-
-This will add a `db.methodName()` to all databases, which runs `myFunction`.It will always be called in context, so that within the function, `this` refers to the database object.
-
-There is a [PouchDB Plugin Seed project](https://github.com/pouchdb/plugin-seed), which is the fastest way to get started writing, building and testing your very own plugin.
-
-#### Example Usage:
-{% highlight js %}
-PouchDB.plugin({
-  sayHello : function () {
-    console.log("Hello!");
-  }
-});
-new PouchDB('foobar').sayHello(); // prints "Hello!"
-{% endhighlight %}
-
-#### Load Plugins from require()
-
-You can load plugins into PouchDB when you load it via `require()`.
-
-{% highlight js %}
-var greet = {sayHello: function() { console.log("Hello!"); }};
-
-var PouchDB = require('pouchdb').plugin(greet);
-
-var db = new PouchDB('foobar');
-db.sayHello(); // prints "Hello!"
-{% endhighlight %}
-
-You can chain plugins, as well:
-
-{% highlight js %}
-var greet = {sayHello: function() { console.log("Hello!"); }};
-var manners = {thank: function(name) { console.log("Thank you, " + name); }};
-
-var PouchDB = require('pouchdb')
-  .plugin(greet)
-  .plugin(manners);
-
-var db = new PouchDB('foobar');
-db.sayHello(); // prints "Hello!"
-db.thank('Mom'); // prints "Thank you, Mom"
-{% endhighlight %}
-
-#### Example Plugin: Intercept Updates
-
-A useful feature of plugins is to intercept updates before they are stored in PouchDB. In this way, a plugin might validate that the data is correct for the application, or even alter documents before they are committed to the database.
-
-The best way to intercept all updates to a PouchDB database is to **override the `bulkDocs()` method**. All changes to PouchDB documents ultimately pass through the `bulkDocs()` method. For example, a call to `put()` will become become a `bulkDocs()` call with a "batch" of one document.
-
-Because PouchDB guarantees to plugin authors that all data changes ultimate happen via `bulkDocs()`, it is the ideal place for an application or plugin to intercept updates.
-
-{% highlight js %}
-// Keep a reference to the "upstream" function.
-var pouchBulkDocs = PouchDB.prototype.bulkDocs;
-PouchDB.plugin({bulkDocs: validBulkDocs});
-
-function validBulkDocs(body, options, callback) {
-  if (typeof options == 'function') {
-    callback = options
-    options = {}
-  }
-
-  if (Array.isArray(body)) {
-    var docs = body;
-  } else {
-    var docs = body.docs;
-  }
-
-  // All documents must have a .name field.
-  for (var i = 0; i < docs.length; i++) {
-    if (!docs[i].name) {
-      var id = doc._id || '(no _id given)';
-      return callback(new Error('Document is missing .name field: ' + id));
-    }
-  }
-
-  // All documents check out. Pass them to PouchDB.
-  return pouchBulkDocs.call(this, docs, options, callback);
-}
-{% endhighlight %}
-
-The above plugin would return an error if anything ever attempts to store an unnamed document, including documents which change during replication.
-
-Note: this is a very, very simple validation example. It does not behave, for example, like the Apache CouchDB `validate_doc_update()` API.
diff --git a/docs/_includes/api/query_database.html b/docs/_includes/api/query_database.html
deleted file mode 100644
index d0c6eca..0000000
--- a/docs/_includes/api/query_database.html
+++ /dev/null
@@ -1,451 +0,0 @@
-{% include anchor.html edit="true" title="Query the database" hash="query_database" %}
-
-{% highlight js %}
-db.query(fun, [options], [callback])
-{% endhighlight %}
-
-Invoke a map/reduce function, which allows you to perform more complex queries on PouchDB than what you get with [allDocs()](#batch_fetch). The [CouchDB documentation for map/reduce](http://docs.couchdb.org/en/latest/couchapp/views/intro.html) applies to PouchDB.
-
-Since views perform a full scan of all documents, this method may be slow, unless you first save your view in a design document. Read the [query guide](/guides/queries.html) for a good tutorial.
-
-{% include alert/start.html variant="info"%}
-
-{% markdown %}
-
-**Heads up:** eventually the `query()` API will be deprecated in favor of the much simpler  [pouchdb-find plugin](https://github.com/nolanlawson/pouchdb-find). You will still be able to use `query()`, but it will be distributed as [a separate plugin](https://github.com/pouchdb/mapreduce).
-
-{% endmarkdown %}
-
-{% include alert/end.html%}
-
-### Options
-
-All options default to `false` unless otherwise specified.
-
-* `fun`: Map/reduce function, which can be one of the following:
-  * A full CouchDB-style map/reduce view: `{map : ..., reduce: ...}`.
-  * A map function by itself (no reduce).
-  * The name of a view in an existing design document (e.g. `'mydesigndoc/myview'`, or `'myview'` as a shorthand for `'myview/myview'`).
-* `options.reduce`: Reduce function, or the string name of a built-in function: `'_sum'`, `'_count'`, or `'_stats'`.  Defaults to `false` (no reduce).
-    * Tip: if you're not using a built-in, [you're probably doing it wrong](http://youtu.be/BKQ9kXKoHS8?t=865s).
-    * PouchDB will always call your reduce function with rereduce == false. As for CouchDB, refer to the [CouchDB documentation](http://docs.couchdb.org/en/1.6.1/couchapp/views/intro.html).
-* `options.include_docs`: Include the document in each row in the `doc` field.
-    - `options.conflicts`: Include conflicts in the `_conflicts` field of a doc.
-  - `options.attachments`: Include attachment data.
-    - `options.binary`: Return attachment data as Blobs/Buffers, instead of as base64-encoded strings.
-* `options.startkey` &amp; `options.endkey`: Get rows with keys in a certain range (inclusive/inclusive).
-* `options.inclusive_end`: Include rows having a key equal to the given `options.endkey`. Default: `true`.
-* `options.limit`: Maximum number of rows to return.
-* `options.skip`: Number of rows to skip before returning (warning: poor performance on IndexedDB/LevelDB!).
-* `options.descending`: Reverse the order of the output rows.
-* `options.key`: Only return rows matching this key.
-* `options.keys`: Array of keys to fetch in a single shot.
-    - Neither `startkey` nor `endkey` can be specified with this option.
-    - The rows are returned in the same order as the supplied `keys` array.
-    - The row for a deleted document will have the revision ID of the deletion, and an extra key `"deleted":true` in the `value` property.
-    - The row for a nonexistent document will just contain an `"error"` property with the value `"not_found"`.
-* `options.group`: True if you want the reduce function to group results by keys, rather than returning a single result. Defaults to `false`.
-* `options.group_level`: Number of elements in a key to group by, assuming the keys are arrays. Defaults to the full length of the array.
-* `options.stale`: One of `'ok'` or `'update_after'`.  Only applies to saved views. Can be one of:
-    * unspecified (default): Returns the latest results, waiting for the view to build if necessary.
-    * `'ok'`: Returns results immediately, even if they're out-of-date.
-    * `'update_after'`: Returns results immediately, but kicks off a build afterwards.
-
-For details, see the [CouchDB query options documentation](http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options).
-
-#### Example Usage:
-
-{% include code/start.html id="query1" type="callback" %}
-{% highlight js %}
-// create a design doc
-var ddoc = {
-  _id: '_design/index',
-  views: {
-    index: {
-      map: function mapFun(doc) {
-        if (doc.title) {
-          emit(doc.title);
-        }
-      }.toString()
-    }
-  }
-}
-
-// save the design doc
-db.put(ddoc, function (err) {
-  if (err && err.status !== 409) {
-    return console.log(err);
-  }
-  // ignore if doc already exists
-  // find docs where title === 'Lisa Says'
-  db.query('index', {
-    key: 'Lisa Says',
-    include_docs: true
-  }, function (err, result) {
-    if (err) { return console.log(err); }
-    // handle result
-  });
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query1" type="async" %}
-{% highlight js %}
-// create a design doc
-var ddoc = {
-  _id: '_design/index',
-  views: {
-    index: {
-      map: function mapFun(doc) {
-        if (doc.title) {
-          emit(doc.title);
-        }
-      }.toString()
-    }
-  }
-}
-
-// save the design doc
-try {
-  try {
-    await db.put(ddoc);
-  } catch (err) {
-    if (err.status !== 409) {
-      throw err;
-    }
-    // ignore if doc already exists
-  }
-  // find docs where title === 'Lisa Says'
-  var result = await db.query('index', {
-    key: 'Lisa Says',
-    include_docs: true
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query1" type="promise" %}
-{% highlight js %}
-// create a design doc
-var ddoc = {
-  _id: '_design/index',
-  views: {
-    index: {
-      map: function mapFun(doc) {
-        if (doc.title) {
-          emit(doc.title);
-        }
-      }.toString()
-    }
-  }
-}
-
-// save the design doc
-db.put(ddoc).catch(function (err) {
-  if (err.status !== 409) {
-    throw err;
-  }
-  // ignore if doc already exists
-}).then(function () {
-  // find docs where title === 'Lisa Says'
-  return db.query('index', {
-    key: 'Lisa Says',
-    include_docs: true
-  });
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "offset" : 0,
-  "rows": [{
-    "id": "doc3",
-    "key": "Lisa Says",
-    "value": null,
-    "doc": {
-      "_id": "doc3",
-      "_rev": "1-z",
-      "title": "Lisa Says"
-    }
-  }],
-  "total_rows" : 4
-}
-{% endhighlight %}
-
-In the result,`total_rows` is the total number of possible results in the view. The response is very similar to that of `allDocs()`.
-
-**Note:** you can also pass in the map function instead of saving a design doc first, but this is slow because it has to do a full database scan. The following examples will use this pattern for simplicity's sake, but you should normally avoid it.
-
-#### Complex keys
-
-You can also use [complex keys](https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Complex_Keys) for fancy ordering:
-
-{% include code/start.html id="query2" type="callback" %}
-{% highlight js %}
-function map(doc) {
-  // sort by last name, first name, and age
-  emit([doc.lastName, doc.firstName, doc.age]);
-}
-db.query(map, function (err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query2" type="async" %}
-{% highlight js %}
-function map(doc) {
-  // sort by last name, first name, and age
-  emit([doc.lastName, doc.firstName, doc.age]);
-}
-try {
-  var result = await db.query(map);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query2" type="promise" %}
-{% highlight js %}
-function map(doc) {
-  // sort by last name, first name, and age
-  emit([doc.lastName, doc.firstName, doc.age]);
-}
-db.query(map).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "offset": 0,
-  "rows": [{
-      "id"  : "bowie",
-      "key" : ["Bowie", "David", 67]
-    }, {
-      "id"  : "dylan",
-      "key" : ["Dylan", "Bob", 72]
-    }, {
-      "id"  : "younger_dylan",
-      "key" : ["Dylan", "Jakob", 44]
-    }, {
-      "id"  : "hank_the_third",
-      "key" : ["Williams", "Hank", 41]
-    }, {
-      "id"  : "hank",
-      "key" : ["Williams", "Hank", 91]
-    }],
-  "total_rows": 5
-}
-{% endhighlight %}
-
-**Tips:**
-
-* The sort order is `[nulls, booleans, numbers, strings, arrays, objects]`, so `{startkey: ['Williams'], endkey: ['Williams', {}]}` would return all people with the last name `'Williams'` because objects are higher than strings. Something like `'zzzzz'` or `'\uffff'` would also work.
-* `group_level` can be very helpful when working with complex keys.  In the example above, you can use `{group_level: 1}` to group by last name, or `{group_level: 2}` to group by last and first name. (Be sure to set `{reduce: true, group: true}` as well.)
-
-#### Linked documents
-
-PouchDB fully supports [linked documents](https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents). Use them to join two types of documents together, by simply adding an `_id` to the emitted value:
-
-{% include code/start.html id="query3" type="callback" %}
-{% highlight js %}
-function map(doc) {
-  // join artist data to albums
-  if (doc.type === 'album') {
-    emit(doc.name, {_id : doc.artistId, albumYear : doc.year});
-  }
-}
-db.query(map, {include_docs : true}, function (err, response) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query3" type="async" %}
-{% highlight js %}
-function map(doc) {
-  // join artist data to albums
-  if (doc.type === 'album') {
-    emit(doc.name, {_id : doc.artistId, albumYear : doc.year});
-  }
-}
-try {
-  var result = await db.query(map, {include_docs : true});
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query3" type="promise" %}
-{% highlight js %}
-function map(doc) {
-  // join artist data to albums
-  if (doc.type === 'album') {
-    emit(doc.name, {_id : doc.artistId, albumYear : doc.year});
-  }
-}
-db.query(map, {include_docs : true}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example response:
-
-{% highlight js %}
-{
-    "offset": 0,
-    "rows": [
-        {
-            "doc": {
-                "_id": "bowie",
-                "_rev": "1-fdb234b78904a5c8293f2acf4be70d44",
-                "age": 67,
-                "firstName": "David",
-                "lastName": "Bowie"
-            },
-            "id": "album_hunkeydory",
-            "key": "Hunky Dory",
-            "value": {
-                "_id": "bowie",
-                "albumYear": 1971
-            }
-        },
-        {
-            "doc": {
-                "_id": "bowie",
-                "_rev": "1-fdb234b78904a5c8293f2acf4be70d44",
-                "age": 67,
-                "firstName": "David",
-                "lastName": "Bowie"
-            },
-            "id": "album_low",
-            "key": "Low",
-            "value": {
-                "_id": "bowie",
-                "albumYear": 1977
-            }
-        },
-        {
-            "doc": {
-                "_id": "bowie",
-                "_rev": "1-fdb234b78904a5c8293f2acf4be70d44",
-                "age": 67,
-                "firstName": "David",
-                "lastName": "Bowie"
-            },
-            "id": "album_spaceoddity",
-            "key": "Space Oddity",
-            "value": {
-                "_id": "bowie",
-                "albumYear": 1969
-            }
-        }
-    ],
-    "total_rows": 3
-}
-{% endhighlight %}
-
-#### Closures
-
-If you pass a function to `db.query` and give it the `emit` function as the second argument, then you can use a closure. (Since PouchDB has to use `eval()` to bind `emit`.)
-
-{% include code/start.html id="query4" type="callback" %}
-{% highlight js %}
-// BAD! will throw error
-var myId = 'foo';
-db.query(function(doc) {
-  if (doc._id === myId) {
-    emit(doc);
-  }
-}, function(err, results) {
-  // you'll get an error here
-});
-
-// will be fine
-var myId = 'foo';
-db.query(function(doc, emit) {
-  if (doc._id === myId) {
-    emit(doc);
-  }
-}, function(err, results) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query4" type="async" %}
-{% highlight js %}
-// BAD! will throw error
-var myId = 'foo';
-try {
-  var result = await db.query(function(doc) {
-    if (doc._id === myId) {
-      emit(doc);
-    }
-  });
-} catch (err) {
-  // you'll get an error here
-}
-
-// will be fine
-var myId = 'foo';
-try {
-  var result = await db.query(function(doc, emit) {
-    if (doc._id === myId) {
-      emit(doc);
-    }
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="query4" type="promise" %}
-{% highlight js %}
-// BAD! will throw error
-var myId = 'foo';
-db.query(function(doc) {
-  if (doc._id === myId) {
-    emit(doc);
-  }
-}).catch(function (err) {
-  // you'll get an error here
-}
-
-// will be fine
-var myId = 'foo';
-db.query(function(doc, emit) {
-  if (doc._id === myId) {
-    emit(doc);
-  }
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-Note that closures are only supported by local databases with temporary views. So if you are using closures, then you must use the slower method that requires a full database scan.
diff --git a/docs/_includes/api/replication.html b/docs/_includes/api/replication.html
deleted file mode 100644
index fc3e91b..0000000
--- a/docs/_includes/api/replication.html
+++ /dev/null
@@ -1,318 +0,0 @@
-{% include anchor.html edit="true" title="Replicate a database" hash="replication" %} 
-
-{% highlight js %}
-PouchDB.replicate(source, target, [options])
-{% endhighlight %}
-
-Replicate data from `source` to `target`.  Both the `source` and `target` can be a PouchDB instance or a string representing a CouchDB database URL or the name of a local PouchDB database. If `options.live` is `true`, then this will track future changes and also replicate them automatically. This method returns an object with the method `cancel()`, which you call if you want to cancel live replication.
-
-Replication is an [event emitter][] like [changes()](#changes) and emits the `'complete'`, `'active'`, `'paused'`, `'change'`, `'denied'` and `'error'` events.
-
-### Options
-
-All options default to `false` unless otherwise specified.
-
-* `options.live`: If `true`, starts subscribing to future changes in the `source` database and continue replicating them.
-* `options.retry`: If `true` will attempt to retry replications in the case of failure (due to being offline), using a backoff algorithm that retries at longer and longer intervals until a connection is re-established. Only applicable if `options.live` is also `true`.
-
-**Filtering Options:**
-
-* `options.filter`: Reference a filter function from a design document to selectively get updates. To use a view function, pass `_view` here and provide a reference to the view function in `options.view`. See [filtered replication](#filtered-replication) for details.
-* `options.doc_ids`: Only show changes for docs with these ids (array of strings).
-* `options.query_params`: Object containing properties that are passed to the filter function, e.g. `{"foo:"bar"}`, where `"bar"` will be available in the filter function as `params.query.foo`. To access the `params`, define your filter function like `function (doc, params) {/* ... */}`.
-* `options.view`: Specify a view function (e.g. `'design_doc_name/view_name'` or `'view_name'` as shorthand for `'view_name/view_name'`) to act as a filter. Documents counted as "passed" for a view filter if a map function emits at least one record for them. **Note**: `options.filter` must be set to `'_view'` for this option to work.
-
-**Advanced Options:**
-
-* `options.since`: Replicate changes after the given sequence number.
-* `options.heartbeat`: Configure the heartbeat supported by CouchDB which keeps the change connection alive.
-* `options.timeout`: Request timeout (in milliseconds).
-* `options.batch_size`: Number of documents to process at a time. Defaults to 100. This affects the number of docs held in memory and the number sent at a time to the target server. You may need to adjust downward if targeting devices with low amounts of memory (e.g. phones) or if the documents are large in size (e.g. with attachments). If your documents are small in size, then increasing this number will probably speed replication up.
-* `options.batches_limit`: Number of batches to process at a time. Defaults to 10. This (along wtih `batch_size`) controls how many docs are kept in memory at a time, so the maximum docs in memory at once would equal `batch_size` &times; `batches_limit`.
-* `options.back_off_function`: backoff function to be used in `retry` replication. This is a function that takes the current backoff as input (or 0 the first time) and returns a new backoff in milliseconds. You can use this to tweak when and how replication will try to reconnect to a remote database when the user goes offline. Defaults to a function that chooses a random backoff between 0 and 2 seconds and doubles every time it fails to connect. (See [Customizing retry replication](#customizing-retry-replication) below.)
-
-#### Example Usage:
-
-{% highlight js %}
-var rep = PouchDB.replicate('mydb', 'http://localhost:5984/mydb', {
-  live: true,
-  retry: true
-}).on('change', function (info) {
-  // handle change
-}).on('paused', function (err) {
-  // replication paused (e.g. replication up to date, user went offline)
-}).on('active', function () {
-  // replicate resumed (e.g. new changes replicating, user went back online)
-}).on('denied', function (err) {
-  // a document failed to replicate (e.g. due to permissions)
-}).on('complete', function (info) {
-  // handle complete
-}).on('error', function (err) {
-  // handle error
-});
-
-rep.cancel(); // whenever you want to cancel
-{% endhighlight %}
-
-There are also shorthands for replication given existing PouchDB objects. These behave the same as `PouchDB.replicate()`:
-
-{% highlight js %}
-db.replicate.to(remoteDB, [options]);
-// or
-db.replicate.from(remoteDB, [options]);
-{% endhighlight %}
-
-The `remoteDB` can either be a string or a `PouchDB` object. If you have special ajax options on a remote database, you will want to use `PouchDB` objects instead of strings, so that the options are used.
-
-#### Replication events
-
-* __`change`__ (`info`) - This event fires when the replication has written a new document. `info` will contain details about the change. `info.docs` will contain the docs involved in that change. See below for an example response.
-* __`complete`__ (`info`) - This event fires when replication is completed or cancelled. In a live replication, only cancelling the replication should trigger this event. `info` will contain details about the replication. See below for an example response.
-* __`paused`__ (`err`) - This event fires when the replication is paused, either because a live replication is waiting for changes, or replication has temporarily failed, with `err`, and is attempting to resume.
-* __`active`__ - This event fires when the replication starts actively processing changes; e.g. when it recovers from an error or new changes are available.
-* __`denied`__ (`err`) - This event fires if a document failed to replicate due to validation or authorization errors.
-* __`error`__ (`err`) - This event is fired when the replication is stopped due to an unrecoverable failure. If `retry` is `false`, this will also fire when the user goes offline or another network error occurs (so you can handle retries yourself, if you want).
-
-#### Single-shot
-
-As with [changes()](#changes), you can also omit `live`, in which case you can use `replicate()` in the callback/promise style and it will be treated as a single-shot operation.
-
-{% include code/start.html id="replication1" type="callback" %}
-{% highlight js %}
-db.replicate.to(remote, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle 'completed' result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="replication1" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.replicate.to(remote);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="replication1" type="promise" %}
-{% highlight js %}
-db.replicate.to(remote).then(function (result) {
-  // handle 'completed' result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-For non-live replications, the returned object is also an event emitter as well as a promise, and you can use all the events described above (except for `'paused'` and `'active'`, which only apply to `retry` replications).
-
-#### Example Response:
-
-Example response in the `'change'` listener:
-
-{% highlight js %}
-{
-  "doc_write_failures": 0,
-  "docs_read": 1,
-  "docs_written": 1,
-  "errors": [],
-  "last_seq": 1,
-  "ok": true,
-  "start_time": "Fri May 16 2014 18:23:12 GMT-0700 (PDT)",
-  "docs": [
-    { _id: 'docId',
-      _rev: '1-e798a1a7eb4247b399dbfec84ca699d4',
-      and: 'data' }
-  ]
-}
-{% endhighlight %}
-
-Example response in the `'complete'` listener:
-
-{% highlight js %}
-{
-  "doc_write_failures": 0,
-  "docs_read": 2,
-  "docs_written": 2,
-  "end_time": "Fri May 16 2014 18:26:00 GMT-0700 (PDT)",
-  "errors": [],
-  "last_seq": 2,
-  "ok": true,
-  "start_time": "Fri May 16 2014 18:26:00 GMT-0700 (PDT)",
-  "status": "complete"
-}
-{% endhighlight %}
-
-Note that replication is supported for both local and remote databases. So you can replicate from local to local or from remote to remote.
-
-However, if you replicate from remote to remote, then the changes will flow through PouchDB. If you want to trigger a server-initiated replication, please use regular ajax to POST to the CouchDB `_replicate` endpoint, as described [in the CouchDB docs](https://wiki.apache.org/couchdb/Replication).
-
-#### Filtered replication
-
-As with [changes()](#changes), you can filter from the source database using:
-
-* an ad-hoc `filter` function
-* an array of `doc_ids`
-* a `filter` function inside of a design document
-* a `filter` function inside of a design document, with `query_params`
-* a `view` function inside of a design document
-
-If you are replicating from a remote CouchDB, then the first method will run client-side, whereas the last four will filter on the server side. Therefore the last four should be preferred, especially if the database is large, because you want to send as few documents over the wire as possible.
-
-You should also beware trying to use filtered replication to enforce security, e.g. to partition a database per user. A better strategy is the ["one database per user" method](https://github.com/nolanlawson/pouchdb-authentication#couchdb-authentication-recipes).
-
-{% include alert/start.html variant="warning" %}
-
-{% markdown %}
-
-**Deleting filtered docs**: When you use filtered replication, you should avoid using `remove()` to delete documents, because that removes all their fields as well, which means they might not pass the filter function anymore, causing the deleted revision to not be replicated. Instead, set the `doc._deleted` flag to `true` and then use `put()` or `bulkDocs()`.
-
-{% endmarkdown %}
-
-{% include alert/end.html %}
-
-#### Filtering examples
-
-In these examples, we'll work with some mammals. Let's imagine our docs are:
-
-{% highlight js %}
-[
-  {_id: 'a', name: 'Kangaroo', type: 'marsupial'},
-  {_id: 'b', name: 'Koala', type: 'marsupial'},
-  {_id: 'c', name: 'Platypus', type: 'monotreme'}
-]
-{% endhighlight %}
-
-Here are 5 examples using the 5 different systems.
-
-**Example 1: Ad-hoc `filter` function**
-
-*Warning*: this runs client-side, if you are replicating from a remote database.
-
-Filter by `type === 'marsupial'`:
-
-{% highlight js %}
-remote.replicate.to(local, {
-  filter: function (doc) {
-    return doc.type === 'marsupial';
-  }
-});
-{% endhighlight %}
-
-**Example 2: Array of `doc_ids`**
-
-Filter documents with `_id`s `['a', 'c']`.
-
-{% highlight js %}
-remote.replicate.to(local, {
-  doc_ids: ['a', 'c']
-});
-{% endhighlight %}
-
-**Example 3: `filter` function inside of a design document**
-
-First `put()` a design document in the remote database:
-
-{% highlight js %}
-{
-  _id: '_design/mydesign',
-  filters: {
-    myfilter: function (doc) {
-      return doc.type === 'marsupial';
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-remote.replicate.to(local, {
-  filter: 'mydesign/myfilter'
-});
-{% endhighlight %}
-
-**Example 4: `filter` function inside of a design document, with `query_params`**
-
-This is the most powerful way to filter, because it allows you to pass in arbitrary options to your filter function.
-
-First `put()` a design document in the remote database:
-
-{% highlight js %}
-{
-  _id: '_design/mydesign',
-  filters: {
-    myfilter: function (doc, req) {
-      return doc.type === req.query.type;
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-remote.replicate.to(local, {
-  filter: 'mydesign/myfilter',
-  query_params: {type: 'marsupial'}
-});
-{% endhighlight %}
-
-**Example 5: `view` function inside of a design document**
-
-This doesn't really offer any advantages compared to the previous two methods, unless you are already using a `view` for map/reduce queries, and you want to reuse it.
-
-Any documents that `emit()` anything will be considered to have passed this filter method.
-
-First `put()` a design document in the remote database:
-
-{% highlight js %}
-{
-  _id: '_design/mydesign',
-  views: {
-    myview: {
-      map: function(doc) {
-        if (doc.type === 'marsupial') {
-          emit(doc._id);
-        }
-      }.toString()
-    }
-  }
-}
-{% endhighlight %}
-
-Then filter by `type === 'marsupial'`:
-
-{% highlight js %}
-remote.replicate.to(local, {
-  filter: '_view',
-  view: 'mydesign/myview'
-});
-{% endhighlight %}
-
-#### Customizing retry replication
-
-During `retry` replication, you can customize the backoff function that determines how long to wait before reconnecting when the user goes offline.
-
-Here's a simple backoff function that starts at 1000 milliseconds and triples it every time a remote request fails:
-
-{% highlight js %}
-
-db.replicate.to(remote, {
-  live: true,
-  retry: true,
-  back_off_function: function (delay) {
-    if (delay === 0) {
-      return 1000;
-    }
-    return delay * 3;
-  }
-});
-
-{% endhighlight %}
-
-The first time a request fails, this function will receive 0 as input. The next time it fails, 1000 will be passed in, then 3000, then 9000, etc. When the user comes back online, the `delay` goes back to 0.
-
-By default, PouchDB uses a backoff function that chooses a random starting number between 0 and 2000 milliseconds and will roughly double every time, with some randommness to prevent client requests from occurring simultaneously.
diff --git a/docs/_includes/api/revisions_diff.html b/docs/_includes/api/revisions_diff.html
deleted file mode 100644
index a1e153e..0000000
--- a/docs/_includes/api/revisions_diff.html
+++ /dev/null
@@ -1,65 +0,0 @@
-{% include anchor.html edit="true" title="Document revisions diff" hash="revisions_diff" %} 
-
-{% highlight js %}
-db.revsDiff(diff, [callback])
-{% endhighlight %}
-
-Given a set of document/revision IDs, returns the subset of those that do not correspond
-to revisions stored in the database. Primarily used in replication.
-
-#### Example Usage:
-
-{% include code/start.html id="revsdiff1" type="callback" %}
-{% highlight js %}
-db.revsDiff({
-  myDoc1: [
-    "1-b2e54331db828310f3c772d6e042ac9c",
-    "2-3a24009a9525bde9e4bfa8a99046b00d"
-  ]
-}, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="revsdiff1" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.revsDiff({
-    myDoc1: [
-      "1-b2e54331db828310f3c772d6e042ac9c",
-      "2-3a24009a9525bde9e4bfa8a99046b00d"
-    ]
-  });
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="revsdiff1" type="promise" %}
-{% highlight js %}
-db.revsDiff({
-  myDoc1: [
-    "1-b2e54331db828310f3c772d6e042ac9c",
-    "2-3a24009a9525bde9e4bfa8a99046b00d"
-  ]
-}).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{
-  "myDoc1": {
-    "missing": ["2-3a24009a9525bde9e4bfa8a99046b00d"]
-  }
-}
-{% endhighlight %}
-
-
diff --git a/docs/_includes/api/save_attachment.html b/docs/_includes/api/save_attachment.html
deleted file mode 100644
index e0320b4..0000000
--- a/docs/_includes/api/save_attachment.html
+++ /dev/null
@@ -1,353 +0,0 @@
-{% include anchor.html edit="true" title="Save an attachment" hash="save_attachment" %} 
-
-{% highlight js %}
-db.putAttachment(docId, attachmentId, [rev], attachment, type, [callback]);
-{% endhighlight %}
-
-Attaches a binary object to a document.
-
-This method will update an existing document to add the attachment, so it requires a `rev` if the document already exists. If the document doesn't already exist, then this method will create an empty document containing the attachment.
-
-What's the point of attachments? If you're dealing with large binary data (such as PNGs), you may incur a performance or storage penalty if you naïvely include them as base64- or hex-encoded strings inside your documents. But if you insert the binary data as an attachment, then PouchDB will attempt to store it in [the most efficient way possible](http://pouchdb.com/faq.html#data_types).
-
-For details, see the [CouchDB documentation on attachments](https://wiki.apache.org/couchdb/HTTP_Document_API#Attachments).
-
-#### Example Usage:
-
-{% include code/start.html id="attach1" type="callback" %}
-{% highlight js %}
-var attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'});
-db.putAttachment('doc', 'att.txt', attachment, 'text/plain', function(err, res) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach1" type="async" %}
-{% highlight js %}
-try {
-  var attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'});
-  var result = await db.putAttachment('doc', 'att.txt', attachment, 'text/plain');
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach1" type="promise" %}
-{% highlight js %}
-var attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'});
-db.putAttachment('doc', 'att.txt', attachment, 'text/plain').then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-
-#### Example Response:
-{% highlight js %}
-{
-  "ok": true,
-  "id": "doc",
-  "rev": "2-068E73F5B44FEC987B51354DFC772891"
-}
-{% endhighlight %}
-
-Within Node, you must use a `Buffer` instead of a `Blob`:
-
-{% highlight js %}
-var attachment = new Buffer('Is there life on Mars?');
-{% endhighlight %}
-
-For details, see the [Mozilla docs on `Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or the [Node docs on `Buffer`](http://nodejs.org/api/buffer.html).
-
-If you need a shim for older browsers that don't support the `Blob` constructor, or you want some convenience methods for Blobs, you can use [blob-util](https://github.com/nolanlawson/blob-util).
-
-#### Save a base64 attachment
-
-If you supply a string instead of a `Blob`/`Buffer`, then it will be assumed to be a base64-encoded string, and will be processed accordingly:
-
-{% include code/start.html id="attach3" type="callback" %}
-{% highlight js %}
-var attachment = 
-        "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-        "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==";
-db.putAttachment('doc', 'att.txt', attachment, 'text/plain', function(err, res) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach3" type="async" %}
-{% highlight js %}
-try {
-  var attachment =
-    "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-    "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==";
-  var result = await db.putAttachment('doc', 'att.txt', attachment, 'text/plain');
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach3" type="promise" %}
-{% highlight js %}
-var attachment = 
-        "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-        "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==";
-db.putAttachment('doc', 'att.txt', attachment, 'text/plain').then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-
-#### Save an inline attachment
-
-You can also inline attachments inside the document. The attachment data may be supplied as a base64-encoded string with the `content_type`:
-
-{% include code/start.html id="attach2" type="callback" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-              "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="
-    }
-  }
-};
-db.put(doc, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach2" type="async" %}
-{% highlight js %}
-try {
-  var doc = {
-    "_id": "doc",
-    "title": "Legendary Hearts",
-    "_attachments": {
-      "att.txt": {
-        "content_type": "text/plain",
-        "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-          "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="
-      }
-    }
-  };
-  var result = await db.put(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach2" type="promise" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
-              "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="
-    }
-  }
-};
-db.put(doc).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Save an inline Blob/Buffer attachment
-
-You can also inline `Blob`s/`Buffer`s:
-
-{% include code/start.html id="attach4" type="callback" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "_attachments": {
-      "att.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'})
-      }
-    }
-  }
-};
-db.put(doc, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach4" type="async" %}
-{% highlight js %}
-try {
-  var doc = {
-    "_id": "doc",
-    "title": "Legendary Hearts",
-    "_attachments": {
-      "att.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'})
-      }
-    }
-  };
-  var result = await db.put(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach4" type="promise" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'})
-    }
-  }
-};
-db.put(doc).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Save many attachments at once
-
-The inline approach allows you to save multiple attachments to the same document in a single shot:
-
-{% include code/start.html id="attach5" type="callback" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "_attachments": {
-      "att.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["And she's hooked to the silver screen"], 
-          {type: 'text/plain'})
-      },
-      "att2.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["But the film is a saddening bore"], 
-          {type: 'text/plain'})
-      },
-      "att3.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["For she's lived it ten times or more"], 
-          {type: 'text/plain'})
-      }
-    }
-  }
-};
-db.put(doc, function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach5" type="async" %}
-{% highlight js %}
-try {
-  var doc = {
-    "_id": "doc",
-    "title": "Legendary Hearts",
-    "_attachments": {
-      "att.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["And she's hooked to the silver screen"],
-          {type: 'text/plain'})
-      },
-      "att2.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["But the film is a saddening bore"],
-          {type: 'text/plain'})
-      },
-      "att3.txt": {
-        "content_type": "text/plain",
-        "data": new Blob(
-          ["For she's lived it ten times or more"],
-          {type: 'text/plain'})
-      }
-    }
-  };
-  var result = await db.put(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="attach5" type="promise" %}
-{% highlight js %}
-var doc = {
-  "_id": "doc",
-  "title": "Legendary Hearts",
-  "_attachments": {
-    "att.txt": {
-      "content_type": "text/plain",
-      "data": new Blob(
-        ["And she's hooked to the silver screen"], 
-        {type: 'text/plain'})
-    },
-    "att2.txt": {
-      "content_type": "text/plain",
-      "data": new Blob(
-        ["But the film is a saddening bore"], 
-        {type: 'text/plain'})
-    },
-    "att3.txt": {
-      "content_type": "text/plain",
-      "data": new Blob(
-        ["For she's lived it ten times or more"], 
-        {type: 'text/plain'})
-    }
-  }
-};
-db.put(doc).then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-See [Inline Attachments](http://wiki.apache.org/couchdb/HTTP_Document_API#Inline_Attachments)
-on the CouchDB wiki for details.
-
-
diff --git a/docs/_includes/api/sync.html b/docs/_includes/api/sync.html
deleted file mode 100644
index 35077e7..0000000
--- a/docs/_includes/api/sync.html
+++ /dev/null
@@ -1,77 +0,0 @@
-{% include anchor.html edit="true" title="Sync a database" hash="sync" %} 
-
-{% highlight js %}
-var sync = PouchDB.sync(src, target, [options])
-{% endhighlight %}
-
-Sync data from `src` to `target` and `target` to `src`. This is a convenience method for bidirectional data replication.
-
-In other words, this code:
-
-{% highlight js %}
-PouchDB.replicate('mydb', 'http://localhost:5984/mydb');
-PouchDB.replicate('http://localhost:5984/mydb', 'mydb');
-{% endhighlight %}
-
-
-is equivalent to this code:
-
-{% highlight js %}
-PouchDB.sync('mydb', 'http://localhost:5984/mydb');
-{% endhighlight %}
-
-
-### Options
-
-* `options.push` + `options.pull`: Allows you to specify separate [replication options](api.html#replication) for the individual replications.
-
-Replication options such as `filter` passed to sync directly will be passed to both replications. Please refer to [replicate()](api.html#replication) for documentation on those options.
-
-#### Example Usage:
-{% highlight js %}
-var sync = PouchDB.sync('mydb', 'http://localhost:5984/mydb', {
-  live: true,
-  retry: true
-}).on('change', function (info) {
-  // handle change
-}).on('paused', function (err) {
-  // replication paused (e.g. replication up to date, user went offline)
-}).on('active', function () {
-  // replicate resumed (e.g. new changes replicating, user went back online)
-}).on('denied', function (err) {
-  // a document failed to replicate (e.g. due to permissions)
-}).on('complete', function (info) {
-  // handle complete
-}).on('error', function (err) {
-  // handle error
-});
-
-sync.cancel(); // whenever you want to cancel
-{% endhighlight %}
-
-There is also a shorthand for syncing given existing PouchDB objects. This behaves the same as `PouchDB.sync()`:
-
-{% highlight js %}
-db.sync(remoteDB, [options]);
-{% endhighlight %}
-
-#### Example Response:
-
-Change events in `sync` have an extra property `direction` which refers to the direction the change was going. Its value will either be `push` or `pull`.
-
-{% highlight js %}
-{ direction: 'push',
-  change:
-   { ok: true,
-     start_time: '2015-10-21T15:26:51.151Z',
-     docs_read: 1,
-     docs_written: 1,
-     doc_write_failures: 0,
-     errors: [],
-     last_seq: 1,
-     docs: [ [Object] ] } }
-{% endhighlight %}
-
-For any further details, please refer to [replicate()](api.html#replication).
-
-
diff --git a/docs/_includes/api/view_cleanup.html b/docs/_includes/api/view_cleanup.html
deleted file mode 100644
index 9ef9091..0000000
--- a/docs/_includes/api/view_cleanup.html
+++ /dev/null
@@ -1,47 +0,0 @@
-{% include anchor.html edit="true" title="View cleanup" hash="view_cleanup" %} 
-
-{% highlight js %}
-db.viewCleanup([callback])
-{% endhighlight %}
-
-Cleans up any stale map/reduce indexes.
-
-As design docs are deleted or modified, their associated index files (in CouchDB) or companion databases (in local PouchDBs) continue to take up space on disk. `viewCleanup()` removes these unnecessary index files.
-
-See [the CouchDB documentation on view cleanup](http://couchdb.readthedocs.org/en/latest/maintenance/compaction.html#views-cleanup) for details.
-
-#### Example Usage:
-
-{% include code/start.html id="viewcleanup" type="callback" %}
-{% highlight js %}
-db.viewCleanup(function (err, result) {
-  if (err) { return console.log(err); }
-  // handle result
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="viewcleanup" type="async" %}
-{% highlight js %}
-try {
-  var result = await db.viewCleanup();
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-{% include code/end.html %}
-
-{% include code/start.html id="viewcleanup" type="promise" %}
-{% highlight js %}
-db.viewCleanup().then(function (result) {
-  // handle result
-}).catch(function (err) {
-  console.log(err);
-});
-{% endhighlight %}
-{% include code/end.html %}
-
-#### Example Response:
-{% highlight js %}
-{ "ok" : "true" }
-{% endhighlight %}
\ No newline at end of file
diff --git a/docs/_includes/code/end.html b/docs/_includes/code/end.html
deleted file mode 100644
index 7f5eaa3..0000000
--- a/docs/_includes/code/end.html
+++ /dev/null
@@ -1 +0,0 @@
-</div>
\ No newline at end of file
diff --git a/docs/_includes/code/start.html b/docs/_includes/code/start.html
deleted file mode 100644
index 3c28df2..0000000
--- a/docs/_includes/code/start.html
+++ /dev/null
@@ -1,14 +0,0 @@
-{% if include.type == 'promise' %}
-  {% assign class = 'active' %}
-{% else %}
-  {% assign class = '' %}
-{% endif %}
-<strong data-code-hide>{{ include.type | capitalize }}:</strong>
-
-<div
-  class="tab-pane {{ class }}"
-  id="{{ include.type }}"
-  data-code-id="{{ include.id }}"
-  data-code-type="{{ include.type }}"
-  role="complementary"
->
diff --git a/docs/_includes/edit_button.html b/docs/_includes/edit_button.html
deleted file mode 100644
index 0bfc860..0000000
--- a/docs/_includes/edit_button.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% if include.path %}
-  {% assign pagePath = include.path %}
-{% elsif page.relative_path %}
-  {% assign pagePath = page.relative_path %}
-{% else %}
-  {% assign pagePath = page.path  %}
-{% endif %}
-<a
-  data-toggle="tooltip"
-  data-placement="top"
-  title="Edit this on Github"
-  class="icon-edit"
-  href="{{ site.github.repository_url }}/edit/master/docs/{{ pagePath }}"
-  target="_blank"
-></a>
diff --git a/docs/_includes/guides_nav.html b/docs/_includes/guides_nav.html
deleted file mode 100644
index d37e091..0000000
--- a/docs/_includes/guides_nav.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% assign guides = (site.guides | sort: 'index') %}
-{% for guide in guides %}
-    {% assign title = guide.title %}
-    {% if guide.nav %}
-        {% assign title = guide.nav %}
-    {% endif %}
-    {% include nav_item.html path=guide.url text=title %}
-{% endfor %}
diff --git a/docs/_includes/iframe.html b/docs/_includes/iframe.html
deleted file mode 100644
index 3afca77..0000000
--- a/docs/_includes/iframe.html
+++ /dev/null
@@ -1 +0,0 @@
-<div class="iframe-responsive"><iframe src="{{ include.src }}" allowfullscreen></iframe></div>
diff --git a/docs/_includes/img.html b/docs/_includes/img.html
deleted file mode 100644
index 5b50838..0000000
--- a/docs/_includes/img.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% if include.href %}
-  {% assign href = include.href %}
-{% else %}
-  {% capture href %}{{ site.baseurl }}/static/img/{{ include.src }}{% endcapture %}
-{% endif %}
-
-<a href="{{ href }}" target="_blank">
-  <img class="img-responsive" {% if include.width %} width="{{include.width}}" {% endif %} src="{{ site.baseurl }}/static/img/{{ include.src }}" alt="{{ include.alt }}" />
-</a>
diff --git a/docs/_includes/nav.html b/docs/_includes/nav.html
deleted file mode 100644
index a8c23f2..0000000
--- a/docs/_includes/nav.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% include nav_item.html path="/learn.html" text="About PouchDB" %}
-{% include nav_item.html path="/users.html" text="Who's using PouchDB?" %}
-{% include nav_item.html path="/getting-started.html" text="Get Started Guide" %}
-{% include nav_item.html path="/api.html" text="API" %}
-{% include nav_item.html path="/adapters.html" text="Adapters" %}
-{% include nav_item.html path="/external.html" text="Plugins" %}
-{% include nav_item.html path="/faq.html" text="FAQ" %}
-{% include nav_item.html path="/errors.html" text="Common Errors" %}
diff --git a/docs/_includes/nav_item.html b/docs/_includes/nav_item.html
deleted file mode 100644
index c857389..0000000
--- a/docs/_includes/nav_item.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<li {% if page.url == include.path %} class="active" {% endif %}>
-    <a href="{{ site.baseurl }}{{ include.path | replace:'index.html','' }}">{{ include.text }}</a>
-</li>
diff --git a/docs/_includes/post_details.html b/docs/_includes/post_details.html
deleted file mode 100644
index c05ce66..0000000
--- a/docs/_includes/post_details.html
+++ /dev/null
@@ -1,40 +0,0 @@
-{% unless post %}
-  {% assign post = page %}
-{% endunless %}
-
-{% assign post_author = post.author %}
-{% assign post_gravatar = 'http://www.fillmurray.com/82/82' %}
-{% assign modified_date = '' %}
-
-{% for author in site.data.authors %}
-  {% if author.name == post.author %}
-    {% if author.twitter %}
-      {% capture post_author %}<a href="https://twitter.com/{{author.twitter}}">{{ post.author }}</a>{% endcapture %}
-    {% endif %}
-    {% if author.gravatar %}
-      {% capture post_gravatar %}https://gravatar.com/avatar/{{ author.gravatar }}{% endcapture %}
-    {% endif %}
-  {% endif %}
-{% endfor %}
-
-{% if post.modified_date %}
-  {% capture modified_date %}<strong>Updated:</strong> {{ post.modified_date | date_to_long_string }}<br>{% endcapture %}
-{% endif %}
-
-<div class="post">
-  <div class="media">
-    <a class="pull-left" href="#">
-    <img class="media-object img-circle img-responsive" src='{{ post_gravatar }}' alt='{{ post.author }}'>
-    </a>
-    <div class="media-body">
-    <p>
-      <strong>By:</strong> {{ post_author }}<br>
-      <strong>Published:</strong> {{ post.date | date_to_long_string }}<br>
-      {% if page.url == "/blog/index.html" or page.url contains "/blog/page" or page.url == "/index.html" %}
-        {{ post.excerpt | strip_html | truncatewords: 30, '' }}
-        <a href='{{ site.baseurl }}{{ post.url }}'>[...]</a>
-      {% endif %}
-    </p>
-    </div>
-  </div>
-</div>
diff --git a/docs/_includes/social.html b/docs/_includes/social.html
deleted file mode 100644
index 4025e6e..0000000
--- a/docs/_includes/social.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% for author in site.data.authors %}
-  {% if author.name == page.author %}
-    {% capture author_twitter %}@{{ author.twitter }}{% endcapture %}
-  {% endif %}
-{% endfor %}
-<a class='btn btn-github' href='https://github.com/daleharvey/pouchdb/tree/master/docs/{{ page.path }}'>View on GitHub</a>
-<a class='btn btn-twitter' href="https://twitter.com/intent/tweet?text={{ page.title }}: {{ site.host }}{{ site.baseurl }}{{ page.url }} -- @pouchdb {{ author_twitter }}">Tweet this article</a>
\ No newline at end of file
diff --git a/docs/_includes/svg/hospitalrun-logo.html b/docs/_includes/svg/hospitalrun-logo.html
deleted file mode 100644
index c973c3f..0000000
--- a/docs/_includes/svg/hospitalrun-logo.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 31.36" width="200">
-  <path d="M51.29 25.59h-4.67V14.71H34.95V25.6h-4.67V.69h4.67V11.4h11.68V.69h4.67v24.9zM61.71 7.65c1.32 0 2.52.21 3.59.64 1.07.42 1.99 1.03 2.75 1.81s1.34 1.73 1.76 2.86c.41 1.13.62 2.38.62 3.77 0 1.4-.21 2.66-.62 3.79-.41 1.13-1 2.08-1.76 2.88-.76.79-1.67 1.4-2.75 1.83-1.07.42-2.27.64-3.59.64-1.32 0-2.52-.21-3.6-.64-1.08-.42-2-1.03-2.76-1.83-.76-.79-1.36-1.75-1.77-2.88-.42-1.13-.63-2.39-.63-3.79 0-1.39.21-2.65.63-3.77.42-1.13 1.01-2.08 1.77-2.86.76-.78 1.68-1.38 2.76-1.81 1.08-.43 2.28-.64 3.6-.64zm0 14.93c1.47 0 2.56-.49 3.26-1.48.71-.99 1.06-2.43 1.06-4.34s-.35-3.36-1.06-4.36c-.71-1-1.79-1.5-3.26-1.5-1.49 0-2.6.5-3.31 1.51-.71 1-1.07 2.45-1.07 4.35 0 1.89.36 3.34 1.07 4.33.71.99 1.81 1.49 3.31 1.49zM83.4 11.37c-.11.18-.24.31-.36.39-.13.07-.29.11-.48.11-.21 0-.43-.06-.66-.17-.24-.11-.51-.24-.82-.39-.31-.14-.66-.27-1.06-.39-.4-.11-.86-.17-1.4-.17-.84 0-1.5.18-1.98.53-.48.36-.72.82-.72 1.39 0 .38.12.7.37.96s.57.49.98.68c.41.2.87.37 1.39.53.52.15 1.04.32 1.58.51.54.18 1.07.39 1.58.63.52.24.98.53 1.39.9.41.36.73.8.98 1.3.25.51.37 1.11.37 1.83 0 .85-.16 1.63-.47 2.35-.31.72-.76 1.34-1.36 1.86-.6.52-1.33.93-2.21 1.22-.88.29-1.89.44-3.02.44-.61 0-1.2-.05-1.78-.16-.58-.11-1.14-.26-1.67-.46s-1.03-.42-1.48-.69c-.45-.26-.85-.55-1.2-.86l.98-1.62c.13-.2.28-.34.45-.45.17-.1.39-.15.65-.15s.51.07.75.22.51.31.82.48c.31.17.67.33 1.09.48.42.15.95.22 1.59.22.51 0 .94-.06 1.3-.18.36-.12.66-.28.9-.47.24-.2.41-.42.52-.68.11-.26.16-.53.16-.8 0-.41-.12-.75-.37-1.02-.25-.26-.57-.49-.98-.69-.41-.2-.87-.37-1.4-.53-.52-.15-1.06-.32-1.6-.51-.55-.18-1.08-.4-1.6-.65s-.99-.56-1.4-.94c-.41-.38-.73-.84-.98-1.4-.25-.55-.37-1.22-.37-2 0-.72.14-1.41.43-2.07.29-.65.71-1.23 1.27-1.71.56-.49 1.25-.88 2.08-1.17.83-.29 1.79-.44 2.88-.44 1.22 0 2.33.2 3.32.6 1 .4 1.83.93 2.5 1.58l-.96 1.56zm3.18 19.99V7.92h2.6c.28 0 .51.06.71.19.2.13.32.32.38.59l.34 1.64c.71-.82 1.53-1.48 2.45-1.98.92-.51 2.01-.76 3.25-.76.96 0 1.85.2 2.64.6.8.4 1.49.98 2.07 1.75.58.76 1.03 1.71 1.34 2.82.32 1.12.47 2.4.47 3.85 0 1.32-.18 2.54-.53 3.67-.36 1.13-.86 2.1-1.52 2.93-.66.83-1.46 1.47-2.39 1.94s-1.98.7-3.14.7c-1 0-1.85-.15-2.54-.46-.69-.3-1.32-.73-1.87-1.27v7.23h-4.26zm8.27-20.41c-.88 0-1.64.19-2.26.56-.63.37-1.21.9-1.75 1.58v7.92c.48.6 1.01 1.01 1.58 1.25.57.24 1.18.35 1.83.35.64 0 1.23-.12 1.75-.36s.96-.61 1.33-1.1c.36-.49.64-1.12.84-1.87.2-.75.29-1.64.29-2.66 0-1.03-.08-1.91-.25-2.63-.17-.72-.41-1.3-.71-1.75-.31-.45-.69-.78-1.13-.98-.45-.2-.96-.31-1.52-.31zm15-8.18c0 .37-.07.71-.22 1.03-.15.32-.35.6-.59.84-.25.24-.54.43-.87.58-.33.14-.69.22-1.07.22-.37 0-.71-.07-1.04-.22-.33-.14-.61-.34-.85-.58-.24-.24-.43-.52-.58-.84-.14-.32-.22-.67-.22-1.03 0-.38.07-.73.22-1.07.14-.33.34-.62.58-.86.24-.24.53-.43.85-.58.33-.14.67-.22 1.04-.22.38 0 .73.07 1.07.22.33.14.62.34.87.58.25.24.44.53.59.86.15.34.22.69.22 1.07zm-.63 5.15v17.67h-4.25V7.92h4.25zm9.23 17.95c-1.53 0-2.7-.43-3.53-1.3-.83-.87-1.24-2.06-1.24-3.59v-9.87h-1.79c-.23 0-.43-.07-.59-.22-.17-.15-.25-.37-.25-.67V8.53l2.84-.47.9-4.82c.05-.23.15-.41.32-.53.17-.13.38-.19.63-.19h2.2v5.56h4.65v3.03h-4.65v9.58c0 .55.14.98.41 1.29.28.31.64.46 1.1.46.26 0 .48-.03.66-.09.18-.06.33-.13.47-.2.13-.07.25-.14.35-.2.1-.06.21-.09.31-.09.13 0 .23.03.31.09.08.06.17.16.26.28l1.27 2.07c-.62.52-1.33.91-2.14 1.17-.8.27-1.63.4-2.49.4zm19.99-.28h-1.91c-.4 0-.72-.06-.95-.18-.23-.12-.4-.36-.52-.73l-.38-1.26c-.45.4-.89.75-1.32 1.06-.43.3-.88.56-1.33.77-.46.21-.95.36-1.46.47-.52.1-1.09.15-1.72.15-.75 0-1.44-.1-2.07-.3-.63-.2-1.17-.5-1.63-.91-.45-.4-.81-.9-1.06-1.5s-.38-1.3-.38-2.09c0-.67.17-1.33.53-1.98.35-.65.93-1.24 1.75-1.76s1.9-.96 3.26-1.3c1.35-.35 3.04-.52 5.05-.52v-1.04c0-1.19-.25-2.07-.75-2.65-.5-.57-1.23-.86-2.18-.86-.69 0-1.26.08-1.72.24-.46.16-.86.34-1.2.54-.34.2-.65.38-.94.54-.29.16-.6.24-.95.24-.29 0-.53-.07-.74-.22-.21-.15-.37-.33-.5-.55l-.77-1.36c2.03-1.86 4.48-2.79 7.35-2.79 1.03 0 1.95.17 2.76.51.81.34 1.5.81 2.06 1.41.56.6.99 1.32 1.28 2.16.29.84.44 1.76.44 2.76v11.15zm-8.26-2.65c.44 0 .84-.04 1.21-.12.37-.08.71-.2 1.04-.36.33-.16.64-.35.95-.58.3-.23.61-.51.92-.82V18.1c-1.24 0-2.28.08-3.11.23-.83.16-1.5.36-2.01.6-.51.24-.86.53-1.08.85-.21.32-.32.68-.32 1.06 0 .75.22 1.29.66 1.61.45.33 1.02.49 1.74.49zM145.78 0v25.59h-4.25V0h4.25z"/>
-  <path d="M152.86 14.18v11.41h-1.82V.37h6.43c2.91 0 5.08.56 6.52 1.68 1.44 1.12 2.16 2.77 2.16 4.95 0 .96-.17 1.84-.5 2.64-.33.8-.81 1.49-1.43 2.09-.62.6-1.38 1.09-2.25 1.48-.88.39-1.87.64-2.98.76.29.18.54.42.77.71l8.68 10.91h-1.59c-.19 0-.35-.04-.49-.11s-.27-.19-.4-.36l-8.07-10.23c-.2-.26-.42-.45-.65-.55-.23-.11-.59-.16-1.08-.16h-3.3zm0-1.36h4.38c1.12 0 2.12-.13 3-.4.88-.27 1.63-.65 2.25-1.15.61-.5 1.08-1.1 1.4-1.8.32-.7.48-1.49.48-2.37 0-1.79-.59-3.12-1.76-3.99-1.18-.87-2.89-1.3-5.13-1.3h-4.62v11.01zm17.99-4.97v11.33c0 1.66.38 2.97 1.14 3.91.76.94 1.93 1.42 3.49 1.42 1.16 0 2.24-.29 3.24-.88 1-.59 1.9-1.4 2.7-2.45V7.85h1.69v17.73h-.93c-.33 0-.5-.15-.51-.46l-.16-2.64c-.82 1.02-1.77 1.84-2.85 2.46-1.08.62-2.28.93-3.6.93-.99 0-1.85-.15-2.59-.46-.74-.31-1.35-.75-1.84-1.34-.49-.58-.86-1.28-1.11-2.1-.25-.82-.37-1.75-.37-2.78V7.85h1.7zm15.21 17.73V7.85h.93c.31 0 .49.15.53.45l.16 2.67c.81-1.02 1.75-1.84 2.82-2.47 1.08-.62 2.27-.94 3.59-.94.97 0 1.83.15 2.58.46.74.31 1.36.75 1.84 1.34.49.58.86 1.28 1.1 2.1.25.82.37 1.75.37 2.78v11.33h-1.69V14.25c0-1.66-.38-2.97-1.14-3.91-.76-.94-1.92-1.42-3.49-1.42-1.16 0-2.25.3-3.24.9-1 .6-1.89 1.42-2.67 2.47v13.29h-1.69zM16.68 9.03V.69H8.34v8.34H0v8.33h8.34v8.34h8.34v-8.34h8.33V9.03" fill="#1ABC9C"/>
-</svg>
diff --git a/docs/_layouts/2ColLeft.html b/docs/_layouts/2ColLeft.html
deleted file mode 100644
index 5e4b168..0000000
--- a/docs/_layouts/2ColLeft.html
+++ /dev/null
@@ -1,22 +0,0 @@
----
-layout: default
----
-
-<article>
-  <div class="container">
-    <div class="row">
-        <div id="sidebar" class="col-sm-3 nav-sidebar-wrapper">
-          <ul class="nav nav-silent nav-sidebar" role="navigation">
-            {% include {{page.sidebar}} %}
-          </ul>
-        </div>
-
-        <div class="col-sm-9" role="main">
-          {{content}}
-        <div>
-
-    </div>
-
-  </div>
-
-</article>
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
deleted file mode 100644
index 1ffb57a..0000000
--- a/docs/_layouts/default.html
+++ /dev/null
@@ -1,225 +0,0 @@
-<!DOCTYPE html>
-<html lang="en" manifest="/manifest.appcache">
-
-  <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>{{ page.title }}</title>
-    <link rel="alternate" title="{{ site.description }}" type="application/rss+xml" href="/feed.xml">
-    <link rel="stylesheet" href="{{ site.baseurl }}/static/css/pouchdb.css" />
-    <meta name="theme-color" content="#6ccb99">
-    <meta name="msapplication-TileColor" content="#6ccb99">
-    <script type="text/javascript">
-      var _gaq = _gaq || [];
-      _gaq.push(['_setAccount', 'UA-42479701-1']);
-      _gaq.push(['_trackPageview']);
-
-      (function() {
-      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-      })();
-    </script>
-    <link href='//fonts.googleapis.com/css?family=Lato:400,700|Open+Sans:400,700' rel='stylesheet' type='text/css'>
-    <link rel="icon" href="/static/favicon.ico" type="image/x-icon"/>
-  </head>
-
-  <body data-spy="scroll" data-target="#sidebar">
-
-    <header role="banner">
-
-      <a href="https://github.com/pouchdb/pouchdb" target="_blank">
-         <div class="ribbon">GitHub</div>
-      </a>
-
-      <div class="container">
-
-        <a class="logo" href="{{ site.baseurl }}/">
-          <div class="logo-img"></div>
-          <span class='logo-type'>PouchDB</span>
-        </a>
-
-        <ul class='nav nav-header nav-pills' role="navigation">
-          <li>
-            <a class='btn btn-link btn-lg' href="{{ site.baseurl }}/blog/">Blog</a>
-          </li>
-          <li>
-            <a class='btn btn-link btn-lg' href="{{ site.baseurl }}/guides/">Guides</a>
-          </li>
-          <li>
-            <a class='btn btn-link btn-lg' href="{{ site.baseurl }}/api.html">API</a>
-          </li>
-          <li>
-            <a class='btn btn-link btn-lg' href="{{ site.baseurl }}/learn.html">Learn</a>
-          </li>
-          <li>
-            <a
-                class='btn btn-primary btn-lg'
-                href="https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb-{{ site.version }}.min.js"
-            >
-                Download <strong>v{{ site.version }}</strong>
-            </a>
-          </li>
-        </ul>
-
-      </div>
-
-    </header>
-    {% if page.url != "/index.html" %}
-      <div class="page-head">
-
-        <div class="container">
-
-          <h1 class="page-title">{{ page.title }}</h1>
-          {% if page.edit != false %}
-            <span class="h1">
-              {% include edit_button.html %}
-            </span>
-          {% endif %}
-          {% if page.sub_title %}
-            <h4>{{ page.sub_title}}</h4>
-          {% endif %}
-
-        </div>
-
-      </div>
-    {% endif %}
-
-    <div role="main">
-      {{ content }}
-    </div>
-
-    <div class="icons">
-
-      <div class="container">
-
-        <div class="row">
-
-          <div class='col-xs-4 col-md-offset-0 col-md-2'>
-            <a href='https://twitter.com/pouchdb' target='_blank'>
-              <div class="icon icon-twitter"></div>
-              <span class="sr-only">PouchDB's Twitter</span>
-            </a>
-          </div>
-
-          <div class='col-xs-4 col-md-2'>
-            <a href='https://github.com/rvagg/node-levelup' target='_blank'>
-              <div class="icon icon-leveldb"></div>
-              <span class="sr-only">Node Levelup</span>
-            </a>
-          </div>
-
-          <div class='col-xs-4 col-md-2'>
-            <a href='https://github.com/pouchdb/pouchdb' target='_blank'>
-              <div class="icon icon-github"></div>
-              <span class="sr-only">PouchDB's Github Repo</span>
-            </a>
-            </div>
-
-          <div class='col-xs-4 col-md-offset-0 col-md-2'>
-            <a href='https://travis-ci.org/pouchdb/pouchdb' target='_blank'>
-              <div class="icon icon-travis"></div>
-              <span class="sr-only">PouchDB's Travis CI</span>
-            </a>
-          </div>
-
-          <div class='col-xs-4 col-md-2'>
-            <a href='http://couchdb.apache.org/' target='_blank'>
-              <div class="icon icon-couchdb"></div>
-              <span class="sr-only">CouchDB</span>
-            </a>
-          </div>
-
-          <div class='col-xs-4 col-md-2'>
-            <a href='https://saucelabs.com' target='_blank'>
-              <div class="icon icon-saucelabs"></div>
-              <span class="sr-only">Saucelabs</span>
-            </a>
-          </div>
-
-        </div>
-
-      </div>
-
-    </div>
-
-    <footer class="footer">
-
-      <div class="container">
-
-        <div class="row">
-
-          <div class='col-sm-3'>
-            <h3 class="nav-head">Learn</h3>
-            <ul class='nav nav-silent'>
-              <li><a href="{{ site.baseurl }}/getting-started.html">Getting Started</a></li>
-              <li><a href="{{ site.baseurl }}/api.html">API Guide</a></li>
-              <li><a href="https://github.com/pouchdb/pouchdb/wiki">Wiki</a></li>
-            </ul>
-          </div>
-
-          <div class='col-sm-3'>
-            <h3 class="nav-head">Discuss</h3>
-            <ul class='nav nav-silent'>
-              <li><a href="https://groups.google.com/forum/#!forum/pouchdb">Mailing List</a></li>
-              <li><a href="irc://freenode.net/#pouchdb">IRC</a></li>
-              <li><a href="http://slack.pouchdb.com/">Slack</a></li>
-              <li><a href="http://twitter.com/pouchdb">Twitter</a></li>
-              <li><a href="http://stackoverflow.com/questions/tagged/pouchdb">StackOverflow</a></li>
-            </ul>
-          </div>
-
-          <div class='col-sm-3'>
-            <h3 class="nav-head">Contribute</h3>
-            <ul class='nav nav-silent'>
-              <li><a href="https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md">Contributing</a></li>
-              <li><a href="https://github.com/pouchdb/pouchdb">Source</a></li>
-              <li><a href="https://github.com/pouchdb/pouchdb/issues">Issues</a></li>
-              <li><a href="https://github.com/pouchdb/pouchdb/blob/master/LICENSE">Apache License</a></li>
-            </ul>
-          </div>
-
-        </div>
-
-      </div>
-
-    </footer>
-    <script type="text/javascript" src="//code.jquery.com/jquery.min.js"></script>
-    <script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
-    <script type="text/javascript" src="{{ site.baseurl }}/static/js/code.min.js"></script>
-    <script type="text/javascript" src="{{ site.baseurl }}/static/js/stickyfill.min.js"></script>
-    <script type="text/javascript" src="//cdn.jsdelivr.net/pouchdb/latest/pouchdb.min.js"></script>
-    <script type="text/javascript">
-      var $navSidebarWrapper = $('.nav-sidebar-wrapper');
-      if ($navSidebarWrapper.length) {
-        $navSidebarWrapper.Stickyfill();
-      }
-      $('[data-toggle="tooltip"]').tooltip();
-      function onCached(e) {
-        if (applicationCache.status === 1) {
-          giveIntro();
-        }
-      }
-
-      function giveIntro() {
-        console.log('%c\n..............................................................................\n.?I...........~+: ............................................................\n.???.........++++.............................................................\n:????+......+++++.............................................................\n.??????+++++++++:.................................H...........D..B............\n...????++++++++...................................H...........D..B............\n...=????++++++.......PPPPP...OOOO...U....U...CCCC.HHHHH...DDDDD..BBBBB........\n...?????+++++++......P...:P.OO...O..U....U..C.....H...H..D....D..B....B.......\n..???????+++++++ ....P. ..P.O....O..U....U.CC.....H...H..D....D..B....B.......\n..?????????????......P...:P.OO...O..U....U..C.....H...H..D....D..B....B.......\n...I??????????~......PPPPP...OOOO...=UUUUU...CCCC.H...H...DDDDD..BBBBB........\n....?????????~.......P.... ...................................................\n.....???????+........P........................................................\n......??????..................................................................\n..............................................................................\n..............................................................................\n..............................................................................', 'color: #4ec084');
-        console.log('%c\nPouchDB itself is hosted at PouchDB.com!\nTo get started, try typing:\nvar db = new PouchDB(\'mydb\');', 'color: #4ec084');
-      }
-      function offerToReload() {
-        $('.js-update-notification')
-          .removeClass('btn-update-hidden')
-          .on('click', function(){
-            window.location.reload();
-          });
-      }
-      if (window.applicationCache) {
-        applicationCache.addEventListener('cached', onCached, false);
-        applicationCache.addEventListener('noupdate', giveIntro, false);
-        applicationCache.addEventListener('updateready', offerToReload, false);
-      }
-    </script>
-    <button type="button" class="js-update-notification btn btn-primary btn-update btn-update-hidden">
-      Content updated, reload now? ↻
-    </button>
-  </body>
-</html>
diff --git a/docs/_layouts/guide.html b/docs/_layouts/guide.html
deleted file mode 100644
index aab65f0..0000000
--- a/docs/_layouts/guide.html
+++ /dev/null
@@ -1,26 +0,0 @@
----
-layout: 2ColLeft
----
-
-{{ content }}
-
-{% assign guides = (site.guides | sort: 'index') %}
-{% for guide in guides %}
-    {% if page.title == guide.title %}
-        {% assign prev = guide.index | minus: 2 %}
-        {% assign next = guide.index %}
-
-        <ul class="pager">
-            {% unless prev == -1 %}
-                <li class="previous">
-                    <a href="{{ guides[prev].url }}">&larr; {{ guides[prev].title }}</a>
-                </li>
-            {% endunless %}
-            {% if guides[next] %}
-                <li class="next">
-                    <a href="{{ guides[next].url }}">{{ guides[next].title }} &rarr;</a>
-                </li>
-            {% endif %}
-        </ul>
-    {% endif %}
-{% endfor %}
diff --git a/docs/_layouts/post.html b/docs/_layouts/post.html
deleted file mode 100644
index 6b2fbd6..0000000
--- a/docs/_layouts/post.html
+++ /dev/null
@@ -1,12 +0,0 @@
----
-layout: default
----
-<article class='container'>
-  <div class='row'>
-    <article class='col-md-offset-1 col-md-10' role="article">
-      {% include post_details.html %}
-
-      {{ content }}
-    </article>
-  </div>
-</article>
diff --git a/docs/_plugins/markdown.rb b/docs/_plugins/markdown.rb
deleted file mode 100644
index 5481a5a..0000000
--- a/docs/_plugins/markdown.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Jekyll
-  class MarkdownBlock < Liquid::Block
-    def initialize(tag_name, text, tokens)
-      super
-    end
-    require "kramdown"
-    def render(context)
-      content = super
-      "#{Kramdown::Document.new(content).to_html}"
-    end
-  end
-end
-Liquid::Template.register_tag('markdown', Jekyll::MarkdownBlock)
\ No newline at end of file
diff --git a/docs/_posts/2014-04-01-pouchdb-2.1.0.md b/docs/_posts/2014-04-01-pouchdb-2.1.0.md
deleted file mode 100644
index 92b7afb..0000000
--- a/docs/_posts/2014-04-01-pouchdb-2.1.0.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-layout: post
-
-title: PouchDB 2.1.0
-
-author: Dale Harvey
-
----
-
-[PouchDB 2.1.0](https://github.com/daleharvey/pouchdb/releases/tag/2.1.0) is now released! Please [file issues](https://github.com/daleharvey/pouchdb/issues) or [tell us what you think](https://github.com/daleharvey/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). We would also like to give a huge thanks to our [new and existing contributors](https://github.com/daleharvey/pouchdb/graphs/contributors?from=2014-03-01&to=2014-04-01).
-
-{% include alert/start.html variant="warning"%}
-This release contains a database migration, which means that once you upgrade you will no longer be able to use previous versions of PouchDB on the same databases.
-{% include alert/end.html %}
-
-### Major Changes:
-
- * Website redesign and a new blog ([#1539](http://github.com/daleharvey/pouchdb/issues/1539), [#893](https://github.com/daleharvey/pouchdb/issues/893))
- * Support optional LevelDOWN builds ([#44](http://github.com/daleharvey/pouchdb/issues/44))
- * Replication performance improvements ([#1732](http://github.com/daleharvey/pouchdb/issues/1732))
- * Performance improvements for skip / limit ([#1649](http://github.com/daleharvey/pouchdb/issues/1649))
- * Cache WebSQL databases, fully passing tests in Safari ([#1068](http://github.com/daleharvey/pouchdb/issues/1068))
- * Fix support for unicode in doc ids (WebSQL) ([#1733](http://github.com/daleharvey/pouchdb/issues/1733))
- * Fix for localStorage detection in Chrome Apps ([#1727](http://github.com/daleharvey/pouchdb/issues/1727))
- * Allow overriding of http functions ([#1602](http://github.com/daleharvey/pouchdb/issues/1602))
- * Improve error reporting from replicator ([#1714](http://github.com/daleharvey/pouchdb/issues/1714))
- * Switch to readAsArrayBuffer for IE binary support ([#1667](http://github.com/daleharvey/pouchdb/issues/1667))
- * Add `npm run shell` for quick shell experimenting ([#1610](http://github.com/daleharvey/pouchdb/issues/1610))
- * Ensure we dont lose data when browsers upgrade from WebSQL to IDB ([#1289](http://github.com/daleharvey/pouchdb/issues/1289))
-
-###### [Complete list of changes](https://github.com/daleharvey/pouchdb/compare/2.0.1...2.1.0)
diff --git a/docs/_posts/2014-04-01-welcome-to-the-pouchdb-blog.md b/docs/_posts/2014-04-01-welcome-to-the-pouchdb-blog.md
deleted file mode 100644
index b3df50b..0000000
--- a/docs/_posts/2014-04-01-welcome-to-the-pouchdb-blog.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-layout: post
-
-title: Welcome to the PouchDB blog
-
-author: Dale Harvey
-
----
-
-Hello World! Welcome to the newly formed PouchDB blog. PouchDB has been an active community for over 2 years now, with almost everything being run via IRC and Github. As the project grows, we wanted a way to communicate with users about the current state of the PouchDB world.
-
-We will obviously be posting updates and releases notes for PouchDB releases, but as well as that, we will also be blogging about related projects and technologies within the PouchDB world, such as Service Workers, CouchDB, etc.
-
-As with the PouchDB source, we would love to invite everyone to contribute.  We have [documented the instructions](https://github.com/daleharvey/pouchdb/blob/master/CONTRIBUTING.md#writing-a-pouchdb-blog-post), so please get involved.
-
-Over the last 4 years PouchDB has had 89 [awesome contributors](https://github.com/daleharvey/pouchdb/graphs/contributors). I would like to give a shout-out to the people who worked together to get this site up and running in such a short time: [nickcolley](https://twitter.com/NickColley), [misosoup](https://twitter.com/misosoup), [zaccolley](https://twitter.com/zaccolley), [nolanlawson](https://twitter.com/nolanlawson) and [virgie](https://github.com/virgie) in particular.
-
-Happy Pouching.
diff --git a/docs/_posts/2014-04-14-pagination-strategies-with-pouchdb.md b/docs/_posts/2014-04-14-pagination-strategies-with-pouchdb.md
deleted file mode 100644
index 53a75b3..0000000
--- a/docs/_posts/2014-04-14-pagination-strategies-with-pouchdb.md
+++ /dev/null
@@ -1,426 +0,0 @@
----
-layout: post
-
-title: Pagination strategies with PouchDB
-
-excerpt: PouchDB, like CouchDB, was designed to store large amounts of data. However, once you're dealing with hundreds, thousands, or even millions of documents in a single database&hellip;
-
-author: Nolan Lawson
-
----
-
-PouchDB, like CouchDB, was designed to store large amounts of data. However, once you're dealing with hundreds, thousands, or even millions of documents in a single database, proper pagination becomes crucial if you want to offer anything manageable to your users.  Nobody likes scrolling through a mile-high web page to try to find what they want.
-
-## A basic example
-
-Let's pretend we're storing 20 documents in PouchDB:
-
-```javascript
-var pouch = new PouchDB('numbers');
-var docs = [
-  {_id : 'doc01', name : 'uno'},        {_id : 'doc02', name : 'dos'},
-  {_id : 'doc03', name : 'tres'},       {_id : 'doc04', name : 'cuatro'},
-  {_id : 'doc05', name : 'cinco'},      {_id : 'doc06', name : 'seis'},
-  {_id : 'doc07', name : 'siete'},      {_id : 'doc08', name : 'ocho'}, 
-  {_id : 'doc09', name : 'nueve'},      {_id : 'doc10', name : 'diez'},  
-  {_id : 'doc11', name : 'once'},       {_id : 'doc12', name : 'doce'},
-  {_id : 'doc13', name : 'trece'},      {_id : 'doc14', name : 'catorce'},
-  {_id : 'doc15', name : 'quince'},     {_id : 'doc16', name : 'dieciseis'},
-  {_id : 'doc17', name : 'diecisiete'}, {_id : 'doc18', name : 'dieciocho'},
-  {_id : 'doc19', name : 'diecinueve'}, {_id : 'doc20', name : 'veinte'},
-];
-pouch.bulkDocs({docs : docs}, function (err, response) {
-  // handle err or response
-});
-```
-
-Now, the simplest kind of Pouch query, called [`allDocs()`](http://pouchdb.com/api.html#batch_fetch), doesn't do any pagination by default.  As the name implies, it just returns all the docs:
-
-```javascript
-pouch.allDocs(function (err, response) {
-  // handle err or response
-});
-```
-
-Here's the response:
-
-```javascript
-{
-  "total_rows": 20,
-  "offset": 0,
-  "rows": [
-    {
-      "id": "doc01",
-      "key": "doc01",
-      "value": { "rev": "1-8e483b9e178a8e58e3f1a4690b3d6e9a"}
-    },
-    {
-      "id": "doc02",
-      "key": "doc02",
-      "value": {"rev": "1-f6fee051188e84ac3d22c645c819a5d2"}
-    },
-    /* etc. */
-    {
-      "id": "doc20",
-      "key": "doc20",
-      "value": {"rev": "1-f6fee051188e84ac3d22c645c819a5d2"}
-    }
-  ]
-}
-```
-
-{% include alert/start.html variant="warning"%}
-
-<strong>Potential gotcha!</strong> Somewhat unintuitively, <code>allDocs()</code> doesn't return the full document data by default.  It only returns the document <code>id</code> and revision hash <code>rev</code>, unless you pass in the option <code>{include_docs : true}</code>.
-
-{% include alert/end.html %}
-
-All 20 documents are returned, no pagination involved.  We can visualize it graphically like this:
-
-```
-First doc returned                                    Last doc returned
- ↓                                                                   ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-Now obviously, returning all 20 docs is nice, but we're here to paginate!  So let's see what we can pass to the `allDocs()` method to slice and dice our data.
-
-## Learning the pagination lingo
-
-`allDocs()` is a pretty flexible API, and we have a lot of parameters to choose from.  Since PouchDB is modeled after CouchDB, we can learn about these parameters by directly consulting [the Couch docs][couch-query-api], but here's a basic rundown:
-
-* `startkey`: the `_id` of the first doc we'd like to fetch
-* `endkey`: the `_id` of the last doc we'd like to fetch
-* `limit`: maximum number of docs to return
-* `skip`: number of docs to skip
-* `descending`: `true` if we want reverse ordering
-
-These parameters are simply passed as the first argument to `allDocs()`, e.g.
-
-```javascript
-pouch.allDocs({startkey : 'doc05', endkey : 'doc06'}, function (err, response) {
-  // handle err or response
-});
-```
-
-Here's the response:
-
-```javascript
-{
-  "total_rows": 20,
-  "offset": 0,
-  "rows": [
-    {
-      "id": "doc05",
-      "key": "doc05",
-      "value": {"rev": "1-15397f81e784ee1a05d3ab6da07afe8d"}
-    },
-    {
-      "id": "doc06",
-      "key": "doc06",
-      "value": {"rev": "1-5b35abcf7cc48e2cea63e64281f271ca"}
-    }
-  ]
-}
-```
-
-Now, let's go through each of these parameters in detail.
-
-### startkey and endkey
-
-`startkey` simply tells PouchDB where you'd like to start in the stream.  For instance, the options `{startkey : 'doc5'}` would return these docs:
-
-```
-      First doc returned                              Last doc returned
-             ↓                                                       ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-Similarly, `endkey` tells PouchDB where to stop reading.  `{endkey : 'doc15'}` would give us:
-
-```
-First doc returned                         Last doc returned
- ↓                                               ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-These two options can be used together!  `{startkey : 'doc5', endkey: 'doc15'}` gives us:
-
-```
-      First doc returned                   Last doc returned
-             ↓                                   ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-Notice that both `startkey` and `endkey` are *inclusive* &mdash; i.e., the matching value itself is included in the results.
-
-However, the value doesn't actually need to be present. So for example, if you have the documents ```['A', 'B', 'X', 'Y']```, calling `{startkey : 'C', endkey : 'Z'}` would return `['X', 'Y']`.
-
-### skip and limit
-
-`skip` tells PouchDB how many documents to skip from its normal starting point.  E.g. `{skip : 5}` gives us:
-
-```
-      First doc returned                              Last doc returned
-             ↓                                                       ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-Whereas `limit` does the opposite: it cuts off documents from the end. `{limit : 15}` only gives us the first 15 docs:
-
-```
-First doc returned                         Last doc returned
- ↓                                               ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-When `skip` and `limit` are used together, `limit` applies after `skip`.  So e.g. `{skip : 5, limit : 10}` would slice your documents like this:
-
-```
-         First doc returned                Last doc returned
-                ↓                                ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-
-### Skipping into a trap
-
-If you come from a SQL background, you might recognize `skip` and `limit` as our old friends from SQL: `OFFSET` and `LIMIT`. You might also imagine that these parameters are the only ones you need for proper pagination.  But this is a trap!
-
-#### Dumb method (do not use!)
-
-```javascript
-var pageSize = 5;
-var offset = 0;
-function fetchNextPage() {
-  pouch.allDocs({limit : pageSize, skip : offset}, function (err, response) {
-    offset += pageSize;
-    // handle err or response
-  });
-}
-```
-
-This method is intuitive, but once `skip` grows to a large number, your performance will start to degrade pretty drastically.  That's because those documents must literally be *skipped* over with each query, and the database will still read into memory every document that it's skipping. This can be really bad for performance, especially on mobile devices with constrained memory.
-
-Just repeat to yourself: `skip` really means "skip"!
-
-#### Smart method (please use!)
-
-```javascript
-var options = {limit : 5};
-function fetchNextPage() {
-  pouch.allDocs(options, function (err, response) {
-    if (response && response.rows.length > 0) {
-      options.startkey = response.rows[response.rows.length - 1];
-      options.skip = 1;
-    }
-    // handle err or response
-  });
-}
-```
-
-This method takes a bit more time to grok, but what it's essentially doing is leveraging `startkey`, instead of relying on the performance-killer `skip`.
-
-In our initial query, we simply tell PouchDB to give us the first 5 documents (or 10, or whatever your page size is).  In our subsequent queries, we tell it to start with the last doc from the previous page, and to `skip` that one doc.
-
-Of course, you could also fetch `pageSize + 1` docs each time, and simply omit the last document when you display the results to the user.  The choice is yours, but either method is preferable to using `skip` and `limit` alone.
-
-{% include alert/start.html  variant="info"%}
-
-<strong>Aside</strong>: To be fair, WebSQL and CouchDB (since <a href='https://issues.apache
-.org/jira/browse/COUCHDB-977'>version 1.1.1</a>) do not
-suffer from this problem, due to their ability to efficiently count SQLite rows/B-tree offsets.
-However, since IndexedDB and LevelDB (and other backends modeled on <a href='https://github
-.com/rvagg/node-leveldown/'>LevelDOWN</a>) are
-traditional key-value stores, they don't have a good way to count offsets.  Also, some <a href='http://danielwertheim.se/2014/04/01/couchdb-pagination-is-skip-and-limit-enough/
-'>experimental data</a> suggests that CouchDB 1.5 is still faster with the <code>startkey</code> pattern. So you're better off just using <code>startkey</code> everywhere.
-
-{% include alert/end.html %}
-
-## Paginating in backwards land
-
-When `descending` is set to `true`, the normal document order is reversed.  Simply passing `{descending : true}` would give us:
-
-```
-First doc returned                                    Last doc returned
- ↓                                                                   ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-Additionally, all the other parameters suddenly work backwards from their normal behavior!  For instance, if we want to fetch the documents from `'doc01'` to `'doc10'`, we'd normally do:
-
-```javascript
-pouch.allDocs({startkey : 'doc01', endkey : 'doc10'}, function (err, response) {
-  // handle err or response
-});
-```
-
-This would give us 10 results, as expected:
-
-```
-First doc returned     Last doc returned
- ↓                           ↓ 
-[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-```
-
-If we set `descending` to `true`, though, we're in backwards land! So that same query will give us zero results:
-
-```
-                                       Last doc???         First doc???
-                                          ↓                          ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-Here's the actual JavaScript `response` object:
-
-```javascript
-{
-  "total_rows": 20,
-  "offset": 0,
-  "rows": []
-}
-```
-
-Whenever `descending` is set to `true`, we need to switch the `startkey` and `endkey` to get the results we want:
-
-```javascript
-pouch.allDocs({startkey : 'doc10', endkey : 'doc01', descending : true}, function (err, response) {
-  // handle err or response
-});
-```
-
-This gives us what we expect:
-
-```
-                               First doc returned     Last doc returned
-                                          ↓                          ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-### Skip and limit in backwards land
-
-Similarly, for `skip` and `limit`, the operations are performed on the reversed list.  Setting `skip` to `5` will skip the "first" 5 documents, so `{skip : 5, descending : true}` returns:
-
-```
-               First doc returned                     Last doc returned
-                      ↓                                              ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-And setting `limit` to `15` will give us the "first" 15 documents, so `{limit : 15, descending : true}` gives us:
-
-```
-First doc returned                              Last doc returned
-  ↓                                                   ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-Of course, you're free to go nuts and combine these parameters together. For example, the somewhat bloated options:
-
-```javascript
-{
-  skip : 1,
-  limit : 5,
-  startkey : 'doc10',
-  descending : true
-}
-```
-
-would give us:
-
-
-```
-                             First doc returned    Last doc returned
-                                             ↓           ↓ 
-[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
-```
-
-## Keeping your strings in order
-
-In the examples up to now, I've been careful to name my documents `'doc01'`, `'doc02'`, etc.  Astute readers might wonder if that's because PouchDB uses standard [JavaScript string ordering][js-string-ordering].  And those smarty-pants readers would be correct!  Since `doc2` comes after `doc10` in lexicographical ASCII order, I pad the single digits with zeroes.
-
-This can be a very useful trick for document sorting.  Normally, PouchDB will generate a random doc ID if you don't specify one (e.g. `'36483B8A-DF4A-4AEB-B946-096BA0FA8813'`), but if you provide your own IDs, you can make sorting incredibly easy for a variety of applications.
-
-### Example: sort by date
-
-Let's imagine we want to sort our documents by date. For the doc IDs, we'll use timestamps in [standard ISO-8601 format][iso8601], given by `new Date().toJSON()`. This guarantees proper lexicographical ordering:
-
-  [iso8601]: http://www.w3.org/TR/NOTE-datetime
-
-```javascript
-var partyLikeIts = new Date(915148800000); // 1999
-var now = new Date(1394841840000);         // 2014
-
-partyLikeIts.toJSON() // "1999-01-01T00:00:00.000Z"
-now.toJSON()          // "2014-03-15T00:04:00.000Z"
-
-// Party on!
-partyLikeIts.toJSON() < now.toJSON(); // true
-```
-
-{% include alert/start.html variant="warning" %}
-
-<strong>Note:</strong> If you're worried about ID collisions, you could also use <code>new Date().toJSON() + Math.random()</code>.
-
-{% include alert/end.html %}
-
-Now we can fetch the 10 most recent docs:
-
-```javascript
-{
-  limit : 10,
-  descending : true
-}
-```
-
-Or the first 10 docs published after January 1st, 2000:
-
-```javascript
-{
-  limit : 10,
-  startkey : '2000-01-01T00:00:00.000Z'
-}
-```
-
-
-And if you need fancier sorting, or more than one index, try the Map/Reduce-powered [`query()` API][query-api], which boasts [complex key collation](http://docs.couchdb.org/en/latest/couchapp/views/collation.html#collation-specification).
-
-## total_rows is totally awesome
-
-When we call `allDocs()`, a typical response object looks like this:
-
-```javascript
-{
-  "total_rows": 20,
-  "offset": 0,
-  "rows": [/* results go here */]
-}
-```
-
-`offset` simply tells us how many documents were `skip`ped, but `total_rows` tells us the total number of docs in our database.  This can be very useful if you want to calculate how many documents are left to be read in, or if you just want to quickly fetch the database size.
-
-For instance, calling `allDocs()` with `{limit : 0}` will simply return an empty list:
-
-```javascript
-{
-  "total_rows": 20,
-  "offset": 0,
-  "rows": []
-}
-```
-
-If you're a SQL jockey, you can think of this as your `COUNT(*)`.
-
-
-## Putting it all together
-
-PouchDB and CouchDB handle pagination like it ain't no thing.  There are more advanced topics, like how to page through Map/Reduce views with the `query()` API, but if you understand `allDocs()`, you're already 75% of the way there.
-
-So congratulations, you're now a [Page Master]!  Try to use your newfound powers for good.
-
-  [couch-query-api]: https://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-  [js-string-ordering]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Comparing_strings
-  [collation-specification]: http://docs.couchdb.org/en/latest/couchapp/views/collation.html#collation-specification
-  [query-api]: http://pouchdb.com/api.html#query_database
-  [page master]: https://en.wikipedia.org/wiki/Pagemaster
-  [remove]: http://pouchdb.com/api.html#delete_document
\ No newline at end of file
diff --git a/docs/_posts/2014-05-01-pouchdb-2.2.0.md b/docs/_posts/2014-05-01-pouchdb-2.2.0.md
deleted file mode 100644
index e56e81a..0000000
--- a/docs/_posts/2014-05-01-pouchdb-2.2.0.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-layout: post
-
-title: PouchDB 2.2.0
-
-author: Dale Harvey
-
----
-
-[PouchDB 2.2.0](https://github.com/daleharvey/pouchdb/releases/tag/2.2.0) is now released! Please [file issues](https://github.com/daleharvey/pouchdb/issues) or [tell us what you think](https://github.com/daleharvey/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). We would also like to give a huge thanks to our [new and existing contributors](https://github.com/daleharvey/pouchdb/graphs/contributors?from=2014-04-01&to=2014-05-01).
-
-{% include alert/start.html variant="warning"%}
-We have removed the ES5 shims from PouchDB. If you require support for older browsers, it can be included from <a href='https://github.com/es-shims/es5-shim'>https://github.com/es-shims/es5-shim</a>.
-{% include alert/end.html %}
-
-### Major Changes:
-
- * Fix replication for large databases ([#1954](https://github.com/pouchdb/pouchdb/issues/1954))
- * Persistent map/reduce ([#1658](https://github.com/pouchdb/pouchdb/issues/1658))
- * Fix experimental `.sync()` API ([#1696](https://github.com/pouchdb/pouchdb/issues/1696))
- * `.replication()` API switched to an `EventEmitter` ([#1916](https://github.com/pouchdb/pouchdb/issues/1916))
- * `.changes()` API switched to an `EventEmitter` ([#1768](http://github.com/daleharvey/pouchdb/issues/1768))
- * Experimental LevelDB-based LocalStorage adapter ([#44](http://github.com/daleharvey/pouchdb/issues/44))
- * Performance improvements ([#1869](http://github.com/daleharvey/pouchdb/issues/1869), [#1871](http://github.com/daleharvey/pouchdb/issues/1871), [#1889](https://github.com/pouchdb/pouchdb/pull/1889), [#1897](https://github.com/pouchdb/pouchdb/pull/1897), [#1990](https://github.com/pouchdb/pouchdb/issues/1990))
- * Remove ES5 shims ([#1753](http://github.com/daleharvey/pouchdb/issues/1753))
- * Performance tests ([#113](http://github.com/daleharvey/pouchdb/issues/113))
-
-
-###### [Complete list of changes](https://github.com/daleharvey/pouchdb/compare/2.1.0...2.2.0)
diff --git a/docs/_posts/2014-05-01-secondary-indexes-have-landed-in-pouchdb.md b/docs/_posts/2014-05-01-secondary-indexes-have-landed-in-pouchdb.md
deleted file mode 100644
index 5a461ea..0000000
--- a/docs/_posts/2014-05-01-secondary-indexes-have-landed-in-pouchdb.md
+++ /dev/null
@@ -1,496 +0,0 @@
----
-layout: post
-
-title: Secondary indexes have landed in PouchDB
-
-author: Nolan Lawson
-
----
-
-With the release of PouchDB 2.2.0, we're happy to introduce a feature that's been cooking on the slow simmer for some time: secondary indexes, a.k.a. persistent map/reduce.
-
-This is a powerful new tool for developers, since it allows you to index anything in your JSON documents &ndash; not just the doc IDs. Starting in 2.2.0, your data is sortable and searchable in ways that just weren't feasible before, thanks to a new cross-platform indexing engine we've built to work with every supported backend - IndexedDB, WebSQL, and LevelDB (and soon: LocalStorage!).
-
-As usual with PouchDB, the new API is modeled after CouchDB's.  So developers who are already familiar with the [CouchDB map/reduce API](https://wiki.apache.org/couchdb/HTTP_view_API) will be up and running in no time.  
-
-And did I mention?  It's fast.  Our [performance tests](https://gist.github.com/nolanlawson/11100235) show that the new persistent map/reduce API could give you orders of magnitude improvements over the old on-the-fly `query()` method.  In a database containing 1,000 documents, we found queries in PouchDB 2.2.0 to be between 10 and 100 times faster than in PouchDB 2.1.2.
-
-Show me the code!
------
-
-Here's the old way to query:
-
-```js
-var pouch = new PouchDB('mydb');
-
-// temporary view, each doc is processed in-memory (slow)
-pouch.query(function (doc) {
-  emit(doc.name);
-}, {key: 'foo'}).then(function (result) {
-  // found docs with name === 'foo'
-});
-```
-
-{% include alert/start.html variant="info" %}
-
-The <code>emit</code> pattern is part of the standard <a href='http://couchdb.readthedocs.org/en/latest/couchapp/views/intro.html'>CouchDB map/reduce API</a>.  What the function basically says is, "for each document, emit <code>doc.name</code> as a key."
-
-{% include alert/end.html %}
-
-And here's the new way:
-
-```js
-// document that tells PouchDB/CouchDB
-// to build up an index on doc.name
-var myIndex = {
-  _id: '_design/my_index',
-  views: {
-    'my_index': {
-      map: function (doc) { emit(doc.name); }.toString()
-    }
-  }
-};
-// save it
-pouch.put(myIndex).then(function () {
-  // kick off an initial build, return immediately
-  return pouch.query('my_index', {stale: 'update_after'});
-}).then(function () {
-  // query the index (much faster now!)
-  return pouch.query('my_index', {key: 'foo'});
-}).then(function (result) {
-  // found docs with name === 'foo'
-});
-```
-
-Ew, you put map/reduce in my JavaScript?
-------------
-
-First, let's define what map/reduce is, so you can understand why you might want it.
-
-#### Indexes in SQL databases
-
-Quick refresher on how indexes work: in relational databases like MySQL and PostgreSQL, you can usually query whatever field you want:
-
-```sql
-SELECT * FROM pokemon WHERE name = 'Pikachu';
-```
-    
-But if you don't want your performance to be terrible, you first add an index:
-
-```sql
-ALTER TABLE pokemon ADD INDEX myIndex ON (name);
-```
-    
-The job of the index is to ensure the field is stored in a B-tree within the database, so your queries run in _O(log(n))_ time instead of _O(n)_ time.
-
-#### Indexes in NoSQL databases
-
-All of the above is also true in document stores like CouchDB and MongoDB, but conceptually it's a little different. By default, documents are assumed to be schemaless blobs with one primary key (called `_id` in both Mongo and Couch), and any other keys need to be specified separately.  The concepts are largely the same; it's mostly just the vocabulary that's different.
-
-In CouchDB, queries are called _map/reduce functions_.  This is because, like most NoSQL databases, CouchDB is designed to scale well across multiple computers, and to perform efficient query operations in parallel. Basically, the idea is that you divide your query into a _map_ function and a _reduce_ function, each of which may be executed in parallel in a multi-node cluster.
-
-#### Map functions
-
-It may sound daunting at first, but in the simplest (and most common) case, you only need the _map_ function.  A basic map function might look like this:
-
-```js
-function myMapFunction(doc) {
-  emit(doc.name);
-}
-```  
-
-This is functionally equivalent to the SQL index given above.  What it essentially says is: "for each document in the database, emit its name as a key."
-
-And since it's just JavaScript, you're allowed to get as fancy as you want here:
-
-```js
-function myMapFunction(doc) {
-  if (doc.type === 'pokemon') {
-    if (doc.name === 'Pikachu') {
-      emit('Pika pi!');
-    } else {
-      emit(name);
-    }
-  }
-}
-```
-
-Then you can query it:
-
-```js
-// find pokemon with name === 'Pika pi!'
-pouch.query(myMapFunction, {key: 'Pika pi!', include_docs: true}).then(function (result) {
-  // handle result
-});
-
-// find the first 5 pokemon whose name starts with 'P'
-pouch.query(myMapFunction, {
-  startkey: 'P', endkey: 'P\uffff', limit: 5, include_docs: true
-}).then(function (result) {
-  // handle result
-});
-```
-
-{% include alert/start.html variant="info"%}
-
-The pagination options for <code>query()</code> &ndash; i.e., <code>startkey</code>/<code>endkey</code>/<code>key</code>/<code>keys</code>/<code>skip</code>/<code>limit</code>/<code>descending</code> &ndash; are exactly the same as with <code>allDocs()</code>. For a beginner's guide to pagination, read <a href='http://pouchdb.com/2014/04/14/pagination-strategies-with-pouchdb.html'>Pagination strategies with PouchDB</a>.
-
-{% include alert/end.html %}
-
-#### Reduce functions
-
-As for _reduce_ functions, there are a few handy built-ins that do aggregate operations (`'_sum'`, `'_count'`, and `'_stats'`), and you can typically steer clear of trying to write your own:
-
-```js
-// emit the first letter of each pokemon's name
-var myMapReduceFun = {
-  map: function (doc) {
-    emit(doc.name.charAt(0));
-  },
-  reduce: '_count'
-};
-// count the pokemon whose names start with 'P'
-pouch.query(myMapReduceFun, {
-  key: 'P', reduce: true, group: true
-}).then(function (result) {
-  // handle result
-});
-```
-
-If you're adventurous, though, you should check out the [CouchDB documentation](http://couchdb.readthedocs.org/en/latest/couchapp/views/intro.html) or the [PouchDB documentation](http://pouchdb.com/api.html#query_database) for details on reduce functions.
-
-Map/reduce, reuse, recycle
-----------
-
-PouchDB has actually had map/reduce queries since way before version 2.2.0, via the `query()` API. It had a big flaw, though: all queries were performed in-memory, reading in every document in the entire database just to perform a single operation.
-
-This is fine when your data set is small, but it could be murder on large databases. On mobile devices especially, memory is a precious commodity, so you want to be as frugal as possible with the resources given to you by the OS.
-
-The new persistent `query()` method is much more memory-efficient, and it won't read in the entire database unless you tell it to.  It has two modes:
-
-* Temporary views (like the old system)
-* Persistent views (new system)
-
-Both of these concepts exist in CouchDB, and they're faithfully emulated in PouchDB.
-
-#### A room with a view
-
-First off, some vocabulary: CouchDB calls indexes _views_, and these views are stored in a special document called a _design document_. Basically, a design document describes a view, and a view describes a map/reduce query, which tells the database that you plan to use that query later, so it better start indexing it now. In other words, creating a view is the same as saying `CREATE INDEX` in a SQL database.
-
-**Temporary views** are exactly that &ndash; temporary. Instead of using a design document, you just call `pouch.query()`, so the view is created, written to disk, queried, and then poof, it's deleted.  That's why, in older version of PouchDB, we could get away with doing it all in-memory.
-
-Crucially, though, temporary views have to do a full scan of all documents _every time you execute them_, along with all the reading and writing to disk that that entails, only to throw it away at the end.  That may be fine for quick testing during development, but in production it can be a big drag on performance.
-
-**Persistent views**, on the other hand, are a much better solution if you want your queries to be fast.  Persistent views need to be saved in a design document (hence "persistent"), so that the emitted fields are already indexed by the time you look them up.  Subsequent lookups don't need to do any additional writes to disk, unless documents have been added or modified, in which case only the updated documents need to be processed.
-
-{% include alert/start.html variant="info"%}
-
-<strong>Why design docs?</strong> <a href='http://guide.couchdb.org/draft/design.html'>Design documents</a> are special meta-documents that CouchDB uses for things like indexes, security, and schema validation (think: "designing" your database).  They are stored, updated, and deleted exactly like normal documents, but their <code>_id</code>s are prefixed with the reserved string <code>'_design/'</code>.  They also show up in <code>allDocs()</code> queries, but you can filter them out by using <code>{startkey: '_design0'}</code>.
-
-{% include alert/end.html %}
-
-#### Writing your first view
-
-A design document with a view looks just like a regular document.  The simplest one might look like this:
-
-```js
-var designDoc = {
-  _id: '_design/my_index',
-  views: {
-    'my_index': {
-      map: function(doc) {
-        emit(doc.name);
-      }.toString()
-    }
-  }
-};
-```
-
-All you need to do is `put()` this document into your database:
-
-```js
-pouch.put(designDoc).then(function (info) {
- // design doc created
-}).catch(function (err) {
-  // if err.name === 'conflict', then
-  // design doc already exists
-});
-```
-
-&hellip; and then it will be available for querying using the name `'my_index'`:
-
-```js
-pouch.query('my_index').then(function(result) {
- // do something with result
-});
-```
-
-Whatever name you give, be sure to use the same one in both the `_id` (after `'_design/'`) and in the `views`; otherwise you will need to use the awkward format `'my_design_doc_name/my_view_name'` when you query.
-
-{% include alert/start.html variant="info"%}
-
-Technically, a design doc can contain multiple views, but there's really no advantage to this. Plus, it can even cause performance problems in CouchDB, since all the indexes are written to a single file. So we recommend that you create one view per design doc, and use the same name for both, in order to make things simpler.
-
-{% include alert/end.html %}
-
-Since there's a lot of boilerplate involved in creating views, you can use the following helper function to create a simple design doc based on a name and a map function:
-
-```js
-function createDesignDoc(name, mapFunction) {
-  var ddoc = {
-    _id: '_design/' + name,
-    views: {
-    }
-  };
-  ddoc.views[name] = { map: mapFunction.toString() };
-  return ddoc;
-}
-```
-
-Then you just need to `put()` it:
-
-```js
-var designDoc = createDesignDoc('my_index', function (doc) {
-  emit(doc.name);
-});
-pouch.put(designDoc).then(function (doc) {
-  // design doc created!
-}).catch(function (err) {
-  // if err.name === 'conflict', then
-  // design doc already exists
-});
-```
-
-From now on, you can call `pouch.query('my_index')` and it will summon this design document for querying.
-
-Just like regular documents, design docs can always be deleted or changed later. The index will be updated automatically the next time you `query()` it.
-
-If you do this a lot, though, then old indexes will build up on disk.  You can call `pouch.viewCleanup()` to clean up any orphaned indexes. 
-
-{% include alert/start.html variant="warning"%}
-
-<strong>Performance tip</strong>: Technically, the view will not be built up on disk until the first time you <code>query()</code> it.  So a good trick is to always call <code>query(viewName, {stale: 'update_after'})</code> after creating a view, to ensure that it starts building in the background.  You can also use <code>{stale: 'ok'}</code> to avoid waiting for the most up-to-date results. In the future, we may add an API for auto-updating.
-
-{% include alert/end.html %}
-
-#### For those who get nostalgic
-
-Of course, some of our loyal Pouchinistas may have been perfectly happy with the old way of doing things. The fact that the old `query()` function slurped the entire database into memory might have served them just fine, thank you.
-
-To be sure, there are some legitimate use cases for this. If you don't store a lot of data, or if all your users are on desktop computers, or if you require closures (not supported by persistent views), then doing map/reduce in memory may have been fine for you. In fact, an upgrade to 2.2.0 might actually make your app _slower_, because now it has to read and write to disk.
-
-Luckily we have a great solution for you: instead of using the `query()` API, you can use the much more straightforward `allDocs()` API.  This will read all documents into memory, just like before, but best of all, you can apply whatever functions you want to the data, without having to bother with learning a new API or even what the heck "map/reduce" is.
-
-But in general, we strongly recommend upgrading your apps to the new API instead.
-
-When *not* to use map/reduce
-----
-
-Now that I've sold you on how awesome map/reduce is, let's talk about the situations where you might want to avoid it.
-
-First off, you may have noticed that the CouchDB map/reduce API is pretty daunting.  As a newbie Couch user who very recently struggled with the API, I can empathize: the vocabulary is new, the concepts are (probably) new, and there's no easy way to learn it, except to clack at your keyboard for awhile and try it out.
-
-Second off, views can take awhile to build up, both in CouchDB and PouchDB. Each document has to be fetched from the database, passed through the map function, and indexed, which is a costly procedure for large databases. And if your database is constantly changing, you will also incur the penalty at `query()` time of running the map function over the changed documents.
-
-Luckily, it turns out that the primary index, `_id`, is often good enough for a variety of querying and sorting operations. So if you're clever about how you name your document `_id`s, you can avoid using map/reduce altogether.
-
-For instance, say your documents are emails that you want to sort by recency: boom, just set the `_id` to `new Date().toJSON()`.  Or say they're web pages that you want to look up by URL: use the URL itself as the `_id`! Neither CouchDB nor PouchDB have a limit on how long your `_id`s can be, so you can get as fancy as you want with this.
-
-#### Use and abuse your doc IDs
-
-For a more elaborate example, let's imagine you're writing a music app.  Your database might contain artists:
-
-```js
-[ { _id: 'artist_bowie',
-    type: 'artist',
-    name: 'David Bowie',
-    age: 67 },
-  { _id: 'artist_dylan',
-    type: 'artist',
-    name: 'Bob Dylan',
-    age: 72 },
-  { _id: 'artist_joni',
-    type: 'artist',
-    name: 'Joni Mitchell',
-    age: 70 } ]
-```
-
-&hellip; as well as albums:
-
-```js
-[ { _id: 'album_bowie_1971_hunky_dory',
-    artist: 'artist_bowie',
-    title: 'Hunky Dory',
-    type: 'album',
-    year: 1971 },
-  { _id: 'album_bowie_1972_ziggy_stardust',
-    artist: 'artist_bowie',
-    title: 'The Rise and Fall of Ziggy Stardust and the Spiders from Mars',
-    type: 'album',
-    year: 1972 },
-  { _id: 'album_dylan_1964_times_they_are_changin',
-    artist: 'artist_dylan',
-    title: 'The Times They Are a-Changin\'',
-    type: 'album',
-    year: 1964 },
-  { _id: 'album_dylan_1965_highway_61',
-    artist: 'artist_dylan',
-    title: 'Highway 61 Revisited',
-    type: 'album',
-    year: 1965 },
-  { _id: 'album_dylan_1969_nashville_skyline',
-    artist: 'artist_dylan',
-    title: 'Nashville Skyline',
-    type: 'album',
-    year: 1969 },
-  { _id: 'album_joni_1974_court_and_spark',
-    artist: 'artist_joni',
-    title: 'Court and Spark',
-    type: 'album',
-    year: 1974 } ]
-```
-
-See what I did there? Artist-type documents are prefixed with `'artist_'`, and album-type documents are prefixed with `'album_'`.  This naming scheme is clever enough that we can already do lots of complex queries using `allDocs()`, even though we're storing two different types of documents.
-
-Want to find all artists?  It's just:
-
-```js
-allDocs({startkey: 'artist_', endkey: 'artist_\uffff'});
-```  
-
-Want to list all the albums?  Try:
-
-```js
-allDocs({startkey: 'album_', endkey: 'album_\uffff'});
-```
-
-How about all albums by David Bowie?  Wham bam, thank you ma'am:
-
-```js
-allDocs({startkey: 'album_bowie_', endkey: 'album_bowie_\uffff'});
-```
-
-Let's go even fancier. Can we find all of Bob Dylan's albums released between 1964 and 1965, in reverse order? Gather 'round people, and try this:
-
-```js
-allDocs({startkey: 'album_dylan_1965_', endkey: 'album_dylan_1964_\uffff', descending: true});
-```
-
-In this example, you're getting all those "indexes" for free, each time a document is added to the database.  It doesn't take up any additional space on disk compared to the randomly-generated UUIDs, and you don't have to wait for a view to get built up, nor do you have to understand the map/reduce API at all.
-
-Of course, this system starts to get shaky when you need to search by a variety of criteria: e.g. all albums sorted by year, artists sorted by age, etc. And you can only sort strings &ndash; not numbers, booleans, arrays, or arbitrary JSON objects, like the map/reduce API supports.  But for a lot of simple applications, you can get by without using the `query()` API at all.
-
-{% include alert/start.html variant="warning"%}
-
-<strong>Performance tip</strong>: if you're just using the randomly-generated doc IDs, then you're not only missing out on an opportunity to get a free index &ndash; you're also incurring the overhead of building an index you're never going to use. So use and abuse your doc IDs!
-
-{% include alert/end.html %}
-
-Tips for writing views
------
-
-When you do need the full map/reduce API, though, it pays to know the tips and tricks.  Below is a list of advanced techniques and common pitfalls, which you may find useful when you're trying to squeeze that last bit of performance out of your views.
-
-**1. Don't index it if you don't need it**
-
-If your database has several document types, but only the "person" type has a `lastName` field, do this:
-
-```js
-function (doc) {
-  if (doc.lastName) {
-    emit(doc.lastName);
-  }
-}
-```
-
-If you took out the `if` statement, you'd emit a `null` key for every non-person in your database, which needlessly bloats the size of your index.
-
-{% include alert/start.html variant="info"%}
-
-If the <code>null</code> field is meaningful for some reason, though, you can emit it and look it up later using <code>query(viewName, {key: null})</code>.  Any <code>undefined</code> fields are treated as <code>null</code>.
-
-{% include alert/end.html %}
- 
-**2. Move logic to the query params**
-
-Don't do:
-
-```js
-function (doc) {
-  if (doc.highScore >= 1000) {
-    emit(doc.highScore);
-  }
-}
-```
-
-Instead, do:
-
-```js
-function (doc) {
-  emit(doc.highScore);
-}
-```
-
-And then query with `{startkey: 1000}`.
-
-**3. Use high characters for prefix search**
-
-To find every `lastName` that starts with an `'L'`, you can use the high Unicode character `'\uffff'`:
-
-```js
-pouch.query(viewName, {startkey: 'L', endkey: 'L\uffff'});
-```
-
-Or you can set `inclusive_end` to `false`:
-
-```js
-pouch.query(viewName, {startkey: 'L', endkey: 'M', inclusive_end: false});
-```
-
-Both queries will do the same thing.
-
-**4. Use {} for complex key ranges**
-
-If your keys are `[lastName, firstName]`, and you need to find everybody with the last name `'Harvey'`, you can do:
-
-```js
-pouch.query(viewName, {startkey: ['Harvey'], endkey: ['Harvey', {}]});
-```
-
-In [CouchDB collation ordering][couchdb-collation], `{}` is higher than everything except other objects.
-
-
-For the database geeks: implementation details
--------
-
-If you want to know how map/reduce works in PouchDB, it's actually exceedingly easy: just open up your browser's developer tools, head over to "Resources," and see where we've created a bonus database to store the index.
-
-One of the neat things about how we implemented map/reduce is that we managed to do it entirely within PouchDB itself.  Yep, that's right: your map/reduce view is just a regular old PouchDB database, and map/reduce itself is a plugin with no special privileges, creating databases in exactly the same way a regular user would.  Since the implementation sits on top of the PouchDB API, it's exactly the same for all three backends: LevelDB, IndexedDB, and WebSQL.
-
-How did we pull off this trick?  To be clear: it's not like we set out to make PouchDB some kind of map/reduce engine.  In fact, as we were debating how to implement this feature, we originally ran on the assumption that we'd need to build additional functionality on top of PouchDB. It was only after a few months of discussions and experiments that we realized the whole thing could be done in PouchDB proper.
-
-In the end, the only additional functionality we had to add to the main PouchDB code was a hook to tell PouchDB to destroy the map/reduce database when its parent database was destroyed.  That's it.
-
-This technique also has a nice parallel in CouchDB: it turns out that they, too, reused the core `_view` code in order to write `_all_docs`.  In CouchDB, `_all_Docs` is just a special kind of `_view`, whereas in PouchDB, we built map/reduce views on top of `allDocs()`.  We did it backwards, but the spirit of the idea was the same.
-
-As for the index itself, what it basically boils down to is clever serialization of arbitrary JSON values into [CouchDB collation ordering][couchdb-collation] &ndash; i.e. nulls before booleans, booleans before numbers, numbers before strings, strings before arrays, arrays before objects, and so on recursively.  Every JSON object maps to an indexable string that guarantees the same ordering in every database backend, and we only deviate from CouchDB by using ASCII string ordering instead of ICU ordering (since that's what our backends use).
-
-  [couchdb-collation]: http://couchdb.readthedocs.org/en/latest/couchapp/views/collation.html
-
-Then, we take this value and concatenate it with whatever else needs to be indexed (usually just the doc `_id`), meaning the entire lookup key is a single string.  We decided on this implementation because:
-
-1. LevelDB does not support complex indexes.
-2. IndexedDB _does_ support complex indexes, but [not in IE][ie-complex-keys].
-3. WebSQL supports multi-field indexes, but it's also a dead spec, so we're not going to prioritize it above the others.
-
-The next part of the design was to divide the data we needed to store into two kinds of documents: 1) emitted key/values with doc IDs, which are used for querying and pagination, and 2) mappings from doc IDs to those key/values, so that we can delete or update them when their parent documents are deleted or updated. Since by design, PouchDB databases do not have multi-document transaction semantics, we implemented a task queue on top of the database to serialize writes.
-
-Aside from that, the only other neat trick was a liberal use of `_local` documents, which are a special class of documents that aren't counted in the `total_rows` count, don't show up in `allDocs`, but can still be accessed using the normal `put()` and `get()` methods.  This is all it takes to fully reimplement CouchDB map/reduce in a tiny JavaScript database!
-
-Anyone interested in more implementation details can read the months-long discussions in [these][mapreduce-12] [Github][1549] [issues][1658].  The [map/reduce code][mapreduce] itself is also pretty succinct.
-
-[mapreduce]: https://github.com/pouchdb/mapreduce
-[mapreduce-12]: https://github.com/pouchdb/mapreduce/issues/12
-[1549]: https://github.com/pouchdb/pouchdb/issues/1549
-[1658]: https://github.com/pouchdb/pouchdb/issues/1658
-[ie-complex-keys]: https://gist.github.com/nolanlawson/8330172
diff --git a/docs/_posts/2014-06-01-pouchdb-2.2.3.md b/docs/_posts/2014-06-01-pouchdb-2.2.3.md
deleted file mode 100644
index e7c6f09..0000000
--- a/docs/_posts/2014-06-01-pouchdb-2.2.3.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-layout: post
-
-title: PouchDB 2.2.3
-
-author: Dale Harvey
-
----
-
-[PouchDB 2.2.3](https://github.com/daleharvey/pouchdb/releases/tag/2.2.3) is now released! Please [file issues](https://github.com/daleharvey/pouchdb/issues) or [tell us what you think](https://github.com/daleharvey/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). We would also like to give a huge thanks to our [new and existing contributors](https://github.com/daleharvey/pouchdb/graphs/contributors?from=2014-05-01&to=2014-06-01).
-
-### Major Changes:
-
- * Experimental browser adapter plugins ([#2190](http://github.com/daleharvey/pouchdb/issues/2190))
- * Fix Ember.js integration ([#2158](http://github.com/daleharvey/pouchdb/issues/2158))
- * Fix Browserify integration ([#2249](http://github.com/daleharvey/pouchdb/issues/2249), [pouchdb/mapreduce#170](https://github.com/pouchdb/mapreduce/issues/170))
- * Fixes for conflict resolution ([#2072](http://github.com/daleharvey/pouchdb/issues/2072))
- * Better error handling in replication ([#2122](http://github.com/daleharvey/pouchdb/issues/2122))
- * Fix Internet Explorer 10-11 ([#1661](http://github.com/daleharvey/pouchdb/issues/1661), [#2198](http://github.com/daleharvey/pouchdb/issues/2198), [#2132](http://github.com/daleharvey/pouchdb/issues/2132))
- * Fix attachments in Android 4.x ([#1992](http://github.com/daleharvey/pouchdb/issues/1992))
- * Fix LevelDB memory leak, race condition, error messages ([#2250](http://github.com/daleharvey/pouchdb/issues/2250), [#2251](http://github.com/daleharvey/pouchdb/issues/2251), [#2144](http://github.com/daleharvey/pouchdb/issues/2144))
- * Perf improvements for replication in WebSQL & IndexedDB ([#2180](http://github.com/daleharvey/pouchdb/issues/2180), [#2178](http://github.com/daleharvey/pouchdb/issues/2178))
- * Bugfixes for IndexedDB inclusive_end ([#2129](http://github.com/daleharvey/pouchdb/issues/2129))
- * Fix `changes()` memory leak ([#2311](http://github.com/daleharvey/pouchdb/issues/2311))
-
-###### [Complete list of changes](https://github.com/daleharvey/pouchdb/compare/2.2.0...2.2.3)
diff --git a/docs/_posts/2014-06-17-12-pro-tips-for-better-code-with-pouchdb.md b/docs/_posts/2014-06-17-12-pro-tips-for-better-code-with-pouchdb.md
deleted file mode 100644
index 8c3b5b4..0000000
--- a/docs/_posts/2014-06-17-12-pro-tips-for-better-code-with-pouchdb.md
+++ /dev/null
@@ -1,284 +0,0 @@
----
-layout: post
-
-title: 12 pro tips for better code with PouchDB
-
-author: Nolan Lawson
-
----
-
-This is not a blog post per se, but more of a list of tips and tricks to get the most out of your PouchDB experience.
-
-There are a lot of PouchDB anti-patterns floating around out there on the Internet, and also some common pitfalls that can trip you up when you're new to the CouchDB API.  I see this stuff all the time on Stack Overflow, Twitter, and IRC, and it never ceases to amaze and horrify me. We need to do better.
-
-So consider this your 12-step program to becoming a better PouchDB coder. Let's put these bad habits to bed.
-
-### 1. Use put(), not post()
-
-Never use `post()`.  You don't need it, so just stop.
-
-Recall that `put()` requires you to supply your own doc ID, whereas `post()` generates a random one for you. However, this leads to inefficiencies, since you pay the cost of indexing a long ID like `'CB89021E-8439-392F-899C-054963FD0B9B'` without ever using it. 
-
-Plus, you'll have to use `put()` anyway whenever you update or delete a document, so if you `post()`, you've got two APIs to learn instead of one. So remember: always `put()`, never `post()`.
-
-### 2. Don't emit(doc.foo, doc)
-
-Don't do:
-
-```js
-function (doc) {
-  emit(doc.foo, doc);
-}
-```
-
-Do:
-
-```js
-function (doc) {
-  emit(doc.foo);
-}
-```
-
-This anti-pattern is everywhere. It seems to date back to pre-PouchDB days, since it shows up in a lot of blog posts and articles about CouchDB.
-
-Folks, you never need to `emit()` the full document in your map/reduce functions.  You can always just use `{include_docs: true}` when you query, and the freshest version of that document will be delivered right to your door.  Free of charge.
-
-Plus, if you emit the full doc, then it will actually _serialize and write out that entire document to disk_.  This is true in both PouchDB and CouchDB, and it's pure waste.
-
-So if you don't want big, inefficient map/reduce functions, then remember: only `emit()` what you need.
-
-### 3. Don't emit(doc.foo, 1) and then _sum
-
-Similar to the above, don't do:
-
-```js
-{
-  map: 
-    function (doc) {
-      emit(doc.foo, 1);
-    }.toString(),
-  reduce: '_sum'
-}
-```
-
-Do:
-
-```js
-{
-  map: 
-    function (doc) {
-      emit(doc.foo);
-    }.toString(),
-  reduce: '_count'
-}
-```
-
-You don't need to use `_sum` when a simple `_count` will do.
-
-### 4. Attachments are overrated
-
-{% include alert/start.html variant="warning" %}
-
-<strong>Update:</strong> since this post was written, the stability and performance of attachments in PouchDB has greatly improved. Replicating large attachments is still not recommended, but attachments can be handy if used correctly. <a href='https://github.com/nolanlawson/blob-util'>blob-util</a> can help.
-
-{% include alert/end.html %}
-
-NPM has [moved away from storing attachments in CouchDB](http://blog.npmjs.org/post/71267056460/fastly-manta-loggly-and-couchdb-attachments). Nowadays they use a CDN for the binaries, and CouchDB just stores the metadata. In PouchDB, attachments have been [one](https://github.com/pouchdb/pouchdb/issues/2098) [of](https://github.com/pouchdb/pouchdb/pull/1078) [the](https://github.com/pouchdb/pouchdb/issues/1992) [biggest](https://github.com/pouchdb/pouchdb/issues/900) [sources](https://github.com/pouchdb/pouchdb/pull/2063) [of](https://github.com/pouchdb/pouchdb/pull/1210) [bugs](https://github.com/pouchdb/pouchdb/pull/502), since every browser seems to handle them differently. Plus, the [attachment API is hard to understand](https://github.com/pouchdb/pouchdb/issues/1251), you need [a Blob shim](https://gist.github.com/nolanlawson/10340255) for older browsers, and let's not even talk about ArrayBuffers, ArrayBufferViews, Uint8Arrays, and browsers that don't even support any of the above.
-
-In general, both CouchDB and PouchDB are just poor fits for storing binary data.  (Databases rarely are.) Instead of attachments, try using a CDN or a simple fileserver, and store the URLs or checksums in the database if you need to.
-
-
-<blockquote>
-
-<p>
-"One of the big things that everybody who's spent a lot of time with databases knows is that you should <em>never</em> put your binaries in the database.  It's a terrible idea.  It always goes wrong.  I have never met a database in 15 years of which it is not true, and it's definitely not true of CouchDB.
-</p>
-
-<p>
-You are taking this thing which is meant to sort and organize data, and you're giving it binary data, which it can neither sort nor organize.  It can't do anything with that data, other than get really fat."
-</p>
-
-<footer>
-<cite title="Source Title">
-  Laurie Voss, on <a href='http://javascriptjabber.com/099-jsj-npm-inc-with-isaac-schlueter-laurie-voss-and-rod-boothby/'>JavaScript Jabber</a>
-</cite>
-</footer>
-
-</blockquote>
-
-
-### 5. Use plugins
-
-[PouchDB has plugins](http://pouchdb.com/external.html).  Use them, and if inspiration ever strikes, [write your own](https://github.com/pouchdb/plugin-seed)!
-
-### 6. Don't just update docs for the hell of it
-
-Every time you modify a document, another revision is added to its revision history &ndash; think Git.  Except unlike Git, these revisions contain the full document data (not just the diffs), which can take up a lot of space on disk.  So if nothing changed in a document, don't bother `put()`ing it again.
-
-### 7. Use and abuse your doc IDs
-
-I already wrote [a blog post about this](http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html), but basically, if you don't want bad performance from your secondary indexes, the best strategy is to avoid secondary indexes altogether. The primary index should be sufficient for sorting and searching in nearly all of your applications, or at least for the hot-path code.
-
-Also, if you really want to get fancy with your doc IDs, you can use [PouchDB Collate](https://github.com/pouchdb/collate/) to serialize arbitrary data into strings that are sorted according to [CouchDB collation ordering](https://wiki.apache.org/couchdb/View_collation).  This allows you to index on arrays, objects, numbers &ndash; whatever you want:
-
-```js
-var pouchCollate = require('pouchdb-collate');
-var myDoc = {
-  firstName: 'Scrooge',
-  lastName: 'McDuck',
-  age: 67,
-  male: true
-};
-// sort by age, then gender, then last name, then first name
-myDoc._id = pouchCollate.toIndexableString(
-  [myDoc.age, myDoc.male, mydoc.lastName, mydoc.firstName]);
-```
-
-In the above example, the doc ID will be a strange string, which will sort correctly in both CouchDB and PouchDB:
-
-```js
-'5323256.70000000000000017764\u000021\u00004McDuck\u00004Scrooge\u0000\u0000'
-```
-
-This is actually what persistent map/reduce uses under the hood!
-
-And for cases where you only need to build complex IDs out of strings, there is also the fantastic [DocURI](https://github.com/jo/docuri) project, which can build a more human-readable ID like this:
-
-```js
-'movie/blade-runner/gallery-image/12/medium'
-```
-
-Choose whichever one fits your app better, or just concatenate the strings yourself.
-
-
-### 8. Use Web SQL for better performance
-
-{% include alert/start.html variant="warning" %}
-
-<strong>Update:</strong> since this post was written, IndexedDB performance has improved, and is often better than WebSQL in Chrome. Your mileage may vary, so try them both out on your target platform(s).
-
-{% include alert/end.html %}
-
-Our performance tests have shown it again and again: Web SQL is faster than IndexedDB. It's hard to tell if that's due to our implementation or the browser vendors', but in any case, if you feel the need for speed, then you'll want to prefer Web SQL to IndexedDB.
-
-So now that Android 4.4, iOS 8, and Safari 8 support IndexedDB in addition to Web SQL, it's more important than ever to consider using Web SQL instead of IndexedDB &ndash; at least, in apps where performance matters.  To do so, the code is simply:
-
-```js
-var pouch = new PouchDB('mydb', {adapter: 'websql'});
-if (!pouch.adapter) { // websql not supported by this browser
-  pouch = new PouchDB('mydb');
-}
-```
-
-{% include alert/start.html variant="info" %}
-
-<em>If Web SQL is so fast, why does PouchDB fall back to Web SQL from IndexedDB instead of the other way around?</em> Because we're trying to move the web forward, not rely on deprecated technology. If browser vendors can rest on their laurels with Web SQL, then they won't work to make IndexedDB faster.
-
-{% include alert/end.html %}
-
-### 9. Move logic from the map function to query()
-
-If you only remember one thing from [my blog post about secondary indexes](http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html), remember this: every `map` function you write has to be executed for every single document in your database.  No exceptions.
-
-On the other hand, the `query()` options like `startkey`, `endkey`, `key`, and `keys` have been optimized to hell, and they leverage the native indexes in the database to deliver the maximum possible performance.
-
-So if you find yourself writing something like this, you're doing it wrong:
-
-```js
-function getPostsSince(when) {
-  return db.query({
-    map: function(doc, emit) {
-      if (doc.timestamp > when) {
-        emit(doc.name, 1);
-      }
-    },
-  // ...
-}
-function getPostsBefore(when) {
-  return db.query({
-    map: function(doc, emit) {
-      if (doc.timestamp < when) {
-        emit(doc.name, 1);
-      }
-    }, 
-  // ...
-}
-function getPostsBetween(startTime, endTime) {
-  return db.query({
-    map: function(doc, emit) {
-      if (doc.timestamp > startTime && doc.timestamp < endTime) {
-        emit(doc.name, 1);
-      }
-    }, 
-  // ...
-}
-```
-
-Each of those `db.query()` calls represents a separate _temporary index_. I.e., all your docs are read in, run through the map function, spit out to an index, queried, and then the whole thing is thrown away.  For every query!  This code is based on a real question I got from a developer on Twitter (sorry to pick on ya), and he described it as "crazy slow." No kidding.
-
-Since all of these map/reduce functions key off of `doc.timestamp`, a better approach (which I recommended to him) would be:
-
-```js
-var ddoc = createDesignDoc('by_timestamp', function (doc) {
-  emit(doc.timestamp, doc.name);
-});
-db.put(ddoc).then(function() {/* etc. */});
-
-function getPostsSince(when) {
-  return db.query('by_timestamp', {endkey: when, descending: true});
-}
-function getPostsBefore(when) {
-  return db.query('by_timestamp', {startkey: when});
-}
-function getPostsBetween(startTime, endTime) {
-  return db.query('by_timestamp', {startkey: startTime, endkey: endTime});
-}
-```
-
-(That `createDesignDoc()` helper function comes from [this blost post](http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html).)
-
-Not only is the above code much simpler, but it's also faster and more tweakable. No need to completely rebuild the index when your query changes; just switch around `startkey`/`endkey`/`descending` and friends at query time to get the data you want.
-
-### 10. You probably don't need reduce
-
-In the previous example, the developer was also doing some fancy operations on the data using `'_count'` and `'_sum'`.  Now, these are fine shortcuts that can save you a lot of code, but unless you're running your queries against the server, they don't buy you any performance benefits.
-
-PouchDB runs in Node or the browser, meaning it's a single-threaded, single-process environment.  There's no massive parallelization of the map/reduce functions like you could get with CouchDB (or at least, BigCouch/Cloudant/Couchbase). So PouchDB takes a shortcut and just runs every `reduce` function in memory (there's no point in writing it to disk), meaning it's not doing anything you couldn't just do yourself.
-
-So if you find yourself writing three different design documents that all `emit` the same thing but have different `reduce` functions: don't bother.  You can get better performance and smaller code by just writing a single design document with no `reduce`, and then doing the reduce yourself.
-
-### 11. Debug with the CouchDB UI 
-
-One common question is: How do I debug my database?  Well, that's easy: just replicate to CouchDB! Then you can browse your data in CouchDB's handy Futon interface.
-
-In your code or in the browser console, just run:
-
-```js
-PouchDB.replicate('mydb', 'http://localhost:5984/mydb', {live: true});
-```
-
-Then open up [http://localhost:5984/_utils](http://localhost:5984/_utils). Or if you want to try the new Fauxton API in CouchDB 1.5: [http://localhost:5984/_utils/fauxton/](http://localhost:5984/_utils/fauxton/). You'll get a nice interface that looks like this:
-
-{% include img.html src="fauxton.png" alt="Fauxton UI in PouchDB Server" %}
-
-And if you don't feel like installing CouchDB, you can install [PouchDB Server](https://github.com/pouchdb/pouchdb-server) instead:
-
-```
-$ npm install -g pouchdb-server
-$ pouchdb-server -p 5984
-```
-
-Then open up [http://localhost:5984/_utils](http://localhost:5984/_utils).
-
-
-### 12. Contribute!
-
-To paraphrase [Martin Fowler's famous talk](https://www.youtube.com/watch?v=qI_g07C_Q5I), part of the motivation behind the NoSQL movement was the collective realization by a generation of developers that, you know, this whole "database" thing? It isn't really that hard. Keys map to values, stuff's written to disk: it's a cinch once you learn the basics. And PouchDB occupies an even humbler niche in the NoSQL community, since our NoSQL database is actually built on other databases.
-
-So if you find a bug, or if there's a missing feature you'd like to request, then check out the code and open a pull request!  We've got a very handsomely documented [contributor's guide](https://github.com/pouchdb/pouchdb/raw/master/CONTRIBUTING.md), and we're always happy to answer questions on [IRC](irc://freenode.net/#pouchdb), [Twitter](http://twitter.com/pouchdb), and [the mailing list](https://groups.google.com/forum/#!forum/pouchdb).
-
-And even if you've committed the above errors (I know I have), we won't judge you too harshly.  If you've read this far, then you're already on the path to recovery.
-
-### More tips
-
-For more CouchDB tips in easily-digestible list format, check out Joan Touzet's awesome presentation: [10 Common Misconceptions about CouchDB](http://youtu.be/BKQ9kXKoHS8). And to see what you can get away with if you bend these rules a bit, watch [the talk that Nathan Vander Wilt gave](http://youtu.be/4QttTEbQ_1I) right after.
diff --git a/docs/_posts/2014-07-25-pouchdb-levels-up.md b/docs/_posts/2014-07-25-pouchdb-levels-up.md
deleted file mode 100644
index d615d27..0000000
--- a/docs/_posts/2014-07-25-pouchdb-levels-up.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-layout: post
-
-title: PouchDB levels up
-
-author: Nolan Lawson
-
----
-
-You might not have noticed it, but PouchDB underwent a quiet revolution over the past few months. The catalyzing moment was [the LevelUP proposal](https://github.com/pouchdb/pouchdb/issues/1250) posted by Nick Thompson back in January 2014, which slowly led to a rewrite of the PouchDB adapter for LevelDB to support arbitrary LevelUP backends.  If that looks like word soup, let me explain why this is such a big deal.
-
-### LevelDB
-
-In 2011, Google invented [LevelDB](https://en.wikipedia.org/wiki/LevelDB) as their answer to the [IndexedDB spec](http://www.w3.org/TR/IndexedDB/) designed by Nikunj Mehta. Like IndexedDB, it's quite a low-level abstraction that provides only the bare bones of what you'd need to qualify as a database &ndash; key-value storage, iteration, batch operations, and little else. Indeed, this was one of the big selling points of IndexedDB: it was low-level and unimposing enough that all the browser vendors could agree on it.
-
-As it turned out, though, Google's implementation was really good.  Due to [its unique design](http://dailyjs.com/2013/04/19/leveldb-and-node-1/) inspired by BigTable, it scales well for anything from small application stores to huge multi-cluster databases. And thanks to its limited scope, it's been adopted as a core building block for more feature-rich databases, most notably Basho's [Riak](http://basho.com/riak/), Facebook's [RocksDB](http://rocksdb.org/), and [Hyperdex](http://hyperdex.org/).
-
-### LevelDB comes to Node
-
-In Node.js, LevelDB took an especially interesting turn when Rod Vagg started the [LevelUP project](https://github.com/rvagg/node-levelup). LevelUP aimed not only to provide a fluent, Node-friendly API for LevelDB, but also to create a new lingua franca for persistent datastores. With LevelUP, the team managed to separate the API from the underlying storage engine (cheekily named LevelDOWN), therefore allowing any database that exposes a LevelUP-compliant API to be swapped in under the hood.
-
-Since the LevelUP project began, the number of compatible datastores has exploded, and today you're spoiled for choice if you write your app to the LevelUP API. As a developer, you can start with LevelDOWN, but if you later decide LevelDB itself isn't to your tastes, you can swap it out for any one of:
-
-* [level-rocksdb](https://github.com/Level/level-rocksdb), Facebook's fork for RocksDB
-* [Level.js](https://github.com/maxogden/level.js), a browser-based store built on IndexedDB
-* [RiakDOWN](https://github.com/nlf/riakdown), a Riak-based store
-* [MemDOWN](https://github.com/rvagg/memdown), an in-memory store
-* and [many others](https://github.com/rvagg/node-levelup/wiki/Modules#storage-back-ends).
-
-What this means in practice is that you could, for instance, use:
-
-* MemDOWN for your unit tests,
-* Level.js when your app runs in a browser,
-* LevelDOWN on your dev server,
-* and Riak in your production server.
-
-In a sense, LevelUP brings to the NoSQL world the same benefits of interoperability that the SQL world enjoyed for so long.  SQL databases share the SQL language, and the LevelUP-compliant databases share the LevelUP API.
-
-### Enter PouchDB
-
-This brings us back to Nick Thompson's [LevelUP proposal](https://github.com/pouchdb/pouchdb/issues/1250). At the time he wrote it, PouchDB had three supported backends &ndash; LevelDB, Web SQL, and IndexedDB.  All three were written as separate adapters tailored to PouchDB's API, but he pointed out that if we integrated with LevelUP, we could piggyback on LevelUP's success and potentially get lots of new backends for free.
-
-For instance, there was [a longstanding issue](https://github.com/pouchdb/pouchdb/issues/44) to add LocalStorage support for older browsers like IE 8 and 9. With LevelUP, we could avoid writing an entirely new, fourth adapter and simply plug into [localstorage-down](https://github.com/No9/localstorage-down). And it certainly wouldn't hurt to have Riak, Redis, or an in-memory database as potential backends.
-
-There was some hemming and hawing (mostly from me), but in the end we decided to cruise ahead with the proposal. (And ultimately, I was happily proven wrong.) Calvin Metcalf deserves the primary credit for integrating [Sublevel](https://github.com/dominictarr/level-sublevel) into the LevelDB adapter, while Adam Shih jumped in to get the new adapter browserified with three different backends: localstorage-down, level-js, and MemDOWN. I put the finishing touches to build them as separate plugins, and as of 2.2.3 they're fully passing the test suite and [ready to use](http://pouchdb.com/adapters.html#pouchdb_in_the_browser).
-
-Additionally, [PouchDB Server](https://github.com/pouchdb/pouchdb-server) has been updated to allow the use of alternate backends via the `--level-backend` option. This provides an instant CouchDB REST API to any LevelUP-compliant datastore &ndash; Redis, Riak, MySQL, you name it. There's also a new `--in-memory` option, courtesy of MemDOWN, of course.
-
-### Community dynamics
-
-Besides getting some new backends, another cool change was that PouchDB started to take a more active role in the LevelUP community. Calvin Metcalf wrote [SQLdown](https://github.com/calvinmetcalf/SQLdown), Adam Shih and I became maintainers of localstorage-down, and all three of us submitted patches to level-js, MemDOWN, [abstract-leveldown](https://github.com/rvagg/abstract-leveldown), and even LevelUP itself. The PouchDB test suite [has been offered](https://github.com/rvagg/abstract-leveldown/issues/26) as an additional means of testing for *DOWN authors, and it's already been used to fix bugs in [RiakDOWN](https://github.com/nlf/riakdown) and [RedisDOWN](https://github.com/hmalphettes/redisdown).
-
-So in a sense, we didn't really get these new adapters "for free." PouchDB is complex enough, and our unit tests are thorough enough, that we ended up pushing the LevelUP folks' code to the limit, discovering many new bugs in the process.
-
-But in a more positive sense, we've actually achieved Nick Thompson's goal of more deeply integrating with the LevelUP community, thereby reducing redundancy and putting more effort into a smaller codebase. And in the future, positive changes in PouchDB will spill over into the LevelUP universe, and vice-versa. 
-
-The only original aim that we haven't achieved is to consolidate our three adapters (LevelDB, Web SQL, and IndexedDB) into one. We have a few reasons for this: our custom IndexedDB adapter is currently faster than Level.js, SQLdown is still a work in progress, and we're wary of the inevitable schema migration.
-
-However, the fact that we can have dozens of PouchDB backends, while only maintaining three parallel adapters, is still a huge boon and was well worth the effort.
-
-### Conclusion
-
-PouchDB has a bright future as part of the LevelUP ecosystem. What would have sounded like a dream half a year ago is now a verifiable reality, with unit tests to boot.  Today you can write an app that:
-
-* Syncs from CouchDB to an in-memory [PouchDB Server](https://github.com/pouchdb/pouchdb-server),
-* Then syncs to LocalStorage on IE 8,
-* Then syncs to [Cloudant](https://cloudant.com/),
-* Then syncs to a PhoneGap app using the [SQLite Plugin](https://github.com/brodysoft/Cordova-SQLitePlugin),
-* Then syncs to any one of Redis, Riak, SQLite, LevelDB, MySQL, PostgreSQL, and potentially [many more](https://github.com/rvagg/node-levelup/wiki/Modules#storage-back-ends).
-
-Or whatever other combination you can cook up!
-
-The marriage of PouchDB and LevelUP has essentially resulted in a marriage of the CouchDB sync protocol to the LevelUP API. Any database that exposes a LevelUP interface is now a full-fledged CouchDB replication target, which is a huge win for application developers.
-
-Which database do you want to sync to?  Well, which database do you feel like today?
diff --git a/docs/_posts/2014-08-12-pouchdb-3.0.0.md b/docs/_posts/2014-08-12-pouchdb-3.0.0.md
deleted file mode 100644
index fcede66..0000000
--- a/docs/_posts/2014-08-12-pouchdb-3.0.0.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.0
-
-author: Calvin Metcalf
-
----
-
-[PouchDB 3.0.0](https://github.com/pouchdb/pouchdb/releases/tag/3.0.1) is finally released! It's faster, it's more stable, it's easier to debug, it doesn't freeze the DOM and it spontaneously generates kittens.
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). We would also like to give a huge thanks to our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors?from=2014-06-01&to=2014-08-12).
-
-{% include alert/start.html variant="warning"%}
-This release includes a migration. Your existing database will be updated automatically, but you cannot downgrade to a previous version of PouchDB once you've upgraded.
-{% include alert/end.html %}
-
-### Breaking Changes:
-* The browser build `pouchdb-nightly.js` has been renamed to `pouchdb.js`. It was never really a nightly anyway. ([#2146](https://github.com/pouchdb/pouchdb/issues/2146)) 
-* `opts.server` has been deprecated from the `replicate()` and `sync()` APIs. You can still replicate from one HTTP server to another, but the data will flow through PouchDB rather than being server-initiated. ([#2313](https://github.com/pouchdb/pouchdb/issues/2313))
-* You can no longer rely on errors to have an identifying name. Instead, rely on CouchDB-centric errors to have a status (i.e. `err.status` instead of `err.name`).  There are some that still have an identifying name, but **these could be removed at any time**. The upside of this is that stack traces should be more consistently helpful. ([#2545](https://github.com/pouchdb/pouchdb/issues/2545))
-
-### Major Changes:
-
- * Constructor option `opts.size` to work around Safari/iOS storage quotas ([#2347](https://github.com/pouchdb/pouchdb/issues/2347))
- * `PouchDB.defaults()` for default constructor options, which permits many new features in pouchdb-server. ([#2054](https://github.com/pouchdb/pouchdb/issues/2054))
- *  `_local` documents are now unversioned in the underlying backend for better map/reduce performance and to better align the `update_seq` with CouchDB ([#2023](https://github.com/pouchdb/pouchdb/issues/2023)). Also fixes an issue with replication and `changes()`. ([#2342](https://github.com/pouchdb/pouchdb/issues/2342))
- * Performance improvements. ([#2391](https://github.com/pouchdb/pouchdb/issues/2391), [#2392](https://github.com/pouchdb/pouchdb/issues/2392), [#2393](https://github.com/pouchdb/pouchdb/issues/2393))
- * MD5 hashes are now calculated incrementally in a way that won't freeze the DOM. ([#445](https://github.com/pouchdb/pouchdb/issues/445), [#2497](https://github.com/pouchdb/pouchdb/issues/2497))
- * More efficient replication. ([#2466](https://github.com/pouchdb/pouchdb/issues/2466), [#2475](https://github.com/pouchdb/pouchdb/issues/2475))
-
-
-### Bugfixes:
-
- * Fix for replication of multiple attachments. ([#2358](https://github.com/pouchdb/pouchdb/issues/2358))
- * Fix for `bulkDocs()` in Cloudant. ([#2365](https://github.com/pouchdb/pouchdb/issues/2365))
- * Fix read-only replication for CORS/40*. ([#2484](https://github.com/pouchdb/pouchdb/issues/2484))
- * Fix for reserved words in docs. ([#2477](https://github.com/pouchdb/pouchdb/issues/2477))
- * Fixes for `change` events in `.sync()`. ([#2555](https://github.com/pouchdb/pouchdb/issues/2555))
- * Fixes for race condition in bulk docs with `new_edits=false` in LevelDB. ([#2574](https://github.com/pouchdb/pouchdb/issues/2574))
- * Fixes for `opts.stale` in `query()`. ([pouchdb/mapreduce#196](https://github.com/pouchdb/mapreduce/issues/196), [pouchdb/mapreduce#198](https://github.com/pouchdb/mapreduce/issues/198))
-
-###### [Complete list of changes](https://github.com/pouchdb/pouchdb/compare/2.2.3...3.0.0)
diff --git a/docs/_posts/2014-08-16-pouchdb-3.0.1.md b/docs/_posts/2014-08-16-pouchdb-3.0.1.md
deleted file mode 100644
index 0e243e6..0000000
--- a/docs/_posts/2014-08-16-pouchdb-3.0.1.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.1
-
-author: Nolan Lawson
-
----
-
-[PouchDB 3.0.1](https://github.com/pouchdb/pouchdb/releases/tag/3.0.1) is a patch release to fix a migration bug in PouchDB 3.0.0 ([#2456](https://github.com/pouchdb/pouchdb/issues/2456)). Please upgrade your existing users directly from 2.2.3 and do not use 3.0.0.
-
-This release also contains a small performance boost for `bulkDocs()` ([#2553](https://github.com/pouchdb/pouchdb/issues/2553)).
\ No newline at end of file
diff --git a/docs/_posts/2014-08-20-pouchdb-3.0.2.md b/docs/_posts/2014-08-20-pouchdb-3.0.2.md
deleted file mode 100644
index 946b372..0000000
--- a/docs/_posts/2014-08-20-pouchdb-3.0.2.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.2
-
-author: Nolan Lawson
-
----
-
-[PouchDB 3.0.2](https://github.com/pouchdb/pouchdb/releases/tag/3.0.2) is another small patch release, this time to fix a bug in replication of deleted documents ([#2636](https://github.com/pouchdb/pouchdb/issues/2636)).
-
-Other fixes:
-
-* Ensure PouchDB stops writing after replication is over ([#2639](https://github.com/pouchdb/pouchdb/issues/2639))
-* Fix a race condition in LevelDB ([#2631](https://github.com/pouchdb/pouchdb/issues/2631))
-* Allow special URI characters in doc IDs ([#2651](https://github.com/pouchdb/pouchdb/issues/2651))
\ No newline at end of file
diff --git a/docs/_posts/2014-08-29-pouchdb-3.0.3.md b/docs/_posts/2014-08-29-pouchdb-3.0.3.md
deleted file mode 100644
index 150cd39..0000000
--- a/docs/_posts/2014-08-29-pouchdb-3.0.3.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.3
-
-author: Nolan Lawson
-
----
-
-Another week, another PouchDB patch release!
-
-This week we present [PouchDB 3.0.3](https://github.com/pouchdb/pouchdb/releases/tag/3.0.3), which fixes some ornery issues with replication that were introduced by recent performance optimizations ([#2685](https://github.com/pouchdb/pouchdb/issues/2685)).
-
-In fact, those performance optimizations have been rolled back. The current implementation appears to be the fastest possible given CouchDB's replication protocol, and the clever tricks introduced in 3.0.0 actually pushed conflicts into CouchDB's revision history, which is bad news for apps that rely on custom conflict resolution. (If you just use the default "pick a random winner," you probably didn't notice anything.)
-
-And although "custom conflict resolution" may only describe a minority of apps, we felt it's better to be correct 100% of the time than to be speedy.
-
-### Dealing with slow replication
-
-If you experience slow replications after upgrading to 3.0.3, here are some suggestions:
-
-1. Avoid CORS if you can, because it uses twice as many HTTP requests. Some tips for doing this:
-    * If you are using IrisCouch, you can [create a couchapp](https://github.com/couchapp/couchapp) (i.e. let CouchDB serve your HTML/CSS/JS).
-    * If you are running your own CouchDB, you can set up a reverse proxy with Apache or Nginx that allows you to serve your app and CouchDB from the same domain. Or create a couchapp.
-2. Try using the "every doc is a delta" pattern, as described in [this blog post](http://atypical.net/archive/2014/04/17/understanding-race-induced-conflicts-in-bigcouch) and exemplified in [the delta-pouch plugin](https://github.com/redgeoff/delta-pouch). Your replications will be much faster, because PouchDB is able to use an optimization for generation-1 documents, and in this setup, every document is a generation-1 document.
-3. Otherwise, just minimize the number of documents you create. Or minimize the number of documents you sync to the client. Views can be helpful with this, although the low performance of the `query()` API relative to the `allDocs()` API should be balanced with that.
-
-### Other fixes in 3.0.3
-
-* Auto-compaction is no longer experimental! It's fully supported. ([#2655](https://github.com/pouchdb/pouchdb/issues/2655))
-* `'change'` listeners aren't called after replication is canceled. ([#2478](https://github.com/pouchdb/pouchdb/issues/2478))
-* Bower package is smaller. ([#2659](https://github.com/pouchdb/pouchdb/issues/2659))
\ No newline at end of file
diff --git a/docs/_posts/2014-09-04-pouchdb-3.0.4.md b/docs/_posts/2014-09-04-pouchdb-3.0.4.md
deleted file mode 100644
index 455fd14..0000000
--- a/docs/_posts/2014-09-04-pouchdb-3.0.4.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.4&#58; Night of the Living Attachments
-
-author: Calvin Metcalf
-
----
-
-This week we present [PouchDB 3.0.4](https://github.com/pouchdb/pouchdb/releases/tag/3.0.4), which fixes a bunch of stuff with attachments. Now the kittens generated by the [3.0.0 release](http://pouchdb.com/2014/08/12/pouchdb-3.0.0.html) may be safely stored in Pouch.
-
-{% include img.html src="kittens_small.jpg" alt="Kittens" %}
-
-### Attachmentspalooza
-
-- In Firefox, different attachments now (correctly) have different MD5 hashes. Previously they were just hashes of the string `'[Object] object'`.  With this, we also now check that the hashes we produce are identical to the ones that CouchDB produces (with the exception of plaintext ones due to Erlang being weird and not having ASCII strings) ([#2698](https://github.com/pouchdb/pouchdb/issues/2698)).
-- Weirdness in Chrome 37-39 with FileReader and empty blobs is now fixed ([#2713](https://github.com/pouchdb/pouchdb/issues/2713)).
-- Fix for [a bug in Chrome 37](https://code.google.com/p/chromium/issues/detail?id=408120) relating to blobs in IndexedDB ([#2701](https://github.com/pouchdb/pouchdb/issues/2701)).
-- HTTP pouches now support buffer/blob data in attachments ([#2577](https://github.com/pouchdb/pouchdb/issues/2577)).
-
-### Other fixes in 3.0.4
-
-* When running sync, it only creates one instance for each database ([#2662](https://github.com/pouchdb/pouchdb/pull/2662)).
-* Performance improvements for persisted map/reduce, and it also uses less space ([pouchdb/mapreduce#191](https://github.com/pouchdb/mapreduce/pull/191) and [pouchdb/mapreduce#185](https://github.com/pouchdb/mapreduce/issues/185)).
diff --git a/docs/_posts/2014-09-07-pouchdb-3.0.5.md b/docs/_posts/2014-09-07-pouchdb-3.0.5.md
deleted file mode 100644
index 3134ac5..0000000
--- a/docs/_posts/2014-09-07-pouchdb-3.0.5.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.5&#58; Turtles All the Way Down
-
-author: Nolan Lawson
-
----
-
-Tonight our fine dining selection is [PouchDB 3.0.5](https://github.com/pouchdb/pouchdb/releases/tag/3.0.5), which fixes some issues with excessive recursion and also `PouchDB.sync` not always working correctly.
-
-### PouchDB.sync un-borked ([#2735](https://github.com/pouchdb/pouchdb/issues/2735))
-
-You can now call `PouchDB.sync('mydb', 'http://localhost:5984/mydb')` using just the database names.
-
-Less typing === more win.
-
-### No more infinite recursion ([#2543](https://github.com/pouchdb/pouchdb/issues/2543))
-
-You can now have as many revisions to your documents as you want, and you'll no longer descend _Inception_-style into a "too much recursion" or "maximum call stack" error.
-
-We literally wrote [a custom JSON parser](https://github.com/nolanlawson/vuvuzela) to fix this. That's how much we love you.
-
-### Notes on excessive revision histories
-
-The ["infinite recursion" bug](https://github.com/pouchdb/pouchdb/issues/2543) shows up when you have many (> 1000) revisions to the same document. For instance, imagine a text editor that `put()`s a new version of the document for every keystroke. This is fine in traditional databases, but it can be a big problem in PouchDB/CouchDB, because we store the entire history of the database.
-
-Make no mistake: inifinitely-large revision histories will now work in PouchDB 3.0.5. However, it's a lot like riding a bicycle without a helmet: you _can_ do it, but you probably shouldn't.
-
-Your mental model for this can be something like Git. Imagine a new `git commit` for every keystroke, and you'll see why it might be a bit problematic.
-
-```js
-{ "text": "The quick brown fox jumps over the lazy doge." }
-{ "text": "The quick brown fox jumps over the lazy doge" }
-{ "text": "The quick brown fox jumps over the lazy dog" }
-//
-// 40 revisions earlier ...
-//
-{ "text": "The q" }
-{ "text": "The " }
-{ "text": "The" }
-{ "text": "Th" }
-{ "text": "T" }
-```
-
-Of course, you can always `compact()` to remove old versions, but this just removes the document data. PouchDB still needs to maintain a permanent tree of the `_rev` hashes in order for the replication algorithm to work properly. If this tree grows excessively, it can bloat your database, whether or not you do compaction.
-
-What this means is that you should be very careful about updating your documents. Try to update your documents in larger batches, or use a pattern like [delta-pouch](https://github.com/redgeoff/delta-pouch) to avoid creating new revisions altogether.
\ No newline at end of file
diff --git a/docs/_posts/2014-09-22-3.0.6.md b/docs/_posts/2014-09-22-3.0.6.md
deleted file mode 100644
index 514cbe7..0000000
--- a/docs/_posts/2014-09-22-3.0.6.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.0.6&#58; Safari Madness
-
-author: Nolan Lawson
-
----
-
-As Cupertino fans snuggle up to their bigger and better iDevices, PouchDB users will appreciate [PouchDB 3.0.6](https://github.com/pouchdb/pouchdb/releases/tag/3.0.6). This release contains a workaround for [some unforeseen hiccups](https://github.com/pouchdb/pouchdb/issues/2533) in Apple's new implementation of IndexedDB for Safari 7.1 and iOS 8.
-
-{% include img.html src="apple-indexeddb.png" alt="Apple introduces IndexedDB support" %}
-
-All joking aside, we are happy to welcome Apple to the IndexedDB party (better late than never!), and [we are working with the WebKit devs](https://bugs.webkit.org/show_bug.cgi?id=136888) to resolve the issue. In the meantime, PouchDB 3.0.6 provides a workaround where we fall back to Web SQL on Apple browsers.
-
-Other fixes in this release:
-------
-
-* `db.compact()` performance improvements ([#2623](https://github.com/pouchdb/pouchdb/pull/2623))
-* Ensure attachments work after Chrome 38 upgrade ([#2773](https://github.com/pouchdb/pouchdb/issues/2773))
-* Invalid/unauthorized documents no longer halt replication ([#2268](https://github.com/pouchdb/pouchdb/issues/2268))
-* Filtering no longer halts replication ([#2689](https://github.com/pouchdb/pouchdb/issues/2689))
-* Update lie dependency to [2.8.0](https://github.com/calvinmetcalf/lie/releases/tag/2.8.0)
-
-New features in this release:
---------
-
-* `db.info()` shows whether `auto_compaction` is set ([#2744](https://github.com/pouchdb/pouchdb/issues/2744))
-
-An aside on browser compatibility
---------
-
-From the get-go, PouchDB's goal was to work seamlessly on every browser, with one API to rule them all. I like to call it the "jQuery for databases" approach.
-
-In practice, this is pretty tough to achieve. I poke fun at Apple, but there are also bugs in IE's implementation of IndexedDB ([here](https://connect.microsoft.com/IE/feedbackdetail/view/866495) [are](https://connect.microsoft.com/IE/feedbackdetail/view/866489) [three](https://connect.microsoft.com/IE/feedbackdetail/view/866474)), Firefox's implementation ([this one](https://bugzilla.mozilla.org/show_bug.cgi?id=701634)), and Chrome's implementation ([these](https://code.google.com/p/chromium/issues/detail?id=408120) [two](https://code.google.com/p/chromium/issues/detail?id=108012)). Additionally, some Android devices ship with [an outdated version of IndexedDB](https://github.com/pouchdb/pouchdb/issues/1207) in the notoriously non-evergreen "stock" browser.
-
-And that's just IndexedDB! Don't even get me started on Web SQL. Here's just a small taste:
-
- * [UTF-8 vs UTF-16 encoding on Chrome vs Safari](https://github.com/pouchdb/pouchdb/pull/1733#issuecomment-38723096)
- * [Null character causes string truncation](https://github.com/pouchdb/pouchdb/pull/1731#issuecomment-38622342)
- * [Cannot use Promises, or the transaction ends early](https://github.com/pouchdb/pouchdb/pull/2536#issuecomment-50435837)
-
-We've written workarounds for all these issues in PouchDB, so that you, dear developer, need never worry your pretty head about them.
-
-So this new Safari/iOS bug doesn't phase us. If we were keeping score, this would probably be workaround #72 by now. We're used to it.
-
-However, that doesn't mean we should get complacent. All of these bugs are opportunities to hold browser vendors' feet to the fire, so that eventually the hacks and workarounds are no longer necessary. You don't want to have to download 10KB of workarounds just to use the native HTML5 APIs. And nobody wants to see HTML5 sink under the weight of browser quirks and non-compliance.
-
-We look forward to removing most of these workarounds from PouchDB (including Web SQL support!), so making some noise in the Microsoft/Mozilla/Chromium/WebKit bug trackers is a great way to get there. Submitting test cases and pull requests is even better.
-
-Thanks to [Elmer Bulthuis](https://github.com/elmerbulthuis) and [Kyaw Tun](https://github.com/yathit) for finding reproducible test cases to submit to the WebKit devs. Let's move the web forward!
-
-And as always, thanks to [our new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors).
diff --git a/docs/_posts/2014-10-26-10-things-i-learned-from-reading-and-writing-the-pouchdb-source.md b/docs/_posts/2014-10-26-10-things-i-learned-from-reading-and-writing-the-pouchdb-source.md
deleted file mode 100644
index 17f82f9..0000000
--- a/docs/_posts/2014-10-26-10-things-i-learned-from-reading-and-writing-the-pouchdb-source.md
+++ /dev/null
@@ -1,422 +0,0 @@
----
-layout: post
-
-title: 10 things I learned from reading (and writing) the PouchDB source
-
-author: Nolan Lawson
-
----
-
-In the spirit of [Paul Irish](http://www.paulirish.com/2010/10-things-i-learned-from-the-jquery-source/), here's a list of some surprising things I learned while reading (and writing) the PouchDB source code.
-
-To set the stage: I first joined the project around December of last year, at which point PouchDB was already fairly mature. (The [first commit from Mikeal Rodgers](https://github.com/pouchdb/pouchdb/commit/d600081962d3f54b410e5cfcf78cd413ad94abb9) is already 4 years old!) My own background was mostly in Android development, but I had some knowledge of Web SQL thanks to [a PhoneGap app](http://www.kaahe.org/app/support_en.html) I had worked on.  
-
-The main goals I had with PouchDB were to increase its performance and browser compatibility.  And having dealt with that ugly F-word that haunts the Android ecosystem ("fragmentation"), I figured compatibility in the web dev world couldn't be much worse. Could it?
-
-**Warning: graphic content ahead.** If you've ever been a soldier on the front lines of the browser compatibility war, the following may make you relive some of those past horrors. Be prepared to weep.
-
-Also, if you're not familiar with [LocalStorage](http://www.w3.org/TR/webstorage/), [Web SQL](http://www.w3.org/TR/webdatabase/), or [IndexedDB](http://www.w3.org/TR/IndexedDB/), you may want to read up on those first.
-
-### 1. Nobody can agree on what the Web SQL "estimated size" means
-
-When you open a Web SQL database, you use [openDatabase()](http://www.w3.org/TR/webdatabase/#dom-opendatabase), e.g.:
-
-```js
-var db = openDatabase('documents', '1.0', 'some description', 5000000);
-```
-
-That last parameter is the so-called *estimated size*. And [here's](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/websql.js#L118-L132) how we set it in PouchDB:
-
-```js
-function getSize(opts) {
-  /* ... */
-  var isAndroid = /Android/.test(window.navigator.userAgent);
-  return isAndroid ? 5000000 : 1;
-}
-``` 
-
-User agent sniffing! Yes, we should be ashamed of ourselves. But here's why we do it:
-
-* In modern **Chrome** and **Android 4.4+**, the size is simply ignored. The browser calculates the remaining size on disk and sets a limit based on that.
-* Aha, but in **Android < 4.4**, this is actually a hard limit! So if you ask for 5000000, you'll only ever get 5 MB.
-* Oh, but in **Safari/iOS**, it gets trickier. If you ask for > 5000000, then it will show an [annoying popup](http://pouchdb.com/errors.html#not_enough_space) when the app is first loaded, which is a great way to spook your users. But if you ask for less, then there's another popup when the database reaches 5MB, and  beyond that there's a bug in iOS 7.1 where the browser will no longer show any more popups, so you're forever capped at 10MB. To store more than 10MB, you need to ask for more than 10MB up-front.
-* Additionally, if you specify anywhere between 0 and 5000000, Safari and iOS will use that size as a hint for when, precisely, to show the popup. And in the case of PouchDB, we need to avoid the popup in our automated tests, because Selenium doesn't give us a way to press the "OK" button, meaning our tests would just fail if we request too much. So the ideal size to request is 0.
-* However, in **PhantomJS** and older WebKit (Safari ~5), if you request 0, then it will blow up.
-
-For the recored, here's what the dreaded Safari popup looks like:
-
-{% include img.html src="safari_popup.png" alt="annoying Safari popup" %}
-
-So that's why we sniff for Android and only bump the size to 5000000 in those cases. In all other cases, we set it to 1.
-
-Additionally, the W3C has done everyone a disservice by using `5*1024*1024` in [their sample code](http://www.w3.org/TR/webdatabase/#introduction), because this has no relation to the 5MB limit in iOS/Safari. The actual cutoff to avoid the popup is 5000000 (i.e. 5 megabytes, aka 5MB), not `5*1024*1024` (5 *mebibytes*, aka 5MiB). And yet, if you read blog posts and Stack Overflow comments about Web SQL, you'll see the mistaken `1024*1024` repeated all over the place.
-
-
-### 2. IE has race conditions in IndexedDB
-
-Microsoft has a very fast implementation of IndexedDB &ndash; it's a bit slower than Chrome's, but much faster than Firefox's ([here are some tests](https://gist.github.com/nolanlawson/11100235)). However, to get that speed, they must have taken some shortcuts, because both IE10 and IE11 have some [nasty](https://connect.microsoft.com/IE/feedbackdetail/view/1009247) [race](https://connect.microsoft.com/IE/feedbackdetail/view/866489) [conditions](https://connect.microsoft.com/IE/feedbackdetail/view/866495).
-
-Due to that, you'll often see PouchDB code [like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L1369-L1372): 
-
-```js
-//Close open request for "name" database to fix ie delay.
-if (IdbPouch.openReqList[name] && IdbPouch.openReqList[name].result) {
-  IdbPouch.openReqList[name].result.close();
-}
-```
-
-Or code [like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L1390-L1398), where we ensure all "open" and "destroy" operations on the databases are done sequentially:
-
-```js
-taskQueue.queue.push({
-  action: function (thisCallback) {
-    destroy(name, opts, thisCallback);
-  },
-  callback: callback
-});
-```
-
-Or code [like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L1215-L1226), where we keep a cache of all databases by name, since IE will not allow us to open two databases with the same name at the same time:
-
-```js
-var cached = cachedDBs[name];
-
-if (cached) {
-  idb = cached.idb;
-  /* ... */
-}
-```
-
-To their credit, though, the IE team has been [very responsive](https://twitter.com/jacobrossi/status/525715434838827009) to our bug reports, so this might be fixed soon.
-
-
-### 3. Binary data in Web SQL is a mess
-
-At the time the Web SQL spec was hammered out, nothing like [Blobs](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [ArrayBuffers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) had been standardized. SQLite of course has support for the [binary BLOB type](https://www.sqlite.org/datatype3.html), but in order to store binary data in WebSQL, you need to do it the old-fashioned way, and pass in a JavaScript binary string.
-
-This produces two interesting problems:
-
-* There is a bug in both [WebKit](https://bugs.webkit.org/show_bug.cgi?id=137637) and [Chromium](https://code.google.com/p/chromium/issues/detail?id=422690), where the `\u0000` character is treated as a null terminator, and although you can insert and sort on the full string, when you retrieve it, it will be truncated. And since BLOBs must be inserted as binary strings, this means *any binary data containing the 0 byte will be truncated*. The only workaround is to use `SELECT HEX(columnName)`, which returns the full binary data in hexadecimal format.
-* However, `HEX()` presents its own problems, because Safari < 7.1 and iOS < 8 [coerce all strings to UTF-16](https://github.com/pouchdb/pouchdb/pull/1733#issuecomment-38723096), meaning that the hexadecimal format must be parsed differently in UTF-8 browsers (Chrome/Opera/Android as well as modern Safari/iOS) vs. UTF-16 browsers (early Safari/iOS).
-
-Thus you will see fun code [like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/websql.js#L89-L101):
-
-```js
-function parseHexString(str, encoding) {
-  var result = '';
-  var charWidth = encoding === 'UTF-8' ? 2 : 4;
-  for (var i = 0, len = str.length; i < len; i += charWidth) {
-    var substring = str.substring(i, i + charWidth);
-    if (charWidth === 4) { // UTF-16, twiddle the bits
-      substring = substring.substring(2, 4) + substring.substring(0, 2);
-    }
-    result += String.fromCharCode(parseInt(substring, 16));
-  }
-  result = encoding === 'UTF-8' ? decodeUtf8(result) : result;
-  return result;
-}
-```
-
-(That "twiddle the bits" comment is a bit inaccurate; the technical term is, of course, [nibble-swizzling](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/com/android/internal/telephony/IccUtils.java#IccUtils.bcdToString%28byte%5B%5D%2Cint%2Cint%29). In the future we will correct this gross oversight by finding some way to work the word "swizzle" into the source code.)
-
-You'll also see us detect UTF-8 vs. UTF-16 encoding [like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/websql.js#L306-L315):
-
-```js
-function checkDbEncoding(tx) {
-  // check db encoding - utf-8 (chrome, opera) or utf-16 (safari)?
-  tx.executeSql('SELECT dbid, hex(dbid) AS hexId FROM ' + META_STORE, [],
-    function (tx, result) {
-      var id = result.rows.item(0).dbid;
-      var hexId = result.rows.item(0).hexId;
-      encoding = (hexId.length === id.length * 2) ? 'UTF-8' : 'UTF-16';
-    }
-  );
-}
-```
-
-In this code, we know based on the length of the hexadecimal string returned whether the database is UTF-16 or not. So thankfully, because it's feature-detected, this "just works" in Safari 7.1+ and iOS 8+.
-
-As of PouchDB 3.1.0, we will also [avoid hexing entirely](https://github.com/pouchdb/pouchdb/pull/2900) for large binary attachments, because it causes performance problems. The new workaround will be to just remove `\u0000` characters while preserving enough information to put them back in later.
-
-
-### 4. Binary data in IndexedDB is a mess too
-
-IndexedDB, as Web SQL's younger, hipper sibling, is supposed to have native support for Blob objects. In practice, though, Blobs [were not supported in Chrome until v37](https://code.google.com/p/chromium/issues/detail?id=108012), and assuming Apple fixes [the more fundamental problems in IndexedDB](http://www.raymondcamden.com/2014/9/25/IndexedDB-on-iOS-8--Broken-Bad), they also apparently [will not support them](http://html5test.com/s/9b895f1cfb68b0d5.html).
-
-In those cases, PouchDB falls back to storing Blobs as base64-encoded strings. And we use [feature detection to test it](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L1303-L1344):
-
-```js
-try {
-  var blob = utils.createBlob([''], {type: 'image/png'});
-  txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');
-  txn.oncomplete = function () {
-    /* ... */
-    blobSupport = true;
-    /* ... */
-  };
-} catch (err) {
-  blobSupport = false;
-  /* ... */
-}
-```
-
-Ah, but if only it were so easy! It turns out that Chrome v37 also [implemented Blob support incorrectly](https://code.google.com/p/chromium/issues/detail?id=408120), returning the wrong MIME type when you fetch it. So in Chrome v37, we need to detect the broken blob support, whereas in v38 we can finally start treating it like the other browsers:
-
-```js
-var storedBlob = e.target.result;
-var url = URL.createObjectURL(storedBlob);
-utils.ajax({
-  url: url,
-  cache: true,
-  binary: true
-}, function (err, res) {
-  if (err && err.status === 405) {
-    // firefox won't let us do that. but firefox doesn't
-    // have the blob type bug that Chrome does, so that's ok
-    blobSupport = true;
-  } else {
-    blobSupport = !!(res && res.type === 'image/png');
-  }
-});
-```
-
-And yes, Firefox has [a tiny bug here](https://bugzilla.mozilla.org/show_bug.cgi?id=1081668) as well! Luckily, it's fixed in the nightly build.
-
-So for those keeping score, PouchDB has three different strategies for each of Chrome v36, v37, and v38. And since Android represents different versions of Chromium frozen in amber, all three variations will be out there in the wild for the near future.
-
-
-### 5. IE doesn't support complex keys
-
-CouchDB is one of the grandaddies of NoSQL databases, so unsurprisingly it influenced IndexedDB's design. One of the more useful but tricky features of CouchDB is *complex keys*, [best described by Christopher Lenz](https://connect.microsoft.com/IE/feedbackdetail/view/866474):
-
-> Obvious to Damien [Katz, creator of CouchDB], but not at all obvious to the rest of us: it's fairly simple to make a view that includes both the content of the blog post document, and the content of all the comments associated with that post. The way you do that is by using *complex keys*. Until now we've been using simple string values for the view keys, but in fact they can be arbitrary JSON values, so let's make some use of that:
-
-
-The example given is:
-
-```js
-function(doc) {
-  if (doc.type == "post") {
-    map([doc._id, 0], doc);
-  } else if (doc.type == "comment") {
-    map([doc.post, 1], doc);
-  }
-}
-```
-
-See that? The key is actually an array containing a string and an integer, meaning it would sort first by the string, then by the integer. Cool, right?
-
-This feature [is in the IndexedDB spec](http://www.w3.org/TR/IndexedDB/#key-construct), and would be a great fit for PouchDB, since we're basically trying to rewrite CouchDB on top of IndexedDB. However, in the source code you will see [pseudo-complex keys like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L512-L514):
-
-```js
-docInfo.data._doc_id_rev = docInfo.data._id + "::" + docInfo.data._rev;
-var seqStore = txn.objectStore(BY_SEQ_STORE);
-var index = seqStore.index('_doc_id_rev');
-```
-
-Leading to [gnarly queries like this](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L174-L179):
-
-```js
-var start = docId + "::";
-var end = docId + "::~";
-var index = seqStore.index('_doc_id_rev');
-var range = global.IDBKeyRange.bound(start, end, false, false);
-var seqCursor = index.openCursor(range);
-```
-
-Did we mess up? Nope, it's intentional: we concatenate the strings together, because [IE does not support complex keys](https://connect.microsoft.com/IE/feedbackdetail/view/866474).
-
-This also heavily influenced our design for [persistent map/reduce](http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html), because instead of assuming the underlying database can sort by more than one value, we invented [a toIndexableString() function](https://github.com/pouchdb/collate/blob/0e22e6e833e24ee5d677d73df2620c20b58aba1f/lib/index.js#L116-L165) that converts any JSON object into a big CouchDB-collation-ordered string. Yeah, we went there.
-
-
-### 6. IndexedDB throws an error if you try to iterate backwards with start/end keys
-
-{% include alert/start.html variant="info" %}
-
-{% markdown %}
-
-**Update:** it turned out I just misunderstood the IndexedDB spec. You can actually swap the start and end in the `IDBKeyRange`, and that allows you to iterate backwards in all browsers. [We updated PouchDB accordingly](https://github.com/pouchdb/pouchdb/issues/3488).
-
-{% endmarkdown %}
-
-{% include alert/end.html %}
-
-This is one of those wonderful "bugs" that is actually part of the IndexedDB spec, so it's faithfully reproduced in all three of Firefox, IE, and Chrome. I guess we should be thankful?
-
-Anyway, [here's the code](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L746-L776):
-
-```js
-try {
-  if (start && end) {
-    keyRange = global.IDBKeyRange.bound(start, end, false, !inclusiveEnd);
-  } else if (start) {
-    /* ... */
-  }
-} catch (e) {
-  if (e.name === "DataError" && e.code === 0) {
-    // data error, start is less than end
-    return callback(null, {
-      total_rows : totalRows,
-      offset : opts.skip,
-      rows : []
-    });
-  } else {
-    return callback(errors.error(errors.IDB_ERROR, e.name, e.message));
-  }
-}
-```
-
-In IndexedDB, an error will be thrown for any `IDBKeyRange` where the start is greater than the end, even if you're iterating backwards. We work around this by [manually checking for the end key](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L832-L838):
-
-```js
-if (manualDescEnd) {
-  if (inclusiveEnd && doc.key < manualDescEnd) {
-    return;
-  } else if (!inclusiveEnd && doc.key <= manualDescEnd) {
-    return;
-  }
-}
-```
-
-Luckily, this doesn't really have a big performance impact, except that we fetch one more key than necessary.
-
-### 7. IndexedDB and Web SQL are jealous of other callbacks
-
-In both IndexedDB and Web SQL, you can forget about using [Promises](https://promisesaplus.com/) or even invoking another callback within a transaction. Whenever control is returned to the event loop, [the transaction auto-closes](https://twitter.com/nolanlawson/status/515893338474831872).
-
-So although your own PouchDB-using code can be elegant and Promisey (thanks especially to Calvin Metcalf's work on [lie](https://github.com/calvinmetcalf/lie)), under the hood, PouchDB's own code is pure callback hell.
-
-Here's a taste of [our IndexedDB code](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L209-L635) and [our WebSQL code](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/websql.js#L456-L899). We party like it's 2009, because you'll see lots of callback patterns like this:
-
-```js
-verifyAttachments(function (err) {
-  if (err) {
-    return callback(err);
-  }
-  /* ... */
-});
-```
-
-Or this wannabe `Promise.all()`: 
-
-```js
-function checkDoneWritingDocs() {
-  if (++numDocsWritten === docInfos.length) {
-    complete();
-  }
-}
-```
-
-And if we need to use some other callback API, such as [FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader), we need to be careful to do it outside of the transaction. Hence you'll see functions like [preprocessAttachments()](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/websql.js#L886-L898):
-
-```js
-preprocessAttachments(function () {
-  db.transaction(function (txn) {
-    /* ... */
-  });
-});
-```
-
-Suffice it to say, if we didn't have extensive integration tests, we'd barely be sure the code worked at all.
-
-### 8. Recursion is a double-edged sword
-
-Consider [this code](https://github.com/pouchdb/pouchdb/blob/c32597564160dcaad7b3e715ddf1c0dc923b59cd/lib/adapters/idb.js#L45-L58):
-
-```js
-// Unfortunately, the metadata has to be stringified
-// when it is put into the database, because otherwise
-// IndexedDB can throw errors for deeply-nested objects.
-// Originally we just used JSON.parse/JSON.stringify; now
-// we use this custom vuvuzela library that avoids recursion.
-// If we could do it all over again, we'd probably use a
-// format for the revision trees other than JSON.
-function encodeMetadata(metadata, winningRev, deleted) {
-  var storedObject = {data: vuvuzela.stringify(metadata)};
-  storedObject.winningRev = winningRev;
-  storedObject.deletedOrLocal = deleted ? '1' : '0';
-  storedObject.id = metadata.id;
-  return storedObject;
-}
-```
-
-As it turns out, this is [a very tricky bug](https://github.com/pouchdb/pouchdb/issues/2543) that ended up affecting all browsers, and even Node.js.
-
-The gist is that any native JavaScript function that takes an object as input, such as `JSON.stringify()` or IndexedDB's `put()`, has a maximum limit on the depth of the object  you can pass in. By depth I mean:
-
-```js
-var object = {
-  enhance: {
-    enhance: {
-      enhance: {
-        /* and so on */
-      }
-    }
-  }
-};
-```
-
-The limit itself will vary based on the available memory, but in any case, if you hit that limit, you get a "too much recursion" or "maximum call stack" error. As well as an unhappy PouchDB user.
-
-Calvin and I solved this by writing [a non-recursive JSON library with a silly name](https://github.com/nolanlawson/vuvuzela). It's slower than the native methods, but in cases where we can't afford to have a crash, this code turned out to be a lifesaver.
-
-### 9. In IndexedDB, unique indexes throw constraint errors, but keyPaths don't 
-
-This is one of those counter-intuitive things that probably made sense to IndexedDB creator [Nikunj Mehta](http://blog.o-micron.com/), but surprised the hell out of me.
-
-In SQLite and Web SQL, you can create a table with a primary key:
-
-```sql
-CREATE TABLE employees (id PRIMARY KEY UNIQUE, name);
-```
-
-And you can also add a unique index:
-
-```sql
-CREATE TABLE employees (id, name);
-CREATE UNIQUE INDEX id_index ON employees (id);
-```
-
-And these two are essentially equivalent, because if you try to `INSERT` a row with an `id` that already exists, you'll get a constraint error.
-
-In IndexedDB, however, object stores with primary keys will *not* throw an error upon insertion, but instead silently overwrite the existing object. In other words, the `put()` is an [upsert](http://en.wiktionary.org/wiki/upsert). Unique indexes, however, behave totally differently and will indeed throw.
-
-Here's [a live example](http://bl.ocks.org/nolanlawson/1afe3b5e98e4111c67c4). The big takeaway is that the following two examples are *not* equivalent:
-
-With a primary key:
-
-```js
-db.createObjectStore('employees', {keyPath : 'id'});
-```
-
-With a unique index:
-
-```js
-db.createObjectStore('employees').createIndex('id', 'id', {unique: true});
-```
-
-Better hope you choose the right one the first time! Otherwise you may get a constraint error when you don't expect one, or vice versa.
-
-**Edit:** As pointed out by [Simon Friis Vindum](https://twitter.com/paldepind/status/539012069061033984), you can use `add()` instead of `put()` to get a constraint error with keyPaths. Here's [a live example](http://bl.ocks.org/nolanlawson/c9a4673830de2b185b8b). Thanks for the tip!
-
-### 10. CouchDB influenced IndexedDB influenced LevelDB influenced...
-
-Databases are not designed in a vacuum, and the more I learn about this stuff, the more I find that everything is related somehow.
-
-Web SQL was originally inspired by [Google Gears](http://gearsblog.blogspot.com/2011/03/stopping-gears.html), which in 2008 [was poised](https://code.google.com/p/gears/wiki/GearsHistory) to become the standard for storing data in mobile webapps. And of course neither would have been possible without SQLite, which, according to creator Richard Hipp, [was heavily influenced](http://use-the-index-luke.com/blog/2014-05/what-i-learned-about-sqlite-at-a-postgresql-conference) by PostgreSQL. In fact, I find [his presentation](http://www.pgcon.org/2014/schedule/attachments/319_PGCon2014OpeningKeynote.pdf) especially inspiring, because Hipp's process of using Postgres as a gold standard for building SQLite reminds me a lot of how PouchDB has been molded in CouchDB's image.
-
-And although [the Web SQL spec was eventually abandoned](http://nolanlawson.com/2014/04/26/web-sql-database-in-memoriam/), it certainly influenced its younger sibling IndexedDB. Among other family traits, they share the same asynchronous structure, auto-closing transactions, and security models. (Compare the "security" sections for [both](http://www.w3.org/TR/webdatabase/) [specs](http://www.w3.org/TR/IndexedDB/), and note how much of the language is simply copied over).
-
-Web SQL also lives on indirectly in IndexedDB, given that both [Mozilla's](https://hacks.mozilla.org/2010/06/beyond-html5-database-apis-and-the-road-to-indexeddb/) and [Apple's](https://bugs.webkit.org/show_bug.cgi?id=132176) implementations are independently (!) implemented on top of SQLite.
-
-What's more intriguing is that you can even find [the influence of CouchDB](http://lists.w3.org/Archives/Public/public-webapps/2009AprJun/0106.html) in early discussions of IndexedDB. This might explain features like complex keys, start/end key iteration, and the document-esque data model. Nikunj Mehta [even said way back in 2009](http://t.co/9N6O9qkn4S):
-
-> Some people find [IndexedDB] good for a JavaScript CouchDB.
-
-In a sense, this statement may be the earliest expression of what eventually became PouchDB!
-
-Furthermore, Google went on to create LevelDB as their implementation of the IndexedDB spec, which is currently enjoying [enormous popularity in the Node.js ecosystem](http://dailyjs.com/2013/04/19/leveldb-and-node-1/), especially thanks to [the LevelUP project](https://github.com/rvagg/node-levelup). PouchDB itself [has hopped on the LevelUP bandwagon](http://pouchdb.com/2014/07/25/pouchdb-levels-up.html), and today we have PouchDB Server, which is a nearly-complete implementation of CouchDB's HTTP API, but based on Node.js and LevelDB. 
-
-So from the earliest discussions of IndexedDB, influenced as it was by CouchDB and Web SQL, through LevelDB and the LevelUP ecosystem, we now have a database that unites them all: PouchDB.
-
-When I look through the PouchDB source code, this enormous accomplishment still gives me chills. It's enough to make you overlook all the odd hacks, workarounds, and inelegancies. The fact that PouchDB works at all is a tiny miracle.
diff --git a/docs/_posts/2014-11-10-3.1.0.md b/docs/_posts/2014-11-10-3.1.0.md
deleted file mode 100644
index e9a00b6..0000000
--- a/docs/_posts/2014-11-10-3.1.0.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.1.0&#58; A Guide to Recognizing Your Marsupials (The PouchDB Guide)
-
-author: Dale Harvey
-
----
-
-Today marks the dawn of a new PouchDB release, [3.1.0](https://github.com/pouchdb/pouchdb/releases/tag/3.1.0) is released today with a whole bunch of goodness. Here are some of the highlights:
-
-{% include alert/start.html variant="warning"%}
-This release includes a migration. Your existing database will be updated automatically, but you cannot downgrade to a previous version of PouchDB once you've upgraded.
-{% include alert/end.html %}
-
-### PouchDB Guides ([#2766](https://github.com/pouchdb/pouchdb/issues/2766))
-
-Nolan Lawson and Nick Colley worked together to produce some excellent guides to PouchDB which you can see @ [http://pouchdb.com/guides/](http://pouchdb.com/guides/). They cover a lot of the issues surrounding building PouchDB applications including conflicts and promises vs callbacks. As a bonus the guides as well as the rest of the website [now work offline](https://github.com/pouchdb/pouchdb/issues/2957).
-
-### Compaction removes orphaned attachments ([#2818](https://github.com/pouchdb/pouchdb/issues/2818))
-
-If you have been using attachments in your PouchDB databases, you may have noticed that it was a bit bigger round the waist than it should have been. We now work harder to ensure there isnt any extra things lying around the database taking up space that you no longer need. This change came along with a lot of compaction and attachment related fixes: [#2890](https://github.com/pouchdb/pouchdb/issues/2890), [#2905](https://github.com/pouchdb/pouchdb/issues/2905), [#2951](https://github.com/pouchdb/pouchdb/issues/2951)
-
-### Test against CouchDB master ([#2850](https://github.com/pouchdb/pouchdb/issues/2850))
-
-There is a big change brewing in CouchDB world, [https://issues.apache.org/jira/browse/COUCHDB-1843](https://issues.apache.org/jira/browse/COUCHDB-1843) is in progress to merge the clustered 'BigCouch' merge from Cloudant into CouchDB master. This will represent a big change towards CouchDB however there is no need to worry, we now run all of our tests against the current master CouchDB (and they are all green!) so when the big CouchDB 2.0 release comes, your PouchDB applications will continue to work as well as before.
-
-### In related news
-
-We keep a list of [plugins and related external projects](http://pouchdb.com/external.html) to PouchDB, here are a few new ones we added during this month:
-
- * PouchDB [Dump](https://github.com/nolanlawson/pouchdb-dump-cli) and [Load](https://github.com/nolanlawson/pouchdb-load) are designed to help you load data into your newly started PouchDB app faster than replication will do currently.
- * If you want to use PouchDB with Angular, you are in luck, there are now 4! adapters to help you integrate them: [angular-pouchdb](https://github.com/wspringer/angular-pouchdb), [Factoryng](https://github.com/redgeoff/factoryng), [ngPouch](https://github.com/jrhicks/ngPouch), [ng-pouchdb](https://github.com/danielzen/ng-pouchdb).
- * Ember users arent left in the wild: [ember-pouchdb](https://github.com/taras/ember-pouchdb) should get you going with PouchDB and Ember.
- * If you are using Blobs with PouchDB, you probably want to take a look at [blob-util](https://github.com/nolanlawson/blob-util).
-
-### Bug fixes Galore
-
-Some of the other important fixes include:
-
- * ([#2951](https://github.com/pouchdb/pouchdb/issues/2951)) - fix concurrency in leveldb.js
- * ([#2935](https://github.com/pouchdb/pouchdb/issues/2935)) - new_edits=false works regardless of order
- * ([#2867](https://github.com/pouchdb/pouchdb/issues/2867)) - do not stack notify change listeners
- * ([#2779](https://github.com/pouchdb/pouchdb/issues/2779)) - fix undeletion with wrong rev
- * ([#2794](https://github.com/pouchdb/pouchdb/issues/2794)) - explain normal 404s in console.info
- * ([#2841](https://github.com/pouchdb/pouchdb/issues/2841)) - respect options when making dependent dbs
- * ([#2844](https://github.com/pouchdb/pouchdb/issues/2844)) - Encode attachment names
- * ([#2807](https://github.com/pouchdb/pouchdb/issues/2807)) - auto_compaction properly trims tree
- * ([#2708](https://github.com/pouchdb/pouchdb/issues/2708)) - implement attachment stub length
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). We would also like to give a huge thanks to our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors).
diff --git a/docs/_posts/2014-11-27-testing-pouchdb.md b/docs/_posts/2014-11-27-testing-pouchdb.md
deleted file mode 100644
index b9fac02..0000000
--- a/docs/_posts/2014-11-27-testing-pouchdb.md
+++ /dev/null
@@ -1,66 +0,0 @@
----
-layout: post
-
-title: How we test PouchDB
-
-author: Dale Harvey
-
----
-
-While working on and researching improvements for automated testing in PouchDB, I found a lack of blog posts and general information about how open-source libraries test themselves. With PouchDB, a huge amount of effort has gone into testing, but we haven't talked about it much outside the project. So I wanted to explain a little about our approach.
-
-### How do we test PouchDB?
-
-Every pull request and check-in to the PouchDB repository goes through the following test run:
-
-{% include img.html href="https://travis-ci.org/pouchdb/pouchdb/builds/40528881" src="travis-screenshot.png" alt="Travis Passing Screenshot" %}
-
-This combination of tests takes around 6 hours running time and covers the minimal options we have found to be confident in not introducing regressions. We test PouchDB against plain CouchDB 1.6.0 on the most popular modern browsers and Node.js, as well as testing alternative backends, servers and options (LocalStorage, PouchDB Server, auto-compaction, etc.). Ideally we would run a full matrix of configurations, however we are hitting the upper limit on how long our tests take to run, so we have picked the ones most likely to surface regressions.
-
-### Why care?
-
-Hopefully I don't need to espouse most of the virtues of testing; things that change and aren't tested are usually broken. PouchDB is fairly complex, so we rely on a comprehensive test suite, primarily to ensure we don't introduce regressions as we work on the code.
-
-With PouchDB, however, I have found an added benefit is enabling contributors. By improving our test infrastructure, we make it easier for contributors to have a clear process for verifying behaviour as bugs, writing a failing test and then confirming a fix.
-
-Being confident in your test suite's ability to catch regressions enables us to accept contributions in a reasonable time frame. If we are ever unsure of whether a contribution may break a particular feature, then we use that as an indication to improve the tests in that area, not as a reason to avoid merging the contribution.
-
-### Test library
-
-We use [Mocha](http://mochajs.org/) to write almost all of our tests. Mocha has become pretty much the de-facto library for testing JavaScript, and it has worked really well for us.
-
-If I had one complaint about Mocha, it would be I often find myself seeing `does not equal [object Object]` as its output too often. Some assertion libraries are better than others, but I rarely remember which. We previously used [QUnit](http://qunitjs.com/), but its Node support was sub-par. I experimented with [Tape](https://www.npmjs.org/package/tape) and it was by far the [easiest to get setup to run in the browser and Node](http://substack.net/how_I_write_tests_for_node_and_the_browser), however it is opinionated, and if you deviate from the expected workflow, we found it got in the way more than it helped.
-
-### Test platform
-
-Our tests run on every check-in and PR on [Travis CI](travis-ci.org). Travis an amazing platform; it was easy to get up and running and has been incredibly stable. PouchDB would be nowhere near the state it is today without it.
-
-However, we are beginning to outgrow Travis's free open-source capacity, and the paid options are prohibitively expensive. So we are beginning to look around for self-hosted alternatives, albiet without a lot of options.
-
-[Travis is open-source](https://github.com/travis-ci/travis-ci), however it is not a well-setup project for self-hosting &ndash; there isn't so much as a README to get started with. We previously used [Jenkins](http://jenkins-ci.org/), however I found it a huge maintenance burden. It's very possible someone with more experience in Jenkins could do a better job, though, and I am also keeping an eye on [Strider](http://stridercd.com/) as a possible alternative.
-
-### Test runner
-
-We use [Selenium](http://www.seleniumhq.org/) to drive tests in the browser, and [Saucelabs](https://saucelabs.com/) to run the browsers that we can't run locally. Saucelabs is great, however due to the nature of our tests, we generate a lot of HTTP traffic that needs to be proxied back to Travis, which has been a common point of failure.
-
-We are also finding some platforms (particularly iPhone and Internet Explorer) will become unstable on Saucelabs. The errors almost always come from our code, but it is hard to maintain a reliable test suite when the underlying platform changes and you have little control over it.
-
-Before settling on Selenium, I had previously tried out [Testling](https://ci.testling.com/), and similiarly to Tape it was very easy to get started but opinionated. It was also broken on OSX with pull requests containing fixes that hadn't been touched for months. Selenium had the advantage that it was very widely used, and new frameworks or platforms are likely to have WebDriver support early on.
-
-I have however found Selenium as a project fustrating to use, from the first time visiting [http://www.seleniumhq.org/](http://www.seleniumhq.org/) to understanding what I needed to download and write a first test that started a browser, it was an unclear and confusing process. Even today getting ChromeDriver started correctly gets me confused, also the download cost of 30MB for what is mostly a proxy server is an annoyance.
-
-I would love to see a project wrap up Selenium / ChromeDriver and possibly Cordova / Appium into a nice, well-documented module that installs and boots your browser(ish) platform of choice, ready to be driven by Selenium tests.
-
-### Performance tests
-
-Performance testing has been troublesome for PouchDB. We have a performance test suite, but it has been hard to integrate it into our CI process, which means it is not comprehensive and often forgotten.
-
-The issue with running in CI is that Travis is set up to run one test per commit, and every time there is a change to the test suite, its data needs to be backfilled in order to properly compare versions. There is also the fact that Saucelabs and Travis may change their running environment at any time, which makes comparisons over time useless.
-
-I expect that to fix this, we will need to run the tests on dedicated hardware and give performance tests some ability to choose which version of PouchDB to test, along with some helper scripts to backfill the performance data.
-
-### And done.
-
-Hopefully that gives a little insight into the process and issues we have with testing. It's a long and ongoing process, and I am hoping that the work we do to improve our testing infrastructure can be reused by other projects.
-
-We would love to hear more about the tools, techniques and issues that other similiar projects have come across while working on their tests. If you have anything to share, please send it along to [@pouchdb](https://twitter.com/pouchdb).
diff --git a/docs/_posts/2014-12-04-3.2.0.md b/docs/_posts/2014-12-04-3.2.0.md
deleted file mode 100644
index 651bb04..0000000
--- a/docs/_posts/2014-12-04-3.2.0.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.2.0&#58; To code is human, to debug is divine
-
-author: Nolan Lawson
-
----
-
-Hot on the heels of the last release, we present [3.2.0](https://github.com/pouchdb/pouchdb/releases/tag/3.2.0), which has new features to increase developer productivity, as well as a slew of bugfixes.
-
-
-### New features
-
-* Finally, PouchDB has a [debug mode][]! ([#2874][], [#3084][])
-* You can now use `{attachments: true}` to fetch attachments in `allDocs()`, `changes()`, and `query()`, just like CouchDB 1.6.0+ ([#2771][], [#3074][], [#190][])
-* The `doc_ids` filter is now supported for `changes()` ([#3056][])
-
-### Bugfixes
-
-* Fix conflict during replication of deleted documents ([#2970][])
-* Only detect blob support once ([#2990][])
-* Fix tree-merging algorithm, correctly attach docs to deleted winning revs ([#2888][])
-* Fix compaction-related race condition in LevelDB ([#3026][])
-* Fix LevelDB `bulkDocs()` ordering ([#3062][])
-* Fix WebSQL `put()` local docs when missing ([#3066][])
-* Fix encoding of base64-string attachments over HTTP ([#3008][])
-* Better error for invalid revs ([#2994][])
-* Upgrade Browserify to v6 ([#2884][])
-
-
-### In related news
-
-* [Hoodie &#9829; PouchDB](https://github.com/hoodiehq/wip-hoodie-store-on-pouchdb) (and the feeling is mutual)
-* [crypto-pouch](https://github.com/calvinmetcalf/crypto-pouch), a plugin to encrypt a CouchDB/PouchDB database
-* [Porting Node.js crypto to the browser, part 1](http://calvinmetcalf.com/post/104082905653/porting-node-js-crypto-to-the-browser-part-1-all)
-* [pouchdb-express-router](https://github.com/daleharvey/pouchdb-express-router), the minimum required to replicate PouchDB to an Express server (which will eventually be folded into express-pouchdb and pouchdb-server)
-* [PouchDB performance report for November 2014](https://github.com/nolanlawson/pouchdb-perf-report-3.10#readme)
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
-
-[3.2.0]: https://github.com/pouchdb/pouchdb/releases/tag/3.2.0
-[#2771]: https://github.com/pouchdb/pouchdb/issues/2771
-[#3074]: https://github.com/pouchdb/pouchdb/issues/3074
-[#2874]: https://github.com/pouchdb/pouchdb/issues/2874
-[#3084]: https://github.com/pouchdb/pouchdb/issues/3084
-[#3056]: https://github.com/pouchdb/pouchdb/issues/3056
-[#2970]: https://github.com/pouchdb/pouchdb/issues/2970
-[#2888]: https://github.com/pouchdb/pouchdb/issues/2888
-[#3026]: https://github.com/pouchdb/pouchdb/issues/3026
-[#3062]: https://github.com/pouchdb/pouchdb/issues/3062
-[#3066]: https://github.com/pouchdb/pouchdb/issues/3066
-[#3008]: https://github.com/pouchdb/pouchdb/issues/3008
-[#2994]: https://github.com/pouchdb/pouchdb/issues/2994
-[#2990]: https://github.com/pouchdb/pouchdb/issues/2990
-[#2884]: https://github.com/pouchdb/pouchdb/issues/2884
-[#190]: https://github.com/pouchdb/mapreduce/issues/190
-[debug mode]: /api.html#debug_mode
\ No newline at end of file
diff --git a/docs/_posts/2014-12-11-the-pains-of-being-async-at-heart.md b/docs/_posts/2014-12-11-the-pains-of-being-async-at-heart.md
deleted file mode 100644
index 5203ffc..0000000
--- a/docs/_posts/2014-12-11-the-pains-of-being-async-at-heart.md
+++ /dev/null
@@ -1,115 +0,0 @@
----
-layout: post
-
-title: The Pains Of Being Async At Heart
-
-author: Dale Harvey
-
----
-
-If you are testing JavaScript you will likely have to test against async API's. These bring up some issues that you may not be familiar with if you are used to testing synchronous code. Here are a few things I have learnt working on the PouchDB test suite.
-
-### Always wait for operations to complete before testing their result
-
-This is the 101 of testing async code but it is the foundation for almost every other problem:
-
-```js
-db.put({_id: 'doc', foo: 'bar'});
-db.get('doc').then(function(doc) {
-  assert.equal(doc.foo, 'bar');
-});
-```
-
-While this test may pass (although unlikely) it relies on a broken assumption that the write behind `.put` completes before the read behind `.get`. The proper way to test this is to wait until the `.put` is complete:
-
-```js
-db.put({_id: 'doc', foo: 'bar'}).then(function() {
-  return db.get('doc');
-}).then(function(doc) {
-  assert.equal(doc.foo, 'bar');
-});
-```
-
-As a side note [Promises](http://www.html5rocks.com/en/tutorials/es6/promises/) are huge improvement over callbacks for testing async code which by nature often involves a long sequential series of steps.
-
-### `setTimeout` is almost always evil
-
-```js
-// Test that a local write gets synced to remote database
-localDB.sync(remoteDB, {live: true});
-localDB.put({_id: 'doc', foo: 'bar'}).then(function() {
-  setTimeout(function() {
-    remoteDB.get('doc').then(function(doc) {
-      assert.equal(doc.foo, 'bar');
-    });
-  }, 1000);
-});
-```
-
-The main issue with `setTimeout` is that nothing is guaranteed to complete before the `setTimeout` finishes. While testing locally 1000ms may be more than enough time for the sync to do its magic if you start testing against non local database with increased latency that 1000ms will often be too short for the test to pass. The correct way to test this would be to listen for an event or to poll for the value:
-
-```js
-var changes = remoteDB.changes({live: true, include_docs: true});
-changes.on('change', function(change) {
-  assert.equal(change.doc.foo, 'bar');
-  done();
-});
-
-localDB.sync(remoteDB, {live: true});
-localDB.put({_id: 'doc', foo: 'bar'});
-```
-
-The added benefit to this is that your test will complete as soon as possible instead of waiting the full 1000ms on every run.
-
-### I said "almost"
-
-I have found one use case where `setTimeout` is useful and that is to "prove a negative". This is a test that will pass if the `setTimeout` ran immediately, for example:
-
-```js
-// Test we only receive one change event for a write
-var numChanges = 0;
-var changes = db.changes({live: true, include_docs: true});
-changes.on('change', function(change) {
-  numChanges++;
-  setTimeout(function() {
-    assert.equal(numChanges, 1);
-    done();
-  }, 500);
-});
-```
-
-Try going through your tests and change any `setTimeout` to `setTimeout(fun, 0);`. If your test fails then it is likely broken.
-
-### You should ensure your test is really really finished
-
-This has been a very tricky issue in PouchDB. You want to make sure that when you call `done()` on a test that you are absolutely finished with any processing otherwise your test may effect follow on tests, to take the previous example:
-
-```js
-var changes = db.changes({live: true, include_docs: true});
-changes.on('change', function(change) {
-  assert.equal(change.doc.foo, 'bar');
-  changes.cancel();
-  done();
-});
-
-db.put({_id: 'doc', foo: 'bar'});
-```
-
-This test looks fine however inside `changes.cancel()` we may be doing some processing that happens asynchronously, specifically we may be aborting a HTTP request that we haven't processed the reply of yet and as we process the reply the next test may have started. This type of issue is extremely problematic as it can lead to unexpected behavour in tests that are not the cause of the problem.
-
-In PouchDB we fix this with:
-
-```js
-var changes = db.changes({live: true, include_docs: true});
-changes.on('change', function(change) {
-  assert.equal(change.doc.foo, 'bar');
-  changes.cancel();
-});
-changes.on('complete', done);
-
-db.put({_id: 'doc', foo: 'bar'});
-```
-
-The `complete` event is fired when we are sure we have dealt with all the processing involved in that changes event listener and so we know the test is completed any processing when we call `done()`.
-
-There are lots of issues when testing JavaScript but this hits on a few of the main issues we have had in PouchDB. I hope its helpful and would love to hear some issues you may have had with it.
diff --git a/docs/_posts/2015-01-05-pouchdb-3.2.1-you-can-always-be-faster.md b/docs/_posts/2015-01-05-pouchdb-3.2.1-you-can-always-be-faster.md
deleted file mode 100644
index ef97084..0000000
--- a/docs/_posts/2015-01-05-pouchdb-3.2.1-you-can-always-be-faster.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.2.1&#58; You can always be faster
-
-author: Nolan Lawson
-
----
-
-A humble release to ring in the new year, PouchDB 3.2.1 is focused on bugfixes and performance improvements. In particular, 3.2.1 boasts some critical fixes for IE11 and node-webkit, as well as a fix for replication of conflicted documents.
-
-{% include alert/start.html variant="warning"%}
-This release contains a database migration, which means that once you upgrade you will no longer be able to use previous versions of PouchDB on the same databases.
-{% include alert/end.html %}
-
-### Gotta go fast
-
-For performance, the biggest gains will be seen in secondary indexes and auto-compaction. Auto-compaction now occurs in the same transaction as `bulkDocs`, which speeds up the build time for secondary indexes (since they use auto-compaction under the hood). This also means that [pouchdb-quick-search](https://github.com/nolanlawson/pouchdb-quick-search) will be faster.
-
-In addition, the LevelDB adapter now makes all its `bulkDocs` writes inside a single `batch` operation. This means that PouchDB can now provide the same consistency guarantees in both Node.js and the browser, since the LevelDB adapter is using the same transactional model as IndexedDB and WebSQL. Also, using a single `batch` boosts the write performance of LevelDB.
-
-A performance comparison between 3.2.0 and 3.2.1 can be found in [this report](https://gist.github.com/nolanlawson/bc6fd6240db820a36a49). The build times for secondary indexes have been reduced by 37%-57%, depending on the browser and environment.
-
-### CouchDB 2.0 is coming
-
-A big shout-out this release goes to [Will Holley](https://github.com/willholley), who has been tirelessly fixing bugs in the PouchDB test suite so that it can pass against CouchDB master. Not only does this improve PouchDB's test coverage against Cloudant, but it also better prepares us for the (soonish!) release of CouchDB 2.0. Thanks, Will!
-
-### PouchDB Server is getting awesome
-
-And if you haven't checked out [PouchDB Server](https://github.com/pouchdb/pouchdb-server/) or [express-pouchdb](https://github.com/pouchdb/express-pouchdb) recently, you'll be pleased to see that [Marten de Vries](https://github.com/marten-de-vries) has made a ton of improvements over there, including cleaner configuration via `config.json`, authentication support, a `--proxy` option, CouchDB-style logging, "modes" to choose different CouchDB server features, and more. Just `$ npm install -g pouchdb-server && pouchdb-server` to try it out!
-
-### Full changelog:
-
-#### Bugfixes
-
-* `leveldown` is now an optional dependency in Node.js due to build issues with Windows ([#3113](https://github.com/pouchdb/pouchdb/issues/3113))
-* Avoid call stack exceeded errors in the merge algorithm ([#2543](https://github.com/pouchdb/pouchdb/issues/2543))
-* Properly destroy MemDOWN-based databases ([#3144](https://github.com/pouchdb/pouchdb/issues/3144))
-* Avoid "too many listeners" errors in `changes()` ([#2867](https://github.com/pouchdb/pouchdb/issues/2867))
-* Non-winning conflicts properly replicated ([#3136](https://github.com/pouchdb/pouchdb/issues/3136))
-* Fixes for node-webkit ([#3229](https://github.com/pouchdb/pouchdb/issues/3229))
-* LevelDB uses a read queue to prevent database corruption ([#3251](https://github.com/pouchdb/pouchdb/issues/3251))
-* Can build and test on Windows ([#2143](https://github.com/pouchdb/pouchdb/issues/2143))
-* Avoid http header error in IE11 ([#3278](https://github.com/pouchdb/pouchdb/issues/3278))
-* Blobs are stored more efficiently in Chrome 38+ ([#3326](https://github.com/pouchdb/pouchdb/issues/3326) [#3325](https://github.com/pouchdb/pouchdb/issues/3325))
-* Many fixes to the test suite to better support CouchDB master ([#136](https://github.com/pouchdb/pouchdb/issues/136))
-* Fix replication when `skipSetup` is true ([#2915](https://github.com/pouchdb/pouchdb/issues/2915))
-* Fixes for webpack ([#3287](https://github.com/pouchdb/pouchdb/issues/3287))
-* `auto_compaction` is correctly reported in `info()` ([#3345](https://github.com/pouchdb/pouchdb/issues/3345))
-
-#### Performance improvements
-
-* Replication doesn't make unnecessary `allDocs()` calls ([#3153](https://github.com/pouchdb/pouchdb/issues/3153))
-* Replication GET requests issued in parallel ([#3015](https://github.com/pouchdb/pouchdb/issues/3015))
-* Auto-compaction occurs in same transaction as writes ([#3089](https://github.com/pouchdb/pouchdb/issues/3089))
-* Formal one-time IndexedDB migration, cleaner schema ([#3211](https://github.com/pouchdb/pouchdb/issues/3211), [#3182](https://github.com/pouchdb/pouchdb/issues/3182))
-* IndexedDB doesn't store duplicated id/rev ([#3213](https://github.com/pouchdb/pouchdb/issues/3213))
-* Fall back from JSON to vuvuzela to improve parse/stringify ([#3188](https://github.com/pouchdb/pouchdb/issues/3188))
-* LevelDB makes changes in a single batch ([#1738](https://github.com/pouchdb/pouchdb/issues/1738))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-02-03-fix-up-look-sharp.md b/docs/_posts/2015-02-03-fix-up-look-sharp.md
deleted file mode 100644
index 382c208..0000000
--- a/docs/_posts/2015-02-03-fix-up-look-sharp.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.3.0&#58; Fix Up, Look Sharp
-author: Dale Harvey
-
----
-
-A new month means a new PouchDB release. Over the last month we have been looking around the rough edges and cleaning things up or chopping them off along with the usual slew of bugfixes and a lot of great news.
-
-### PouchDB-Inspector
-
-[Marten de Vries](https://twitter.com/commandoline) has taken the awesome work done by the CouchDB Fauxton team and wrapped Fauxton up in Firefox and Chrome plugins so you can inspect your local data in each browser.
-
- * [Install as Firefox Addon](https://addons.mozilla.org/firefox/addon/pouchdb-inspector/) - [Github](https://github.com/marten-de-vries/pouchdb-fauxton-firefox-addon)
- * [Install from Chrome Web Store](https://chrome.google.com/webstore/detail/pouchdb-inspector/hbhhpaojmpfimakffndmpmpndcmonkfa) - [Github](https://github.com/marten-de-vries/pouchdb-fauxton-chrome-extension)
-
-### PouchDB-Find
-
-A few months ago Cloudant released a preview of [Mango](https://github.com/cloudant/mango), a MongoDB-inspired query API for Cloudant and CouchDB. The MapReduce API exposed by CouchDB has long been a source of confusion for developers, and this will hopefully provide a more natural way to query data held within CouchDB / PouchDB.
-
-Nolan Lawson took on the mantle and has developed an implementation of Mango for PouchDB. It is currently in beta, and you can try it out [as a plugin](https://github.com/nolanlawson/pouchdb-find), try the [live demo](http://nolanlawson.github.io/pouchdb-find/) or even test it by installing [PouchDB-Server](https://github.com/pouchdb/pouchdb-server).
-
-### In other news
-
-The excellent team at [CozyCloud](https://www.cozycloud.cc/) have been working on a web-based email application that you can run on a personal server based on PouchDB and ReactJS @ [https://www.npmjs.com/package/emails](https://www.npmjs.com/package/emails). Yours truly will be speaking about PouchDB and the offline web at [Web Rebels in Oslo](https://www.webrebels.org/speakers#daleharvey) and the [Hood.ie](http://hood.ie/) team are working on 1. [migrating their data storage to PouchDB](https://github.com/hoodiehq/wip-hoodie-store-on-pouchdb) and 2. [extracting some of PouchDB's test setup to be reusable](https://github.com/gr2m/testmate). Contributions and discussion always welcome.
-
-## Release Changes
-
-### Sync Events - [#3155](https://github.com/pouchdb/pouchdb/issues/3155)
-
-We have introduced [new events](/api.html#replication) to give you more information what is happening during syncing. There are now `active` and `paused` events triggered during replication and the `uptodate` event is now deprecated.
-
-### Retry Replication - [#966](https://github.com/pouchdb/pouchdb/issues/966)
-
-Calvin did the base work for this a long time ago, however we now officially support a `retry` option to replication. If you do a `db.replicate(to, {retry: true})` or `db.sync(db, {retry: true})` then the replication process will not halt when you go offline, and will automatically resume when you (or your server) comes back online.
-
-### Docs property in change events - [#3358](https://github.com/pouchdb/pouchdb/pull/3358)
-
-A lot of developers wanted to know what documents were being referred to when they recieved a change event. Gregor from hood.ie implemented a new `docs` property in the change event, so you know exactly what documents have changed.
-
-### local_seq now deprecated - [#3367](https://github.com/pouchdb/pouchdb/issues/3367)
-
-`local_seq` was a rarely used property that will be unsupported in CouchDB 2.0, so we have deprecated it and will be removed in future versions.
-
-### Changelog:
-
-* We now have all tests passing against CouchDB master ([#136](https://github.com/pouchdb/pouchdb/issues/136))
-* Fixed return of `.compact` ([#3350](https://github.com/pouchdb/pouchdb/issues/3350))
-* Fix a typo in the Error constructor ([#1167](https://github.com/pouchdb/pouchdb/issues/1167))
-* Disabled blob support due to bugs in Chrome, so we now use base64 for attachments in Chrome ([#3369](https://github.com/pouchdb/pouchdb/issues/3369))
-* Fix races in `.destroy()` ([mapreduce/#251](https://github.com/pouchdb/mapreduce/issues/251))
-* Ensure both replications are cancelled properly during `.sync` ([#3431](https://github.com/pouchdb/pouchdb/issues/3431))
-* Replace ajax calls with `request` polyfill ([#3200](https://github.com/pouchdb/pouchdb/issues/3200))
-* Prefer readAsArrayBuffer to BinaryString ([#3379](https://github.com/pouchdb/pouchdb/issues/3379))
-* Get all tests green on Travis (including iPhone and IE)  ([#3058](https://github.com/pouchdb/pouchdb/issues/3058))
-* Map/reduce views built concurrently ([pouchdb/mapreduce#240](https://github.com/pouchdb/mapreduce/issues/240))
-* Quicker map/reduce view build times ([pouchdb/mapreduce#242](https://github.com/pouchdb/mapreduce/issues/242))
-
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-02-14-a-quick-one.md b/docs/_posts/2015-02-14-a-quick-one.md
deleted file mode 100644
index 42cb266..0000000
--- a/docs/_posts/2015-02-14-a-quick-one.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.3.1&#58; A quick one while he's away
-author: Nolan Lawson
-
----
-
-This is a quick release, ahead of our normal monthly release schedule, to fix some critical bugs and ship them out sooner to our eager PouchDB fanbase.
-
-### Bugfixes
-
-* Fixed live replication of conflicting revisions ([#3179](https://github.com/pouchdb/pouchdb/issues/3179))
-* Fixed in-memory/localStorage plugins ([#3528](https://github.com/pouchdb/pouchdb/issues/3528))
-* Fixed [SQLite Plugin][] support ([#3505](https://github.com/pouchdb/pouchdb/issues/3505))
-* Fixed web worker support (beware [cross-browser issues](https://github.com/pouchdb/pouchdb/issues/2806), though) ([#3314](https://github.com/pouchdb/pouchdb/issues/3314))
-
-### New stuff
-
-* Debugging details added to `db.info()` ([#3398](https://github.com/pouchdb/pouchdb/issues/3398))
-* PouchDB blog as an RSS feed ([#3516](https://github.com/pouchdb/pouchdb/issues/3516))
-* Testing Couchbase Sync Gateway in Travis ([#3526](https://github.com/pouchdb/pouchdb/issues/3526))
-
-### Debugging details
-
-As noted above, `db.info()` now provides adapter-specific debugging info, such as:
-
-* `idb_attachment_format`: (IndexedDB) either `'base64'` or `'binary'`, depending on whether the browser [supports binary blobs](/faq.html#data_types).
-* `sqlite_plugin`: (WebSQL) true if the [SQLite Plugin][] is being used.
-* `websql_encoding`: (WebSQL) either `'UTF-8'` or `'UTF-16'`, depending on the [WebSQL implementation](http://pouchdb.com/faq.html#data_types)
-
-This should not be considered a stable API, since it's only for debugging and could change at any time.
-
-### RSS feed
-
-Thanks to Nick Colley, the PouchDB blog is now available as an RSS feed! Point your RSS reader over to [pouchdb.com/feed.xml](http://pouchdb.com/feed.xml) and get notified whenever a new PouchDB version is released.
-
-### Couchbase Sync Gateway
-
-The goal of PouchDB is to work seamlessly with any server that's CouchDB-compliant. And thanks to some help from J. Chris Anderson over at Couchbase, we are slowly improving our support for Couchbase Sync Gateway!
-
-The current status is that CSG is being tested in Travis, but not all the tests are succeeding yet. So the next step is to start whittling away the failing tests. In the meantime, we recommend that CSG users who experience any problems (most likely with [attachment support](https://github.com/pouchdb/pouchdb/issues/2832)) should replicate from PouchDB to CouchDB, then from CouchDB to CSG.
-
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
-
-[SQLite Plugin]: https://github.com/brodysoft/Cordova-SQLitePlugin
diff --git a/docs/_posts/2015-02-28-efficiently-managing-ui-state-in-pouchdb.md b/docs/_posts/2015-02-28-efficiently-managing-ui-state-in-pouchdb.md
deleted file mode 100644
index 0a3738a..0000000
--- a/docs/_posts/2015-02-28-efficiently-managing-ui-state-in-pouchdb.md
+++ /dev/null
@@ -1,128 +0,0 @@
----
-layout: post
-
-title: Efficiently managing UI state with PouchDB
-
-author: Nolan Lawson
-
----
-
-A common pattern in data-driven apps is to display the entire database in the UI. If you're using PouchDB, that means you want to mirror the contents of PouchDB to some in-memory representation used by the UI.
-
-This could apply to any JavaScript framework such as React, Ember, or Angular. But whatever framework we choose, we'd like to use PouchDB in an efficient way, so that the UI does as little work as possible. Let's learn how.
-
-First off, let's say you are sorting all your documents by `_id`. You might have a database:
-
-```js
-var db = new PouchDB('my_db');
-```
-
-And a function to fetch all the documents (using `allDocs()`) and then render them:
-
-```js
-function fetchAndRenderAllDocs() {
-  db.allDocs({include_docs: true}).then(function (res) {
-    var docs = res.rows.map(function (row) { return row.doc; });  
-    renderDocsSomehow(docs);
-  }).catch(console.log.bind(console));
-}
-```
-
-This is okay, but it would be better if the UI could update automatically whenever a document is changed.
-
-A naïve implementation might look like this:
-
-```js
-db.changes({live: true, since: 'now'}).on('change', function () {
-  fetchAndRenderAllDocs();
-}).on('error', console.log.bind(console));
-
-fetchAndRenderAllDocs();
-```
-
-This code works, but now we are re-fetching the documents every time a single document changes. This can get pretty slow, especially if you have a lot of documents, because you are constantly re-reading the entire database into memory.
-
-Wouldn't it be better if we could update only the part of the `docs` array that actually changed? Yes, and we can!
-
-The PouchDB changes feed has a `{include_docs: true}` option, which will give us exactly the document that changed. There is also a `deleted` flag that tells us if a document was deleted. So let's react to that:
-
-```js
-var docs;
-
-function fetchInitialDocs() {
-  return db.allDocs({include_docs: true}).then(function (res) {
-    docs = res.rows.map(function (row) { return row.doc; });
-    renderDocsSomehow();
-  });
-}
-
-function reactToChanges() {
-  db.changes({live: true, since: 'now', include_docs: true}).on('change', function (change) {
-    if (change.deleted) {
-      // change.id holds the deleted id
-      onDeleted(change.id);
-    } else { // updated/inserted
-      // change.doc holds the new doc
-      onUpdatedOrInserted(change.doc);
-    }
-    renderDocsSomehow();
-  }).on('error', console.log.bind(console));
-}
-
-fetchInitialDocs().then(reactToChanges).catch(console.log.bind(console));
-```
-
-Now, we need some way to update the array after the changes come in. Our documents are already sorted by `_id`, but we want to keep them sorted.
-
-So, let's write a quick binary search implementation:
-
-```js
-function binarySearch(arr, docId) {
-  var low = 0, high = arr.length, mid;
-  while (low < high) {
-    mid = (low + high) >>> 1; // faster version of Math.floor((low + high) / 2)
-    arr[mid]._id < docId ? low = mid + 1 : high = mid
-  }
-  return low;
-}
-```
-
-Now let's implement the `onDeleted()` function:
-
-```js
-function onDeleted(id) {
-  var index = binarySearch(docs, id);
-  var doc = docs[index];
-  if (doc && doc._id === id) {
-    docs.splice(index, 1);
-  }
-}
-```
-
-And the `onUpdatedOrInserted()` function:
-
-```js
-function onUpdatedOrInserted(newDoc) {
-  var index = binarySearch(docs, newDoc._id);
-  var doc = docs[index];
-  if (doc && doc._id === newDoc._id) { // update
-    docs[index] = newDoc;
-  } else { // insert
-    docs.splice(index, 0, newDoc);
-  }
-}
-```
-
-There you have it! Now the `docs` array will be kept perfectly in sync with PouchDB.
-
-And even if you're not displaying the entire database in memory (which may be unfeasible for large databases), you can still use this pattern. You'll just need to change the way you render your initial state (e.g. using a `query()` instead of `allDocs()`), and to filter the documents in your `on('change')` listener. You can either do it directly in code, or you can have PouchDB do it for you with the `filter`/`view`/`doc_ids` options.
-
-{% include alert/start.html variant="info" %}
-
-There's no performance benefit to using <code>filter</code>/<code>view</code>/<code>doc_ids</code> on a local database. With a remote database, however, you may get a performance boost, because it's not sending so much data over the wire.
-
-{% include alert/end.html %}
-
-Another neat thing about this code is that it elegantly handles conflicts. Since `{include_docs: true}` will only give us the *winning* revision of a document, we are guaranteed that we'll never show conflicting versions of the same document in the array. We can still handle conflicts in [the usual way](http://pouchdb.com/guides/conflicts.html), and the changes feed will simply tell us if the winning revision has changed.
-
-I've written [a toy app](http://bl.ocks.org/nolanlawson/3e096160b848689f1058) to demonstrate this code. Feel free to borrow it for your next super-fast PouchDB-powered app.
diff --git a/docs/_posts/2015-03-05-taming-the-async-beast-with-es7.md b/docs/_posts/2015-03-05-taming-the-async-beast-with-es7.md
deleted file mode 100644
index a54f5d0..0000000
--- a/docs/_posts/2015-03-05-taming-the-async-beast-with-es7.md
+++ /dev/null
@@ -1,331 +0,0 @@
----
-layout: post
-
-title: Taming the asynchronous beast with ES7
-
-author: Nolan Lawson
-
----
-
-One of the trickiest aspects of PouchDB is that its API is asynchronous. I see no shortage of confused questions on Stack Overflow, Github, and IRC, and most often they stem from a misunderstanding of callbacks and promises.
-
-We can't really help it. PouchDB is an abstraction over IndexedDB, WebSQL, LevelDB (in Node), and CouchDB (via Ajax). All of those APIs are asynchronous; hence PouchDB must be asynchronous.
-
-When I think of elegant database APIs, however, I'm still struck by the simplicity of LocalStorage:
-
-{% highlight js %}
-if (!localStorage.foo) {
-  localStorage.foo = 'bar';
-};
-console.log(localStorage.foo);
-{% endhighlight %}
-
-To work with LocalStorage, you simply treat it like a magical JavaScript object that happens to persist your data. It uses the same synchronous toolset that you're already used to from working with JavaScript itself.
-
-For all of [LocalStorage's](http://www.html5rocks.com/en/tutorials/offline/quota-research/) [faults](https://blog.mozilla.org/tglek/2012/02/22/psa-dom-local-storage-considered-harmful/), the ergonomics of this API go a long way to explain its continuing popularity. People keep using LocalStorage, because it's simple and works exactly as expected.
-
-### Promises aren't a panacea
-
-For PouchDB, we can try to mitigate the complexity of asynchronous APIs with promises, and that certainly helps us escape the [pyramid of doom](https://medium.com/@wavded/managing-node-js-callback-hell-1fe03ba8baf).
-
-However, promisey code is still hard to read, because promises are basically a bolt-on replacement for language primitives like `try`, `catch`, and `return`:
-
-{% highlight js %}
-var db = new PouchDB('mydb');
-db.post({}).then(function (result) { // post a new doc
-  return db.get(result.id);          // fetch the doc
-}).then(function (doc) {
-  console.log(doc);                  // log the doc
-}).catch(function (err) {
-  console.log(err);                  // log any errors
-});
-{% endhighlight %}
-
-As JavaScript developers, we now have two parallel systems &ndash; sync and async &ndash; that we have to keep straight in our heads. And this gets even worse as our control flow becomes more complex, and we need to reach for APIs like `Promise.all()` and `Promise.resolve()`. Or maybe we just opt for [one](https://github.com/petkaantonov/bluebird) [of](https://github.com/tildeio/rsvp.js) [the](https://github.com/caolan/async) [many](https://github.com/kriskowal/q) [helper](https://github.com/cujojs/when) [libraries](https://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx) and pray we can understand the documentation.
-
-Until recently, this was the best we could hope for. But all of that changes with ES7.
-
-### Enter ES7
-
-What if I told you that, with ES7, you could rewrite the above code to look like this:
-
-{% highlight js %}
-let db = new PouchDB('mydb');
-try {
-  let result = await db.post({});
-  let doc = await db.get(result.id);
-  console.log(doc);
-} catch (err) {
-  console.log(err);
-}
-{% endhighlight %}
-
-And what if I told you that, thanks to tools like [Babel.js](https://babeljs.io/) and [Regenerator](http://facebook.github.io/regenerator/), you can transpile that down to ES5 and run it in a browser *today*?
-
-{% include img.html src="orson_welles_clapping.gif" alt="Orson Welles clapping enthusiastically in 'Citizen Kane'" %}
-
-Please ladies and gentlemen, hold your applause until the end of the blog post.
-
-First, let's take a look at how ES7 is accomplishing this amazing feat.
-
-### Async functions
-
-ES7 gives us a new kind of function, the `async function`. Inside of an `async function`, we have a new keyword, `await`, which we use to "wait for" a promise:
-
-{% highlight js %}
-async function myFunction() {
-  let result = await somethingThatReturnsAPromise();
-  console.log(result); // cool, we have a result
-}
-{% endhighlight %}
-
-
-If the promise resolves, we can immediately interact with it on the next line. And if it rejects, then an error is thrown. So `try`/`catch` actually works again!
-
-{% highlight js %}
-async function myFunction() {
-  try {
-    await somethingThatReturnsAPromise();
-  } catch (err) { 
-    console.log(err); // oh noes, we got an error
-  }
-}
-{% endhighlight %}
-
-This allows us to write code that looks synchronous on the surface, but is actually asynchronous under the hood. The fact that the API returns a promise instead of blocking the event loop is just an implementation detail.
-
-{% include img.html src="pepperidge_farm_remembers.png" alt="Remember when you could just use 'return' and 'try/catch'? Pepperidge Farm remembers. (Pepperidge Farm meme, old man holding a bag of biscuits and looking at you wistfully.)" %}
-
-And the best part is, we can use this *today* with any library that returns promises. PouchDB is such a library, so let's use it to test our theory.
-
-### Managing errors and return values
-
-First, consider a common idiom in PouchDB: we want to `get()` a document by `_id` if it exists, or return a new document if it doesn't.
-
-With promises, you'd have to write something like this:
-
-{% highlight js %}
-db.get('docid').catch(function (err) {
-  if (err.status === 404) { // not found
-    return {}; // new doc
-  }
-  throw err; // some error other than 404
-}).then(function (doc) {
-  console.log(doc);
-})
-{% endhighlight %}
-
-With async functions, this becomes:
-
-{% highlight js %}
-let doc;
-try {
-  doc = await db.get('docid');
-} catch (err) {
-  if (err.status === 404) { // not found
-    doc = {};
-  } else {
-    throw err; // some error other than 404
-  }
-}
-console.log(doc);
-{% endhighlight %}
-
-Much more readable! This is almost the exact same code we would write if `db.get()` directly returned a document rather than a promise. The only difference is that we have to add the `await` keyword when we call any promise-returning function.
-
-### Potential gotchas
-
-There are a few subtle issues that I ran into while playing with this, so it's good to be aware of them.
-
-First off, anytime you `await` something, you need to be inside an async function. So if your code relies heavily on PouchDB, you may find that you write lots of async functions, but very few regular functions.
-
-Another, more insidious problem is that you have to be careful to wrap your code in `try`/`catch`es, or else a promise might be rejected, in which case the error is silently swallowed. (!)
-
-My advice is to ensure that your async functions are entirely surrounded by `try`/`catch`es, at least at the top level:
-
-{% highlight js %}
-async function createNewDoc() {
-  let response = await db.post({}); // post a new doc
-  return await db.get(response.id); // find by id
-}
-
-async function printDoc() {
-  try {
-    let doc = await createNewDoc();
-    console.log(doc);
-  } catch (err) {
-    console.log(err);
-  }
-}
-{% endhighlight %}
-
-### Loops
-
-Async functions get really impressive when it comes to iteration. For instance, Let's say that we want to insert some documents into the database, but *sequentially*. That is, we want the promises to execute one after the other, not concurrently.
-
-Using standard ES6 promises, we'd have to roll our own promise chain:
-
-{% highlight js %}
-var promise = Promise.resolve();
-var docs = [{}, {}, {}];
-
-docs.forEach(function (doc) {
-  promise = promise.then(function () {
-    return db.post(doc);
-  });
-});
-
-promise.then(function () {
-  // now all our docs have been saved
-});
-{% endhighlight %}
-
-This works, but it sure is ugly. It's also error-prone, because if you accidentally do:
-
-{% highlight js %}
-docs.forEach(function (doc) {
-  promise = promise.then(db.post(doc));
-});
-{% endhighlight %}
-
-Then the promises will actually execute *concurrently*, which can lead to unexpected results.
-
-With ES7, though, we can just use a regular for-loop:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-
-for (let i = 0; i < docs.length; i++) {
-  let doc = docs[i];
-  await db.post(doc);
-}
-{% endhighlight %}
-
-This (very concise) code does the same thing as the promise chain! We can make it even shorter by using `for...of`:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-
-for (let doc of docs) {
-  await db.post(doc);
-}
-{% endhighlight %}
-
-Note that you cannot use a  `forEach()` loop here. If you were to naïvely write:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-
-// WARNING: this won't work
-docs.forEach(function (doc) {
-  await db.post(doc);
-});
-{% endhighlight %}
-
-Then Babel.js will fail with a somewhat opaque error:
-
-    Error : /../script.js: Unexpected token (38:23)
-    > 38 |     await db.post(doc);
-         |           ^
-
-This is because you cannot use `await` from within a normal function. You have to use an async function.
-
-However, if you try to use an async function, then you will get a more subtle bug:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-
-// WARNING: this won't work
-docs.forEach(async function (doc, i) {
-  await db.post(doc);
-  console.log(i);
-});
-console.log('main loop done');
-{% endhighlight %}
-
-This will compile, but the problem is that this will print out:
-
-    main loop done
-    0
-    1
-    2
-
-What's happening is that the main function is exiting early, because the `await` is actually in the sub-function. Furthermore, this will execute each promise *concurrently*, which is not what we intended.
-
-The lesson is: be careful when you have any function inside your async function. The `await` will only pause its parent function, so check that it's doing what you actually think it's doing.
-
-### Concurrent loops
-
-If we do want to execute multiple promises concurrently, though, then this is pretty easy to accomplish with ES7.
-
-Recall that with ES6 promises, we have `Promise.all()`. Let's use it to return an array of values from an array of promises:
-
-{% highlight js %}
-var docs = [{}, {}, {}];
-
-return Promise.all(docs.map(function (doc) {
-  return db.post(doc);
-})).then(function (results) {
-  console.log(results);
-});
-{% endhighlight %}
-
-In ES7, we can do this is a more straightforward way:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-let promises = docs.map((doc) => db.post(doc));
-
-let results = [];
-for (let promise of promises) {
-  results.push(await promise);
-}
-console.log(results);
-{% endhighlight %}
-
-The most important parts are 1) creating the `promises` array, which starts invoking all the promises immediately, and 2) that we are `await`ing those promises within the main function. If we tried to use `Array.prototype.map`, then it wouldn't work:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-let promises = docs.map((doc) => db.post(doc));
-
-// WARNING: this doesn't work
-let results = promises.map(async function(promise) {
-  return await promise;
-});
-
-// This will just be a list of promises :(
-console.log(results);
-{% endhighlight %}
-
-The reason this doesn't work is because we are `await`ing inside of the sub-function, and not the main function. So the main function exits before we are really done waiting.
-
-If you don't mind using `Promise.all`, you can also use it to tidy up the code a bit:
-
-{% highlight js %}
-let docs = [{}, {}, {}];
-let promises = docs.map((doc) => db.post(doc));
-
-let results = await Promise.all(promises);
-console.log(results);
-{% endhighlight %}
-
-Presumably this could look even nicer if we used [array comprehesions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions). However, the spec isn't final yet, so it's currently [not supported](https://github.com/facebook/regenerator/issues/182) by Regenerator.
-
-### Caveats
-
-ES7 is still very bleeding-edge. Async functions aren't supported in either Node.js or io.js, and you have to set some experimental flags to even get Babel to consider it. Officially, [the async/await spec](https://github.com/lukehoban/ecmascript-asyncawait#status-of-this-proposal) is still in the "proposal" stage.
-
-Also, you'll need to include the Regenerator runtime and ES6 shims in your transpiled code for this to work in ES5 browsers. For me, that added up to about 60KB, minified and gzipped. For many developers, that's just way too much to ship down the wire.
-
-However, all of these new tools are very fun to play with, and they paint a bright picture of what working with asynchronous libraries will look like in the sunny ES7 future.
-
-So if you want to play with it yourself, I've put together a [small demo library](https://github.com/nolanlawson/async-functions-in-pouchdb). To get started, just check out the code, run `npm install && npm run build`, and you're good to go. And for more about ES7, check out [this talk by Jafar Husain](https://www.youtube.com/watch?v=DqMFX91ToLw).
-
-### Conclusion
-
-Async functions are an empowering new concept in ES7. They give us back our lost `return`s and `try`/`catch`es, and they reward the knowledge we've already gained from writing synchronous code with new idiioms that look a lot like the old ones, but are much more performant.
-
-Most importantly, async functions make APIs like PouchDB's a lot easier to work with. So hopefully this will lead to fewer user errors and confusion, as well as more elegant and readable code.
-
-And who knows, maybe folks will finally abandon LocalStorage, and opt for a more modern client-side database.
diff --git a/docs/_posts/2015-04-05-filtered-replication.md b/docs/_posts/2015-04-05-filtered-replication.md
deleted file mode 100644
index 7d1f784..0000000
--- a/docs/_posts/2015-04-05-filtered-replication.md
+++ /dev/null
@@ -1,133 +0,0 @@
----
-layout: post
-
-title: Filtered replication&#58; from Couch to Pouch and back
-
-author: Giovanni Ornaghi
-
----
-
-Filtered replication can become a vital feature for many applications, when you realize you don't need the whole dataset to be replicated to each client. At the same time, filtered replication can be the wrong solution to your problem if:
-
-* __You're trying to address security concerns.__ Replicating only the user's documents via filtering might seem simplest, but filtering isn't a substitute for proper authentication. 
-* __There's no big security concern, but you'd like to provide a better per-user or per-role experience.__ There's no shame in creating a DB per user or DB per role! Nolan Lawson discussed such recipes [here](https://github.com/nolanlawson/pouchdb-authentication#couchdb-authentication-recipe).
-
-So what is filtered replication good for? One use case is apparent: you want to give your users only a certain amount of documents, which may or may not involve their identity or roles. Sometimes these documents need to be shared by multiple users with real-time feedback, which would make the DB-per-user solution impractical. And often, these groups of users are too volatile to effectively implement a DB-per-role solution.
-
-In these situations, the best solution is filtering.
-
-### Filters in PouchDB
-
-In the PouchDB world, there are two shapes of filtered replication:
-
-* __Client-side filtering__ takes nothing more than a JS function. This will prevent useless documents from being stored locally, but it means the documents will still go over the wire, and the client will waste CPU cycles to handle them properly.
-* __Server-side filtering__, again, takes nothing more than a JS function, but it's executed by CouchDB. This will prevent documents from going over the wire in the first place! So obviously we prefer this one.
-
-### A simple implementation
-
-{% include alert/start.html variant="warning" %}
-To reproduce the examples you’ll need PouchDB v3.4.0, which contains some bugfixes for filtered replication.
-{% include alert/end.html %}
-
-The first step in implementing your server-side filtering solution is to create the design document. This is an example:
-
-{% highlight js %}
-{
-   "_id": "_design/app",
-   "filters": {
-     "by_agent": function(doc, req) {
-       return doc.agent === req.query.agent;
-     }.toString()
-   }
-}
-{% endhighlight %}
-
-Filters in CouchDB are like filters as higher-order functions: they take some arguments and return `true` or `false`. Note that the function needs to be stringified when you store it!
-
-{% include alert/start.html variant="info" %}
-
-{% markdown %}
-
-While in these examples I'm using a filter, the rest of this post will hold if you decide to use a view instead.
-
-At this point you might be wondering about the difference between a view and a filter. My reason for using filters is easy: I want to emit the whole document, and I want to emit documents according to a parameter provided by the client. While you could create a view that emits the whole document, taking parameters becomes [a bit too complicated for my taste](http://guide.couchdb.org/editions/1/en/cookbook.html). 
-
-{% endmarkdown %}
-
-{% include alert/end.html %}
-
-We'll come back to this design document later. Now it's time to implement our client-side logic. By reading the awesome [API docs](http://pouchdb.com/api.html#replication), we see that `sync` has various options:
-
-* `filter`: can take either the string corresponding to the filter function (see example below), or a JS function (for client-side filtering).
-* `query_params`: takes a JS object. This object is what we find in the `req.query` object inside the design document function. Just what we need!
-
-{% highlight js %}
-localDB.sync(remoteDB, {
-  live: true,
-  retry: true,
-  filter: 'app/by_agent',
-  query_params: { "agent": agent }
-}).on('change', function(result) {
-  if (change.deleted){
-    // remove
-  } else {
-    // upsert
-  }
-});
-{% endhighlight %}
-
-We're doing a two-way replication (from Couch to Pouch and back), using a filter (in our faithful design document) all in real-time (see `live` and `retry` options). Couch will give us a batch of documents from the `_changes` feed, which we then iterate and manage according to our needs.
-
-### Caveats
-
-Now, this looks easy, and it is, but there are a few gotchas:
-
-* Since we're doing live replication, the `complete` event will not trigger, so use `paused` instead.
-* Documents will come in batches, so you might not get the whole `_changes` feed at once.
-* You cannot really delete documents in the local database. Purging is a feature the PouchDB team is [still working on](https://github.com/pouchdb/pouchdb/issues/802).
-* If you change something on the server side to cause the document to no longer pass the filter, then the document won't pass the filter. Weird, right? CouchDB won't check the last two versions of the document &ndash; just the last one. This simply means that those documents will persist on the client and never be present in the `_changes` feed.
-* Watch how you delete your documents! Simply going into Futon and happily clicking "Delete Document&hellip;" won't replicate the deletion. What you want to do is update the document, adding a `_deleted: true` field. From the [CouchDB docs](https://wiki.apache.org/couchdb/Replication):
-
-> When using filtered replication, you should not use the `DELETE` method to remove documents, but instead use `PUT` and add a `_deleted:true`
-> field to the document, preserving the fields required for the filter. Your Document Update Handler should make sure these fields are always 
-> present. This will ensure that the filter will propagate deletions properly. 
-
-In PouchDB, this corresponds to `put()`ing a document with `_deleted: true`, rather than `remove()`ing it.
-
-The next gotcha deserves a bit more space. I find it very counter-intuitive, and my guess is that you'll feel the same. Since you're interested in two-way replication, you want the client to not only read data, but write data as well. What you expect is that saves on the local database will get replicated to the remote database. Let's look at some code:
-
-{% highlight js %}
-this.save = function (foobar) {
-  return localDB.get(foobar._id).then(function (doc) {
-    doc.someNiceField = foobar.someNiceField;
-    return localDB.put(doc);
-  });
-};
-{% endhighlight %}
-
-In ORM parlance, this is a "connected scenario" update. You retrieve the document from the local database, you change the fields you need to change, then you put it back into the local database.
-
-If you followed this post step-by-step, however, this won't work. Why? To make two-way filtered replication work, the design document needs to be in both the remote database and the local database. To do this, we might decide to simply replicate the design document alongside the other documents. Hence our design document becomes:
-
-{% highlight js %}
-{
-  "_id": "_design/app",
-  "filters": {
-    "by_agent": function(doc, req) {
-      return doc._id === '_design/app' || doc.agent === req.query.agent;
-    }.toString()
-  }
-}
-{% endhighlight %}
-
-It is enough to have it stored locally; Pouch will handle the rest. The downside is that now we need to remember to handle the design document, by not letting it mingle with the documents needed in the UI.
-
-If you feel you'd rather keep the filter function clean and not worry about filtering the design document itself, then you could also have two different design documents by the same id, one in Couch and one in Pouch, not replicating.
-
-### Conclusion
-
-With the new trend of offline-first apps and microservices, data replication has become the norm, even for boring CRUD apps. Rolling out your set of webservices, push notifications, or background services might give you more control, but at the same time it will force you to engineer, write, test, and maintain a whole new ecosystem.
-
-And still, two-way replication is as much about a new set of tools as it is a new way of thinking. In offline-first apps, for example, as the number of edge cases regarding the user interaction with data multiplies, so do the possibilities for conflicts between documents.
-
-So is it worth it? CouchDB + PouchDB make an excellent, almost turnkey solution by taming a good number of use cases. My hope is that this short post will make your own transition easier.
diff --git a/docs/_posts/2015-04-07-better-late-than-never.md b/docs/_posts/2015-04-07-better-late-than-never.md
deleted file mode 100644
index 2b9bd7a..0000000
--- a/docs/_posts/2015-04-07-better-late-than-never.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.4.0&#58; Better late than never
-author: Dale Harvey
-
----
-
-Everyone needs a break, and for March PouchDB relaxed and enjoyed the arrival of spring. However, regularly scheduled programming has resumed, and today I am happy to announce PouchDB 3.4.0.
-
-### Documentation, Documentation, Documentation
-
-Over the last 2 months a huge amount of work has gone into PouchDB's documentation, including [#3584](https://github.com/pouchdb/pouchdb/pull/3584), which allows you to switch between a Promises and a callback format for your code examples.
-
-We have hugely expanded the coverage of the documentation, so if there is anything missing please feel free to point it out.
-
-### Changelog:
-
-* Fix incompatibilities with Couchbase Sync Gateway ([#3556](https://github.com/pouchdb/pouchdb/issues/3556), [#3552](https://github.com/pouchdb/pouchdb/issues/3552), [#3555](https://github.com/pouchdb/pouchdb/issues/3555), [#3561](https://github.com/pouchdb/pouchdb/issues/3561), [#3562](https://github.com/pouchdb/pouchdb/issues/3562),  [#3562](https://github.com/pouchdb/pouchdb/issues/3562), [#3495](https://github.com/pouchdb/pouchdb/issues/3495), [#3493](https://github.com/pouchdb/pouchdb/issues/3493))
-* Added a copy of PouchDB to PouchDB.com (check the inspector - [#2960](https://github.com/pouchdb/pouchdb/issues/2960))
-* Fix replication using design documents ([#3543](https://github.com/pouchdb/pouchdb/issues/3543))
-* Fix immediately cancelling live replication ([#3605](https://github.com/pouchdb/pouchdb/issues/3605))
-* Fix replication with a view ([#3606](https://github.com/pouchdb/pouchdb/issues/3606))
-* Add support for new SqlitePlugin parameters ([#3617](https://github.com/pouchdb/pouchdb/issues/3617))
-* Fix for deleted conflicts ([#3646](https://github.com/pouchdb/pouchdb/issues/3646))
-* Fix design documents that contain a slash ([#3680](https://github.com/pouchdb/pouchdb/issues/3680))
-* Fix for setting ajax headers in GET requests ([#3689](https://github.com/pouchdb/pouchdb/issues/3689))
-* Allow setting auth headers in replication ([#3543](https://github.com/pouchdb/pouchdb/issues/3543))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-05-07-pouchdb-3.5.0-vote-for-pouchdb.md b/docs/_posts/2015-05-07-pouchdb-3.5.0-vote-for-pouchdb.md
deleted file mode 100644
index eb69ae9..0000000
--- a/docs/_posts/2015-05-07-pouchdb-3.5.0-vote-for-pouchdb.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.5.0&#58; Vote for PouchDB
-author: Dale Harvey
-
----
-
-Do you support better documentation for PouchDB users? Do you value faster CORS and better Service Worker support? If so, then today you should cast your vote in support of PouchDB. Together, we can make a better future (release of PouchDB).
-
-### New features
-
-* [Extras API](/api.html#apis-for-plugin-authors) for PouchDB plugin authors ([#3338](https://github.com/pouchdb/pouchdb/issues/3338))
-* In-memory/LocalStorage/Level.js adapters are now [browserifiable](/api.html#browser-adapter-plugins) ([#2286](https://github.com/pouchdb/pouchdb/issues/2286))
-
-### Bugfixes
-
-* Fallback to the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) where XMLHTTPRequest does not exist (e.g. in Service Workers) ([#3678](https://github.com/pouchdb/pouchdb/pull/3678))
-* Stop triggering unneccesary OPTIONS requests during CORS replication ([#3573](https://github.com/pouchdb/pouchdb/issues/3573))
-* Multitudes of documentation fixes
-* Fix es3ify behavior with dependencies ([#3688](https://github.com/pouchdb/pouchdb/issues/3688))
-* Add source maps to dev environment ([#3731](https://github.com/pouchdb/pouchdb/pull/3731))
-* Fix constructor when called with `{name: 'foo'}` ([#3471](https://github.com/pouchdb/pouchdb/issues/3741))
-* Support for Blackberry 10 ([#3737](https://github.com/pouchdb/pouchdb/pull/3737))
-* Fix detection for `xhr.upload` in React Native ([#3796](https://github.com/pouchdb/pouchdb/pull/3796))
-* Webpack support ([#3319](https://github.com/pouchdb/pouchdb/issues/3319))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-05-18-we-have-a-problem-with-promises.md b/docs/_posts/2015-05-18-we-have-a-problem-with-promises.md
deleted file mode 100644
index 1ecab4c..0000000
--- a/docs/_posts/2015-05-18-we-have-a-problem-with-promises.md
+++ /dev/null
@@ -1,669 +0,0 @@
----
-layout: post
-
-title: We have a problem with promises
-author: Nolan Lawson
-
----
-
-Fellow JavaScripters, it's time to admit it: we have a problem with promises.
-
-No, not with promises themselves. Promises, as defined by the [A+ spec](https://promisesaplus.com/), are awesome.
-
-The big problem, which has revealed itself to me over the course of the past year, as I've watched numerous programmers struggle with the PouchDB API and other promise-heavy APIs, is this:
-
-Many of us are using promises *without really understanding them*.
-
-If you find that hard to believe, consider this puzzle [I recently posted to Twitter](https://twitter.com/nolanlawson/status/578948854411878400):
-
-**Q: What is the difference between these four promises?**
-
-```js
-doSomething().then(function () {
-  return doSomethingElse();
-});
-
-doSomething().then(function () {
-  doSomethingElse();
-});
-
-doSomething().then(doSomethingElse());
-
-doSomething().then(doSomethingElse);
-```
-
-If you know the answer, then congratulations: you're a promises ninja. You have my permission to stop reading this blog post.
-
-For the other 99.99% of you, you're in good company. Nobody who responded to my tweet could solve it, and I myself was surprised by the answer to #3. Yes, even though I wrote the quiz!
-
-The answers are at the end of this post, but first, I'd like to explore why promises are so tricky in the first place, and why so many of us &ndash; novices and experts alike &ndash; get tripped up by them. I'm also going to offer what I consider to be the singular insight, the *one weird trick*, that makes promises a cinch to understand. And yes, I really do believe they're not so hard after that!
-
-But to start with, let's challenge some common assumptions about promises.
-
-Wherefore promises?
-------
-
-If you read the literature on promises, you'll often find references to [the pyramid of doom](https://medium.com/@wavded/managing-node-js-callback-hell-1fe03ba8baf), with some horrible callback-y code that steadily stretches toward the right side of the screen.
-
-Promises do indeed solve this problem, but it's about more than just indentation. As explained in the brilliant talk ["Redemption from Callback Hell"](http://youtu.be/hf1T_AONQJU), the real problem with callbacks it that they deprive us of keywords like `return` and `throw`. Instead, our program's entire flow is based on *side effects*: one function incidentally calling another one.
-
-And in fact, callbacks do something even more sinister: they deprive us of the *stack*, which is something we usually take for granted in programming languages. Writing code without a stack is a lot like driving a car without a brake pedal: you don't realize how badly you need it, until you reach for it and it's not there.
-
-The whole point of promises is to give us back the language fundamentals we lost when we went async: `return`, `throw`, and the stack. But you have to know how to use promises correctly in order to take advantage of them.
-
-Rookie mistakes
----
-
-Some people try to explain promises [as a cartoon](http://andyshora.com/promises-angularjs-explained-as-cartoon.html), or in a very noun-oriented way: "Oh, it's this thing you can pass around that represents an asynchronous value."
-
-I don't find such explanations very helpful. To me, promises are all about code structure and flow. So I think it's better to just go over some common mistakes and show how to fix them. I call these "rookie mistakes" in the sense of, "you're a rookie now, kid, but you'll be a pro soon."
-
-Quick digression: "promises" mean a lot of different things to different people, but for the purposes of this article, I'm only going to talk about [the official spec](https://promisesaplus.com/), as exposed in modern browsers as `window.Promise`. Not all browsers have `window.Promise` though, so for a good polyfill, check out the cheekily-named [Lie](https://github.com/calvinmetcalf/lie), which is about the smallest spec-compliant library out there.
-
-Rookie mistake #1: the promisey pyramid of doom
----
-
-Looking at how people use PouchDB, which has a largely promise-based API, I see a lot of poor promise patterns. The most common bad practice is this one:
-
-```js
-remotedb.allDocs({
-  include_docs: true,
-  attachments: true
-}).then(function (result) {
-  var docs = result.rows;
-  docs.forEach(function(element) {
-    localdb.put(element.doc).then(function(response) {
-      alert("Pulled doc with id " + element.doc._id + " and added to local db.");
-    }).catch(function (err) {
-      if (err.status == 409) {
-        localdb.get(element.doc._id).then(function (resp) {
-          localdb.remove(resp._id, resp._rev).then(function (resp) {
-// et cetera...
-```
-
-Yes, it turns out you can use promises as if they were callbacks, and yes, it's a lot like using a power sander to file your nails, but you can do it.
-
-And if you think this sort of mistake is only limited to absolute beginners, you'll be surprised to learn that I actually took [the above code](https://github.com/blackberry/BB10-WebWorks-Community-Samples/blob/d6ee75fe23a10d2d3a036013b6b1a0c07a542099/pdbtest/www/js/index.js) from [the official BlackBerry developer blog](http://devblog.blackberry.com/2015/05/connecting-to-couchbase-with-pouchdb/)! Old callback habits die hard. (And to the developer: sorry to pick on you, but your example is instructive.)
-
-A better style is this one:
-
-```js
-remotedb.allDocs(...).then(function (resultOfAllDocs) {
-  return localdb.put(...);
-}).then(function (resultOfPut) {
-  return localdb.get(...);
-}).then(function (resultOfGet) {
-  return localdb.put(...);
-}).catch(function (err) {
-  console.log(err);
-});
-```
-
-This is called *composing promises*, and it's one of the great superpowers of promises. Each function will only be called when the previous promise has resolved, and it'll be called with that promise's output. More on that later.
-
-Rookie mistake #2: WTF, how do I use `forEach()` with promises?
-----
-
-This is where most people's understanding of promises starts to break down. As soon as they reach for their familiar `forEach()` loop (or `for` loop, or `while` loop), they have no idea how to make it work with promises. So they write something like this:
-
-```js
-// I want to remove() all docs
-db.allDocs({include_docs: true}).then(function (result) {
-  result.rows.forEach(function (row) {
-    db.remove(row.doc);  
-  });
-}).then(function () {
-  // I naively believe all docs have been removed() now!
-});
-```
-
-What's the problem with this code? The problem is that the first function is actually returning `undefined`, meaning that the second function isn't waiting for `db.remove()` to be called on all the documents. In fact, it isn't waiting on anything, and can execute when any number of docs have been removed!
-
-This is an especially insidious bug, because you may not notice anything is wrong, assuming PouchDB removes those documents fast enough for your UI to be updated. The bug may only pop up in the odd race conditions, or in certain browsers, at which point it will be nearly impossible to debug.
-
-The TLDR of all this is that `forEach()`/`for`/`while` are not the constructs you're looking for. You want `Promise.all()`:
-
-```js
-db.allDocs({include_docs: true}).then(function (result) {
-  return Promise.all(result.rows.map(function (row) {
-    return db.remove(row.doc);
-  }));
-}).then(function (arrayOfResults) {
-  // All docs have really been removed() now!
-});
-```
-
-What's going on here? Basically `Promise.all()` takes an *array of promises* as input, and then it gives you another promise that only resolves when every one of those other promises has resolved. It is the asynchronous equivalent of a for-loop.
-
-`Promise.all()` also passes an array of results to the next function, which can get very useful, for instance if you are trying to `get()` multiple things from PouchDB. The `all()` promise is also rejected if *any one of its sub-promises are rejected*, which is even more useful.
-
-Rookie mistake #3: forgetting to add .catch()
------
-
-This is another common mistake. Blissfully confident that their promises could never possibly throw an error, many developers forget to add a `.catch()` anywhere in their code. Unfortunately this means that any thrown errors *will be swallowed*, and you won't even see them in your console. This can be a real pain to debug.
-
-To avoid this nasty scenario, I've gotten into the habit of simply adding the following code to my promise chains:
-
-```js
-somePromise().then(function () {
-  return anotherPromise();
-}).then(function () {
-  return yetAnotherPromise();
-}).catch(console.log.bind(console)); // <-- this is badass
-```
-
-Even if you never expect an error, it's always prudent to add a `catch()`. It'll make your life easier, if your assumptions ever turn out to be wrong.
-
-Rookie mistake #4: using "deferred"
-----
-
-This is a mistake I see [all the time](http://gonehybrid.com/how-to-use-pouchdb-sqlite-for-local-storage-in-your-ionic-app/), and I'm reluctant to even repeat it here, for fear that, like Beetlejuice, merely invoking its name will summon more instances of it.
-
-In short, promises have a long and storied history, and it took the JavaScript community a long time to get them right. In the early days, jQuery and Angular were using this "deferred" pattern all over the place, which has now been replaced with the ES6 Promise spec, as implemented by "good" libraries like Q, When, RSVP, Bluebird, Lie, and others.
-
-So if you are writing that word in your code (I won't repeat it a third time!), you are doing something wrong. Here's how to avoid it.
-
-First off, most promise libraries give you a way to "import" promises from third-party libraries. For instance, Angular's `$q` module allows you to wrap non-`$q` promises using `$q.when()`. So Angular users can wrap PouchDB promises this way:
-
-```js
-$q.when(db.put(doc)).then(/* ... */); // <-- this is all the code you need
-```
-
-Another strategy is to use the [revealing constructor pattern](https://blog.domenic.me/the-revealing-constructor-pattern/), which is useful for wrapping non-promise APIs. For instance, to wrap a callback-based API like Node's `fs.readFile()`, you can simply do:
-
-```js
-new Promise(function (resolve, reject) {
-  fs.readFile('myfile.txt', function (err, file) {
-    if (err) {
-      return reject(err);
-    }
-    resolve(file);
-  });
-}).then(/* ... */)
-```
-
-Done! We have defeated the dreaded def... Aha, caught myself. :)
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-For more about why this is an anti-pattern, check out [the Bluebird wiki page on promise anti-patterns](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern).
-{% endmarkdown %}
-{% include alert/end.html %}
-
-
-Rookie mistake #5: using side effects instead of returning
-----
-
-What's wrong with this code?
-
-```js
-somePromise().then(function () {
-  someOtherPromise();
-}).then(function () {
-  // Gee, I hope someOtherPromise() has resolved!
-  // Spoiler alert: it hasn't.
-});
-```
-
-Okay, this is a good point to talk about everything you ever need to know about promises.
-
-Seriously, this is the *one weird trick* that, once you understand it, will prevent all of the errors I've been talking about. You ready?
-
-As I said before, the magic of promises is that they give us back our precious `return` and `throw`. But what does this actually look like in practice?
-
-Every promise gives you a `then()` method (or `catch()`, which is just sugar for `then(null, ...)`). Here we are inside of a `then()` function:
-
-```js
-somePromise().then(function () {
-  // I'm inside a then() function!
-});
-```
-
-What can we do here? There are three things:
-
-1. `return` another promise
-2. `return` a synchronous value (or `undefined`)
-3. `throw` a synchronous error
-
-That's it. Once you understand this trick, you understand promises. So let's go through each point one at a time.
-
-#### 1. Return another promise
-
-This is a common pattern you see in the promise literature, as in the "composing promises" example above:
-
-```js
-getUserByName('nolan').then(function (user) {
-  return getUserAccountById(user.id);
-}).then(function (userAccount) {
-  // I got a user account!
-});
-```
-
-Notice that I'm `return`ing the second promise &ndash; that `return` is crucial. If I didn't say `return`, then the `getUserAccountById()` would actually be a *side effect*, and the next function would receive `undefined` instead of the `userAccount`.
-
-#### 2. Return a synchronous value (or undefined)
-
-Returning `undefined` is often a mistake, but returning a synchronous value is actually an awesome way to convert synchronous code into promisey code. For instance, let's say we have an in-memory cache of users. We can do:
-
-```js
-getUserByName('nolan').then(function (user) {
-  if (inMemoryCache[user.id]) {
-    return inMemoryCache[user.id];    // returning a synchronous value!
-  }
-  return getUserAccountById(user.id); // returning a promise!
-}).then(function (userAccount) {
-  // I got a user account!
-});
-```
-
-Isn't that awesome? The second function doesn't care whether the `userAccount` was fetched synchronously or asynchronously, and the first function is free to return either a synchronous or asynchronous value.
-
-Unfortunately, there's the inconvenient fact that non-returning functions in JavaScript technically return `undefined`, which means it's easy to accidentally introduce side effects when you meant to return something.
-
-For this reason, I make it a personal habit to *always return or throw* from inside a `then()` function. I'd recommend you do the same.
-
-#### 3. Throw a synchronous error
-
-Speaking of `throw`, this is where promises can get even more awesome. Let's say we want to `throw` a synchronous error in case the user is logged out. It's quite easy:
-
-```js
-getUserByName('nolan').then(function (user) {
-  if (user.isLoggedOut()) {
-    throw new Error('user logged out!'); // throwing a synchronous error!
-  }
-  if (inMemoryCache[user.id]) {
-    return inMemoryCache[user.id];       // returning a synchronous value!
-  }
-  return getUserAccountById(user.id);    // returning a promise!
-}).then(function (userAccount) {
-  // I got a user account!
-}).catch(function (err) {
-  // Boo, I got an error!
-});
-```
-
-Our `catch()` will receive a synchronous error if the user is logged out, and it will receive an asynchronous error if *any of the promises are rejected*. Again, the function doesn't care whether the error it gets is synchronous or asynchronous.
-
-This is especially useful because it can help identify coding errors during development. For instance, if at any point inside of a `then()` function, we do a `JSON.parse()`, it might throw a synchronous error if the JSON is invalid. With callbacks, that error would get swallowed, but with promises, we can simply handle it inside our `catch()` function.
-
-Advanced mistakes
-----
-
-Okay, now that you've learned the single trick that makes promises dead-easy, let's talk about the edge cases. Because of course, there are always edge cases.
-
-These mistakes I'd classify as "advanced," because I've only seen them made by programmers who are already fairly adept with promises. But we're going to need to discuss them, if we want to be able to solve the puzzle I posed at the beginning of this post.
-
-Advanced mistake #1: not knowing about `Promise.resolve()`
-----
-
-As I showed above, promises are very useful for wrapping synchronous code as asynchronous code. However, if you find yourself typing this a lot:
-
-```js
-new Promise(function (resolve, reject) {
-  resolve(someSynchronousValue);
-}).then(/* ... */);
-```
-
-You can express this more succinctly using `Promise.resolve()`:
-
-```js
-Promise.resolve(someSynchronousValue).then(/* ... */);
-```
-
-This is also incredibly useful for catching any synchronous errors. It's so useful, that I've gotten in the habit of beginning nearly all of my promise-returning API methods like this:
-
-```js
-function somePromiseAPI() {
-  return Promise.resolve().then(function () {
-    doSomethingThatMayThrow();
-    return 'foo';
-  }).then(/* ... */);
-}
-```
-
-Just remember: any code that might `throw` synchronously is a good candidate for a nearly-impossible-to-debug swallowed error somewhere down the line. But if you wrap everything in `Promise.resolve()`, then you can always be sure to `catch()` it later.
-
-Similarly, there is a `Promise.reject()` that you can use to return a promise that is immediately rejected:
-
-```js
-Promise.reject(new Error('some awful error'));
-```
-
-Advanced mistake #2: `catch()` isn't exactly like `then(null, ...)`
-----
-
-I said above that `catch()` is just sugar. So these two snippets are equivalent:
-
-```js
-somePromise().catch(function (err) {
-  // handle error
-});
-
-somePromise().then(null, function (err) {
-  // handle error
-});
-```
-
-However, that doesn't mean that the following two snippets are equivalent:
-
-```js
-somePromise().then(function () {
-  return someOtherPromise();
-}).catch(function (err) {
-  // handle error
-});
-
-somePromise().then(function () {
-  return someOtherPromise();
-}, function (err) {
-  // handle error
-});
-```
-
-If you're wondering why they're not equivalent, consider what happens if the first function throws an error:
-
-```js
-somePromise().then(function () {
-  throw new Error('oh noes');
-}).catch(function (err) {
-  // I caught your error! :)
-});
-
-somePromise().then(function () {
-  throw new Error('oh noes');
-}, function (err) {
-  // I didn't catch your error! :(
-});
-```
-
-As it turns out, when you use the `then(resolveHandler, rejectHandler)` format, the `rejectHandler` *won't actually catch an error* if it's thrown by the `resolveHandler` itself.
-
-For this reason, I've made it a personal habit to never use the second argument to `then()`, and to always prefer `catch()`. The exception is when I'm writing asynchronous [Mocha](http://mochajs.org/) tests, where I might write a test to ensure that an error is thrown:
-
-```js
-it('should throw an error', function () {
-  return doSomethingThatThrows().then(function () {
-    throw new Error('I expected an error!');
-  }, function (err) {
-    should.exist(err);
-  });
-});
-```
-
-Speaking of which, [Mocha](http://mochajs.org/) and [Chai](http://chaijs.com/) are a lovely combination for testing promise APIs. The [pouchdb-plugin-seed](https://github.com/pouchdb/plugin-seed) project has [some sample tests](https://github.com/pouchdb/plugin-seed/blob/master/test/test.js) that can get you started.
-
-Advanced mistake #3: promises vs promise factories
-------
-
-Let's say you want to execute a series of promises one after the other, in a sequence. That is, you want something like `Promise.all()`, but which doesn't execute the promises in parallel.
-
-You might na&iuml;vely write something like this:
-
-```js
-function executeSequentially(promises) {
-  var result = Promise.resolve();
-  promises.forEach(function (promise) {
-    result = result.then(promise);
-  });
-  return result;
-}
-```
-
-Unfortunately, this will not work the way you intended. The promises you pass in to `executeSequentially()` will *still* execute in parallel.
-
-The reason this happens is that you don't want to operate over an array of promises at all. Per the promise spec, as soon as a promise is created, it begins executing. So what you really want is an array of *promise factories*:
-
-```js
-function executeSequentially(promiseFactories) {
-  var result = Promise.resolve();
-  promiseFactories.forEach(function (promiseFactory) {
-    result = result.then(promiseFactory);
-  });
-  return result;
-}
-```
-
-I know what you're thinking: "Who the hell is this Java programmer, and why is he talking about factories?" A promise factory is very simple, though &ndash; it's just a function that returns a promise:
-
-```js
-function myPromiseFactory() {
-  return somethingThatCreatesAPromise();
-}
-```
-
-Why does this work? It works because a promise factory doesn't create the promise until it's asked to. It works the same way as a `then` function &ndash; in fact, it's the same thing!
-
-If you look at the `executeSequentially()` function above, and then imagine `myPromiseFactory` being substituted inside of `result.then(...)`, then hopefully a light bulb will click in your brain. At that moment, you will have achieved promise enlightenment.
-
-Advanced mistake #4: okay, what if I want the result of two promises?
-----
-
-Often times, one promise will depend on another, but we'll want the output of both promises. For instance:
-
-```js
-getUserByName('nolan').then(function (user) {
-  return getUserAccountById(user.id);
-}).then(function (userAccount) {
-  // dangit, I need the "user" object too!
-});
-```
-
-Wanting to be good JavaScript developers and avoid the pyramid of doom, we might just store the `user` object in a higher-scoped variable:
-
-```js
-var user;
-getUserByName('nolan').then(function (result) {
-  user = result;
-  return getUserAccountById(user.id);
-}).then(function (userAccount) {
-  // okay, I have both the "user" and the "userAccount"
-});
-```
-
-This works, but I personally find it a bit kludgey. My recommended strategy: just let go of your preconceptions and embrace the pyramid:
-
-
-```js
-getUserByName('nolan').then(function (user) {
-  return getUserAccountById(user.id).then(function (userAccount) {
-    // okay, I have both the "user" and the "userAccount"
-  });
-});
-```
-
-...at least, temporarily. If the indentation ever becomes an issue, then you can do what JavaScript developers have been doing since time immemorial, and extract the function into a named function:
-
-```js
-function onGetUserAndUserAccount(user, userAccount) {
-  return doSomething(user, userAccount);
-}
-
-function onGetUser(user) {
-  return getUserAccountById(user.id).then(function (userAccount) {
-    return onGetUserAndUserAccount(user, userAccount);
-  });
-}
-
-getUserByName('nolan')
-  .then(onGetUser)
-  .then(function () {
-  // at this point, doSomething() is done, and we are back to indentation 0
-});
-```
-
-As your promise code starts to get more complex, you may find yourself extracting more and more functions into named functions. I find this leads to very aesthetically-pleasing code, which might look like this:
-
-```js
-putYourRightFootIn()
-  .then(putYourRightFootOut)
-  .then(putYourRightFootIn)  
-  .then(shakeItAllAbout);
-```
-
-That's what promises are all about.
-
-Advanced mistake #5: promises fall through
------
-
-Finally, this is the mistake I alluded to when I introduced the promise puzzle above. This is a very esoteric use case, and it may never come up in your code, but it certainly surprised me.
-
-What do you think this code prints out?
-
-```js
-Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
-  console.log(result);
-});
-```
-
-If you think it prints out `bar`, you're mistaken. It actually prints out `foo`!
-
-The reason this happens is because when you pass `then()` a non-function (such as a promise), it actually interprets it as `then(null)`, which causes the previous promise's result to fall through. You can test this yourself:
-
-```js
-Promise.resolve('foo').then(null).then(function (result) {
-  console.log(result);
-});
-```
-
-Add as many `then(null)`s as you want; it will still print `foo`.
-
-This actually circles back to the previous point I made about promises vs promise factories. In short, you *can* pass a promise directly into a `then()` method, but it won't do what you think it's doing. `then()` is supposed to take a function, so most likely you meant to do:
-
-```js
-Promise.resolve('foo').then(function () {
-  return Promise.resolve('bar');
-}).then(function (result) {
-  console.log(result);
-});
-```
-
-This will print `bar`, as we expected.
-
-So just remind yourself: always pass a function into `then()`!
-
-Solving the puzzle
----
-
-Now that we've learned everything there is to know about promises (or close to it!), we should be able to solve the puzzle I originally posed at the start of this post.
-
-Here is the answer to each one, in graphical format so you can better visualize it:
-
-### Puzzle #1
-
-```js
-doSomething().then(function () {
-  return doSomethingElse();
-}).then(finalHandler);
-```
-
-Answer:
-
-```
-doSomething
-|-----------------|
-                  doSomethingElse(undefined)
-                  |------------------|
-                                     finalHandler(resultOfDoSomethingElse)
-                                     |------------------|
-```
-
-
-### Puzzle #2
-
-```js
-doSomething().then(function () {
-  doSomethingElse();
-}).then(finalHandler);
-```
-
-Answer:
-
-```
-doSomething
-|-----------------|
-                  doSomethingElse(undefined)
-                  |------------------|
-                  finalHandler(undefined)
-                  |------------------|
-```
-
-
-### Puzzle #3
-
-```js
-doSomething().then(doSomethingElse())
-  .then(finalHandler);
-```
-
-Answer:
-
-```
-doSomething
-|-----------------|
-doSomethingElse(undefined)
-|---------------------------------|
-                  finalHandler(resultOfDoSomething)
-                  |------------------|
-```
-
-### Puzzle #4
-
-```js
-doSomething().then(doSomethingElse)
-  .then(finalHandler);
-```
-
-Answer:
-
-```
-doSomething
-|-----------------|
-                  doSomethingElse(resultOfDoSomething)
-                  |------------------|
-                                     finalHandler(resultOfDoSomethingElse)
-                                     |------------------|
-```
-
-If these answers still don't make sense, then I encourage you to re-read the post, or to define the `doSomething()` and `doSomethingElse()` methods and try it out yourself in your browser.
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-**Clarification:** for these examples, I'm assuming that both `doSomething()` and `doSomethingElse()` return promises, and that those promises represent something done outside of the JavaScript event loop (e.g. IndexedDB, network, `setTimeout`), which is why they're shown as being concurrent when appropriate. Here's a [JSBin](http://jsbin.com/tuqukakawo/1/edit?js,console,output) to demonstrate.
-{% endmarkdown %}
-{% include alert/end.html %}
-
-And for more advanced uses of promises, check out my [promise protips cheat sheet](https://gist.github.com/nolanlawson/6ce81186421d2fa109a4).
-
-Final word about promises
----
-
-Promises are great. If you are still using callbacks, I strongly encourage you to switch over to promises. Your code will become smaller, more elegant, and easier to reason about.
-
-And if you don't believe me, here's proof: [a refactor of PouchDB's map/reduce module](https://t.co/hRyc6ENYGC) to replace callbacks with promises. The result: 290 insertions, 555 deletions.
-
-Incidentally, the one who wrote that nasty callback code was&hellip; me! So this served as my first lesson in the raw power of promises, and I thank the other PouchDB contributors for coaching me along the way.
-
-That being said, promises aren't perfect. It's true that they're better than callbacks, but that's a lot like saying that a punch in the gut is better than a kick in the teeth. Sure, one is preferable to the other, but if you had a choice, you'd probably avoid them both.
-
-While superior to callbacks, promises are still difficult to understand and error-prone, as evidenced by the fact that I felt compelled to write this blog post. Novices and experts alike will frequently mess this stuff up, and really, it's not their fault. The problem is that promises, while similar to the patterns we use in synchronous code, are a decent substitute but not quite the same.
-
-In truth, you shouldn't have to learn a bunch of arcane rules and new APIs to do things that, in the synchronous world, you can do perfectly well with familiar patterns like `return`, `catch`, `throw`, and for-loops. There shouldn't be two parallel systems that you have to keep straight in your head at all times.
-
-Awaiting async/await
----
-
-That's the point I made in ["Taming the asynchronous beast with ES7"](http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html), where I explored the ES7 `async`/`await` keywords, and how they integrate promises more deeply into the language. Instead of having to write pseudo-synchronous code (with a fake `catch()` method that's kinda like `catch`, but not really), ES7 will allow us to use the real `try`/`catch`/`return` keywords, just like we learned in CS 101.
-
-This is a huge boon to JavaScript as a language. Because in the end, these promise anti-patterns will still keep cropping up, as long as our tools don't tell us when we're making a mistake.
-
-To take an example from JavaScript's history, I think it's fair to say that [JSLint](http://jslint.com/) and [JSHint](http://jshint.com/) did a greater service to the community than [*JavaScript: The Good Parts*](http://amzn.com/0596517742), even though they effectively contain the same information. It's the difference between being told *exactly the mistake you just made in your code*, as opposed to reading a book where you try to understand other people's mistakes.
-
-The beauty of ES7 `async`/`await` is that, for the most part, your mistakes will reveal themselves as syntax/compiler errors rather than subtle runtime bugs. Until then, though, it's good to have a grasp of what promises are capable of, and how to use them properly in ES5 and ES6.
-
-So while I recognize that, like *JavaScript: The Good Parts*, this blog post can only have a limited impact, it's hopefully something you can point people to when you see them making these same mistakes. Because there are still way too many of us who just need to admit: "I have a problem with promises!"
-
-{% include alert/start.html variant="info"%}
-{% markdown %}
-**Update:** it's been pointed out to me that Bluebird 3.0 will [print out warnings](http://imgur.com/a/t3xng) that can prevent many of the mistakes I've identified in this post. So using Bluebird is another great option while we wait for ES7!
-{% endmarkdown %}
-{% include alert/end.html %}
diff --git a/docs/_posts/2015-06-01-pouchdb-3.6.0.md b/docs/_posts/2015-06-01-pouchdb-3.6.0.md
deleted file mode 100644
index b30431f..0000000
--- a/docs/_posts/2015-06-01-pouchdb-3.6.0.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-layout: post
-
-title: PouchDB 3.6.0
-author: Nolan Lawson
-
----
-
-PouchDB 3.6.0 is a monthly release containing several bugfixes, most notably for "retry" replication and attachment replication. It also contains one minor new feature.
-
-### New features
-
-* `getAttachment()` now supports `rev` ([#3871](https://github.com/pouchdb/pouchdb/issues/3871))
-* Add `androidDatabaseImplementation` option for the SQLite Plugin in Cordova ([#3835](https://github.com/pouchdb/pouchdb/issues/3835))
-
-### Performance improvements
-
-* Avoid `application/json` when `GET`ing remote documents with attachments. This makes the replicator and `get()`s on remote PouchDBs more efficient, by preferring to fetch the attachments directly in separate parallel requests. You may see a negative performance impact if you have many small attachments, in which case you should inline them instead of using attachments. However, "normal" attachment use cases should see a big improvement, because attachments are no longer sent over the wire as base64-encoded strings. This also improves support for syncing attachments in Couchbase Sync Gateway, which does not support the `application/json` format. ([#3870](https://github.com/pouchdb/pouchdb/issues/3870))
-* Similarly, for uploading of documents with attachments, use the `multipart/related` format rather than `application/json`, because it is more efficient. This also improves Couchbase Sync Gateway support. ([#3876](https://github.com/pouchdb/pouchdb/issues/3876))
-* Avoid using `readAsBinaryString` when `readAsArrayBuffer` is more direct ([#3877](https://github.com/pouchdb/pouchdb/issues/3877))
-* Better bit-twiddling in the md5 checksum ([#3878](https://github.com/pouchdb/pouchdb/issues/3878))
-
-### Bugfixes
-
-* Fix EventEmitter memory leaks in retry replication (#3858 #3699)
-* Fix retry replication when started offline ([#3768](https://github.com/pouchdb/pouchdb/issues/3768))
-* Fixes for `fetch()` in Service Workers on Chrome 41 ([#3885](https://github.com/pouchdb/pouchdb/issues/3885))
-* Fix a race condition when retry replication is immediately canceled ([#3894](https://github.com/pouchdb/pouchdb/issues/3894))
-
-### Test infrastructure
-
-* Fuzzy replication tests ([#3767](https://github.com/pouchdb/pouchdb/issues/3767))
-* Test multiple versions of Node/io.js ([#3843](https://github.com/pouchdb/pouchdb/issues/3843))
-* BlackBerry Cordova tests (#3818 #3845)
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-08-03-pouchdb-4.0.0-ballast-overboard.md b/docs/_posts/2015-08-03-pouchdb-4.0.0-ballast-overboard.md
deleted file mode 100644
index dae55da..0000000
--- a/docs/_posts/2015-08-03-pouchdb-4.0.0-ballast-overboard.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-layout: post
-
-title: PouchDB 4.0.0 - Ballast Overboard
-author: Dale Harvey
-
----
-
-> When discussing what features we should add,
-> we should also discuss what to remove. - possibly Joe Armstrong
-
-I can't remember or find the exact quote, but it was something along those lines. We try to maintain backwards compatibility as much as possible with PouchDB, however sometimes we need to let go of those features that just didn't work out like planned. We have previously marked quite a few things as deprecated, and in this 4.0.0 release we have finally removed them along with our usual slew of bugfixes, improvements and new features.
-
-### Deprecations
-
-* Remove `bluebird` and use `lie` as only `Promise` polyfill - ([#3839](https://github.com/pouchdb/pouchdb/issues/3839))
-
-We previously used `bluebird` as our `Promise` polyfill in node.js because it is a fast library. However `bluebird` contains a lot of non-standard `Promise` functionality, which authors could use and then have their code break in browsers as well as iojs and future versions of node.js, which have introduced a standard `Promise` implementation.
-
-PouchDB will always use the globally available `Promise` object where available, so if you have only used standard `Promise` functionality, this change will not break anything. If you require the extra functionality provided by `bluebird`, then you can have PouchDB use it with
-
-```js
-global.Promise = require('bluebird');
-````
-
-* Remove `local_seq` - ([#4080](https://github.com/pouchdb/pouchdb/issues/4080))
-
-This was a little-used functionality whose semantics are due to change in CouchDB 2.0.
-
-* Remove `onChange` and `complete` callbacks - ([#4098](https://github.com/pouchdb/pouchdb/issues/4098))
-
-These callbacks have long been replaced with the `EventEmitter`-style `changes()`, `replicate()` and `sync()` APIs, and are finally being removed. If you still have:
-
-```js
-db.changes({
-  onChange: changeFun,
-  complete: completeFun
-});
-```
-
-You can replace them with:
-
-```js
-db.changes()
-  .on('change', changeFun)
-  .on('complete', completeFun);
-```
-
-* Remove `uptodate` event - ([#4100](https://github.com/pouchdb/pouchdb/issues/4100))
-
-`uptodate` was an event introduced to indicate when a `live` replication had finished processing all current changes and was waiting on future changes. It has since been replaced by the `paused` event, which will do the same and additionally indicate whether the replication was paused due to an error. If you have:
-
-```js
-replication.on('uptodate', doneFun);
-```
-
-You can replace it with:
-
-```js
-replication.on('paused', doneFun);
-```
-
-### New features
-
-* Return Blobs (or Buffers) in `get()` + `allDocs()` + `changes()` + `query()` with `{binary: true}` ([#2858](https://github.com/pouchdb/pouchdb/issues/2858))
-* Allow chaining of plugin registration ([#3943](https://github.com/pouchdb/pouchdb/issues/3943))
-* Allow option to raise timeouts in changes / replication ([#4022](https://github.com/pouchdb/pouchdb/issues/4022))
-* Add direct edit button to website ([#3747](https://github.com/pouchdb/pouchdb/issues/3747))
-
-### Bugfixes
-
-* Fix attachment length for stubs ([#3963](https://github.com/pouchdb/pouchdb/issues/3963))
-* Reduce the number of checkpoint mismatches ([#4009](https://github.com/pouchdb/pouchdb/issues/4009))
-* Fallback from checkpoint mismatch correctly (less replication start from the beginning) ([#3999](https://github.com/pouchdb/pouchdb/issues/3999))
-* Dont fail replication when attachment request fails ([#4021](https://github.com/pouchdb/pouchdb/issues/4021))
-* Fix check for `localStorage` in Safari private mode ([#4070](https://github.com/pouchdb/pouchdb/issues/4070))
-
-### Coverage improvements
-
-* Large number of new tests and dead code removed to increase our [test coverage](https://coveralls.io/github/pouchdb/pouchdb/) - ([#4071](https://github.com/pouchdb/pouchdb/issues/4071))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-09-01-pouchdb-4.0.1-gotta-go-fast.md b/docs/_posts/2015-09-01-pouchdb-4.0.1-gotta-go-fast.md
deleted file mode 100644
index 3c105e6..0000000
--- a/docs/_posts/2015-09-01-pouchdb-4.0.1-gotta-go-fast.md
+++ /dev/null
@@ -1,154 +0,0 @@
----
-layout: post
-
-title: PouchDB 4.0.1 - Gotta Go Fast
-author: Nolan Lawson
-
----
-
-I'm a big fan of classic video games. So when I hack on PouchDB, my inspiration is this guy:
-
-{% include img.html src="sonic_waiting.gif" alt="Sonic the Hedgehog tapping his foot with visible irritation" %}
-
-In *Sonic the Hedgehog*, the titular hero taps his foot impatiently any time you stop moving. It's almost as if he's egging you on, urging you to go faster. *Come on, what's the holdup?*
-
-With PouchDB, performance is one of our top concerns; we don't want any holdups either. So 4.0.1 is a patch release containing some bugfixes, but mostly a lot of speedups.
-
-This blog post has a detailed performance report as well as some community news, but first the changelog:
-
-### Changelog
-
-#### Bugfixes
-
-* Correctly support `start_key` and `end_key` aliases ([#3833](https://github.com/pouchdb/pouchdb/issues/3833) [#4154](https://github.com/pouchdb/pouchdb/issues/4154))
-* Fix memory leak in `PouchDB` constructor ([#4157](https://github.com/pouchdb/pouchdb/issues/4157) [#4168](https://github.com/pouchdb/pouchdb/pull/4168) [#4182](https://github.com/pouchdb/pouchdb/pull/4182))
-* Update Uglify to patch security vulnerability ([#4203](https://github.com/pouchdb/pouchdb/issues/4203))
-* Fix inconsistent Date serialization in IndexedDB ([#3444](https://github.com/pouchdb/pouchdb/issues/3444))
-* Fix error for invalid `doc_ids` ([#2204](https://github.com/pouchdb/pouchdb/issues/2204))
-* Better CORS warning message ([#4189](https://github.com/pouchdb/pouchdb/issues/4189))
-* Fix memory adapter in IE10 by shimming `Function.prototype.name` ([#4216](https://github.com/pouchdb/pouchdb/issues/4216))
-* Don't fail replication if fetching uuid fails ([#4094](https://github.com/pouchdb/pouchdb/issues/4094))
-
-#### Code cleanup, simplification
-
-* Update `lie` ([#4130](https://github.com/pouchdb/pouchdb/issues/4130))
-* Deleted/simplified lots of code ([#4103](https://github.com/pouchdb/pouchdb/issues/4103) [#4121](https://github.com/pouchdb/pouchdb/issues/4121) [#4160](https://github.com/pouchdb/pouchdb/issues/4160) [#4144](https://github.com/pouchdb/pouchdb/issues/4144))
-
-#### Performance improvements
-
-* Avoid extra HTTP call for `destroy()` ([#4159](https://github.com/pouchdb/pouchdb/issues/4159))
-* Various fixes to improve performance of updating documents ([#3921](https://github.com/pouchdb/pouchdb/issues/3921) [#4140](https://github.com/pouchdb/pouchdb/issues/4140) [#4149](https://github.com/pouchdb/pouchdb/issues/4149) [#4151](https://github.com/pouchdb/pouchdb/issues/4151) [#4162](https://github.com/pouchdb/pouchdb/issues/4162) [#4183](https://github.com/pouchdb/pouchdb/issues/4183) [#4110](https://github.com/pouchdb/pouchdb/issues/4110) [#4185](https://github.com/pouchdb/pouchdb/issues/4185) [#4188](https://github.com/pouchdb/pouchdb/issues/4188))
-* Improve performance of `api.html` page in docs ([#4117](https://github.com/pouchdb/pouchdb/issues/4117))
-
-### Community news
-
-#### Slack channel
-
-PouchDB now has a [Slack channel](http://slack.pouchdb.com). It's linked to the [IRC channel](irc://freenode.net/#pouchdb), so any messages will show up in both.
-
-Please note: this isn't a vote against IRC. While we love open-source, decentralized software (such as PouchDB itself!), many folks find it easier and more familiar to collaborate with Slack. So we're happy to support both systems.
-
-#### First timers
-
-Inspired by Kent C. Dodd's article ["First Timers Only"](https://medium.com/@kentcdodds/first-timers-only-78281ea47455), we set up [two](https://github.com/pouchdb/pouchdb/issues/3883#issuecomment-130370436) [issues](https://github.com/pouchdb/pouchdb/issues/4154#issuecomment-134572814) designed for first-time contributors, with detailed instructions to get started with the PouchDB source code.
-
-We're happy to report that the experiment was a success. Both issues were fixed in no time flat &ndash; less than 24 hours each! And as a result, we've been pleased to welcome [Charlotte Spencer](https://github.com/charlotteis) and [Nicolas Brugneaux](https://github.com/nicolasbrugneaux) as PouchDB contributors. Welcome to the gang, Charlotte and Nicolas!
-
-If you'd like to join PouchDB's [esteemed roster of contributors](https://github.com/pouchdb/pouchdb/graphs/contributors) (161 and counting!), then hit us up in IRC, Slack, or Github, and we'll be happy to coach you to help find an issue where you can pitch in. We also plan to continue this program by marking issues as ["Help wanted"](https://github.com/pouchdb/pouchdb/labels/help%20wanted) and ["First-timers only"](https://github.com/pouchdb/pouchdb/labels/first%20timers%20only).
-
-#### PouchDB Server improvements
-
-[PouchDB Server](http://github.com/pouchdb/pouchdb-server) and its core, [express-pouchdb](http://github.com/pouchdb/express-pouchdb), have seen some notable improvements in the past month. In addition to a roughly 4% per-request [performance improvement](https://github.com/pouchdb/pouchdb-size/pull/2), the UI now supports [uploading attachments](https://github.com/pouchdb/express-pouchdb/pull/237) and sports a snazzier version of the Fauxton UI:
-
-{% include img.html src="fauxton_updated.png" alt="New Fauxton UI in PouchDB Server" %}
-
-This update fixes lots of UI and UX bugs with the Fauxton interface, as well as allowing an easy way to test the new [Mango query language](https://github.com/cloudant/mango), which are partially supported in PouchDB Server via [pouchdb-find](https://github.com/nolanlawson/pouchdb-find). You can get the latest version by running `npm install -g pouchdb-server`.
-
-Many thanks to Nick Colley, Marten de Vries, and the formidable [CouchDB Fauxton team](https://github.com/pouchdb/pouchdb-fauxton/graphs/contributors) for their help with this release!
-
-#### Hoodie + PouchDB Server = &#10084;
-
-In related news, Hoodie has [added support for PouchDB Server](https://twitter.com/gr2m/status/632197399314866176), replacing CouchDB as their default backend.
-
-This is a great vote of confidence for PouchDB Server, and shows how its combination of easy installation and near-complete API compatibility with CouchDB makes it a perfect drop-in replacement, especially during development and testing.
-
-### Performance report
-
-We recently had a [performance problem](https://github.com/pouchdb/pouchdb/issues/3921) reported to us via StackOverflow. So I took it as an opportunity to thoroughly profile the codebase and experiment with some performance improvements.
-
-#### Analysis of the problem
-
-The part of the code that was causing a slowdown was related to updating documents. Per the CouchDB spec, whenever a document is updated, we need to merge its [revision tree](https://wiki.apache.org/couchdb/Replication_and_conflicts) with that of the previous version. However, the merge algorithm was not very optimized, so PouchDB was spending a lot of time in JavaScript just traversing through tree structures, as well as allocating unnecessary memory along the way.
-
-The most shocking illustration of the slowdown came when we ran performance tests using the in-memory adapter. Most of the time, PouchDB is bound by the underlying storage engine (LevelDB, IndexedDB, and WebSQL), but in this case even the in-memory adapter was chugging along much too slowly.
-
-#### The fix is in
-
-The fix involved some major overhauls to the merge algorithm:
-
-* Use [well-known JavaScript optimization techniques](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers), such as removing functions-within-functions and preferring `for` loops to `forEach()`.
-* Where possible, cache the calculated metadata values such as the winning revision and whether or not the winner was deleted.
-* Simplify PouchDB's `extend()` and `clone()` methods, removing our [long-in-the-tooth jQuery version](https://github.com/pouchdb/pouchdb-extend).
-* Use less memory by avoiding `extend()` and `clone()` entirely when we don't need them.
-
-Of course, these improvements were justified by data! The Chrome [Dev Tools profiler](https://github.com/pouchdb/pouchdb/pull/4183#issue-102570121) and [Node.js flame graphs](https://github.com/pouchdb/pouchdb/pull/4185#issuecomment-133856702) are a performance junkie's best friends.
-
-#### Measuring the fix
-
-To determine how much we improved over PouchDB v4.0.0, I ran the [basic-updates test](https://github.com/pouchdb/pouchdb/blob/677450f58d1deb84039a15fb5180fbb2393dd81c/tests/performance/perf.basics.js#L39-L57) with 200 iterations, meaning that it inserted 100 documents and updated them 200 times. All numbers are in milliseconds, and were recorded on a 2013 MacBook Pro running OS X Yosemite.
-
-<div class="table-responsive">
-<table class="table">
-<tr>
-    <th></th>
-    <th>v4.0.0</th>
-    <th>v4.0.1</th>
-    <th>Improvement</th>
-</tr>
-<tr>
-<tr><th>Safari 9.0 (WebSQL)</th><td>24867</td><td>17232</td><td>30.70%</td></tr>
-<tr><th>Firefox 40 (IndexedDB)</th><td>50519</td><td>26265</td><td>48.01%</td></tr>
-<tr><th>Chrome 44 (IndexedDB)</th><td>49613</td><td>26667</td><td>46.25%</td></tr>
-<tr><th>Chrome 44 (WebSQL)</th><td>46336</td><td>26358</td><td>43.12%</td></tr>
-<tr><th>iojs 2.1.0 (LevelDB via LevelDOWN)</th><td>37593</td><td>15426</td><td>58.97%</td></tr>
-<tr><th>iojs 2.1.0 (in-memory via MemDOWN)</th><td>33908</td><td>11433</td><td>66.28%</td></tr>
-</tr>
-</table>
-</div>
-
-Note that these numbers don't apply to PouchDB as a whole &ndash; for instance, you can't really say "PouchDB is now 46% faster in Chrome." This test applies to a very specific part of the codebase (updating documents), so basic reads, writes, and secondary indexes will be largely unaffected.
-
-Just for fun, I also ran the above performance test against CouchDB 1.6.1, over HTTP. Surprisingly it finished in 10956 milliseconds, which is even faster than our in-memory adapter! So clearly we've still got some work to do, and I encourage any JavaScript performance gurus to [run the tests](https://github.com/pouchdb/pouchdb/blob/master/TESTING.md#performance-tests) and lend a hand.
-
-### A note on PouchDB performance
-
-PouchDB is a very fast database, and I think it holds up well compared to alternatives. It's worth noting, though, that we have a lot of factors that make performance a challenge.
-
-First off, PouchDB is optimized for syncing. This means that we have some complicated data structures (such as revision trees) that add overhead compared to databases that don't need to retain old or conflicting revisions of documents.
-
-Second off, PouchDB supports multiple storage engines, and they have different performance characteristics. For instance, `allDocs()` can be [40x slower in IndexedDB than in WebSQL](https://github.com/pouchdb/pouchdb/issues/3921#issuecomment-107954085) because joins and cursors are fairly slow in IndexedDB, whereas in WebSQL we can use one big SQL query to do it all.
-
-There's been [some](http://discourse.wicg.io/t/indexeddb-2-0-performance-improvements/916) [discussion](http://discourse.wicg.io/t/indexeddb-api-clean-up-promises/876) in the W3C about improving IndexedDB performance, and [IndexedDB v2](http://w3c.github.io/IndexedDB/) offers some new methods like `getAll()` that could boost performance. However, this has limited value for PouchDB, because 1) it only solves half the problem (IndexedDB cursors being slow) while leaving the other half unresolved (joins being slow), and 2) methods like `getAll()` are only implemented in recent versions of Chrome and Firefox, so it would significantly complicate the codebase to support both versions.
-
-Thirdly, PouchDB relies heavily on these underlying storage engines. This means that, when PouchDB gives you a callback after a `put()`, data has actually been written to disk, and when you do an `allDocs()`, PouchDB is actually progressively fetching data from disk. This disk-heavy model allows PouchDB to run well on low-memory devices (such as phones), but also means that it runs better when the storage engine provides better tools, which is why WebSQL is still faster than IndexedDB for us.
-
-#### What you can do about performance
-
-Here are some tips to get the best performance out of PouchDB:
-
-* Don't update your documents too many times. For instance, if you're writing a text editor, don't update the document for every keystroke; set a [debounce](http://underscorejs.org/#debounce), or allow the user to explicitly save.
-* Don't continually read the entire database in and out of memory; use [pagination](http://pouchdb.com/2014/04/14/pagination-strategies-with-pouchdb.html) and [the changes feed](http://pouchdb.com/2015/02/28/efficiently-managing-ui-state-in-pouchdb.html).
-* Prefer `allDocs()` to either `query()` or `pouchdb-find`. Building up secondary indexes [is expensive](http://pouchdb.com/guides/queries.html).
-
-If you are not using PouchDB's sync capabilities, or if you require complicated queries (such as full-text search) on a large set of data (>1000 documents), I would also advise looking into other databases. PouchDB is designed for sync and it excels at that, but if you have different needs, then you should explore other libraries.
-
-For instance, databases like [LocalForage](https://mozilla.github.io/localForage/), [Dexie](http://www.dexie.org/),
-[Lovefield](https://google.github.io/lovefield/), and [YDN-DB](http://dev.yathit.com/ydn-db/index.html) run in more-or-less the same browsers as PouchDB, but have a much simpler data model, where updated/removed data is simply overwritten. These databases are particularly good for quick storage, lookup, and querying. If you are not using sync, you will probably also appreciate the cognitive benefit of not having to think about `_rev`!
-
-If you need even more sophisticated querying capabilities and don't require a low memory footprint, then you could also look into in-memory databases such as [AlaSQL](http://alasql.org/) and [LokiJS](http://lokijs.org/). These databases can periodically write data to a storage engine like IndexedDB, but are primarily queried via in-memory methods, meaning they can be much faster than PouchDB because they don't have to touch disk. On the other hand, they have a high memory footprint and may drop data unless you are careful to flush the in-memory representation to disk.
-
-Make no mistake: PouchDB is committed to being the fastest JavaScript database it can be. However, our primary goal is correctness, especially when it comes to sync. (The [massive test suite](https://travis-ci.org/pouchdb/pouchdb) should be a testament to that.) Every design decision comes with tradeoffs, and our decisions are driven by the goal of providing a free, open-source database that 1) never drops data, 2) syncs like a champ, and 3) runs flawlessly in every modern browser. If PouchDB can do all that while being fast, then that's just icing on the cake!
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-09-12-pouchdb-4.0.2-a-little-extra.md b/docs/_posts/2015-09-12-pouchdb-4.0.2-a-little-extra.md
deleted file mode 100644
index 7a652b6..0000000
--- a/docs/_posts/2015-09-12-pouchdb-4.0.2-a-little-extra.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-layout: post
-
-title: PouchDB 4.0.2 - A Little Extra
-author: Nolan Lawson
-
----
-
-4.0.2 is a quick update to sneak in some important bugfixes in anticipation of the next monthly release.
-
-The most visible change in 4.0.2 is the long-awaited upgrade of `levelup` and `leveldown` to 1.x ([#3873](https://github.com/pouchdb/pouchdb/issues/3873)), which contains some big improvements to how `leveldown` is installed. With 4.0.2, instead of needing to recompile `leveldown` every time PouchDB is `npm install`ed, it will simply be downloaded thanks to [leveldown-prebuilt](https://github.com/mafintosh/leveldown-prebuilt). So if you've ever groaned at the dreaded `node-gyp rebuild` console message, hop onto 4.0.2 and enjoy the faster install times!
-
-Also noteworthy is that the in-memory adapter is now fully tested and working in IE 10+, thanks to fixes in [#4216](https://github.com/pouchdb/pouchdb/issues/4216).
-
-Another big change is that PouchDB is more stable when replicating during intermittent connectivity, thanks to a new "stateless constructor" in the HTTP adapter ([#4146](https://github.com/pouchdb/pouchdb/issues/4146)). Instead of kicking off HTTP requests immediately when you call `new PouchDB('http://example.com/db')`, the new version will wait for the first method call, such as `db.info()`.
-
-### Changelog
-
-#### Bugfixes
-
-* Handle errors thrown from `filter` functions ([#3356](https://github.com/pouchdb/pouchdb/issues/3356))
-* Upgrade `levelup` to 1.2.1, `leveldown` to 1.4.1, and `level-sublevel` to 6.5.0 ([#3873](https://github.com/pouchdb/pouchdb/issues/3873))
-* Stateless constructor for the HTTP adapter, fixes errors syncing while offline ([#4146](https://github.com/pouchdb/pouchdb/issues/4146))
-* Ensure document properties are maintained, e.g. docs with keys like `hasOwnProperty` ([#3968](https://github.com/pouchdb/pouchdb/issues/3968))
-* Validate attachment names don't start with `_` ([#3357](https://github.com/pouchdb/pouchdb/issues/3357))
-* Correctly respect the `revs_limit` of 1000, trim revision trees ([#4204](https://github.com/pouchdb/pouchdb/issues/4204))
-* Allow passing in opts to `destroy()` ([#4219](https://github.com/pouchdb/pouchdb/issues/4219))
-* Update `request` to 2.61.0 ([#4260](https://github.com/pouchdb/pouchdb/issues/4260))
-* Use `Function.prototype.name` shim consistently for IE ([#4216](https://github.com/pouchdb/pouchdb/issues/4216))
-* Better CORS warning ([#4256](https://github.com/pouchdb/pouchdb/issues/4256))
-
-### Thank yous
-
-A special thanks for this release goes to [Julian Gruber](https://github.com/juliangruber) of the [Level](https://github.com/level) community, without [whose help](https://github.com/dominictarr/level-sublevel/pull/96) we wouldn't have been able to upgrade `levelup`/`leveldown`/`level-sublevel`. Thanks, Julian!
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2015-10-06-pouchdb-5.0.0-five-years-of-pouchdb.md b/docs/_posts/2015-10-06-pouchdb-5.0.0-five-years-of-pouchdb.md
deleted file mode 100644
index 0c503f9..0000000
--- a/docs/_posts/2015-10-06-pouchdb-5.0.0-five-years-of-pouchdb.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-layout: post
-
-title: PouchDB 5.0.0 - Five years of PouchDB
-author: Nolan Lawson
-
----
-
-Fitting with the fact that [PouchDB turned five years old this year](https://github.com/pouchdb/pouchdb/commit/d600081962d3f54b410e5cfcf78cd413ad94abb9), we're proud to announce PouchDB 5.0.0. This release contains the usual number of bugfixes and improvements, as well as several deprecations, since it is a major version bump.
-
-The biggest news in terms of features is support for [\_bulk\_get](https://mail-archives.apache.org/mod_mbox/couchdb-dev/201509.mbox/%3CCA%2BvSmEYjimR3emsgHOTkNqdBcN_Rvh-V9gQZtDBVAEEcMO1TQQ%40mail.gmail.com%3E), which is a new CouchDB API that enables vastly faster replication, set to be debuted in CouchDB 2.0. This API is also shipped in the newly-released PouchDB Server 1.0.0, meaning you can test out the faster replication now.
-
-### Deprecations
-
-* Remove `PouchDB.destroy()` ([#4223](http://github.com/pouchdb/pouchdb/issues/4223))
-
-Having a `destroy()` function on the `PouchDB` object was always a little awkward, which is why we introduced the `db.destroy()` alternative. So now that `PouchDB.destroy()` is out, upgrading your code should look like this:
-
-```js
-PouchDB.destroy('mydb');
-```
-
-becomes:
-
-```js
-new PouchDB('mydb').destroy();
-```
-
-Keep in mind that the `PouchDB` object is no longer usable after you `destroy()` it. So you should call `new PouchDB()` again if you want to re-use it.
-
-* Remove CRUD events ([#4224](http://github.com/pouchdb/pouchdb/issues/4224))
-
-These events (`'create'`, `'update'`, and `'delete'`) were intended to make the `changes()` API easier to work with, but they ended up being too ambitious and confusing, so 5.0.0 removes them.
-
-If you are relying on these events, then you can upgrade like so:
-
-```js
-db.changes({live: true})
-  .on('create', createListener)
-  .on('update', updateListener)
-  .on('delete', deleteListener);
-```
-
-becomes:
-
-
-```js
-db.changes({live: true})
-  .on('change', function (change) {
-    if (change.deleted) {
-      deleteListener(change);
-    } else if (change.changes.length === 1 &&
-               /^1-/.test(change.changes[0].rev)) {
-      createListener(change);
-    } else {
-      updateListener(change);
-    }
-  });
-```
-
-Keep in mind that this "update vs. create" test is not foolproof (what happens if a `2-` document is the first version that gets synced? what happens if two conflicting `1-` revisions are synced?), but it will match the old behavior.
-
-Most of the time, your UI should be able to handle document "updates" or "creates" equivalently, so `change.deleted` becomes the only special case. See [Efficiently managing UI state with PouchDB](http://pouchdb.com/2015/02/28/efficiently-managing-ui-state-in-pouchdb.html) for some details about how to do this.
-
-* Remove `idb-alt` plugin ([#4222](http://github.com/pouchdb/pouchdb/issues/4222))
-
-This was an alternative IndexedDB adapter based on [Level.js](https://github.com/maxogden/level.js), which was experimental and probably unused by anyone except the PouchDB developers themselves.
-
-### New features
-
-* Implement `bulkGet()` ([#3424](http://github.com/pouchdb/pouchdb/issues/3424))
-* Add [FruitDOWN](https://github.com/nolanlawson/fruitdown) as a supported adapter ([#4329](http://github.com/pouchdb/pouchdb/issues/4329))
-* Allow user to specify Firefox persistent storage ([#4315](http://github.com/pouchdb/pouchdb/issues/4315))
-* Allow setting http options per request ([#3941](http://github.com/pouchdb/pouchdb/issues/3941))
-
-### Bugfixes
-
-* Maintain canceled state in replicator better ([#4276](http://github.com/pouchdb/pouchdb/issues/4276))
-* Don't mutate binary objects provided by the user ([#3955](http://github.com/pouchdb/pouchdb/issues/3955) [#4273](http://github.com/pouchdb/pouchdb/issues/4273))
-* Fire events on sync, eensure we only fire one active event ([#4251](http://github.com/pouchdb/pouchdb/issues/4251))
-* Catch errors from WebSQL `openDatabase()` ([#4018](http://github.com/pouchdb/pouchdb/issues/4018))
-* Ensure setup errors propagate to the API ([#4358](http://github.com/pouchdb/pouchdb/issues/4358))
-* Prevent replication firing extra events ([#4293](http://github.com/pouchdb/pouchdb/issues/4293))
-* Proper propagation of quota exceeded errors ([#4018](http://github.com/pouchdb/pouchdb/issues/4018))
-* Remove `'use strict'` from `eval()` ([#4344](http://github.com/pouchdb/pouchdb/issues/4344))
-* Alias `skip_setup` to `skipSetup` ([#3535](http://github.com/pouchdb/pouchdb/issues/3535))
-* Fix options usage within http adapter ([#4313](http://github.com/pouchdb/pouchdb/issues/4313))
-* Fix Firefox `FileReader` usage in a web worker ([#4402](http://github.com/pouchdb/pouchdb/issues/4402))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
\ No newline at end of file
diff --git a/docs/_posts/2015-11-03-cover-all.md b/docs/_posts/2015-11-03-cover-all.md
deleted file mode 100644
index 83a1d55..0000000
--- a/docs/_posts/2015-11-03-cover-all.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-layout: post
-
-title: PouchDB 5.1.0 - Cover all the things
-author: Dale Harvey
-
----
-
-It is time for the regularly scheduled PouchDB release, this month has a nice set of improvements, and we even managed to remove a little (`3KB`) around the edges.
-
-### Coverage
-
-We are now very happy to be hitting [100% coverage on our tests](https://coveralls.io/github/pouchdb/pouchdb/). This currently only covers Node.js and excludes some cases that are difficult to test but it does give us confidence that our shared code is very well tested and we can ensure new code that is merged has the same level of testing.
-
-### GreenKeeper
-
-We have had issues in the past with how to manage npm dependencies. Version ranges can lead to other people breaking PouchDB with their releases, and strict versions lead to us using stagnant packages and not being aware of upcoming breakages. During this month, the [hood.ie team](http://hood.ie) released [GreenKeeper](http://greenkeeper.io) which gives us best of both worlds, stable versions that are always kept up to date!
-
-### New features
-
-* Add an option to configure `withCredentials` on CORS requests ([#2513](http://github.com/pouchdb/pouchdb/issues/2513))
-* Allow user to disable `heartbeat` in HTTP requests ([#4490](http://github.com/pouchdb/pouchdb/issues/4490))
-
-### Bugfixes
-
-* Explain http error caused by checking for `_bulk_get` ([#4435](http://github.com/pouchdb/pouchdb/issues/4435))
-* Dont create a database just to delete it ([#4467](http://github.com/pouchdb/pouchdb/issues/4467))
-* Add friendly err msg to common leveldown err ([#4447](http://github.com/pouchdb/pouchdb/issues/4447))
-* Avoid empty bulkGet() ([#4474](http://github.com/pouchdb/pouchdb/issues/4474))
-* Fix http url with port 80 ([#247](https://github.com/pouchdb/express-pouchdb/issues/247))
-* Url encode http database name ([#4314](http://github.com/pouchdb/pouchdb/issues/4314))
-* Handle invalid view name consistently ([#4451](http://github.com/pouchdb/pouchdb/issues/4451))
-* Remove put implementation and fix local doc handling ([#1526](http://github.com/pouchdb/pouchdb/issues/1526))
-* Fix cross origin check ([#4501](http://github.com/pouchdb/pouchdb/issues/4501))
-
-### Get in touch
-
-Please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/_posts/2016-01-13-pouchdb-5.2.0-a-better-build-system-with-rollup.md b/docs/_posts/2016-01-13-pouchdb-5.2.0-a-better-build-system-with-rollup.md
deleted file mode 100644
index 50b711e..0000000
--- a/docs/_posts/2016-01-13-pouchdb-5.2.0-a-better-build-system-with-rollup.md
+++ /dev/null
@@ -1,105 +0,0 @@
----
-layout: post
-
-title: PouchDB 5.2.0&#58; A better build system with Rollup
-author: Nolan Lawson
-
----
-
-> "Rollup! Rollup for the mystery tour!"
-> - Lennon and McCartney
-
-Besides a slew of bugfixes and the new `revs_limit` feature, the big news about 5.2.0 is that PouchDB is now authored with ES6 modules rather than CommonJS. Using [Rollup](http://rollupjs.org/), it's transpiled into one big `index.js` for Node and an `index-browser.js` for Webpack/Browserify.
-
-The most immediate benefit is that PouchDB's minified/gzipped size has dropped by 3KB (6.7% smaller!) with no loss of functionality. This is thanks to Rollup's ability to remove the typical Browserify/Webpack cruft by [hoisting all submodules into a single scope](https://github.com/nolanlawson/rollup-comparison).
-
-Another benefit is that PouchDB is now insulated from subtle differences between build systems like Browserify, Webpack, Babel, and Rollup itself. This is an esoteric problem for JavaScript library authors, but I think it's worth going into detail, because it affects more libraries than just PouchDB.
-
-I'll explore that topic later on in the post, but first, here's the full changelog for 5.2.0:
-
-### Changelog
-
-#### Features and improvements
-
-* Implement `revs_limit` ([#2839](https://github.com/pouchdb/pouchdb/issues/2839))
-* Migrate to ES6/Rollup, build one `index.js` ([#4652](https://github.com/pouchdb/pouchdb/issues/4652))
-* Add ability to disable timeout in `changes()` ([#4583](https://github.com/pouchdb/pouchdb/issues/4583))
-
-#### Bugfixes
-
-* Return conflict error when inserting an unknown rev ([#4712](https://github.com/pouchdb/pouchdb/issues/4712))
-* Catch XHR errors and propagate ([#4595](https://github.com/pouchdb/pouchdb/issues/4595))
-* Fix and test Webpack ([#4700](https://github.com/pouchdb/pouchdb/issues/4700))
-* Improve error when user sends invalid base64 ([#4208](https://github.com/pouchdb/pouchdb/issues/4208))
-* Consider changes erroring a valid result ([#4677](https://github.com/pouchdb/pouchdb/issues/4677))
-* Allow bulkGet requests without an explicit rev ([#4530](https://github.com/pouchdb/pouchdb/issues/4530)) 
-* Fix for xhr.upload detection failing ([#4560](https://github.com/pouchdb/pouchdb/issues/4560))
-* Coerce options which should be numbers to number ([#4578](https://github.com/pouchdb/pouchdb/issues/4578))
-* Add timeout option to replication ([#4540](https://github.com/pouchdb/pouchdb/issues/4540))
-* Remove binary string conversion ([#4529](https://github.com/pouchdb/pouchdb/issues/4529))
-* Remove CORS explanation ([#4677](https://github.com/pouchdb/pouchdb/issues/4677))
-* Add browser sniffing and remove nonce by default ([#4543](https://github.com/pouchdb/pouchdb/issues/4543))
-* Remove unneeded host.headers from ajax ([#4567](https://github.com/pouchdb/pouchdb/issues/4567))
-* Fix double-encoding name in http adapter ([#4514](https://github.com/pouchdb/pouchdb/issues/4514))
-* Fix and document heartbeat for replication ([#4538](https://github.com/pouchdb/pouchdb/issues/4538))
-* Fallback from `_bulk_get` on 50x requests ([#4542](https://github.com/pouchdb/pouchdb/issues/4542))
-* Remove Cordova init checks ([#4756](https://github.com/pouchdb/pouchdb/issues/4756))
-* Reset `changedDocs` in `write_docs` ([#4627](https://github.com/pouchdb/pouchdb/issues/4627))
-
-### PouchDB and JavaScript build systems
-
-To explain why we're now using Rollup to bundle one big `index.js` for Node, we'll need to take a look at the open-source JavaScript landscape, as it stands in 2016.
-
-I've been working on PouchDB for about two years. In that short amount of time, I've seen the frontend ecosystem largely transition from prebuilt `<script>`-ready JavaScript files, usually distributed via Bower, CDN, or direct download, to Node modules distributed by npm and directly consumed by build tools like Browserify, Webpack, Babel, Grunt, Gulp, etc.
-
-A big impact of this is that library authors no longer have control over the "last mile." Whereas our code used to be plopped directly into an HTML page (or merely concatenated), nowadays it's often parsed, chopped up, and transformed before it reaches that HTML page. This process inevitably introduces bugs and inconsistencies.
-
-For instance, PouchDB has been [struggling with Webpack support](https://gist.github.com/nolanlawson/e5e3b3856f1a8347f277) for much of the past year. The number of times we've had Webpack-related bugs filed on us, and the number of times we've later regressed because we only test with Browserify, eventually compelled us to [test Webpack separately](https://github.com/pouchdb/pouchdb/pull/4701). This means we're essentially testing both Browserify and Webpack as build targets.
-
-Think this sounds extreme? Consider this example.
-
-#### Example 1: requiring JSON
-
-Let's say you added this seemingly-innocuous line of code to your JavaScript library:
-
-```js
-MyLibrary.version = require('./package.json').version;
-```
-
-This will work in Browserify and Node, but it will break in Webpack unless the end-user adds a special [json-loader](https://github.com/webpack/json-loader) to their Webpack configuration. 
-
-Does your library do this? Do you have a _dependency_ that does this? Then congratulations, you cannot fix this for your users. All you can do is document it in your README and/or endure the inevitable bug reports.
-
-This is not something Webpack intends to fix, since it seems to constitute a philosophical difference between Browserify and Webpack. Their argument is that end-users should have control over how libraries are built. (You can read [this discussion](https://github.com/webpack/webpack/issues/378) for details.)
-
-#### Example 2: Browserify transforms
-
-Another good example of Browserify/Webpack differences is [Browserify transforms](https://github.com/substack/node-browserify/wiki/list-of-transforms). These are modules that can transform your library at build time, when it's consumed by Browserify.
-
-Transforms are very popular in the Browserify ecosystem, but unfortunately they don't work in Webpack unless you use the [transform-loader](https://github.com/webpack/transform-loader). Worse, this is another thing that end-users are expected to configure for every dependency (and every dependency of a dependency&hellip;).
-
-So if your project is built with Browserify, it's easy to accidentally add a Browserify transform, while forgetting that it will break for Webpack users. (We nearly made that mistake ourselves, before we started testing Webpack.) So the only reasonable choice for library authors is to avoid Browserify transforms entirely.
-
-#### Example 3: strict mode
-
-To stop picking on Webpack for a bit, I also [recently blogged about a bug](http://nolanlawson.com/2015/12/28/how-to-fix-a-bug-in-an-open-source-project/) in the ["buffer" project](https://github.com/feross/buffer) that was caused by Babel re-interpreting the code as strict, even though it was not distributed in strict mode. This is another great example of a "last mile" bug that ended up being something the library author needed to deal with.
-
-Of course, in this case, the library author could have just said "not my bug." But then the Babel authors might have (quite reasonably) responded, "your library should be strict; we don't support non-strict code," at which point it would become a game of hot potato. And all the while, end-users would be adding messy hacks to their build scripts to work around the issue.
-
-#### Lessons from the browser world
-
-This story should sound familiar. We've been here before. JavaScript developers have always had to struggle with a hostile and unpredictable environment, which required us to write robust code that could anticipate bugs and implementation differences. Of course, I'm talking about the browser.
-
-Now, I won't argue that writing code for Browserify, Webpack, Babel, and friends is nearly as difficult as writing code for a half-dozen browsers, but it's definitely getting there. So in my opinion, the only reasonable solution is to start bundling code before distribution on npm, which is desirable anyway since we have so many nice tools for transpiling future JavaScript to browser-safe ES5 (such as Babel itself).
-
-The benefits are clear: we can use Browserify transforms and `require('./package.json')` and whatever else we want, as long as they're only _compile steps_ that build a bundle to be consumed by Node (and therefore Browserify/Webpack). As a bonus, this allows us to build a smaller and sleeker bundle, which is also faster for the end-user to build, since most of the build steps have already been run in advance.
-
-I believe most JavaScript libraries are already moving in this direction, so this puts PouchDB firmly in that bandwagon. But to be clear: we don't intend to start using all the various experimental ES6/ES7 features in PouchDB. In fact, we are _only_ transforming ES6 modules into CommonJS ; in all other ways, PouchDB is still standard ES5. The reason we're doing this is that transpiled ES5 is often cruftier than hand-written ES5. So for now, we're avoiding it.
-
-The goal of implementing CouchDB in JavaScript has always been an ambitious one. The fact that we've done so in ~45KB is an even more impressive accomplishment. But despite the challenges, we're going to keep the bar high; we even have [a CI test](https://github.com/pouchdb/pouchdb/blob/541867814da313855bd802cdc87cce8fcfb12320/bin/verify-bundle-size.sh) that fails if our minified bundle ever exceeds 50KB.
-
-Along those same lines, we also have an [open issue](https://github.com/pouchdb/pouchdb/issues/4449) to add the ability to create custom builds (e.g. no WebSQL, no map/reduce, no replication, etc.). Presumably this can be made even easier with Rollup's tree-shaking capabilities, but we're still investigating this feature.
-
-### Get in touch
-
-As always, please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
\ No newline at end of file
diff --git a/docs/_posts/2016-03-04-pouchdb-5.3.0-sqlite-support-in-node.md b/docs/_posts/2016-03-04-pouchdb-5.3.0-sqlite-support-in-node.md
deleted file mode 100644
index b615216..0000000
--- a/docs/_posts/2016-03-04-pouchdb-5.3.0-sqlite-support-in-node.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-layout: post
-
-title: PouchDB 5.3.0&#58; SQLite support in Node
-author: Nolan Lawson
-
----
-
-PouchDB 5.3.0 is released today, with a new feature: SQLite support in Node,
-using [node-websql](https://github.com/nolanlawson/node-websql). This means
-that, in addition to the LevelDB-based [LevelDOWN](https://github.com/Level/leveldown) (or any [other *DOWN adapter](https://github.com/Level/levelup/wiki/Modules#storage-back-ends)), you can now
-also use [sqlite3](https://github.com/mapbox/node-sqlite3), via PouchDB's
-WebSQL adapter.
-
-To get started, just do:
-
-```js
-require('pouchdb/extras/websql');
-var db = new PouchDB('database.db', {adapter: 'websql'})
-```
-
-This feature will also be available in [PouchDB Server](https://github.com/pouchdb/pouchdb-server/), as `pouchdb-server --sqlite`.
-
-Note that this doesn't change the behavior of the WebSQL adapter in the browser.
-That adapter is still bundled by default in PouchDB's browser version. For more
-details, see the ["extras" API documentation](http://pouchdb.com/api.html#extras).
-
-### Changelog
-
-#### Features
-
-* Support WebSQL in Node via node-websql ([#4915](https://github.com/pouchdb/pouchdb/issues/4915))
-
-#### Bugfixes
-
-* Escape unicode in auth header ([#4903](https://github.com/pouchdb/pouchdb/issues/4903))
-* Fix cache-busting in Edge ([#4827](https://github.com/pouchdb/pouchdb/issues/4827))
-* Better error when trying to re-use a destroyed database ([#4339](https://github.com/pouchdb/pouchdb/issues/4339))
-* Cache ddoc views and filters ([#4867](https://github.com/pouchdb/pouchdb/issues/4867))
-* Allow creating databases with reserved words ([#4898](https://github.com/pouchdb/pouchdb/issues/4898))
-* Fix missing key in ungrouped (custom) reduce functions ([#4878](https://github.com/pouchdb/pouchdb/issues/4878))
-* Fix leaking of stemmed revisions ([#4372](https://github.com/pouchdb/pouchdb/issues/4372))
-
-### Get in touch
-
-As always, please [file issues](https://github.com/pouchdb/pouchdb/issues) or [tell us what you think](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md#get-in-touch). And as always, a big thanks to all of our [new and existing contributors](https://github.com/pouchdb/pouchdb/graphs/contributors)!
diff --git a/docs/adapters.md b/docs/adapters.md
deleted file mode 100644
index 830b5ea..0000000
--- a/docs/adapters.md
+++ /dev/null
@@ -1,357 +0,0 @@
----
-layout: 2ColLeft
-title: Adapters
-sidebar: nav.html
----
-
-PouchDB is not a self-contained database; it is a CouchDB-style abstraction layer over other databases. By default, PouchDB ships with [IndexedDB][] and [WebSQL][] adapters in the browser, and a [LevelDB][] adapter in Node.js.
-
-PouchDB attempts to provide a consistent API that "just works" across every browser and JavaScript environment, and in most cases, you can just use the defaults. However, if you're trying to reach the widest possible audience, or if you want the best performance, then you will sometimes want to tinker with the adapter settings.
-
-#### Topics:
-* [PouchDB in the browser](#pouchdb_in_the_browser)
-* [PouchDB in Node.js](#pouchdb_in_node_js)
-* [PouchDB over HTTP](#pouchdb_over_http)
-* [More resources](#more_resources)
-
-
-{% include anchor.html title="PouchDB in the browser" hash="pouchdb_in_the_browser"%}
-
-In the browser, PouchDB prefers IndexedDB, and falls back to WebSQL if IndexedDB is not available.  As of 2015, the browser support looks like this:
-
-### Desktop
-
-<div class="table-responsive">
-<table class="table">
-<tr>
-    <td></td>
-	<th><img src="static/img/browser-logos/internet-explorer_32x32.png" alt="IE"/></th>
-	<th><img src="static/img/browser-logos/firefox_32x32.png" alt="Firefox"/></th>
-	<th><img src="static/img/browser-logos/chrome_32x32.png" alt="Chrome"/></th>
-	<th><img src="static/img/browser-logos/safari_32x32.png" alt="Safari"/></th>
-	<th><img src="static/img/browser-logos/opera_32x32.png" alt="Opera"/></th>
-</tr>
-<tr>
-    <th>Adapter</th>
-	<th>IE</th>
-	<th>Firefox</th>
-	<th>Chrome</th>
-	<th>Safari</th>
-	<th>Opera</th>
-</tr>
-<tr>
-    <td>IndexedDB</td>
-	<td>&#10003; (10+)</td>
-	<td>&#10003;</td>
-	<td>&#10003;</td>
-	<td></td>
-	<td>&#10003;</td>
-</tr>
-<tr>
-	<td>WebSQL</td>
-	<td></td>
-	<td></td>
-	<td>&#10003;</td>
-	<td>&#10003;</td>
-	<td>&#10003;</td>
-</tr>
-</table>
-</div>
-
-### Mobile
-
-<div class="table-responsive">
-<table class="table">
-<tr>
-    <th></th>
-	<th><img src="static/img/browser-logos/safari-ios_32x32.png" alt="Safari iOS"/></th>
-	<th><img src="static/img/browser-logos/opera_32x32.png" alt="Opera"/></th>
-	<th><img src="static/img/browser-logos/android_32x32.png" alt="Android"/></th>
-	<th><img src="static/img/browser-logos/blackberry_32x32.png" alt="BlackBerry"/></th>
-	<th><img src="static/img/browser-logos/opera_32x32.png" alt="Opera"/></th>
-	<th><img src="static/img/browser-logos/chrome-android_32x32.png" alt="Chrome for Android"/></th>
-	<th><img src="static/img/browser-logos/firefox_32x32.png" alt="Firefox for Android"/></th>
-	<th><img src="static/img/browser-logos/internet-explorer-tile_32x32.png" alt="IE"/></th>
-</tr>
-<tr>
-    <th>Adapter</th>
-	<th>iOS Safari</th>
-	<th>Opera Mini</th>
-    <th>Android Browser</th>
-	<th>BlackBerry Browser</th>
-	<th>Opera Mobile</th>
-	<th>Chrome for Android</th>
-	<th>Firefox for Android</th>
-	<th>IE Mobile</th>
-</tr>
-<tr>
-    <td>IndexedDB</td>
-    <td></td>
-    <td></td>
-    <td>&#10003; (4.4+)</td>
-    <td>&#10003; (10+)</td>
-    <td>&#10003; (21+)</td>
-    <td>&#10003;</td>
-    <td>&#10003;</td>
-    <td>&#10003;</td>
-<tr>
-<tr>
-    <td>WebSQL</td>
-    <td>&#10003;</td>
-    <td></td>
-    <td>&#10003;</td>
-    <td>&#10003;</td>
-    <td>&#10003;</td>
-    <td>&#10003;</td>
-    <td></td>
-    <td></td>
-<tr>
-</table>
-</div>
-
-{% include alert/start.html variant="info"%}
-Safari 7.1+ and iOS 8+ supposedly support IndexedDB, but their implementation has many bugs, so PouchDB currently ignores it.
-{% include alert/end.html%}
-
-If you're ever curious which adapter is being used in a particular browser, you can use the following method:
-
-```js
-var pouch = new PouchDB('myDB');
-console.log(pouch.adapter); // prints either 'idb' or 'websql'
-```
-
-
-### SQLite plugin for Cordova/PhoneGap
-
-On Cordova/PhoneGap, the native SQLite database is often a popular choice, because it allows unlimited storage (compared to [IndexedDB/WebSQL storage limits](http://www.html5rocks.com/en/tutorials/offline/quota-research)). It also offers more flexibility in backing up and pre-loading databases, because the SQLite files are directly accessible to app developers.
-
-Luckily, there is a [SQLite Plugin][] (also known as SQLite Storage) that accomplishes exactly this.  If you include this plugin in your project, then PouchDB will automatically pick it up based on the `window.sqlitePlugin` object.
-
-However, this only occurs if the adapter is `'websql'`, not `'idb'` (e.g. on Android 4.4+).  To force PouchDB to use the WebSQL adapter, you can do:
-
-```js
-var db = new PouchDB('myDB', {adapter: 'websql'});
-```
-
-Note that a recent change to Cordova SQLite Plugin requires the `location` or `iosDatabaseLocation` parameters in the openDatabase and deleteDatabase calls (the second is preferred - see [SQLite Plugin][] for details). In PouchDB, all given options are passed through to the SQLite plugin, so you can pass this param like so:
-
-```js
-var db = new PouchDB('myDB', {adapter: 'websql', iosDatabaseLocation: 'default'});
-```
-
-
-If you are unsure whether PouchDB is using the SQLite Plugin or not, just run:
-
-```js
-db.info().then(console.log.bind(console));
-```
-
-This will print some database information, including the attribute `sqlite_plugin`, which will be `true` if the SQLite Plugin is being used.
-
-{% include alert/start.html variant="warning"%}
-{% markdown %}
-
-The SQLite Plugin does not currently pass the PouchDB test suite. It also tends to be slower than direct IndexedDB/WebSQL.
-
-We recommend avoiding the SQLite Plugin, unless you are hitting the 50MB storage limit in iOS or you require native or preloaded access to the database files.
-
-{% endmarkdown %}
-{% include alert/end.html%}
-
-### Cordova SQLite Plugin 2
-
-There is now a rewrite of the SQLite Plugin available, appropriately named [SQLite Plugin 2][], which should be a drop-in replacement for the SQLite Plugin.  We recommend preferring the [SQLite Plugin 2][] over the original, because it passes the PouchDB test suite on both iOS and Android.  Note that the rewrite does not require the `location` or `iosDatabaseLocation` parameter, as the SQLite Plugin does.
-
-### Browser adapter plugins
-
-PouchDB also offers separate browser plugins that use backends other than IndexedDB and WebSQL. These plugins fully pass the PouchDB test suite and are rigorously tested in our CI process.
-
-**Downloads:**
-
-* [pouchdb.memory.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.memory.js) (Minified: [pouchdb.memory.min.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.memory.min.js))
-* [pouchdb.localstorage.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.localstorage.js) (Minified: [pouchdb.localstorage.min.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.localstorage.min.js))
-* [pouchdb.fruitdown.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.fruitdown.js) (Minified: [pouchdb.fruitdown.min.js](https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb.fruitdown.min.js))
-
-{% include alert/start.html variant="warning"%}
-{% markdown %}
-These plugins add a hefty footprint due to external dependencies, so take them with a grain of salt. You may want to [use the Browserify/Webpack versions](/api.html#extras) to deduplicate code and create a smaller bundle.
-{% endmarkdown %}
-{% include alert/end.html%}
-
-#### In-memory adapter
-
-If you want a quick database for your unit tests, you can use the `pouchdb.memory.js` plugin, which offers a pure in-memory PouchDB:
-
-```html
-<script src="pouchdb.js"></script>
-<script src="pouchdb.memory.js"></script>
-<script>
-  // this pouch is ephemeral; it only exists in memory
-  var pouch = new PouchDB('mydb', {adapter: 'memory'});
-</script>
-```
-
-This pouch will act exactly like a normal one &ndash; replicating, storing attachments, pagination, etc. &ndash; but it will be deleted as soon as the user closes their browser. However, multiple `PouchDB` objects with the same database name will share the same data:
-
-```js
-// pouch1 and pouch2 will share the same data
-var pouch1 = new PouchDB('myDB', {adapter: 'memory'});
-var pouch2 = new PouchDB('myDB', {adapter: 'memory'});
-
-// pouch3 will have its own data
-var pouch3 = new PouchDB('myOtherDB', {adapter: 'memory'});
-```
-
-#### LocalStorage adapter
-
-If you need to support very old browsers, such as IE &le; 9.0 and Opera Mini, you can use the `pouchdb.localstorage.js` plugin, which allows PouchDB to fall back to [LocalStorage][] on browsers that don't support either IndexedDB or WebSQL.  The [es5-shims][] will also be necessary.
-
-```html
-<script src="pouchdb.js"></script>
-<script src="pouchdb.localstorage.js"></script>
-<script>
-  // this pouch is backed by LocalStorage
-  var pouch = new PouchDB('mydb', {adapter: 'localstorage'});
-</script>
-```
-
-{% include alert/start.html variant="warning"%}
-The LocalStorage plugin should be considered highly experimental, and the underlying structure may change in the future.  Currently it stores all document IDs in memory, which works fine on small databases but may crash on larger databases.  You can follow <a href='https://github.com/No9/localstorage-down'>localstorage-down</a> to track our progress.
-{% include alert/end.html %}
-
-#### FruitDOWN adapter
-
-If you need to support IndexedDB in Apple browsers (which PouchDB normally does not support due to instability), then you can use FruitDOWN, which works over all IndexedDB implementations at the expense of using a much smaller part of the IndexedDB API and therefore being slower and less efficient.
-
-```html
-<script src="pouchdb.js"></script>
-<script src="pouchdb.fruitdown.js"></script>
-<script>
-  // this pouch is backed by FruitDOWN
-  var pouch = new PouchDB('mydb', {adapter: 'fruitdown'});
-</script>
-```
-
-{% include anchor.html title="PouchDB in Node.js" hash="pouchdb_in_node_js"%}
-
-In Node.js, the adapter situation is much simpler than in browsers.  By default, if you create a PouchDB like this one:
-
-```js
-var pouch = new PouchDB('./path/to/db');
-```
-
-then a LevelDB-based database will be created in the directory `./path/to/db`.
-
-Plus, since the LevelDB adapter is based on [LevelDOWN][], you also benefit from the rich ecosystem of LevelDOWN-based adapters. They may be installed using plain old `npm install` and `require()`. Below are a few examples.
-
-#### In-memory
-
-Just as in the browser, you can create a pure in-memory pouch based on [MemDOWN][]:
-
-```
-$ npm install memdown
-```
-
-then:
-
-```js
-var pouch = new PouchDB('myDB', {db: require('memdown')});
-```
-
-Notice that in Node.js, we use the key `'db'` instead of `'adapter'`.  In Node.js the adapter is always called `'leveldb'` for historical reasons.
-
-#### Riak-based adapter
-
-This pouch is backed by [RiakDOWN][]:
-
-```
-$ npm install riakdown
-```
-
-then:
-
-```js
-var pouch = new PouchDB('riak://localhost:8087/somebucket', {db: require('riakdown')});
-```
-
-#### More LevelDOWN adapters
-
-There are many other LevelDOWN-based plugins &ndash; far too many to list here. You can find a [mostly-complete list on Github](https://github.com/rvagg/node-levelup/wiki/Modules#storage-back-ends) that includes implementations on top of MySQL, Windows Azure Table Storage, and SQLite.
-
-#### node-websql adapter
-
-In addition to the LevelDOWN-based adapters, you can also use PouchDB over
-[SQLite3](https://github.com/mapbox/node-sqlite3) in Node, using the WebSQL adapter and
-[node-websql](https://github.com/nolanlawson/node-websql):
-
-```js
-var PouchDB = require('pouchdb');
-require('pouchdb/extras/websql');
-
-var db = new PouchDB('mydatabase.db', {adapter: 'websql'});
-```
-
-This should be more efficient than something like [sqldown](https://github.com/calvinmetcalf/SQLdown), because
-instead of using a LevelDB-esque adapter over SQLite, PouchDB is directly using
-SQLite queries to build the database.
-
-
-{% include alert/start.html variant="warning"%}
-We do not currently test against any LevelDOWN adapters other than LevelDB and MemDOWN, so the other backends should be considered experimental.
-{% include alert/end.html%}
-
-{% include anchor.html title="PouchDB over HTTP" hash="pouchdb_over_http"%}
-
-In both the browser and in Node.js, PouchDB can also function as a straightforward API on top of any [CouchDB](https://couchdb.apache.org/)-compliant database:
-
-```js
-var pouch = new PouchDB('http://my-site.com:5984/my-db');
-var securePouch = new PouchDB('https://my-secure-site.com:5984/my-secure-db');
-```
-
-You can also sync to and from these databases to your local PouchDB.
-
-Currently PouchDB has full support for:
-
-* CouchDB 1.x ([tested in CI](https://travis-ci.org/pouchdb/pouchdb))
-* [IrisCouch](http://www.iriscouch.com/) (same as 1.x)
-* [Couchappy](https://www.couchappy.com/) (same as 1.x)
-* CouchDB 2.x ([tested in CI](https://travis-ci.org/pouchdb/pouchdb))
-* [Cloudant](https://cloudant.com/) (roughly the same as 2.x)
-* [PouchDB Server](https://github.com/pouchdb/pouchdb-server) ([tested in CI](https://travis-ci.org/pouchdb/pouchdb))
-* [PouchDB Server --in-memory mode](https://github.com/pouchdb/pouchdb-server) ([tested in CI](https://travis-ci.org/pouchdb/pouchdb))
-
-[Couchbase Sync Gateway](http://docs.couchbase.com/sync-gateway/) support is [in progress](https://github.com/pouchdb/pouchdb/pull/3521). It will work, but you may run into issues, especially with [attachments](https://github.com/pouchdb/pouchdb/issues/2832). [Drupal 8](http://wearepropeople.com/blog/a-content-staging-solution-for-drupal-8-and-more) has also announced support for PouchDB, and there is [rcouch](https://github.com/rcouch/rcouch) as well, but these are both untested by PouchDB.
-
-If you are ever unsure about a server, consider replicating from PouchDB to CouchDB, then from that CouchDB to the other server.
-
-#### PouchDB Server
-
-[PouchDB Server](https://github.com/pouchdb/pouchdb-server) is a standalone REST server that implements the CouchDB API, while using a LevelDB-based PouchDB under the hood. It also supports an `--in-memory` mode and any [LevelDOWN][] adapter, which you may find handy.
-
-PouchDB Server passes the PouchDB test suite at 100%, but be aware that it is not as full-featured or battle-tested as CouchDB.
-
-#### PouchDB Express
-
-The underlying module for PouchDB Server, [Express PouchDB](https://github.com/pouchdb/express-pouchdb) is an Express submodule that mimics most of the CouchDB API within your Express application.
-
-{% include anchor.html title="More resources" hash="more_resources"%}
-
-The best place to look for information on which browsers support which databases is [caniuse.com](http://caniuse.com).  You can consult their tables on browser support for various backends:
-
-* [IndexedDB](http://caniuse.com/indexeddb)
-* [WebSQL](http://caniuse.com/sql-storage)
-* [LocalStorage](http://caniuse.com/namevalue-storage)
-
-[IndexedDB]: http://www.w3.org/TR/IndexedDB/
-[WebSQL]: http://www.w3.org/TR/webdatabase/
-[LevelDB]: https://code.google.com/p/leveldb/
-[LocalStorage]: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
-[es5-shims]: https://github.com/es-shims/es5-shim
-[sqlite plugin]: https://github.com/brodysoft/Cordova-SQLitePlugin
-[sqlite plugin 2]: https://github.com/nolanlawson/cordova-plugin-sqlite-2
-[leveldown]: https://github.com/rvagg/node-leveldown
-[level-js]: https://github.com/maxogden/level.js
-[memdown]: https://github.com/rvagg/memdown
-[localstorage-down]: https://github.com/No9/localstorage-down
-[RiakDOWN]: https://github.com/nlf/riakdown
diff --git a/docs/api.html b/docs/api.html
deleted file mode 100644
index 9d3ca1c..0000000
--- a/docs/api.html
+++ /dev/null
@@ -1,36 +0,0 @@
----
-layout: 2ColLeft
-title: API Reference
-sidebar: api.html
-edit: false
----
-
-{% markdown %}
-
-{% include api/overview.html %}
-{% include api/create_database.html %}
-{% include api/delete_database.html %}
-{% include api/create_document.html %}
-{% include api/fetch_document.html %}
-{% include api/delete_document.html %}
-{% include api/batch_create.html %}
-{% include api/batch_fetch.html %}
-{% include api/changes.html %}
-{% include api/replication.html %}
-{% include api/sync.html %}
-{% include api/save_attachment.html %}
-{% include api/get_attachment.html %}
-{% include api/delete_attachment.html %}
-{% include api/query_database.html %}
-{% include api/view_cleanup.html %}
-{% include api/database_information.html %}
-{% include api/compaction.html %}
-{% include api/revisions_diff.html %}
-{% include api/bulk_get.html %}
-{% include api/events.html %}
-{% include api/defaults.html %}
-{% include api/plugins.html %}
-{% include api/extras.html %}
-{% include api/debug_mode.html %}
-
-{% endmarkdown %}
diff --git a/docs/blog/index.html b/docs/blog/index.html
deleted file mode 100644
index 9791cc0..0000000
--- a/docs/blog/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
----
-layout: default
-title: Blog
-edit: false
----
-
-<article class='container'>
-<div class='row'>
-<div class='col-md-8'>
-{% for post in paginator.posts %}
-
-<a class='h3' href='{{ site.baseurl }}{{ post.url }}'>{{ post.title }}</a>
-{% include post_details.html %}
-
-{% endfor %}
-<ul class='pagination'>
-  <li {% if paginator.page == 1 %}class='disabled'{% endif %}><a href='{{paginator.previous_page_path | replace:'/index.html','' }}/'>&laquo;</a></li>
-  {% for page in (1..paginator.total_pages) %}
-    {% if page == paginator.page %}
-    <li class='active'><a>{{page}}</a></li>
-    {% elsif page == 1 %}
-    <li><a href='/blog/'>{{page}}</a></li>
-    {% else %}
-    <li><a href='/blog/page{{page}}/'>{{page}}</a></li>
-    {% endif %}
-  {% endfor %}
-  <li {% if paginator.page == paginator.total_pages %} class='disabled' {% endif %}><a href='{{paginator.next_page_path}}/'>&raquo;</a></li>
-</ul>
-</div>
-</div>
-</article>
diff --git a/docs/errors.md b/docs/errors.md
deleted file mode 100644
index fef0aba..0000000
--- a/docs/errors.md
+++ /dev/null
@@ -1,313 +0,0 @@
----
-layout: 2ColLeft
-title: Common Errors
-sidebar: nav.html
----
-
-{% include anchor.html class="h3" title="No 'Access-Control-Allow-Origin' header" hash="no_access_control_allow_origin_header" %}
-
-If you see the error:
-
-> XMLHttpRequest cannot load [...]
-> No 'Access-Control-Allow-Origin' header is present on the requested resource.
-> Origin [...] is therefore not allowed access.
-
-or this one:
-
-> Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://[couchDBIP]:[couchDBPort]/[dbname]/?_nonce=[request hash]. This can be fixed by moving the resource to the same domain or enabling CORS
-
-it's because you need to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) on CouchDB/IrisCouch/whatever you're using. Otherwise, your scripts can only access the server database if they're served from the same origin &#8212; the protocol (ex: _http://_, _https://_), domain, and port number must match.
-
-You can enable CORS in CouchDB using `curl` or the Futon web interface, but we've saved you some time by making a Node script called [add-cors-to-couchdb](https://github.com/pouchdb/add-cors-to-couchdb). Just run:
-
-{% highlight bash %}
-$ npm install -g add-cors-to-couchdb
-$ add-cors-to-couchdb
-{% endhighlight %}
-
-Or if your database is not at `127.0.0.1:5984`:
-
-{% highlight bash %}
-$ add-cors-to-couchdb http://me.iriscouch.com \
-    -u myusername -p mypassword
-{% endhighlight %}
-
-You can check that CORS is now enabled by visiting [http://localhost:5984/_utils/config.html](http://localhost:5984/_utils/config.html) in your browser. You should see something like this:
-
-{% include img.html src="cors_in_couchdb.png" alt="CORS settings in CouchDB" %}
-
-{% include anchor.html class="h3" title="PouchDB throws a `No valid adapter found` error" hash="no_valid_adapter" %}
-
-Reading from/writing to a local database from an `iframe` with a different origin will cause PouchDB to throw a `No valid adapter found` error in Firefox. This is due to Firefox's IndexedDB implementation.
-
-IndexedDB has a same-origin restriction. Read/write operations from another origin will always fail, but only Firefox triggers a `No valid adapter found` error. Chrome / Opera will instead throw an [`UnknownError`](#unknown_error_chrome).
-
-{% include anchor.html class="h3" title="iOS/Safari: \"there was not enough remaining storage space\"" hash="not_enough_space" %}
-
-On iOS and Safari, if you expect your app to use more than 5MB of space, you will need to request the space up-front from the user.  In certain versions, notably Safari/iOS 7, you can never request more than what the user originally grants you.
-
-{% include img.html src="safari_popup.png" alt="Safari storage quota popup" %}
-
-To get around this, when you create your PouchDB, use the `opts.size` option for the expected _maximum_ size of the database in MB.  Valid increments are 10, 50, 100, 500, and 1000.  For instance, if you request 50, then Safari will show a popup saying "allow 50MB?" but if you request 51, then Safari will show a popup saying "allow 100MB?".
-
-If you don't use the `size` option, then you'll be able to use up to 5MB without any popup, but then once you use more, there will be a popup asking for 10.
-
-```js
-new PouchDB('mydb', {size: 10}); // request 10 MB with a popup
-new PouchDB('mydb', {size: 50}); // request 50 MB with a popup
-new PouchDB('mydb'); // implicitly request 5 MB, no popup until you exceed 5MB
-```
-
-This does not affect any backend other than Web SQL. Chrome, Android, and Opera do not show the popup. On PhoneGap/Cordova apps, you can also use the [SQLite plugin][sqlite] to get around this problem. Here's [more information about storage quotas](http://www.html5rocks.com/en/tutorials/offline/quota-research) and [details on the Safari/iOS 7 bug](https://github.com/pouchdb/pouchdb/issues/2347).
-
-{% include anchor.html class="h3" title="PouchDB throws 404 (Object Not Found) for '_local' document" hash="404__local_document" %}
-
-Don't worry, nothing is amiss, this is expected behaviour:
-During PouchDB's initial replication PouchDB will check for a checkpoint, if it doesn't exist a 404 will be returned and a checkpoint will subsequently be written.
-
-{% include anchor.html class="h3" title="PouchDB is throwing `InvalidStateError`" hash="throwing_invalidstateerror" %}
-
-Are you in private browsing mode? IndexedDB is [disabled in private browsing mode](https://developer.mozilla.org/en-US/docs/IndexedDB/Using_IndexedDB) in Firefox.
-
-{% include anchor.html class="h3" title="Can't open second database on Android WebView with Cordova/Phone Gap" hash="phonegap_cordova_second_database" %}
-
-There is a limit of one database per app in some versions of the Android WebView. Install the [SQLite plugin][sqlite], then PouchDB will use that if it is available.
-
-{% include anchor.html class="h3" title="Possible EventEmitter memory leak detected" hash="event_emitter_limit" %}
-
-If you see this warning:
-
-    (node) warning: possible EventEmitter memory leak detected. 11 listeners added.
-    Use emitter.setMaxListeners() to increase limit.
-
-This is because PouchDB uses Node-style [EventEmitters](https://nodejs.org/api/events.html) for its events. An EventEmitter is any object that has an `.on()` or `once()` method, such as `db.changes().on('change', ...`.
-
-By default, all EventEmitters have 10 listeners, and if you exceed that limit, e.g. by attaching many `changes()` listeners or running many simultaneous `replicate()` or `sync()` events, then you may exceed this limit.
-
-**This could indicate a memory leak in your code**. Check to make sure that you are calling `cancel()` on any `changes()`, `replicate()`, or `sync()` handlers, if you are constantly starting and stopping those events.
-
-If you're sure it's not a memory leak, though, you can increase the limit by doing:
-
-{% highlight javascript %}
-db.setMaxListeners(20);  // or 30 or 40 or however many you need
-{% endhighlight %}
-
-In the above example, `db` refers to a database object you created using `new PouchDB('dbname')`.
-
-{% include anchor.html class="h3" title="Database size limitation of ~5MB on iOS with Cordova/Phone Gap" hash="size_limitation_5mb" %}
-
-If you're storing large amounts of data, such as PNG attachments, the [SQLite plugin][sqlite] is again your friend. (See [issue #1260](https://github.com/pouchdb/pouchdb/issues/1260) for details.)
-
-{% include anchor.html class="h3" title="CouchDB returns a 404 for GETs from a CouchApp" hash="404_get_couchapp" %}
-
-Certain URL rewrites are broken by PouchDB's cache-busting; try adding `{cache : false}` to the PouchDB constructor. (See [issue #1233](https://github.com/pouchdb/pouchdb/issues/1233) for details.)
-
-{% include anchor.html class="h3" title="Uncaught TypeError: object is not a function" hash="typeerror_object_is_not_a_function" %}
-
-Did you include the [es6-promise shim library](https://github.com/jakearchibald/es6-promise)?  Not every browser implements ES6 Promises correctly. (See [issue #1747](https://github.com/pouchdb/pouchdb/issues/1747) for details.)
-
-{% include anchor.html class="h3" title="Uncaught TypeError: 'undefined' is not a function" hash="undefined_is_not_a_function" %}
-
-Did you include the [es5-shim library][es5shim]? In particular this shows up in PhantomJS because of [this bug](https://github.com/ariya/phantomjs/issues/10522).
-
-{% include anchor.html class="h3" title="SyntaxError: Parse error (Cordova on Android)" hash="cordova_android_parse_error" %}
-
-Did you include the [es5-shim library][es5shim]?  PouchDB is written in ES5, which is supported by modern browsers, but requires shims for older browsers (e.g. IE 9, Android 2.1 WebView).
-
-In Android, if you're loading PouchDB directly via `webView.loadUrl('javascript://' + js')`, you should prefer the minified PouchDB javascript file to the unminified one, since code comments can also cause parse errors.
-
-{% include anchor.html class="h3" title="PouchDB object fails silently (Safari)" hash="safari_object_silent_fail" %}
-
-Safari requires users to confirm that they want to allow an app to store data locally ("Allow this website to use space on your disk?").  If PouchDB is loaded in an `iframe` or some other unusual way, the dialog might not be shown, and the database will silently fail.
-
-{% include anchor.html class="h3" title="window.localStorage is not available (Chrome apps)" hash="window_localstorage_chrome_apps" %}
-
-In Chrome apps, you'll see the warning "window.localStorage is not available in packaged apps. Use chrome.storage.local instead."  This is harmless; since PouchDB doesn't use localStorage if it's not available.
-
-{% include anchor.html class="h3" title="Error: UnknownError (Firefox)" hash="unknown_error_ff" %}
-
-Are you using a webserver to host and run your code? This error can be caused by running your script/file locally using the `file:///` setting in Firefox, since Firefox does not [allow access to IndexedDB locally](https://bugzilla.mozilla.org/show_bug.cgi?id=643318). You can use the SimpleHTTPServer to deploy your script by running `python -m SimpleHTTPServer` from the directory containing the script, or use the Apache webserver and then access the script by using `http://localhost/{path_to_your_script}`.
-
-{% include anchor.html class="h3" title="Error: UnknownError (Chrome / Opera)" hash="unknown_error_chrome" %}
-
-This can occur when attempting to read from or write to IndexedDB from a different origin. IndexedDB has a same-origin restriction. Attempting to write to the database associated with _http://example.com_ from an `iframe` served from _http://api.example.com_, for example, will fail.
-
-In Firefox, PouchDB instead throws a [`No valid adapter found`](#no_valid_adapter) error.
-
-{% include anchor.html class="h3" title="DataCloneError: An object could not be cloned" hash="could_not_be_cloned" %}
-
-If you ever see:
-
-    Uncaught DataCloneError:
-      Failed to execute 'put' on 'IDBObjectStore':
-      An object could not be cloned.
-
-Or:
-
-    DataCloneError: The object could not be cloned.
-
-Then the problem is that the document you are trying to store is not a pure JSON object. For example, an object with its own class (`new Foo()`) or with special methods like getters and setters cannot be stored in PouchDB/CouchDB.
-
-If you are ever unsure, then run this on the document:
-
-```js
-JSON.parse(JSON.stringify(myDocument));
-```
-
-If the object you get out is the same as the object you put in, then you are storing the right kind of object.
-
-Note that this also means that you cannot store `Date`s in your document. You must convert them to strings or numbers first. `Date`s will be stored as-is in IndexedDB, but in the other adapters and in CouchDB, they will be automatically converted to ISO string format, e.g. `'2015-01-01T12:00:00.000Z'`. This can caused unwanted results. See [#2351](https://github.com/pouchdb/pouchdb/issues/2351) and [#2158](https://github.com/pouchdb/pouchdb/issues/2158) for details.
-
-{% include anchor.html class="h3" title="DOM Exception 18 in Android pre-Kitkat WebView" hash="android_pre_kitkat" %}
-
-This applies to hybrid apps designed to run in Android pre-Kitkat (i.e. before 4.4).
-
-If you are directly using a `WebView` and not using Cordova/PhoneGap, you will probably either run into an error where PouchDB silently fails or you see `Error: SECURITY_ERR: DOM Exception 18` in the console. As a sanity test, you can run this JavaScript:
-
-```js
-openDatabase('mydatabase', 1, 'mydatabase', 5000000, function (db) { console.log('it works!'); });
-```
-
-If you see "it works" in the console, then everything's peachy. Otherwise there are a few things you have to do.
-
-First, make sure Web SQL is enabled on your `WebView` in the first place using [setDatabaseEnabled](http://developer.android.com/reference/android/webkit/WebSettings.html#setDatabaseEnabled%28boolean%29):
-
-```java
-myWebView.getSettings().setDatabaseEnabled(true);
-```
-
-Second, specify a path for the database. Yes, you need to do this, even though it's deprecated in Kitkat:
-
-```java
-String databasePath = getContext().getApplicationContext().getDir(
-  "database", Context.MODE_PRIVATE).getPath();
-webView.getSettings().setDatabasePath(databasePath);
-```
-
-Third, you'll need to set an `onExceededDatabaseQuota` handler. Yes, it's also deprecated in Kitkat. Yes, you still need to do it.
-
-```java
-webView.setWebChromeClient(new WebChromeClient() {
-
-  @Override
-  public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
-                                      long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
-    quotaUpdater.updateQuota(estimatedSize * 2);
-  }
-});
-```
-
-If you skip any one of these three steps, then you will get the `DOM Exception 18` error. You need to do all three.
-
-Alternatively, you can also load the `WebView` with a fake `http://` URL, but this may cause other errors when you try to fetch files based on a relative path:
-
-```java
-webView.loadDataWithBaseURL("http://www.example.com",
-    htmlContent,
-    "text/html",
-    "utf-8",
-    null);
-```
-
-{% include anchor.html class="h3" title="PouchDB on Windows" hash="windows_leveldown" %}
-
-It is known that building/compiling Node modules with native code on Windows can be frustrating, as there are lots of required dependencies to be installed, which may take many Gigabytes, as opossed to Unix platforms, where compiling is a breeze. Installing PouchDB on Node for Windows gave many headaches, specifically with the leveldown dep.
-
-Since v3.2.1 leveldown was changed to be an *optional dependency*: this way, npm will not refuse installing PouchDB even when having compiling errors. That way, you can use PouchDB normally, and will get an error only when trying to use leveldown as the backend. To avoid that, you can specify any compatible adapter, as pointed in the [Adapters](/adapters.html#pouchdb_in_node_js) section.
-
-For example, if you want a SQLite backend, you can install:
-
-{% highlight bash %}
-npm install sqlite3
-npm install sqldown
-{% endhighlight %}
-
-and then use PouchDB with:
-
-```js
-var db = new PouchDB('database', { db: require('sqldown') });
-
-```
-
-Also, you have the option to use [leveldown] (>= 1.2.2)(https://github.com/level/leveldown), which avoids native leveldown building when installing. Make sure the `win32-x64.tar.gz` is uploaded for your [leveldown] (https://github.com/Level/leveldown/releases) version. Then for use leveldown as backend, you can install:
-
-{% highlight bash %}
-npm install leveldown@1.2.2
-{% endhighlight %}
-
-and instance your PouchDB like this:
-
-```js
-var db = new PouchDB('database', { db: require('leveldown') });
-
-```
-
-{% include anchor.html class="h3" title="Replication with attachments is slow or fails" hash="replicating_attachments_slow" %}
-
-The symptoms for this issues are:
-
-1. Replicating a database that has many attachments from a CouchDB server is either slow or fails randomly.
-2. You get server error message of the nature `No buffer space available`.
-
-Chances are that your server runs inside a virtual machine. The host system, or hypervisor, imposes limits on how much data each virtual machine can use for networking. If you are on a cheap virtual server, it is possible, that the default settings for PouchDB pull-replication (10 parallel batches of 100 documents each) exhaust the narrow limit of your server. Even a single client can cause this.
-
-The solution is to move to a better server, but if that is not an immediate option, a workaround would be reducing the `options.batch_size` and `options.batches_limit` [replication options](http://pouchdb.com/api.html#replication).
-
-To find optimal values, start by setting them both to 1 (meaning that PouchDB should download one document after the other) and increase from there and stop when the symptoms begin again. Note that multiple concurrent clients can still cause an issue, if you get too many. If all your documents have one or more attachments (e.g. a photos database), setting both options to `1` is probably a good idea.
-
-{% include alert/start.html variant="info" %}
-
-Generally, reducing these options that replicating the database down will take more time. Please test various settings to see what works for you and your hardware.
-
-{% include alert/end.html %}
-
-{% include alert/start.html variant="info" %}
-
-This issue has been found on OpenVZ systems, but other Hypervisors might also be affected. See
-<a
-  href="http://blog.aplikacja.info/2010/01/105-no-buffer-space-available-on-openvz-vps/"
-  target="_blank"
->http://blog.aplikacja.info/2010/01/105-no-buffer-space-available-on-openvz-vps/</a>
-on how to diagnose this issue.
-
-{% include alert/end.html %}
-
-[es5shim]: https://github.com/es-shims/es5-shim
-[sqlite]: https://github.com/brodysoft/Cordova-SQLitePlugin
-
-{% include anchor.html class="h3" title="Packaging PouchDB in an app with WebPack" hash="package_pouchdb_webpack" %}
-
-PouchDB may have various dependencies that may not play nicely with WebPack. Here are some issues you may run into and their resolutions:
-
-**You may need an appropriate loader to handle this file type.**
-
-If you run into the following error (or similar):
-
-```sh
-ERROR in ./~/pouchdb/~/levelup/package.json
-Module parse failed: /path/to/node_modules/pouchdb/node_modules/levelup/package.json Line 2: Unexpected token :
-You may need an appropriate loader to handle this file type.
-| {
-|   "name": "levelup",
-|   "description": "Fast & simple storage - a Node.js-style LevelDB wrapper",
-|   "version": "0.18.6",
- @ ./~/pouchdb/~/levelup/lib/util.js 102:30-56
-
-```
-WebPack needs to be configured to recognize how to load json files. Simply, install `json-loader` and edit `webpack.config.js` as follows: 
-
-```js
-module: {
-    loaders: [
-        // https://github.com/pouchdb/pouchdb/issues/3319
-        {
-            test: /\.json$/,
-            loader: "json-loader"
-        }
-    ]
-}
-```
-
-{% include anchor.html class="h3" title="Failed to load resource: the server responded with a status of 400 (Bad request) " hash="couchbase_dbname" %}
-
-If you are using Couchbase Lite to sync with PouchDB then you cannot use capital letters in your database name as Couchbase Lite has restrictions on valid database names.
diff --git a/docs/external.md b/docs/external.md
deleted file mode 100644
index 94175cc..0000000
--- a/docs/external.md
+++ /dev/null
@@ -1,257 +0,0 @@
----
-layout: 2ColLeft
-title: Plugins and External Projects
-sidebar: nav.html
----
-
-Below is a list of known plugins, tools and projects can be used with PouchDB.
-
-{% include anchor.html title="Plugins" hash="plugins" %}
-
-#### [PouchDB allDbs()](https://github.com/nolanlawson/pouchdb-all-dbs)
-
-Revives the `allDbs()` function, which lists all PouchDB databases.
-
-#### [PouchDB Authentication](https://github.com/nolanlawson/pouchdb-authentication)
-
-Plugin for CouchDB's authentication system.
-
-#### [Pouch Box](https://github.com/jo/pouch-box)
-
-Allows decentralized authentication and access control per document, using asymmetric encryption.
-
-#### [PouchDB Collate](https://github.com/pouchdb/collate)
-
-Collation utilities, so you can use complex keys as doc IDs.
-
-#### [Crypto Pouch](https://github.com/calvinmetcalf/crypto-pouch)
-
-Encrypt a PouchDB/CouchDB database.
-
-#### [Pouch Dat](https://github.com/calvinmetcalf/pouch-dat)
-
-Replicate from PouchDB to Dat.
-
-#### [Pouch Datalog](https://github.com/dahjelle/pouch-datalog)
-
-Implement the Datalog query language on PouchDB, with indexes.
-
-#### [PouchDB Dump](https://github.com/nolanlawson/pouchdb-dump-cli) and [PouchDB Load](https://github.com/nolanlawson/pouchdb-load)
-
-Dump a PouchDB/CouchDB to a file, then load it wholesale. Designed for fast initial replication.
-
-#### [Delta Pouch](https://github.com/redgeoff/delta-pouch)
-
-Implements the handy "every document is a delta" pattern, so you don't have to deal with conflicts.
-
-#### [PouchDB Erase](https://github.com/marten-de-vries/pouchdb-erase)
-
-A replicating `db.destroy()` alternative.
-
-#### [PouchDB Find](https://github.com/nolanlawson/pouchdb-find)
-
-MongoDB-like query language, based on CouchDB 2.0. ([Live demo](http://nolanlawson.github.io/pouchdb-find/))
-
-#### [PouchDB Full Sync](https://github.com/nolanlawson/pouchdb-full-sync)
-
-Fully replicate two PouchDB/CouchDB databases, preserving absolutely all revision history.
-
-#### [PouchDB GQL](https://github.com/pouchdb/GQL)
-
-Google Query Language (GQL) queries with PouchDB. ([Documentation](http://pouchdb.com/gql.html))
-
-#### [PouchDB Hoodie API](https://github.com/hoodiehq/pouchdb-hoodie-api)
-
-Hoodie-like API for PouchDB. ([Documentation](http://hoodiehq.github.io/pouchdb-hoodie-api/))
-
-#### [PouchDB Hoodie Store](https://www.npmjs.com/package/pouchdb-hoodie-store)
-
-PouchDB with Hoodie's Store API.
-
-#### [PouchDB List](http://python-pouchdb.marten-de-vries.nl/plugins.html)
-
-Allows you to re-use your CouchDB list functions on the client side. ([Documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-rewrite-plug-in))
-
-#### [Pouch Mirror](https://github.com/colinskow/pouch-mirror)
-
-Creates a synced in-memory mirror of a remote CouchDB for faster reads.
-
-#### [PouchDB No-Eval Map/Reduce](https://github.com/evidenceprime/pouchdb.mapreduce.noeval)
-
-Allows you to use the `query()` API in environments that disallow `eval()`, like Chrome packaged apps.
-
-#### [Peer Pouch](https://github.com/natevw/PeerPouch)
-
-PouchDB over WebRTC. (Note: only works with PouchDB 1.1.)
-
-#### [PouchDB Resolve Conflicts](https://github.com/jo/pouch-resolve-conflicts)
-
-Plugin to assist in PouchDB conflict resolving.
-
-#### [PouchDB Migrate](https://github.com/eHealthAfrica/pouchdb-migrate)
-
-PouchDB plugin for running data migrations.
-
-#### [PouchDB Quick Search](https://github.com/nolanlawson/pouchdb-quick-search)
-
-Full-text search engine on top of PouchDB.
-
-#### [Relational Pouch](https://github.com/nolanlawson/relational-pouch)
-
-A relational database API on top of PouchDB/CouchDB.
-
-#### [PouchDB Replication Stream](https://github.com/nolanlawson/pouchdb-replication-stream)
-
-Replicate between CouchDB/PouchDB using streams.
-
-#### [PouchDB Rewrite](http://python-pouchdb.marten-de-vries.nl/plugins.html)
-
-A PouchDB plugin that allows you to re-use your CouchDB rewrites on the client side. ([Documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-list-plug-in))
-
-#### [PouchDB Show](http://python-pouchdb.marten-de-vries.nl/plugins.html)
-
-A PouchDB plugin that allows you to re-use your CouchDB show functions on the client side. ([Documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-show-plug-in))
-
-#### [SocketPouch](https://github.com/nolanlawson/socket-pouch)
-
-PouchDB/CouchDB replication over WebSockets, using Engine.io (Socket.io).
-
-#### [PouchDB Spatial](https://github.com/pouchdb/geopouch)
-
-Multidimensional and spatial queries with PouchDB.
-
-#### [Superlogin](https://www.npmjs.com/package/superlogin)
-
-Powerful authentication for APIs and single page apps using the CouchDB ecosystem, which supports a variety of providers.
-
-#### [Store.PouchDB](https://github.com/chunksnbits/store.pouchdb)
-
-ORM-style storage plugin for PouchDB.
-
-#### [Pouch Stream](https://github.com/calvinmetcalf/PouchStream)
-
-A plugin to let PouchDB talk streams.
-
-#### [Transform Pouch](https://github.com/nolanlawson/transform-pouch)
-
-Transforms documents before and after storage, e.g. for encryption, compression, or massaging data.
-
-
-#### [PouchDB Update](http://python-pouchdb.marten-de-vries.nl/plugins.html)
-
-A PouchDB plugin that allows you to re-use your CouchDB update functions on the client side. ([Documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-update-plug-in))
-
-#### [PouchDB Upsert](https://github.com/nolanlawson/pouchdb-upsert)
-
-Convenience functions for working with documents: `upsert()` and `putIfNotExists()`.
-
-#### [PouchDB Validation](http://python-pouchdb.marten-de-vries.nl/plugins.html)
-
-A PouchDB plugin that allows you to re-use your CouchDB `validate_doc_update` functions on the client side. ([Documentation](http://pythonhosted.org/Python-PouchDB/js-plugins.html#pouchdb-validation-plug-in))
-
-#### [WorkerPouch](http://github.com/nolanlawson/worker-pouch)
-
-PouchDB adapter for web workers, so that PouchDB blocks the DOM less.
-
-{% include anchor.html title="Server Side" hash="Server Side" %}
-
-#### [PouchDB Server](https://github.com/pouchdb/pouchdb-server)
-
-A standalone CouchDB-style REST interface server to PouchDB.
-
-#### [Express PouchDB](https://github.com/pouchdb/express-pouchdb)
-
-An Express submodule with a CouchDB-style REST interface to PouchDB. Powers PouchDB Server.
-
-#### [Express PouchDB Replication Stream](https://github.com/conor-mac-aoidh/express-pouchdb-replication-stream)
-
-Server-side Express endpoint to deliver a stream from [PouchDB Replication Stream](https://github.com/nolanlawson/pouchdb-replication-stream).
-
-{% include anchor.html title="Framework adapters" hash="framework_adapters" %}
-
-### Angular
-
-#### [angular-pouchdb](https://github.com/angular-pouchdb/angular-pouchdb)
-
-Wrapper for using PouchDB within Angular.js.
-
-#### [Factoryng - AngularJS Adapter](https://github.com/redgeoff/factoryng)
-
-An all-in-one AngularJS factory that wraps PouchDB and Delta Pouch.
-
-#### [ngPouch](https://github.com/jrhicks/ngPouch)
-
-Angular service to persist remote connection settings and maintain continuous replication.
-
-#### [ng-pouchdb](https://github.com/danielzen/ng-pouchdb)
-
-AngularJS binding for PouchDB.
-
-### Ampersand
-
-#### [ampersand-collection-pouchdb-mixin](https://github.com/svnlto/ampersand-collection-pouchdb-mixin)
-
-A mixin for extending ampersand-collection with pouchdb persistance.
-
-### Backbone
-
-#### [Backbone PouchDB](https://github.com/jo/backbone-pouch)
-
-Backbone PouchDB Sync Adapter.
-
-### Ember
-
-#### [Ember Pouch](https://github.com/nolanlawson/ember-pouch)
-
-Ember Data adapter for PouchDB/CouchDB.
-
-#### [ember-pouchdb](https://github.com/taras/ember-pouchdb)
-
-Promisy PouchDB wrapper for Ember.js.
-
-### Kendo UI
-
-#### [kendo-pouchdb](https://github.com/terikon/kendo-pouchdb)
-
-Kendo UI DataSource adapter.
-
-### React/Flux
-
-#### [pouch-redux](https://github.com/UXtemple/pouch-redux)
-
-Pouch and Redux integration. With Pouch in control this time around. 
-
-#### [redux-pouchdb](https://github.com/vicentedealencar/redux-pouchdb)
-
-Sync store state to PouchDB.
-
-#### [redux-pouch](https://github.com/UXtemple/redux-pouch)
-
-PouchDB-backed Redux.
-
-{% include anchor.html title="Other languages" hash="Other languages" %}
-
-#### [Python-PouchDB](http://python-pouchdb.marten-de-vries.nl/)
-A Python interface to PouchDB, with both a synchronous and an asynchronous API. Uses QtWebKit internally (via either PySide, PyQt4 or PyQt5). Some PouchDB plugins are also wrapped. ([Documentation](http://pythonhosted.org/Python-PouchDB/) / [Launchpad](https://launchpad.net/python-pouchdb))
-
-#### [PouchDroid](https://github.com/nolanlawson/PouchDroid/)
-
-Android adapter with a native Java interface to PouchDB.
-
-{% include anchor.html title="Tools" hash="Tools" %}
-
-#### [blob-util](https://github.com/nolanlawson/blob-util)
-
-Shims and utils for working with binary Blobs in the browser.
-
-#### [Pouchy] (https://www.npmjs.com/package/pouchy)
-
-PouchDB sugar API. ([Github](https://github.com/cdaringe/pouchy))
-
-#### [Puton](http://puton.jit.su/)
-
-A bookmarklet for inspecting PouchDB databases within the browser. ([Github](http://github.com/ymichael/puton))
-
-#### [Revision Tree Visualizer](http://neojski.github.io/visualizeRevTree)
-
-A tool drawing revision tree of a couchdb document. You can see what is a conflict, which revisions are deleted and which is winning. ([Github](https://github.com/neojski/visualizeRevTree))
diff --git a/docs/faq.md b/docs/faq.md
deleted file mode 100644
index c927edd..0000000
--- a/docs/faq.md
+++ /dev/null
@@ -1,143 +0,0 @@
----
-layout: 2ColLeft
-title: FAQ
-sidebar: nav.html
----
-
-{% include anchor.html class="h3" title="Can PouchDB sync with MongoDB/MySQL/my current non-CouchDB database?" hash="sync_non_couchdb" %}
-
-
-No, your backend needs to speak the [CouchDB replication protocol](http://couchdb.readthedocs.org/en/latest/replication/protocol.html). The magic of PouchDB <&ndash;> CouchDB sync comes from this design, which in particular requires all documents to be versioned with the `_rev` marker. This allows PouchDB and CouchDB to [elegantly handle conflicts](http://writing.jan.io/2013/12/19/understanding-couchdb-conflicts.html), among other benefits.
-
-{% include anchor.html class="h3" title="What can PouchDB sync with?" hash="what_can_pouchdb_sync_with" %}
-
-There are a number of databases that implement a CouchDB-like protocol, and PouchDB should be able to replicate with them. They include:
-
- * [CouchDB](http://couchdb.apache.org/) &ndash; CouchDB is our primary reference database and is used for automated testing.
- * [Cloudant](https://cloudant.com/) &ndash; A cluster-aware fork of CouchDB.
- * [Couchbase Sync Gateway](http://www.couchbase.com/communities/couchbase-sync-gateway) &ndash; A sync gateway for Couchbase.
- * [IrisCouch](http://iriscouch.com/) &ndash; CouchDB in the cloud.
- * [PouchDB Server](https://github.com/pouchdb/pouchdb-server) &ndash; An HTTP API written on top of PouchDB. Additionally, it supports alternate backends like in-memory, Redis, Riak and MySQL via [the LevelUP ecosystem](https://github.com/rvagg/node-levelup/wiki/Modules#storage). Note that your application must use the PouchDB API rather than directly modifying the database, however.
-
-{% include anchor.html class="h3" title="The web is nice, but I want to build a native app?" hash="native_support" %}
-
-PouchDB is one of multiple projects that implement the CouchDB protocol, and these can all be used to sync the same set of data.
-
-For desktop applications, you may want to look into embedding CouchDB (or [rcouch](https://github.com/refuge/rcouch)). PouchDB also works great with web-based frameworks like [node-webkit](https://github.com/rogerwang/node-webkit), [Chrome apps](https://developer.chrome.com/apps/about_apps), [Electron](https://github.com/atom/electron) and [WinJS](http://try.buildwinjs.com/#listview).
-
-For mobile applications, you can use PouchDB within [PhoneGap](http://phonegap.com/)/[Cordova](http://cordova.apache.org/) (optionally using the [SQLite Plugin](https://github.com/brodysoft/Cordova-SQLitePlugin)), or there are several native libraries:
-
-**iOS**:
-
-* [Couchbase Lite for iOS](https://github.com/couchbase/couchbase-lite-ios)
-* [Cloudant Sync for iOS](https://github.com/cloudant/CDTDatastore)
-
-**Android**:
-
-* [Couchbase Lite for Android](https://github.com/couchbase/couchbase-lite-android)
-* [Cloudant Sync for Android](https://github.com/cloudant/sync-android)
-
-{% include anchor.html class="h3" title="How much data can PouchDB store?" hash="data_limits" %}
-
-In **Firefox**, PouchDB uses IndexedDB. Though Firefox has no upper limit besides disk space, if your application wishes to store more than 50MB locally, Firefox will [ask the user](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) using a non-modal dialog to confirm that this is okay.
-
-**Chrome** also uses IndexedDB, and it determines the amount of storage available on the user&#8217;s hard drive and uses that [to calculate a limit](https://developers.google.com/chrome/whitepapers/storage#temporary).
-
-**Opera 15+** shares a codebase with Chromium/Blink, and behaves similarly.
-
-**Internet Exporer 10+** has a hard 250MB limit, and will prompt the user with a non-modal dialog at 10MB.
-
-**Mobile Safari** on iOS has a hard 50MB limit, whereas **desktop Safari** has no limit. Both will prompt the user with a modal dialog if an application requests more than 5MB of data, at increments of 5MB, 10MB, 50MB, 100MB, etc. Some versions of Safari have a bug where they only let you request additional storage once, so you'll need to request the desired space up-front. PouchDB allows you to do this using [the `size` option](http://pouchdb.com/api.html#create_database).
-
-**Android** works the same as Chrome as of 4.4+ (IndexedDB), while older versions can store up to 200MB (WebSQL).
-
-In [PhoneGap](http://phonegap.com/)/[Cordova](http://cordova.apache.org/), you can have unlimited data on both iOS and Android by using the [SQLite Plugin](https://github.com/brodysoft/Cordova-SQLitePlugin).
-
-For more information, see [Working with quota on mobile browsers](http://www.html5rocks.com/en/tutorials/offline/quota-research/).
-
-{% include anchor.html class="h3" title="What data types does PouchDB support?" hash="data_types" %}
-
-PouchDB has two types of data: documents and attachments.
-
-#### Documents
-
-As in CouchDB, the documents you store must be serializable as JSON. Modifying the `Object` prototype or storing classes is not supported.
-
-IndexedDB will actually support non-JSON data (e.g. `Date`s aren't stringified), but you should not rely on this, because CouchDB, LevelDB, and Web SQL do not behave the same.
-
-#### Attachments
-
-PouchDB also supports attachments, which are the most efficient way to store binary data. Attachments may either be supplied as base64-encoded strings or as `Blob` objects.
-
-Different backends have different strategies for storing binary data, which may affect the overall database size. Attachment stubs have a `length` property that describes the number of bytes in the `Blob` object, but under the hood, it may actually take up more space than that.
-
-PouchDB's strategies are:
-
-* **Blob**: data is stored in a true binary format. The most efficient method.
-* **UTF-16 Blob**: blobs are coerced to UTF-16, so they takes up 2x the normal space.
-* **Base-64**: data is stored as a base-64-encoded string. The least efficient method.
-
-Here are the strategies used by various browsers in PouchDB:
-
-<div class="table-responsive">
-<table class="table">
-<tr>
-    <td></td>
-	<th><img src="static/img/browser-logos/internet-explorer_32x32.png" alt="IE"/></th>
-	<th><img src="static/img/browser-logos/firefox_32x32.png" alt="Firefox"/></th>
-	<th><img src="static/img/browser-logos/chrome_32x32.png" alt="Chrome"/></th>
-	<th><img src="static/img/browser-logos/chrome_32x32.png" alt="Chrome"/></th>
-	<th><img src="static/img/browser-logos/safari_32x32.png" alt="Safari"/></th>
-	<th><img src="static/img/browser-logos/safari_32x32.png" alt="Safari"/></th>
-</tr>
-<tr>
-    <th>Adapter</th>
-	<th>IE (10+)</th>
-	<th>Firefox</th>
-	<th>Chrome < 43,<br/>Android</th>
-	<th>Chrome >= 43</th>
-	<th>Safari < 7.1,<br/>iOS < 8</th>
-	<th>Safari >= 7.1,<br/>iOS >= 8</th>
-</tr>
-<tr>
-    <td>IndexedDB</td>
-	<td>Blob</td>
-	<td>Blob</td>
-	<td>Base-64</td>
-	<td>Blob</td>
-	<td></td>
-	<td></td>
-</tr>
-<tr>
-	<td>WebSQL</td>
-	<td></td>
-	<td></td>
-	<td>Blob</td>
-	<td>Blob</td>
-	<td>UTF-16 Blob</td>
-	<td>Blob</td>
-</tr>
-</table>
-</div>
-
-Attachments are deduplicated based on their MD5 sum, so duplicate attachments won't take up extra space.
-
-To truly remove an attachment from the data store, you will need to use [compaction](http://pouchdb.com/api.html#compaction) to remove document revisions that reference that attachment.
-
-{% include anchor.html class="h3" title="Is it safe to upgrade PouchDB?" hash="safe_to_upgrade" %}
-
-Since v1.0.0, PouchDB has supported automatic schema migrations. This means that if you open a database that was built with an older version of PouchDB, the newer version will run all the steps necessary to get the old database up to date. We have extensive tests in place to guarantee that this feature works correctly.
-
-Even in the case of a major version release, PouchDB still performs the schema migrations. So for instance, you can create a database with PouchDB 1.0.0 and it will still work after you open it in 3.0.0.
-
-Once a database is migrated, however, you can no longer open it with an older version of PouchDB. So if an update contains a migration, it will be clearly marked in the release notes.
-
-{% include anchor.html class="h3" title="How is PouchDB different from CouchDB?" hash="couchdb_differences" %}
-
-PouchDB is also a CouchDB client, and you should be able to switch between a local database or an online CouchDB instance without changing any of your application's code.
-
-However, there are some minor differences to note:
-
-**View Collation** - CouchDB uses ICU to order keys in a view query; in PouchDB they are ASCII ordered.
-
-**View Offset** - CouchDB returns an `offset` property in the view results. In PouchDB, `offset` just mirrors the `skip` parameter rather than returning a true offset.
diff --git a/docs/feed.xml b/docs/feed.xml
deleted file mode 100644
index 71eafcc..0000000
--- a/docs/feed.xml
+++ /dev/null
@@ -1,27 +0,0 @@
----
----
-<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
-  <channel>
-    <title>{{ site.name | xml_escape }}</title>
-    <description>{% if site.description %}{{ site.description | xml_escape }}{% endif %}</description>
-    <link>{{ site.url }}</link>
-    <atom:link href="{{ site.url }}/feed.xml" rel="self" type="application/rss+xml" />
-    {% for post in site.posts limit:10 %}
-      <item>
-        <title>{{ post.title | xml_escape }}</title>
-        {% if post.author %}
-          <dc:creator>{{ post.author | xml_escape }}</dc:creator>
-        {% endif %}
-        {% if post.excerpt %}
-          <description>{{ post.excerpt | xml_escape }}</description>
-        {% else %}
-          <description>{{ post.content | xml_escape }}</description>
-        {% endif %}
-        <pubDate>{{ post.date | date: "%a, %d %b %Y %H:%M:%S %z" }}</pubDate>
-        <link>{{ site.url }}{{ post.url }}</link>
-        <guid isPermaLink="true">{{ site.url }}{{ post.url }}</guid>
-      </item>
-    {% endfor %}
-  </channel>
-</rss>
diff --git a/docs/getting-started.md b/docs/getting-started.md
deleted file mode 100644
index 7356703..0000000
--- a/docs/getting-started.md
+++ /dev/null
@@ -1,214 +0,0 @@
----
-layout: 2ColLeft
-title: Getting Started Guide
-sidebar: nav.html
----
-
-{% include alert/start.html variant="info" %}
-
-If you get stuck, download a <a href="https://github.com/nickcolley/getting-started-todo/archive/master.zip" target="_blank">working version</a>,
-or check out the <a href="https://github.com/nickcolley/getting-started-todo" target="_blank">full repo</a>
-and <a href="https://github.com/nickcolley/getting-started-todo/commits/master" target="_blank">commit history</a>.
-
-{% include alert/end.html %}
-
-In this tutorial we will write a basic Todo web application based on [TodoMVC](http://todomvc.com/) that syncs to an online CouchDB server. It should take around 10 minutes.
-
-{% include anchor.html class="h3" title="Video Tutorial" hash="video_tutorial" %}
-
-Prefer video tutorials? This guide is available in video format:
-
-{% include iframe.html src="//www.youtube.com/embed/-Z7UF2TuSp0" %}
-
-{% include anchor.html class="h3" title="Download Assets" hash="download" %}
-
-We will start with a template of the project where all the data related functions have been replaced with empty stubs. Download and unzip [pouchdb-getting-started-todo.zip]({{ site.baseurl }}/static/assets/pouchdb-getting-started-todo.zip). When dealing with XHR and IndexedDB you are better off running web pages from a server as opposed to a filesystem. To do this you can run:
-
-{% highlight bash %}
-$ cd pouchdb-getting-started-todo
-$ python -m SimpleHTTPServer
-{% endhighlight %}
-
-Then visit [http://127.0.0.1:8000/](http://127.0.0.1:8000/). If you see the following screenshot, you are good to go:
-
-{% include img.html src="screenshots/todo-1.png" alt="Todo Screenshot" %}
-
-It's also a good idea to open your browser's console so you can see any errors or confirmation messages.
-
-{% include anchor.html class="h3" title="Installing PouchDB" hash="installing_pouchdb" %}
-
-Open `index.html` and include PouchDB in the app by adding a script tag:
-
-{% highlight html %}
-<script src="//cdn.jsdelivr.net/pouchdb/{{site.version}}/pouchdb.min.js"></script>
-<script src="js/base.js"></script>
-<script src="js/app.js"></script>
-{% endhighlight %}
-
-PouchDB is now installed in your app and ready to use! (In production, you should use a local copy of the script.)
-
-{% include anchor.html class="h3" title="Creating a database" hash="creating_a_database" %}
-
-The rest of the work will be done inside `app.js`. We will start by creating a database to enter your todos. To create a database simply instantiate a new PouchDB object with the name of the database:
-
-{% highlight js %}
-// EDITING STARTS HERE (you dont need to edit anything above this line)
-
-var db = new PouchDB('todos');
-var remoteCouch = false;
-{% endhighlight %}
-
-You don't need to create a schema for the database. After giving it a name, you can immediately start writing objects to it.
-
-{% include anchor.html class="h3" title="Write todos to the database" hash="write_todos_to_database" %}
-
-The first thing we shall do is start writing items to the database. The main input will call `addTodo` with the current text when the user presses `Enter`. We can complete this function with the following code:
-
-{% highlight js %}
-function addTodo(text) {
-  var todo = {
-    _id: new Date().toISOString(),
-    title: text,
-    completed: false
-  };
-  db.put(todo, function callback(err, result) {
-    if (!err) {
-      console.log('Successfully posted a todo!');
-    }
-  });
-}
-{% endhighlight %}
-
-In PouchDB each document is required to have a unique `_id`. Any subsequent writes to a document with the same `_id` will be considered updates. Here we are using a date string as an `_id`. For our use case, it will be unique, and it can also be used to sort items in the database. You can use `db.post()` if you want random ids. The `_id` is the only thing required when creating a new document. The rest of the object you can create as you like.
-
-The `callback` function will be called once the document has been written (or failed to write). If the `err` argument is not null, then it will have an object explaining the error, otherwise the `result` will hold the result.
-
-{% include anchor.html class="h3" title="Show items from the database" hash="show_database_items" %}
-
-We have included a helper function `redrawTodosUI` that takes an array of todos to display, so all we need to do is read the todos from the database. Here we will simply read all the documents using `db.allDocs`. The `include_docs` option tells PouchDB to give us the data within each document, and the `descending` option tells PouchDB how to order the results based on their `_id` field, giving us newest first.
-
-{% highlight js %}
-function showTodos() {
-  db.allDocs({include_docs: true, descending: true}, function(err, doc) {
-    redrawTodosUI(doc.rows);
-  });
-}
-{% endhighlight %}
-
-Once you have included this code, you should be able to refresh the page to see any todos you have entered.
-
-{% include anchor.html class="h3" title="Update the UI" hash="update_the_ui" %}
-
-We dont want to refresh the page to see new items. More typically you would update the UI manually when you write data to it, however, in PouchDB you may be syncing data remotely, so you want to make sure you update whenever the remote data changes. To do this we will call `db.changes` which subscribes to updates to the database, wherever they come from. You can enter this code between the `remoteCouch` and `addTodo` declaration:
-
-{% highlight js %}
-var remoteCouch = false;
-
-db.changes({
-  since: 'now',
-  live: true
-}).on('change', showTodos);
-
-// We have to create a new todo document and enter it in the database
-function addTodo(text) {
-{% endhighlight %}
-
-So every time an update happens to the database, we redraw the UI to show the new data. The `live` flag means this function will continue to run indefinitely. Now try entering a new todo and it should appear immediately.
-
-{% include anchor.html class="h3" title="Edit a todo" hash="edit_a_todo" %}
-
-When the user checks a checkbox, the `checkboxChanged` function will be called, so we'll fill in the code to edit the object and call `db.put`:
-
-{% highlight js %}
-function checkboxChanged(todo, event) {
-  todo.completed = event.target.checked;
-  db.put(todo);
-}
-{% endhighlight %}
-
-This is similiar to creating a document, however the document must also contain a `_rev` field (in addition to `_id`), otherwise the write will be rejected. This ensures that you dont accidently overwrite changes to a document.
-
-You can test that this works by checking a todo item and refreshing the page. It should stay checked.
-
-{% include anchor.html class="h3" title="Delete an object" hash="delete_an_object" %}
-
-To delete an object you can call db.remove with the object.
-
-{% highlight js %}
-function deleteButtonPressed(todo) {
-  db.remove(todo);
-}
-{% endhighlight %}
-
-Similiar to editing a document, both the `_id` and `_rev` properties are required. You may notice that we are passing around the full object that we previously read from the database. You can of course manually construct the object, like: `{_id: todo._id, _rev: todo._rev}`, but passing around the existing object is usually more convenient and less error prone.
-
-{% include anchor.html class="h3" title="Complete rest of the Todo UI" hash="complete_todo_ui" %}
-
-`todoBlurred` is called when the user edits a document. Here we'll delete the document if the user has entered a blank title, and we'll update it otherwise.
-
-{% highlight js %}
-function todoBlurred(todo, event) {
-  var trimmedText = event.target.value.trim();
-  if (!trimmedText) {
-    db.remove(todo);
-  } else {
-    todo.title = trimmedText;
-    db.put(todo);
-  }
-}
-{% endhighlight %}
-
-{% include anchor.html class="h3" title="Installing CouchDB" hash="installing_couchdb" %}
-
-Now we'll implement the syncing. You need to have a CouchDB instance, which you can either install yourself [CouchDB(1.3+) locally](http://couchdb.apache.org/) or use with an online provider like [IrisCouch](http://iriscouch.com).
-
-{% include anchor.html class="h3" title="Enabling CORS" hash="enabling_cors" %}
-
-To replicate directly with CouchDB, you need to make sure CORS is enabled. Only set the username and password if you have set them previously. By default, CouchDB will be installed in "Admin Party," where username and password are not needed. You will need to replace `myname.iriscouch.com` with your own host (`127.0.0.1:5984` if installed locally):
-
-You can enable CORS in CouchDB using `curl` or the Futon web interface, but we've saved you some time by making a Node script called [add-cors-to-couchdb](https://github.com/pouchdb/add-cors-to-couchdb). Just run:
-
-{% highlight bash %}
-$ npm install -g add-cors-to-couchdb
-$ add-cors-to-couchdb
-{% endhighlight %}
-
-Or if your database is not at `127.0.0.1:5984`:
-
-{% highlight bash %}
-$ add-cors-to-couchdb http://me.iriscouch.com -u myusername -p mypassword
-{% endhighlight %}
-
-You can check that CORS is now enabled by visiting [http://localhost:5984/_utils/config.html](http://localhost:5984/_utils/config.html) in your browser. You should see something like this:
-
-{% include img.html src="cors_in_couchdb.png" alt="CORS settings in CouchDB" %}
-
-{% include anchor.html class="h3" title="Implement basic two way sync" hash="basic_two_way_sync" %}
-
-Now we will have the todo list sync. Back in `app.js` we need to specify the address of the remote database. Remember to replace `user`, `pass` and `myname.iriscouch.com` with the credentials of your own CouchDB instance:
-
-{% highlight js %}
-// EDITING STARTS HERE (you dont need to edit anything above this line)
-
-var db = new PouchDB('todos');
-var remoteCouch = 'http://user:pass@mname.iriscouch.com/todos';
-{% endhighlight %}
-
-Then we can implement the sync function like so:
-
-{% highlight js %}
-function sync() {
-  syncDom.setAttribute('data-sync-state', 'syncing');
-  var opts = {live: true};
-  db.replicate.to(remoteCouch, opts, syncError);
-  db.replicate.from(remoteCouch, opts, syncError);
-}
-{% endhighlight %}
-
-`db.replicate()` tells PouchDB to transfer all the documents `to` or `from` the `remoteCouch`. This can either be a string identifier or a PouchDB object. We call this twice: once to receive remote updates, and once to push local changes. Again, the `live` flag is used to tell PouchDB to carry on doing this indefinitely. The callback will be called whenever this finishes. For live replication, this will mean an error has occured, like losing your connection or you canceled the replication.
-
-You should be able to open [the todo app](http://127.0.0.1:8000) in another browser and see that the two lists stay in sync with any changes you make to them. You may also want to look at your CouchDB's Futon administration page and see the populated database.
-
-{% include anchor.html class="h3" title="Congratulations!" hash="congratulations" %}
-
-You've completed your first PouchDB application. This is a basic example, and a real world application will need to integrate more error checking, user signup, etc. But you should now understand the basics you need to start working on your own PouchDB project. If you have any more questions, please get in touch on [IRC](irc://freenode.net#pouchdb) or the [mailing list](https://groups.google.com/forum/#!forum/pouchdb).
diff --git a/docs/gql.md b/docs/gql.md
deleted file mode 100644
index d6d3b1d..0000000
--- a/docs/gql.md
+++ /dev/null
@@ -1,285 +0,0 @@
----
-layout: 2ColLeft
-title: GQL Documentation
-sidebar: nav.html
----
-
-The Google Query Language (GQL) interface provides an alternative method for accessing data.
-The version of GQL implemented here is based on the Google Visualization API Query Language
-(https://developers.google.com/chart/interactive/docs/querylanguage).
-The syntax of GQL queries should be familiar to those who have used SQL,
-but the capabilities of GQL are much more limited.
-
-GQL queries are performed by passing a query object to the gql method along with a callback.
-Callbacks are in the node.js idiom of `function(err, data)` Where the first argument will be undefined
-unless there is an error, and further arguments specify the result.
-Note that only identifiers and string literals are case-sensitive.
-
-### Language Syntax
-
- * [Select](#select)
- * [Where](#where)
- * [Group By](#groupBy)
- * [Pivot](#pivot)
- * [Label](#label)
- * [Functions](#functions)
-  * [Aggregation Functions](#aggregation_functions)
-  * [Scalar Functions](#scalar_functions)
-  * [Arithmetic Operators](#arithmetic_operators)
- * [Miscellaneous](#miscellaneous)
-  * [Literals](#literals)
-  * [Identifiers](#identifiers)
-  * [Reserved Words](#reserved_words)
-
-## Perform a Query
-
-    db.gql(query, [options], [callback])
-
-Although only the query is mandatory, the callback is required to access the query result.
-Currently no query options are implemented.
-
-    var pouchdb;
-    PouchDB('idb://test', function(err, db) {
-       pouchdb = db;
-      // Use pouchdb to call further functions
-        db.gql({select: "*", where: "type='Fire' and name is not null"}, function(err, result){
-            if(!err){
-            // Use the results of the query here
-            }
-          }
-    })
-
-## Select
-
-    db.gql({select: "`name!`, price-discount, upper(vendor)"}, callback)
-
-Select returns an object for each document in the database (unless limited by another clause).
-Each of these objects will be populated with the properties specified in the select clause.
-Arithmetic operators, aggregation functions, and scalar functions are all fair game.
-Properties that are missing from an object in the database are assigned null.
-
-With these documents in the database
-
-    {name!: "pencil", price: 2, discount: 0.7, vendor: "store1"},
-    {name!: "pen", price:3, discount: 2, vendor: "store2"}
-
-The above query will return
-
-    {name!: "pen", price - discount: 1, upper(vendor): "STORE2"},
-    {name!: "pencil", price - discount: 1.3, upper(vendor): "STORE1"}
-
-
-## Where
-
-    db.gql({select: "*", where: "type='Fire' and name is not null"}, callback)
-
-Where allows filtering of the objects that are passed to the select clause.  In this way, unwanted documents
-can be excluded from the query result.  The where clause is composed of conditions which are joined by the
-logical operators AND and OR.  An additional operator, NOT, provides negation.
-
-Comparison operators can be used in conditions to perform comparisons.  The supported comparison operators are
-<=, <, >, >=, !=, and <>.  != and <> are equivalent.  Null is treated slightly differently; to check if
-something is null IS NULL is used.  To check if something is not null, IS NOT NULL is used.
-
-With these documents in the database
-
-    {name: "charmander", type: "Fire"},
-    {type: "Fire", attack:"tail whip"},
-    {name: "charizard", type: "Fire", attack:"slash"}
-
-The above query will return
-
-    {_id: "0D715E2C-CEDD-46B4-A060-9C9C290BEBE8", _rev: "1-71d1e0f8ab00cf432306890a4116602b",
-    attack: "slash", name: "charizard", type: "Fire"},
-    {_id: "3153F94B-0568-4D4C-BFA1-83EDF6185915" _rev: "1-d24f7405c5a63943391eaff9a260139c",
-    name: "charmander", type: "Fire"}
-
-Note the inclusion of the \_rev and \_id fields.  This is the result of using 'select \*' instead of naming the
-desired fields explicitly.
-
-## Group By
-
-    db.gql({select: "max(charizard), charmeleon", groupBy: "charmeleon"}, callback)
-
-Group by creates one object for each unique combination of values in the group by clause. For the query above,
-if every document in the database had the value "Level 22" for the property "charmeleon", only a single
-object would be generated.
-
-If a group by clause is present, every identifier in the select clause must either be the argument of an
-aggregation function or present in the group by clause.  Otherwise, the composite objects formed by the group by
-clause could have multiple values for some identifiers.
-
-With these documents in the database
-
-    {charizard: 50, charmander: 24, charmeleon: 2, haunter:true},
-    {charizard: 40, charmeleon: 2, charmander: 50},
-    {charizard: 7, charmeleon: 20, charmander: 15}
-
-The above query will return
-
-    {charmeleon: 2, max(charizard): 50}
-    {charmeleon: 20, max(charizard): 7}
-
-## Pivot
-
-     db.gql({select: "max(charizard)", pivot: "charmeleon"}, callback)
-
-Pivot is essentially group by for properties.  Each distinct value in the pivot clause gets its own property.
-Unless used with group by, the result will have only a single document.
-
-The same restriction for group by applies here; every identifier in the select clause must either be the
-argument of an aggregation function or preset in the group by clause.  Additionally, identifiers in the pivot
-clause may not be used in the group by clause.
-
-Note that using pivot will generate novel property names.  See below for an example.
-
-With these documents in the database
-
-    {charizard: 50, charmeleon: "hello"},
-    {charizard: 40, charmeleon: "hello"},
-    {charizard: 7, charmeleon: "world", charmander: 15}
-
-The above query will return
-
-    {'hello max(charizard)': 50, 'world max(charizard)': 7}
-
-## Label
-
-     db.gql({select: 'upper(dept), charizard',
-     label: "upper(dept) 'Department', charizard 'Maximum Charizard!'"}, callback)
-
-Label is used to transform cryptic identifiers into something that can be displayed directly to the end user.
-Items in the label clause can be identifiers, aggregation functions, scalar functions, or operators.  The label
-clause is composed of any number of statement label pairs, where the statement corresponds to some statement in
-the select clause and the label is a string literal.
-
-With these documents in the database
-
-    {charizard: 50, dept: "eng", lunch:"2"},
-    {charizard: 40, lunch: "1", dept: "market"},·
-    {charizard: 99, dept: "eng", lunch: 1},
-    {charizard: 7, dept: "eng", lunch: 2}
-
-The above query will return
-
-    {Department: "ENG", Maximum Charizard!: 7},
-    {Department: "ENG", Maximum Charizard!: 99},
-    {Department: "MARKET", Maximum Charizard!: 40},
-    {Department: "ENG", Maximum Charizard!: 50}
-
-## Functions
-
-GQL contains a number of operators and functions that can operate on retrived documents.
-
-### Aggregation Functions
-
-    db.gql({select: "max(charizard), min(charizard), average(charizard), count(charizard), sum(charizard)"},
-    callback)
-
-The currently supported aggregation functions are avg, count, max, min, and sum.  Each of these takes a single
-statement as an argument.  A statement can be composed of one or more identifiers joined by operators.
-Avg and sum expect their arguments to evaluate to numbers; the other aggregators will accept any type of input.
-Aggregation functions operate on entire identifiers, returning only a single property. Aggregation functions
-may only appear in the select and label clauses.
-
-With these documents in the database
-
-    {charizard: 50},
-    {charizard: 40},
-    {charizard: 7}
-
-The above query will return
-
-    {average(charizard): 32.333333333333336, count(charizard): 3, max(charizard): 50,
-    min(charizard): 7, sum(charizard): 97}
-
-### Scalar Functions
-
-    db.gql({select: "`name!`, price-discount, upper(vendor)"}, callback)
-
-Currently only two scalar functions are supported, upper and lower.  These change the characters in their inputs
-to uppercase and lowercase respectively.  Unlike aggregator functions, scalar functions take only a single
-identifier as their input.  Scalar functions may only appear in the select and label clauses.
-
-With these documents in the database
-
-    {name!: "pencil", price: 2, discount: 0.7, vender: "store1"},
-    {name!: "pen", price:3, discount: 2, vendor: "store2"}
-
-The above query will return
-
-    {name!: "pen", price - discount: 1, upper(vendor): "STORE2"},
-    {name!: "pencil", price - discount: 1.3, upper(vendor): "STORE1"}
-
-
-### Arithmetic Operators
-
-    db.gql({select: "*", where: "charizard <=charmander * charmeleon + 2 and (charmander - 7 !=  24/3)"},
-    callback)
-
-Arithmetic operators are used to perform basic math on the values from documents.  Their arguments must be
-numbers.  Arithmetic operators may only appear in the select, label, and where clauses.  The arguments are
-implicitly upcast to floats if necessary. The supported arithmetic operators are:
-
-* Addition: '+'
-* Subtraction: '-'
-* Multiplication: '\*'
-* Division: '/'
-
-
-With these documents in the database
-
-    {charizard: 50, charmander: 24, charmeleon: 2, haunter:true},
-    {charizard: 40, charmeleon: .5, charmander: 50},
-    {charizard: 7, charmeleon: 20, charmander: 15}
-
-The above query will return
-
-    {charizard: 50, charmander: 24, charmeleon: 2, haunter: true}
-
-## Miscellaneous
-
-Some features that are not covered in other sections.
-
-### Literals
-
-Literals are used for comparison or arithmetic.  These are the supported literals:
-
-* string: Any characters surrounded by single or double quotes
-* number: Numbers in regular decimal form.  They may have a single period, a single negative sign, and no commas
-* boolean: Either true or false
-
-### Identifiers
-
-Identifiers correspond to the properties of documents in the database.  There are strict rules governing the
-way that identifiers can be expressed in queries.  If your identifier has spaces, is a reserved word, contains
-any characters that are not letters or numbers or underscores, or starts with a digit, it must be surrounded
-by backquotes \(\`identifier\`\).
-
-### Reserved Words
-
-This is the current list of reserved words.  Because the GQL implementation is currently under development,
-this list is likely to grow over time.
-
-    and
-    asc
-    by
-    date
-    datetime
-    desc
-    false
-    format
-    group
-    label
-    limit
-    not
-    offset
-    options
-    or
-    order
-    pivot
-    select
-    timeofday
-    timestamp
-    true
-    where
diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
index 11cd9e9..0000000
--- a/docs/index.md
+++ /dev/null
@@ -1,127 +0,0 @@
----
-layout: default
-title: PouchDB, the JavaScript Database that Syncs!
----
-
-<div class="intro">
-
-  <div class="container">
-
-    <div class="row">
-
-      <div class='col-sm-6'>
-
-        <h1>The Database that Syncs!</h1>
-
-        <p>PouchDB is an open-source JavaScript database inspired by <a href="http://couchdb.apache.org/">Apache CouchDB</a> that is designed to run well within the browser.</p>
-
-        <p>PouchDB was created to help web developers build applications that work as well offline as they do online.<br>
-        <p>It enables applications to store data locally while offline, then synchronize it with CouchDB and compatible servers when the application is back online, keeping the user's data in sync no matter where they next login.</p>
-
-        <a href="{{ site.baseurl }}/learn.html" class="btn btn-primary btn-lg">Learn more</a>
-
-      </div>
-
-      <div class='col-sm-6'>
-
-{% highlight js %}
-var db = new PouchDB('dbname');
-
-db.put({
-  _id: 'dave@gmail.com',
-  name: 'David',
-  age: 69
-});
-
-db.changes().on('change', function() {
-  console.log('Ch-Ch-Changes');
-});
-
-db.replicate.to('http://example.com/mydb');
-{% endhighlight %}
-
-      </div>
-
-    </div>
-
-  </div>
-
-</div>
-
-<div class="infoblocks">
-
-  <div class="container">
-
-    <div class='row'>
-
-
-      <div class='block col-sm-6 col-md-3'>
-
-        <div class="icon icon-node"></div>
-
-        <h3>Cross Browser</h3>
-        <p>Works in Firefox, Chrome, Opera, Safari, IE and Node.js</p>
-
-      </div>
-
-      <div class='block col-sm-6 col-md-3'>
-
-        <div class="icon icon-light"></div>
-
-        <h3>Lightweight</h3>
-        <p>PouchDB is just a script tag and 46KB (gzipped) away in the browser, or <code>$ npm install pouchdb</code> away
-        in Node.</p>
-
-      </div>
-
-      <div class='block col-sm-6 col-md-3'>
-
-        <div class="icon icon-learn"></div>
-
-        <h3>Easy to Learn</h3>
-        <p>Requires some programming knowledge, however PouchDB is a piece of cake to learn.</p>
-
-      </div>
-
-      <div class='block col-sm-6 col-md-3'>
-
-        <div class="icon icon-open"></div>
-
-        <h3>Open Source</h3>
-        <p>Everything is developed out in the open on Github, contributors always welcome!</p>
-
-      </div>
-
-    </div>
-  </div>
-
-</div>
-
-<div class="blog">
-
-  <div class="container">
-
-    <h3>Latest</h3>
-
-        <div class="row">
-
-{% for post in site.posts limit:2 %}
-
-<div class="col-md-6">
-
-
-  <p><a class='h4' href='{{ site.baseurl }}{{ post.url }}'>{{ post.title }}</a></p>
-
-{% include post_details.html %}
-
-  </div>
-
-{% endfor %}
-
-   </div>
-
-   <a class="btn btn-primary btn-lg" href="/blog/index.html">View more</a>
-
-  </div>
-
-</div>
diff --git a/docs/learn.md b/docs/learn.md
deleted file mode 100644
index 33c38b7..0000000
--- a/docs/learn.md
+++ /dev/null
@@ -1,94 +0,0 @@
----
-layout: 2ColLeft
-title: About PouchDB
-sidebar: nav.html
----
-
-PouchDB is an **in-browser database** that allows applications to save data locally, so that users can enjoy all the features of an app even when they're offline. Plus, the data is synchronized between clients, so users can stay up-to-date wherever they go.
-
-PouchDB also runs in **Node.js** and can be used as a direct interface to **CouchDB**-compatible servers. The API works the same in every environment, so you can spend less time worrying about browser differences, and more time writing clean, consistent code.
-
-PouchDB is a free open-source project, written in JavaScript and driven by our [wonderful  community](https://github.com/pouchdb/pouchdb/graphs/contributors). If you want to get involved, then check out the [contributing guide](https://github.com/pouchdb/pouchdb/blob/master/CONTRIBUTING.md).
-
-{% include anchor.html class="h3" title="Installing" hash="installing" %}
-
-To start using PouchDB in your website, simply [download][latest-min] it and include it in your page:
-
-{% highlight html %}
-<script src="pouchdb-{{ site.version }}.min.js"></script>
-{% endhighlight %}
-
-Or install it with Bower:
-
-{% highlight bash %}$ bower install --save pouchdb{% endhighlight %}
-
-Or install it as a Node.js module:
-
-{% highlight bash %}$ npm install --save pouchdb{% endhighlight %}
-
-{% include anchor.html class="h3" title="Using PouchDB" hash="using_pouchdb" %}
-
-In the browser, getting started is as simple as:
-
-{% highlight javascript %}
-var db = new PouchDB('my_database');
-{% endhighlight %}
-
-In Node.js, you'll need to `require()` it first:
-
-{% highlight javascript %}
-var PouchDB = require('pouchdb');
-var db = new PouchDB('my_database');
-{% endhighlight %}
-
-Or, to use PouchDB as a direct client to CouchDB, simply pass in a URL:
-
-{% highlight javascript %}
-var db = new PouchDB('http://localhost:5984/my_database');
-{% endhighlight %}
-
-All of these `db`s share the same API, regardless of where they're storing data!
-
-To learn more about how to use PouchDB, check out our [Getting Started Tutorial](getting-started.html), [Guides](/guides/) and the [API Documentation](api.html).
-
-{% include anchor.html class="h3" title="Browser Support" hash="browser_support" %}
-
-PouchDB supports all modern browsers, using [IndexedDB][] under the hood and falling back to [WebSQL][] where IndexedDB isn't supported. It is [fully tested](https://travis-ci.org/pouchdb/pouchdb/) and supported in:
-
- * Firefox 29+ (Including Firefox OS and Firefox for Android)
- * Chrome 30+
- * Safari 5+
- * Internet Explorer 10+
- * Opera 21+
- * Android 4.0+
- * iOS 7.1+
- * Windows Phone 8+
-
-PouchDB also runs in [Cordova/PhoneGap](https://github.com/nolanlawson/pouchdb-phonegap-cordova), [NW.js](https://github.com/nolanlawson/pouchdb-nw), [Electron](https://github.com/nolanlawson/pouchdb-atom-shell), and [Chrome apps](https://github.com/nolanlawson/pouchdb-chrome-app). It is framework-agnostic, and you can use it with Angular, React, Ember, Backbone, or your framework of choice. There are [many adapters](http://pouchdb.com/external.html#framework_adapters), or you can just use PouchDB as-is.
-
-PouchDB requires a modern ES5 environment, so if you need to support older browsers (IE <10, Android <4.0, Opera Mini), then you should include the [es5-shim](https://github.com/es-shims/es5-shim) library.  You can also use the [LocalStorage and in-memory adapters](/adapters.html#pouchdb_in_the_browser), or fall back to a live CouchDB.
-
-{% include anchor.html class="h3" title="Node.js" hash="node_js" %}
-
-In Node.js, PouchDB uses [LevelDB][] under the hood, and also supports [many other backends](/adapters.html#pouchdb_in_node_js) via the [LevelUP ecosystem](https://github.com/rvagg/node-levelup).
-
-PouchDB can also run as its own CouchDB-compatible web server, using [PouchDB Server](https://github.com/pouchdb/pouchdb-server).
-
-{% include anchor.html class="h3" title="Downloads" hash="downloads" %}
-
-Latest and greatest:
-
-* [pouchdb-{{ site.version }}.min.js][latest-min] (compressed for production)
-* [pouchdb-{{ site.version }}.js][latest] (uncompressed for debugging)
-
-PouchDB is also hosted on [jsdelivr](http://www.jsdelivr.com/#!pouchdb) and [cdnjs](https://cdnjs.com/libraries/pouchdb).
-
-For past releases and changelog, check out the [Github releases page](https://github.com/pouchdb/pouchdb/releases).
-
-For plugins, see the [plugins page](/external.html).
-
-[IndexedDB]: http://caniuse.com/#feat=indexeddb
-[WebSQL]: http://caniuse.com/#feat=sql-storage
-[LevelDB]: http://leveldb.org/
-[latest]: https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb-{{ site.version }}.js
-[latest-min]: https://github.com/pouchdb/pouchdb/releases/download/{{ site.version }}/pouchdb-{{ site.version }}.min.js
diff --git a/docs/manifest.appcache b/docs/manifest.appcache
deleted file mode 100644
index d590558..0000000
--- a/docs/manifest.appcache
+++ /dev/null
@@ -1,62 +0,0 @@
----
----
-
-CACHE MANIFEST
-# rev {{ site.time }}
-
-CACHE:
-{% for page in site.pages %}{% if page.url != '/manifest.appcache' %}{{ page.url | replace:'index.html','' }}{% endif %}
-{% endfor %}
-{% for page in site.guides %}{{ page.url | replace:'index.html','' }}
-{% endfor %}
-{% for page in site.posts %}{{ page.url | replace:'index.html','' }}
-{% endfor %}
-
-/static/css/pouchdb.css
-/static/favicon.ico
-/static/js/code.min.js
-/static/js/stickyfill.min.js
-
-http://code.jquery.com/jquery.min.js
-http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js
-http://cdn.jsdelivr.net/pouchdb/latest/pouchdb.min.js
-
-http://fonts.googleapis.com/css?family=Lato:400,700|Open+Sans:400,700
-http://fonts.gstatic.com/s/lato/v11/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
-http://fonts.gstatic.com/s/lato/v11/MDadn8DQ_3oT6kvnUq_2rxTbgVql8nDJpwnrE27mub0.woff2
-http://fonts.gstatic.com/s/lato/v11/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
-http://fonts.gstatic.com/s/lato/v11/MgNNr5y1C_tIEuLEmicLm1KPGs1ZzpMvnHX-7fPOuAc.woff2
-http://fonts.gstatic.com/s/opensans/v10/u-WUoqrET9fUeobQW7jkRZBw1xU1rKptJj_0jans920.woff2
-http://fonts.gstatic.com/s/opensans/v10/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2
-http://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzCYtBUPDK3WL7KRKS_3q7OE.woff2
-http://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2
-
-/static/img/apple-indexeddb.png
-/static/img/cors_in_couchdb.png
-/static/img/fauxton.png
-/static/img/kittens.jpg
-/static/img/logo.svg
-/static/img/safari_popup.png
-/static/img/dev_tools.png
-/static/img/icons.svg
-/static/img/kittens_small.jpg
-/static/img/mark.svg
-/static/img/icon-edit.svg
-/static/img/screenshots/todo-1.png
-/static/img/travis-screenshot.png
-
-/static/img/browser-logos/android_32x32.png
-/static/img/browser-logos/chrome-android_32x32.png
-/static/img/browser-logos/firefox_32x32.png
-/static/img/browser-logos/internet-explorer_32x32.png
-/static/img/browser-logos/safari-ios_32x32.png
-/static/img/browser-logos/blackberry_32x32.png
-/static/img/browser-logos/chrome_32x32.png
-/static/img/browser-logos/internet-explorer-tile_32x32.png
-/static/img/browser-logos/opera_32x32.png
-/static/img/browser-logos/safari_32x32.png
-
-NETWORK:
-*
-http://*
-https://*
diff --git a/docs/static/assets/pouchdb-getting-started-todo.zip b/docs/static/assets/pouchdb-getting-started-todo.zip
deleted file mode 100644
index 3ff9a51..0000000
--- a/docs/static/assets/pouchdb-getting-started-todo.zip
+++ /dev/null
Binary files differ
diff --git a/docs/static/favicon.ico b/docs/static/favicon.ico
deleted file mode 100644
index 99c00b8..0000000
--- a/docs/static/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/HoodieLogo.png b/docs/static/img/HoodieLogo.png
deleted file mode 100644
index d455b23..0000000
--- a/docs/static/img/HoodieLogo.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/apple-indexeddb.png b/docs/static/img/apple-indexeddb.png
deleted file mode 100644
index 9aebf2e..0000000
--- a/docs/static/img/apple-indexeddb.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/android_32x32.png b/docs/static/img/browser-logos/android_32x32.png
deleted file mode 100644
index e22e823..0000000
--- a/docs/static/img/browser-logos/android_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/blackberry_32x32.png b/docs/static/img/browser-logos/blackberry_32x32.png
deleted file mode 100644
index 267ae0e..0000000
--- a/docs/static/img/browser-logos/blackberry_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/chrome-android_32x32.png b/docs/static/img/browser-logos/chrome-android_32x32.png
deleted file mode 100644
index 60bd3c8..0000000
--- a/docs/static/img/browser-logos/chrome-android_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/chrome_32x32.png b/docs/static/img/browser-logos/chrome_32x32.png
deleted file mode 100644
index 407b8d1..0000000
--- a/docs/static/img/browser-logos/chrome_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/firefox_32x32.png b/docs/static/img/browser-logos/firefox_32x32.png
deleted file mode 100644
index 204925d..0000000
--- a/docs/static/img/browser-logos/firefox_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/internet-explorer-tile_32x32.png b/docs/static/img/browser-logos/internet-explorer-tile_32x32.png
deleted file mode 100644
index d756425..0000000
--- a/docs/static/img/browser-logos/internet-explorer-tile_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/internet-explorer_32x32.png b/docs/static/img/browser-logos/internet-explorer_32x32.png
deleted file mode 100644
index fb38945..0000000
--- a/docs/static/img/browser-logos/internet-explorer_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/opera_32x32.png b/docs/static/img/browser-logos/opera_32x32.png
deleted file mode 100644
index 8774e8c..0000000
--- a/docs/static/img/browser-logos/opera_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/safari-ios_32x32.png b/docs/static/img/browser-logos/safari-ios_32x32.png
deleted file mode 100644
index 08173d3..0000000
--- a/docs/static/img/browser-logos/safari-ios_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/browser-logos/safari_32x32.png b/docs/static/img/browser-logos/safari_32x32.png
deleted file mode 100644
index 0786006..0000000
--- a/docs/static/img/browser-logos/safari_32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/cloudwall.png b/docs/static/img/cloudwall.png
deleted file mode 100644
index fe36d4b..0000000
--- a/docs/static/img/cloudwall.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/cors_in_couchdb.png b/docs/static/img/cors_in_couchdb.png
deleted file mode 100644
index efd6b8e..0000000
--- a/docs/static/img/cors_in_couchdb.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/cozy.png b/docs/static/img/cozy.png
deleted file mode 100644
index 8a1f2b4..0000000
--- a/docs/static/img/cozy.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/debug_mode.png b/docs/static/img/debug_mode.png
deleted file mode 100644
index 6367cc5..0000000
--- a/docs/static/img/debug_mode.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/dev_tools.png b/docs/static/img/dev_tools.png
deleted file mode 100644
index e69e7d9..0000000
--- a/docs/static/img/dev_tools.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/ehealth_africa.png b/docs/static/img/ehealth_africa.png
deleted file mode 100644
index a893a3a..0000000
--- a/docs/static/img/ehealth_africa.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/fauxton.png b/docs/static/img/fauxton.png
deleted file mode 100644
index 7ad162a..0000000
--- a/docs/static/img/fauxton.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/fauxton_updated.png b/docs/static/img/fauxton_updated.png
deleted file mode 100644
index c48549e..0000000
--- a/docs/static/img/fauxton_updated.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/icon-edit.svg b/docs/static/img/icon-edit.svg
deleted file mode 100644
index 6ffe141..0000000
--- a/docs/static/img/icon-edit.svg
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 48 48" height="48px" id="Layer_1" version="1.1" viewBox="0 0 48 48" width="48px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path clip-rule="evenodd" d="M44.929,14.391c-0.046,0.099-0.102,0.194-0.183,0.276L16.84,42.572  c-0.109,0.188-0.26,0.352-0.475,0.434l-13.852,3.88c-0.029,0.014-0.062,0.016-0.094,0.026l-0.047,0.014  c-0.008,0.003-0.017,0.001-0.024,0.004c-0.094,0.025-0.187,0.046-0.286,0.045c-0.098,0.003-0.189-0.015-0.282-0.041  c-0.021-0.006-0.04-0.002-0.061-0.009c-0.008-0.003-0.013-0.01-0.021-0.013c-0.088-0.033-0.164-0.083-0.24-0.141  c-0.039-0.028-0.08-0.053-0.113-0.086s-0.058-0.074-0.086-0.113c-0.058-0.075-0.107-0.152-0.141-0.24  c-0.004-0.008-0.01-0.013-0.013-0.021c-0.007-0.02-0.003-0.04-0.009-0.061c-0.025-0.092-0.043-0.184-0.041-0.281  c0-0.1,0.02-0.193,0.045-0.287c0.004-0.008,0.001-0.016,0.004-0.023l0.014-0.049c0.011-0.03,0.013-0.063,0.026-0.093l3.88-13.852  c0.082-0.216,0.246-0.364,0.434-0.475l27.479-27.48c0.04-0.045,0.087-0.083,0.128-0.127l0.299-0.299  c0.015-0.015,0.034-0.02,0.05-0.034C34.858,1.87,36.796,1,38.953,1C43.397,1,47,4.603,47,9.047  C47,11.108,46.205,12.969,44.929,14.391z M41.15,15.5l-3.619-3.619L13.891,35.522c0.004,0.008,0.014,0.011,0.018,0.019l2.373,4.827  L41.15,15.5z M3.559,44.473l2.785-0.779l-2.006-2.005L3.559,44.473z M4.943,39.53l3.558,3.559l6.12-1.715  c0,0-2.586-5.372-2.59-5.374l-5.374-2.59L4.943,39.53z M12.49,34.124c0.008,0.004,0.011,0.013,0.019,0.018L36.15,10.5l-3.619-3.619  L7.663,31.749L12.49,34.124z M38.922,3c-1.782,0-3.372,0.776-4.489,1.994l-0.007-0.007L33.912,5.5l8.619,8.619l0.527-0.528  l-0.006-0.006c1.209-1.116,1.979-2.701,1.979-4.476C45.031,5.735,42.296,3,38.922,3z" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/docs/static/img/icons.svg b/docs/static/img/icons.svg
deleted file mode 100644
index 295847f..0000000
--- a/docs/static/img/icons.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" version="1.2" width="729.162" height="86.576"><path d="M30.99 7.92c1.113-.643 2.485-.643 3.598 0l28.65 16.75c1.116.642 1.802 1.83 1.802 3.117v31.037c0 1.286-.686 2.474-1.8 3.118L34.593 78.627c-1.115.642-2.487.642-3.602 0l-6.98-4.28m-2.69-43.26v33.977c0 1.503-4.208 3.18-6.175 2.886-4.12-.83-8.312-3.46-12.476-5.91-1.115-.642-1.8-1.832-1.8-3.117v-31.14c0-1.286.685-2.473 1.8-3.116l28.32-16.75m20.66 29.37c-.706-7.354-7.873-6.97-11.987-6.95-3.794.018-9.143.82-9.22 6.676-.063 4.915 6.458 5.486 10.3 6 4.957.666 11.893 1.26 12.085 6.548.136 3.724-3.505 7.568-10.647 7.568-12.23 0-12.89-7.353-12.89-7.353m254.34-25.583h40.914m-40.916 9.224h40.916m-40.916 9.42h40.916m9.368-25.274c-6.568-6.964-17.36-11.51-29.576-11.51-20.023 0-36.255 12.205-36.255 27.27 0 10.15 7.375 19.003 18.31 23.7.487 1.592 1.696 4.727 3.133 6.75 1.593 2.245 5.925 5.756 5.925 5.756s.05-5.63.05-8.183c.326-.57.52-.797 1.165-.923 1.483 0 3.49.04 4.225.05 1.133.08 2.287.12 3.448.12 2.4 0 4.724-.175 6.994-.51m22.582-42.52c4.198 4.45 6.678 9.886 6.678 15.76 0 13.26-12.595 24.303-29.26 26.76 6.568 6.964 17.36 11.51 29.576 11.51 1.16 0 2.315-.04 3.448-.12.736-.01 2.743-.05 4.225-.05.644.126.837.35 1.164.923 0 2.555.05 8.183.05 8.183s4.33-3.51 5.924-5.755c1.436-2.023 2.645-5.157 3.132-6.75 10.934-4.697 18.31-13.55 18.31-23.7 0-15.065-16.232-27.27-36.255-27.27-2.4 0-4.724.175-6.994.51zM73.594 83.942s2.774-5.473 4.362-8.095c2.632-4.346 5.497-8.585 8.54-12.626 7.2-9.56 15.882-18.06 25.18-25.6 4.34-3.52 10.794-8.29 16.473-12.03 10.085-6.646 31.185-18.45 31.185-18.45s-20.82 12.745-30.76 19.602c-5.606 3.87-11.915 9.004-16.16 12.508-9.288 7.667-18.092 16.125-25.392 25.704-2.925 3.837-5.548 7.77-8.017 11.85-1.487 2.46-4.08 7.592-4.08 7.592zm9.508-15.37c-2.436-2.82-4.572-4.206-4.572-4.206s1.902-.14 3.6 1.48c0 0-1.357-3.5-1.972-6.353-.607-2.817-.238-5.782-.07-6.563.55 1.595 2.676 5.39 2.676 5.39s-.577-5.447-.156-8.06c.42-2.613 1.243-7.247 1.654-7.755-.116 1.158 2.342 7.4 2.342 7.4s-.243-5.45.793-7.878c2.416-5.658 11.987-14.035 11.987-14.035s-.52 2.672-.614 4.026c-.196 2.834.39 6.023.39 6.023s.425-4.8 1.216-8.372c.29-1.313 1.188-3.854 1.188-3.854l.513 2.372s.92-2.198 1.678-3.09c3.893-4.577 14.256-11.03 14.256-11.03s-.61 3.033-.214 5.735c.39 2.683.79 5.307.82 5.116.03-.17.114-4.282.57-6.362.576-2.64 2.713-7.64 2.713-7.64l.174 1.628s.553-.83.93-1.146c2.09-1.77 7.153-4.043 7.153-4.043s.138 3.94.566 5.853c.215.96.995 2.774.995 2.774s-.115-1.938-.115-2.908c0-2.443.286-7.32.286-7.32s4.716-1.57 7.165-1.895c2.208-.292 6.68-.03 6.68-.03s.515 1.924.91 2.834c.242.557.886 1.59.886 1.59s.127-1.277.12-1.957c-.016-1.338.08-2.126.08-2.126s3.59-1.688 5.53-1.933c1.95-.246 5.875.503 5.875.503s-.334.895-.368 1.365c-.023.316-.304 1.22-.304 1.22s.82-.62 1.06-.72c.682-.28 2.177-.39 2.177-.39s2.067 2.374 2.435 3.846c.422 1.684-.385 5.193-.385 5.193s-1.55-.68-2.348-.957c-.576-.202-1.755-.517-1.755-.517s1.138.774 1.603 1.273c.567.61 1.41 2.06 1.41 2.06s-.725.963-1.124 1.416c-.353.4-1.12 1.147-1.12 1.147s-.982-.135-1.47-.088c-.287.028-.838.216-.838.216s.467.236.647.418c.223.224.507.8.507.8s-1.834 2.023-2.788 3c-3.283 3.357-10.098 9.822-10.098 9.822s-2.088-1.47-3.203-2.09c-.95-.526-2.952-1.373-2.952-1.373s1.76 1.24 2.563 1.953c1.057.94 2.952 3.047 2.952 3.047s-3.045 2.194-4.518 3.354c-.646.51-1.893 1.584-1.893 1.584s-.948-.01-1.41.083c-.42.085-1.218.43-1.218.43s1.056.236 1.553.442c.49.203 1.395.775 1.395.775s-8.14-.255-12.202-.022c-1.346.077-4.017.47-4.017.47s2.594.22 3.874.442c2.477.433 7.343 1.74 7.343 1.74s-4.456 3.835-6.91 5.438c-.762.497-2.406 1.282-2.406 1.282s-3.883-.81-5.995-1.09c-1.47-.194-4.433-.31-4.433-.31s2.982.582 4.403 1.104c1.304.48 3.737 2.33 3.737 2.33s-7.815.883-11.74.377c-1.81-.23-3.08-.33-3.08-.33s1.2.598 2.97 1.076c3.367.91 8.39 1.49 8.39 1.49s-7.243 3.445-12.492 3.912c-1.74.098-5.203.49-5.203.49s3.688.816 5.565.9c1.755.078 5.258-.375 5.258-.375s-3.09 2.695-6.054 3.227c-1.05.196-3.483-.034-3.483-.034s2.045 1.18 2.823 1.506c.568.237 1.6.927 1.6.927l.044.28c.002.12-.045.36-.045.36s-4.604-.385-7.68-.844c-1.143-.17-3.447-.343-3.447-.343s2.23.803 3.31 1.293c2.392 1.09 5.518 2.673 5.518 2.673s-2.163.584-3.274.66c-.88.062-2.647-.16-2.647-.16s1.4.75 1.67.96c.51.404 1.36 1.404 1.36 1.404s-3.785.796-5.692.677c-1.465-.092-3.85-.815-4.277-1.062 1.24.716 2.083 3.814 2.083 3.814s-4.133-2.874-6.392-3.958c-1.6-.768-3.17-.963-5.018-1.78zm108.727 8.29s15.632-17.2 23.36-25.883c6.276-7.057 18.25-20.44 18.683-21.298-3.078-2.293-3.406-17.705 2.408-21.432 14.42-9.137 21.74 1.73 21.74 1.73l-12.906 6.243 7.354 16.65s-4.7 2.578-7.216 3.47c-1.882.668-3.673 1.42-5.828 1.388L204.04 86.02c-5.028-.025-9.382-1.44-12.21-9.158zm30.573-15.77l16.605 23.403c4.774-1.36 9.723-2.287 12.35-9.02l-22.242-23.777m-7.35-7.858l-12.592-13.463c-.744-.618-.964-2.023-.97-3.747l-6.8-7.77c2.455-12.252 9.842-14.966 17.76-16.652-7.604-4.2-17.927-.425-31.082 11.656-1.29 5.998-4.78 9.668-12.35 9.02l-4.44 3.884c1.376 3.672 2.096 7.522 7.91 9.99l5.688-4.162c.384-5.297 3.754-6.794 8.187-6.938l6.52 7.91c1.39.092 2.776-.238 4.164 1.248l11.42 16.096m26.74-19.217l4.3-2.012-4.092-9.575-4.44 2.22zm6.035-9.158l12.905-5.76s.633 4.952-.486 7.008c-1.768 3.25-8.88 6.66-8.88 6.66" fill="none" stroke="#908f8f" stroke-width="1.111"/><path d="M560.346 22.49c-11.776 0-21.326 9.547-21.326 21.325 0 9.422 6.11 17.416 14.584 20.236 1.066.2 1.457-.46 1.457-1.024 0-.51-.02-2.188-.027-3.97-5.933 1.29-7.185-2.516-7.185-2.516-.97-2.466-2.368-3.12-2.368-3.12-1.936-1.325.145-1.297.145-1.297 2.14.15 3.27 2.198 3.27 2.198 1.9 3.26 4.988 2.32 6.205 1.774.19-1.378.744-2.32 1.354-2.852-4.737-.538-9.716-2.367-9.716-10.538 0-2.328.833-4.23 2.197-5.724-.22-.537-.95-2.706.207-5.644 0 0 1.79-.573 5.866 2.186 1.7-.473 3.525-.71 5.338-.718 1.812.008 3.638.245 5.342.718 4.07-2.76 5.86-2.186 5.86-2.186 1.16 2.937.43 5.106.208 5.644 1.367 1.493 2.195 3.396 2.195 5.724 0 8.19-4.987 9.994-9.736 10.522.765.662 1.446 1.96 1.446 3.95 0 2.852-.026 5.15-.026 5.85 0 .57.384 1.233 1.465 1.024 8.467-2.823 14.57-10.814 14.57-20.233 0-11.778-9.548-21.326-21.325-21.326" fill="#1b1817" fill-rule="evenodd"/><path d="M523.655 35.1V19.54h-74.56V35.1h-5.833v31.88h86.113V35.1z" fill="#f00"/><path d="M441.707 67.71V33.56h5.84V17.988h77.747V33.56h5.726v34.15h-89.313zm2.435-1.227l84.128.074-.365-29.88h-5.728V21.102H450.66v15.575h-5.84l-.57 28.818-.11.99z" fill="#eb1019"/><path d="M455.64 28.46l7.81-2.65-.03-10.59-10.438 2.634v7.012z" fill="#fff"/><path d="M518.08 53.332l.01 13.905h-63.525l.035-13.616 17.628 3.985zm-11.017-9.58l-4.792-1.988-9.962-6.803-11.905 3.625-25.815-1.955v9.157l16.37 4.696 46.773-4.155v-9.553z" fill="#bd101d" stroke="#bd101d" stroke-width=".412"/><path d="M450.522 37.07h4.066l7.526 11.33 2.775.758 3.767 15.617 1.955.81 1.383 5.715H482.9l-5.243-21.674 14.815-9.62 8.057 6.81 1.955-.768.743 2.024 14.5-1.302-1.258-3.213-8.16-1.995-14.773-12.037-16.1 6.106-4.945-6.51 7.452-7.574h7.102l2.8 2.36v-2.36h5.583l-1.35-3.133-16.35-2.59-15.094 9.668-15.106 5.065-2.95 3.12v8.37l4.165 1.773v-4.834l1.772 1.39z" fill="#fff"/><path d="M402.18 61.976c-5.33 0-10.29-1.562-14.465-4.24.738.088 1.49.133 2.25.133 4.422 0 8.49-1.51 11.72-4.04-4.13-.077-7.614-2.805-8.814-6.554.578.11 1.17.17 1.777.17.86 0 1.694-.116 2.486-.332-4.317-.867-7.57-4.68-7.57-9.252l.002-.12c1.272.708 2.727 1.132 4.274 1.18-2.533-1.69-4.2-4.58-4.2-7.853 0-1.73.466-3.35 1.278-4.745 4.654 5.71 11.607 9.465 19.45 9.86-.162-.692-.245-1.412-.245-2.15 0-5.212 4.225-9.437 9.436-9.437 2.713 0 5.165 1.145 6.887 2.98 2.15-.424 4.17-1.21 5.992-2.29-.706 2.202-2.2 4.052-4.15 5.22 1.91-.228 3.727-.735 5.42-1.486-1.265 1.892-2.865 3.554-4.708 4.885.02.404.028.81.028 1.22 0 12.47-9.49 26.847-26.847 26.847" fill="#6babe1"/><path d="M594.842 21.81h35.407c1.755 0 3.17 1.304 3.17 2.923v35.752c0 1.62-1.415 2.923-3.17 2.923h-35.41c-1.757 0-3.17-1.304-3.17-2.923V24.733c0-1.62 1.413-2.923 3.17-2.923z" fill="#cc2b29"/><path d="M597.945 26.3v11.45h8.245v-3.366h1.9v15.77h-2.78v8.762h14.41v-8.76h-2.766V34.383h1.913v3.365h8.28V26.3h-29.203zm2.52 2.374h24.162v6.723h-3.4v-3.33h-6.793v20.678h2.98v3.798h-9.738v-3.798h2.904V32.067h-6.716v3.33h-3.4v-6.723z" fill="#fff"/><path d="M729.162 63.407V21.81h-38.34v41.597z"/><path d="M725.63 39.84v20.2h-31.277V48.31h6.108c.048.002.086.02.094.074.19 6.41 4.095 9.79 8.462 10.026 6.323.34 8.925-4.334 9.123-8.71 0-4.38-3.408-6.686-7.495-8.578-2.45-1.3-4.91-3.152-4.848-5.627.063-2.5 1.89-5.43 5.174-5.43 3.285 0 5.098 3 5.15 7.1-.017 1.552 1.14 2.64 3.236 2.646 2.103 0 4.556.03 6.276.03z" fill="#f00"/><path d="M694.353 44.726V25.178h31.277v11.077h-5.998c-.175-.036-.175-.086-.206-.222-.232-6.3-4.285-9.227-8.457-9.227-4.65 0-8.367 2.648-8.775 8.27-.278 3.824 3.057 7.126 7.144 9.018 2.45 1.3 5.273 3.11 5.217 5.606-.062 2.784-1.396 5.125-5.218 5.125-2.8 0-5.294-2.184-5.294-6.516 0-1.52-.958-3.586-3.21-3.586z" fill="#ff0"/><g fill="none"><path d="M663.047 30.84l-16.196 7.996V55.1l16.197 8.13 16.195-8.13V38.835l-16.195-7.996z" fill="#d4eb95"/><path d="M663.047 28.255l-16.196 7.997v16.263l16.197 8.132 16.195-8.132V36.252l-16.195-7.997z" fill="#96dc75"/><path d="M663.047 21.708l-16.196 7.996v16.264l16.197 8.132 16.195-8.132V29.704l-16.195-7.996z" opacity=".553" fill="#317342"/><path d="M663.047 37.245l-16.196-7.61v16.31l16.197 8.155 16.195-8.156v-16.31l-16.195 7.61z" opacity=".553" fill="#34954c"/></g></svg>
\ No newline at end of file
diff --git a/docs/static/img/kittens.jpg b/docs/static/img/kittens.jpg
deleted file mode 100644
index fe87f9b..0000000
--- a/docs/static/img/kittens.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/kittens_small.jpg b/docs/static/img/kittens_small.jpg
deleted file mode 100644
index ddcf454..0000000
--- a/docs/static/img/kittens_small.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/logo.svg b/docs/static/img/logo.svg
deleted file mode 100644
index e3907c4..0000000
--- a/docs/static/img/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="1124.731" height="351.571"><path d="M19.997 0L0 97.532l57.353 54.113L20.09 218.07l75.823 133.5h82.95l76.148-133.5-37.586-66.425 55.41-54.113L254.593 0l-77.997 103.878h-78.09z" fill="#6ccb94" fill-opacity=".996"/><path d="M57.353 151.645l80.028 66.426-38.876-114.19z" fill="#64c48c" fill-opacity=".996"/><path d="M255.01 218.07l-37.587-66.426-80.04 66.426z" fill="#6ecc95" fill-opacity=".996"/><path d="M95.912 351.57h82.95l-41.48-133.5z" fill="#5ebe86" fill-opacity=".996"/><path d="M217.423 151.645l-80.04 66.426 39.213-114.19z" fill="#76d29c" fill-opacity=".996"/><path d="M20.09 218.07l37.262-66.426 80.028 66.426z" fill="#5dbd85" fill-opacity=".996"/><path d="M254.593 0l18.238 97.532-55.408 54.113-40.828-47.767z" fill="#74d09b" fill-opacity=".996"/><path d="M137.38 218.07l41.483 133.5 76.147-133.5z" fill="#64c48c" fill-opacity=".996"/><path d="M137.38 218.07L95.9 351.57l-75.81-133.5z" fill="#58b880" fill-opacity=".996"/><path d="M19.997 0L0 97.532l57.353 54.113 41.152-47.767z" fill="#5fbf87" fill-opacity=".996"/><path d="M137.38 218.07l39.215-114.192h-78.09z" fill="#6ecc95" fill-opacity=".996"/><path d="M331.274 300.22v-151.5h12.737c2.98 0 4.842 1.414 5.587 4.245l1.788 12.96c4.767-5.735 10.242-10.353 16.424-13.854 6.256-3.574 13.406-5.362 21.45-5.362 6.48 0 12.328 1.266 17.542 3.8 5.288 2.457 9.795 6.144 13.52 11.06 3.798 4.916 6.702 10.986 8.714 18.21 2.01 7.152 3.016 15.42 3.017 24.805 0 8.417-1.117 16.238-3.352 23.463-2.234 7.15-5.474 13.37-9.72 18.658-4.245 5.288-9.384 9.46-15.417 12.513-6.033 2.98-12.85 4.47-20.446 4.47-6.927 0-12.81-1.118-17.653-3.353-4.84-2.235-9.162-5.437-12.96-9.61v49.496h-21.228m51.06-136.418c-6.407 0-11.993 1.452-16.76 4.357-4.693 2.83-9.05 6.89-13.072 12.177v54.187c3.575 4.693 7.448 8.007 11.62 9.944 4.246 1.862 8.975 2.793 14.19 2.793 10.203 0 18.06-3.65 23.573-10.948 5.512-7.3 8.268-17.876 8.268-31.73 0-7.225-.633-13.407-1.9-18.547-1.265-5.14-3.09-9.348-5.474-12.625-2.383-3.352-5.288-5.773-8.714-7.262-3.426-1.564-7.337-2.346-11.73-2.346m115.223-16.87c8.34 0 15.864 1.377 22.568 4.133 6.704 2.68 12.402 6.555 17.094 11.62 4.693 5.065 8.305 11.21 10.838 18.435 2.532 7.15 3.8 15.195 3.8 24.133 0 8.938-1.267 17.02-3.8 24.245-2.533 7.225-6.145 13.37-10.838 18.435-4.692 5.065-10.39 8.975-17.094 11.73-6.704 2.682-14.227 4.023-22.57 4.023-8.34 0-15.902-1.34-22.68-4.022-6.704-2.756-12.44-6.666-17.206-11.73-4.692-5.066-8.305-11.21-10.837-18.436-2.533-7.225-3.8-15.307-3.8-24.245s1.267-16.982 3.8-24.133c2.532-7.225 6.145-13.37 10.837-18.435 4.767-5.065 10.502-8.938 17.206-11.62 6.778-2.756 14.338-4.134 22.68-4.134m0 100.22c10.876 0 18.994-3.65 24.357-10.95 5.363-7.298 8.044-17.577 8.044-30.836 0-13.184-2.682-23.463-8.045-30.837-5.363-7.374-13.482-11.06-24.356-11.06-11.025 0-19.255 3.686-24.693 11.06-5.363 7.374-8.044 17.653-8.044 30.837 0 13.258 2.68 23.537 8.044 30.837 5.437 7.3 13.668 10.95 24.692 10.95m89.305-98.43v72.286c0 8.193 1.9 14.6 5.698 19.217 3.8 4.544 9.57 6.815 17.318 6.815 5.662 0 10.95-1.303 15.866-3.91 4.99-2.68 9.608-6.368 13.854-11.06v-83.35h21.228v113.404H648.09c-2.978 0-4.84-1.415-5.585-4.246l-1.676-11.73c-4.917 5.287-10.392 9.57-16.425 12.847-5.96 3.277-12.886 4.916-20.78 4.916-6.258 0-11.77-1.044-16.537-3.13-4.693-2.085-8.64-4.99-11.843-8.714-3.128-3.8-5.512-8.305-7.15-13.52-1.64-5.287-2.458-11.134-2.458-17.54V148.72h21.228m179.506 20.89c-.595.82-1.228 1.453-1.898 1.9-.596.447-1.453.67-2.57.67-1.192 0-2.458-.447-3.8-1.34-1.34-.97-2.98-1.975-4.915-3.017-1.937-1.117-4.32-2.123-7.15-3.017-2.83-.968-6.294-1.452-10.39-1.452-5.438 0-10.243.968-14.414 2.905-4.17 1.936-7.672 4.73-10.502 8.38-2.755 3.65-4.84 8.043-6.256 13.183-1.415 5.14-2.123 10.95-2.123 17.43 0 6.704.746 12.662 2.236 17.876 1.564 5.213 3.724 9.608 6.48 13.183 2.83 3.575 6.22 6.294 10.167 8.156 4.022 1.86 8.49 2.792 13.407 2.792 4.767 0 8.677-.56 11.73-1.676 3.055-1.192 5.587-2.458 7.598-3.8 2.01-1.34 3.687-2.57 5.028-3.686 1.415-1.192 2.83-1.788 4.246-1.788 1.788 0 3.128.67 4.022 2.01l6.033 7.71c-2.607 3.128-5.512 5.81-8.715 8.044-3.203 2.235-6.63 4.06-10.28 5.475-3.65 1.416-7.448 2.46-11.395 3.13-3.948.67-7.97 1.005-12.066 1.005-7.075 0-13.667-1.304-19.775-3.91-6.108-2.607-11.433-6.406-15.977-11.396-4.47-4.99-8.007-11.1-10.614-18.324-2.533-7.3-3.8-15.567-3.8-24.803 0-8.417 1.155-16.163 3.464-23.24 2.384-7.15 5.847-13.332 10.39-18.546s10.13-9.273 16.76-12.178c6.704-2.906 14.375-4.358 23.016-4.358 8.12 0 15.232 1.303 21.34 3.91 6.182 2.607 11.62 6.257 16.312 10.95l-5.586 7.82m26.777 92.51V97.323h21.228v65.92c4.767-4.917 10.055-8.865 15.865-11.844 5.81-2.98 12.513-4.47 20.11-4.47 6.183 0 11.62 1.044 16.313 3.13 4.767 2.085 8.752 5.027 11.955 8.826 3.203 3.724 5.623 8.23 7.262 13.52 1.64 5.213 2.455 11.023 2.458 17.428v72.287H867.11v-72.286c0-8.193-1.9-14.562-5.698-19.105-3.8-4.62-9.57-6.928-17.318-6.928-5.735 0-11.06 1.34-15.977 4.022s-9.497 6.368-13.742 11.06v83.238h-21.228m201.032 0c-2.98 0-4.842-1.416-5.587-4.247l-1.9-13.295c-2.383 2.905-4.952 5.55-7.708 7.933-2.756 2.31-5.698 4.32-8.826 6.033-3.13 1.64-6.444 2.905-9.945 3.8-3.5.893-7.262 1.34-11.284 1.34-6.48 0-12.363-1.23-17.652-3.687-5.214-2.533-9.72-6.258-13.52-11.174-3.723-4.916-6.59-10.95-8.602-18.1-2.01-7.225-3.017-15.53-3.017-24.915 0-8.416 1.116-16.2 3.35-23.35 2.236-7.225 5.476-13.482 9.72-18.77 4.247-5.288 9.386-9.422 15.42-12.402 6.032-3.054 12.848-4.58 20.445-4.58 6.853 0 12.7 1.154 17.54 3.463 4.917 2.236 9.274 5.4 13.073 9.498V97.325h21.228v164.797H994.18m-38.323-15.53c6.33 0 11.88-1.415 16.647-4.246 4.767-2.905 9.162-7.002 13.184-12.29V175.98c-3.575-4.767-7.486-8.082-11.73-9.944-4.247-1.936-8.94-2.905-14.08-2.905-10.203 0-18.062 3.65-23.573 10.95-5.512 7.3-8.268 17.876-8.268 31.73 0 7.226.633 13.408 1.9 18.548 1.265 5.14 3.09 9.385 5.474 12.737 2.385 3.277 5.29 5.698 8.716 7.262 3.426 1.49 7.337 2.235 11.73 2.235m68.097 15.53V97.323h21.228v67.37c4.694-5.436 10.02-9.756 15.978-12.96 6.033-3.202 12.886-4.803 20.558-4.803 6.63 0 12.588 1.304 17.876 3.91 5.363 2.533 9.906 6.183 13.63 10.95 3.725 4.767 6.555 10.614 8.492 17.54 2.01 6.854 3.016 14.563 3.017 23.128 0 9.162-1.154 17.504-3.463 25.027-2.235 7.523-5.475 13.966-9.72 19.33-4.17 5.362-9.273 9.533-15.307 12.512-5.96 2.905-12.7 4.357-20.223 4.357-7.448 0-13.705-1.378-18.77-4.134-4.99-2.83-9.385-6.704-13.184-11.62l-1.006 9.72c-.67 2.98-2.458 4.47-5.363 4.47h-13.742m50.724-98.32c-6.33 0-11.843 1.45-16.536 4.356-4.618 2.83-8.938 6.89-12.96 12.178v54.187c3.575 4.694 7.486 8.008 11.73 9.945 4.247 1.862 8.865 2.793 13.855 2.793 10.353 0 18.286-3.65 23.798-10.95 5.512-7.298 8.268-18.322 8.268-33.07 0-13.556-2.457-23.5-7.373-29.83-4.842-6.407-11.77-9.61-20.78-9.61" style="text-align:start;line-height:125%;-inkscape-font-specification:Lato Medium" font-size="144" font-weight="500" letter-spacing="-.153" word-spacing="0" fill="#3e3e3e" font-family="Lato"/></svg>
diff --git a/docs/static/img/mark.svg b/docs/static/img/mark.svg
deleted file mode 100644
index a795ae1..0000000
--- a/docs/static/img/mark.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="272.833" height="351.571"><path d="M19.997 0L0 97.532l57.353 54.113L20.09 218.07l75.823 133.5h82.95l76.148-133.5-37.586-66.425 55.41-54.113L254.593 0l-77.997 103.878h-78.09z" fill="#6ccb94" fill-opacity=".996"/><path d="M20.09 218.07l37.262-66.425 80.028 66.426z" fill="#5dbd85" fill-opacity=".996"/><path d="M57.353 151.646l80.028 66.426L98.505 103.88z" fill="#64c48c" fill-opacity=".996"/><path d="M255.01 218.07l-37.587-66.425-80.04 66.426z" fill="#6ecc95" fill-opacity=".996"/><path d="M95.912 351.57h82.95l-41.48-133.5z" fill="#5ebe86" fill-opacity=".996"/><path d="M217.423 151.646l-80.04 66.426 39.213-114.192z" fill="#76d29c" fill-opacity=".996"/><path d="M254.593 0l18.238 97.533-55.408 54.113-40.828-47.767z" fill="#74d09b" fill-opacity=".996"/><path d="M137.38 218.07l41.483 133.5 76.147-133.5z" fill="#64c48c" fill-opacity=".996"/><path d="M137.38 218.07L95.9 351.57l-75.81-133.5z" fill="#58b880" fill-opacity=".996"/><path d="M19.997 0L0 97.534l57.353 54.113 41.152-47.767z" fill="#5fbf87" fill-opacity=".996"/><path d="M137.38 218.07l39.215-114.19h-78.09z" fill="#6ecc95" fill-opacity=".996"/></svg>
diff --git a/docs/static/img/mbta_alerts.jpeg b/docs/static/img/mbta_alerts.jpeg
deleted file mode 100644
index b943bc9..0000000
--- a/docs/static/img/mbta_alerts.jpeg
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/offline_replication.gif b/docs/static/img/offline_replication.gif
deleted file mode 100644
index b5d5b4d..0000000
--- a/docs/static/img/offline_replication.gif
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/orson_welles_clapping.gif b/docs/static/img/orson_welles_clapping.gif
deleted file mode 100644
index 9f9001a..0000000
--- a/docs/static/img/orson_welles_clapping.gif
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/pepperidge_farm_remembers.png b/docs/static/img/pepperidge_farm_remembers.png
deleted file mode 100644
index a575023..0000000
--- a/docs/static/img/pepperidge_farm_remembers.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/pokedexorg-logo.png b/docs/static/img/pokedexorg-logo.png
deleted file mode 100644
index 4f75cf4..0000000
--- a/docs/static/img/pokedexorg-logo.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/pouchdb_inspector.png b/docs/static/img/pouchdb_inspector.png
deleted file mode 100644
index 13e207e..0000000
--- a/docs/static/img/pouchdb_inspector.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/safari_inspector.png b/docs/static/img/safari_inspector.png
deleted file mode 100644
index 4b690ef..0000000
--- a/docs/static/img/safari_inspector.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/safari_popup.png b/docs/static/img/safari_popup.png
deleted file mode 100644
index 983e6a7..0000000
--- a/docs/static/img/safari_popup.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/screenshots/todo-1.png b/docs/static/img/screenshots/todo-1.png
deleted file mode 100644
index 8a82807..0000000
--- a/docs/static/img/screenshots/todo-1.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/sonic_waiting.gif b/docs/static/img/sonic_waiting.gif
deleted file mode 100644
index 9a23218..0000000
--- a/docs/static/img/sonic_waiting.gif
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/squarespace_blog.png b/docs/static/img/squarespace_blog.png
deleted file mode 100644
index 63e1060..0000000
--- a/docs/static/img/squarespace_blog.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/img/travis-screenshot.png b/docs/static/img/travis-screenshot.png
deleted file mode 100644
index f1d7c84..0000000
--- a/docs/static/img/travis-screenshot.png
+++ /dev/null
Binary files differ
diff --git a/docs/static/js/code.js b/docs/static/js/code.js
deleted file mode 100644
index e3a3b88..0000000
--- a/docs/static/js/code.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* jshint jquery: true */
-
-function codeWrap(){
-  "use strict";
-
-  var DEFAULT_TYPE = 'promise';
-
-  var $codes = $('[data-code-id]').get();
-
-  var codeIds =
-    $codes
-      .map(function(div){
-          return div.attributes["data-code-id"].value
-      })
-      .filter(function(item, index, inputArray){
-          // Each code block has multiple versions so let's only grab one.
-          return inputArray.indexOf(item) == index;
-      });
-
-  wrap();
-  setAll();
-
-  $('[data-code-tablist] [href]').on('click', function(e){
-    var href = $(this).attr('href');
-
-    setAll(href.replace('#', ''));
-
-    setEqualHeights();
-
-    e.preventDefault();
-  });
-
-  function wrap(){
-    var codeTpl = '' +
-      '<ul class="nav nav-tabs nav-code" data-code-tablist="{{codeId}}">' +
-        '<li>' +
-            '<a href="#async">Async functions</a>' +
-        '</li>' +
-        '<li class="active">' +
-            '<a href="#promise">Promises</a>' +
-        '</li>' +
-        '<li>' +
-            '<a href="#callback">Callbacks</a>' +
-        '</li>' +
-      '</ul>' +
-      '<div class="tab-content">{{tapPanes}}</div>';
-    codeIds
-      .forEach(function(id){
-        var $code = $("[data-code-id='" + id + "']");
-
-        var paneHtml = $code.get().map(function(div){
-          return div.outerHTML;
-        }).join('');
-
-        var codeHtml = codeTpl
-                          .replace(/{{tapPanes}}/g, paneHtml)
-                          .replace(/{{codeId}}/g, id);
-        $code
-          .first()
-          .replaceWith(codeHtml);
-        $code.remove();
-      });
-    // Remove items that are only useful for non-JS users.
-    $('[data-code-hide]').addClass('hide');
-  }
-
-  function setAll(type){
-
-    // We default to callback so no need to do anything the first time.
-    var firstTime = !localStorage.getItem('codeStyle');
-    if(firstTime){
-      localStorage.setItem('codeStyle', DEFAULT_TYPE);
-    }
-
-    type = type || localStorage.getItem('codeStyle');
-    if(typeof type === "undefined" || type === null) {
-      return;
-    }
-
-    var $tablist = $('[data-code-tablist] [href="#' + type + '"]').parent();
-    $('[data-code-tablist] li').removeClass('active');
-    $tablist.addClass('active');
-
-    $('.tab-pane').removeClass('active');
-    $('.tab-pane[id="' + type + '"]').addClass('active');
-    localStorage.setItem('codeStyle', type);
-  }
-
-
-  var setHeights = [];
-  function setEqualHeights(){
-    if(setHeights.length > 0){
-      return;
-    }
-    codeIds
-      .forEach(function(id){
-        var $code = $("[data-code-id='" + id + "']");
-
-        var paneHeight = 0;
-
-        $code.get().forEach(function(div){
-          var originalDisplay = div.style.display;
-          div.style.display = 'block';
-          var clientHeight = div.clientHeight;
-          div.style.display = originalDisplay;
-          if(clientHeight > paneHeight){
-            paneHeight = clientHeight;
-          }
-        });
-        $code.find('pre').css('height', paneHeight);
-        setHeights.push(id);
-      });
-  }
-}
-codeWrap();
diff --git a/docs/static/js/code.min.js b/docs/static/js/code.min.js
deleted file mode 100644
index 5bf9fd3..0000000
--- a/docs/static/js/code.min.js
+++ /dev/null
@@ -1 +0,0 @@
-function codeWrap(){"use strict";function a(){var a='<ul class="nav nav-tabs nav-code" data-code-tablist="{{codeId}}"><li><a href="#async">Async functions</a></li><li class="active"><a href="#promise">Promises</a></li><li><a href="#callback">Callbacks</a></li></ul><div class="tab-content">{{tapPanes}}</div>';l.forEach(function(e){var t=$("[data-code-id='"+e+"']"),c=t.get().map(function(a){return a.outerHTML}).join(""),i=a.replace(/{{tapPanes}}/g,c).replace(/{{codeId}}/g,e);t.first().replaceWith(i),t.remove()}),$("[data-code-hide]").addClass("hide")}function e(a){var e=!localStorage.getItem("codeStyle");if(e&&localStorage.setItem("codeStyle",c),a=a||localStorage.getItem("codeStyle"),"undefined"!=typeof a&&null!==a){var t=$('[data-code-tablist] [href="#'+a+'"]').parent();$("[data-code-tablist] li").removeClass("active"),t.addClass("active"),$(".tab-pane").removeClass("active"),$('.tab-pane[id="'+a+'"]').addClass("active"),localStorage.setItem("codeStyle",a)}}function t(){o.length>0||l.forEach(function(a){var e=$("[data-code-id='"+a+"']"),t=0;e.get().forEach(function(a){var e=a.style.display;a.style.display="block";var c=a.clientHeight;a.style.display=e,c>t&&(t=c)}),e.find("pre").css("height",t),o.push(a)})}var c="promise",i=$("[data-code-id]").get(),l=i.map(function(a){return a.attributes["data-code-id"].value}).filter(function(a,e,t){return t.indexOf(a)==e});a(),e(),$("[data-code-tablist] [href]").on("click",function(a){var c=$(this).attr("href");e(c.replace("#","")),t(),a.preventDefault()});var o=[]}codeWrap();
diff --git a/docs/static/js/stickyfill.min.js b/docs/static/js/stickyfill.min.js
deleted file mode 100644
index 9d8326f..0000000
--- a/docs/static/js/stickyfill.min.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*!
- * Stickyfill -- `position: sticky` polyfill
- * v. 1.1.3 | https://github.com/wilddeer/stickyfill
- * Copyright Oleg Korsunsky | http://wd.dizaina.net/
- *
- * MIT License
- */
-!function(a,b){function c(){y=D=z=A=B=C=K}function d(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}function e(a){return parseFloat(a)||0}function f(){F={top:b.pageYOffset,left:b.pageXOffset}}function g(){return b.pageXOffset!=F.left?(f(),void z()):void(b.pageYOffset!=F.top&&(f(),i()))}function h(){setTimeout(function(){b.pageYOffset!=F.top&&(F.top=b.pageYOffset,i())},0)}function i(){for(var a=H.length-1;a>=0;a--)j(H[a])}function j(a){if(a.inited){var b=F.top<=a.limit.start?0:F.top>=a.limit.end?2:1;a.mode!=b&&p(a,b)}}function k(){for(var a=H.length-1;a>=0;a--)if(H[a].inited){var b=Math.abs(t(H[a].clone)-H[a].docOffsetTop),c=Math.abs(H[a].parent.node.offsetHeight-H[a].parent.height);if(b>=2||c>=2)return!1}return!0}function l(a){isNaN(parseFloat(a.computed.top))||a.isCell||"none"==a.computed.display||(a.inited=!0,a.clone||q(a),"absolute"!=a.parent.computed.position&&"relative"!=a.parent.computed.position&&(a.parent.node.style.position="relative"),j(a),a.parent.height=a.parent.node.offsetHeight,a.docOffsetTop=t(a.clone))}function m(a){var b=!0;a.clone&&r(a),d(a.node.style,a.css);for(var c=H.length-1;c>=0;c--)if(H[c].node!==a.node&&H[c].parent.node===a.parent.node){b=!1;break}b&&(a.parent.node.style.position=a.parent.css.position),a.mode=-1}function n(){for(var a=H.length-1;a>=0;a--)l(H[a])}function o(){for(var a=H.length-1;a>=0;a--)m(H[a])}function p(a,b){var c=a.node.style;switch(b){case 0:c.position="absolute",c.left=a.offset.left+"px",c.right=a.offset.right+"px",c.top=a.offset.top+"px",c.bottom="auto",c.width="auto",c.marginLeft=0,c.marginRight=0,c.marginTop=0;break;case 1:c.position="fixed",c.left=a.box.left+"px",c.right=a.box.right+"px",c.top=a.css.top,c.bottom="auto",c.width="auto",c.marginLeft=0,c.marginRight=0,c.marginTop=0;break;case 2:c.position="absolute",c.left=a.offset.left+"px",c.right=a.offset.right+"px",c.top="auto",c.bottom=0,c.width="auto",c.marginLeft=0,c.marginRight=0}a.mode=b}function q(a){a.clone=document.createElement("div");var b=a.node.nextSibling||a.node,c=a.clone.style;c.height=a.height+"px",c.width=a.width+"px",c.marginTop=a.computed.marginTop,c.marginBottom=a.computed.marginBottom,c.marginLeft=a.computed.marginLeft,c.marginRight=a.computed.marginRight,c.padding=c.border=c.borderSpacing=0,c.fontSize="1em",c.position="static",c.cssFloat=a.computed.cssFloat,a.node.parentNode.insertBefore(a.clone,b)}function r(a){a.clone.parentNode.removeChild(a.clone),a.clone=void 0}function s(a){var b=getComputedStyle(a),c=a.parentNode,d=getComputedStyle(c),f=a.style.position;a.style.position="relative";var g={top:b.top,marginTop:b.marginTop,marginBottom:b.marginBottom,marginLeft:b.marginLeft,marginRight:b.marginRight,cssFloat:b.cssFloat,display:b.display},h={top:e(b.top),marginBottom:e(b.marginBottom),paddingLeft:e(b.paddingLeft),paddingRight:e(b.paddingRight),borderLeftWidth:e(b.borderLeftWidth),borderRightWidth:e(b.borderRightWidth)};a.style.position=f;var i={position:a.style.position,top:a.style.top,bottom:a.style.bottom,left:a.style.left,right:a.style.right,width:a.style.width,marginTop:a.style.marginTop,marginLeft:a.style.marginLeft,marginRight:a.style.marginRight},j=u(a),k=u(c),l={node:c,css:{position:c.style.position},computed:{position:d.position},numeric:{borderLeftWidth:e(d.borderLeftWidth),borderRightWidth:e(d.borderRightWidth),borderTopWidth:e(d.borderTopWidth),borderBottomWidth:e(d.borderBottomWidth)}},m={node:a,box:{left:j.win.left,right:J.clientWidth-j.win.right},offset:{top:j.win.top-k.win.top-l.numeric.borderTopWidth,left:j.win.left-k.win.left-l.numeric.borderLeftWidth,right:-j.win.right+k.win.right-l.numeric.borderRightWidth},css:i,isCell:"table-cell"==b.display,computed:g,numeric:h,width:j.win.right-j.win.left,height:j.win.bottom-j.win.top,mode:-1,inited:!1,parent:l,limit:{start:j.doc.top-h.top,end:k.doc.top+c.offsetHeight-l.numeric.borderBottomWidth-a.offsetHeight-h.top-h.marginBottom}};return m}function t(a){for(var b=0;a;)b+=a.offsetTop,a=a.offsetParent;return b}function u(a){var c=a.getBoundingClientRect();return{doc:{top:c.top+b.pageYOffset,left:c.left+b.pageXOffset},win:c}}function v(){G=setInterval(function(){!k()&&z()},500)}function w(){clearInterval(G)}function x(){I&&(document[L]?w():v())}function y(){I||(f(),n(),b.addEventListener("scroll",g),b.addEventListener("wheel",h),b.addEventListener("resize",z),b.addEventListener("orientationchange",z),a.addEventListener(M,x),v(),I=!0)}function z(){if(I){o();for(var a=H.length-1;a>=0;a--)H[a]=s(H[a].node);n()}}function A(){b.removeEventListener("scroll",g),b.removeEventListener("wheel",h),b.removeEventListener("resize",z),b.removeEventListener("orientationchange",z),a.removeEventListener(M,x),w(),I=!1}function B(){A(),o()}function C(){for(B();H.length;)H.pop()}function D(a){for(var b=H.length-1;b>=0;b--)if(H[b].node===a)return;var c=s(a);H.push(c),I?l(c):y()}function E(a){for(var b=H.length-1;b>=0;b--)H[b].node===a&&(m(H[b]),H.splice(b,1))}var F,G,H=[],I=!1,J=a.documentElement,K=function(){},L="hidden",M="visibilitychange";void 0!==a.webkitHidden&&(L="webkitHidden",M="webkitvisibilitychange"),b.getComputedStyle||c();for(var N=["","-webkit-","-moz-","-ms-"],O=document.createElement("div"),P=N.length-1;P>=0;P--){try{O.style.position=N[P]+"sticky"}catch(Q){}""!=O.style.position&&c()}f(),b.Stickyfill={stickies:H,add:D,remove:E,init:y,rebuild:z,pause:A,stop:B,kill:C}}(document,window),window.jQuery&&!function($){$.fn.Stickyfill=function(){return this.each(function(){Stickyfill.add(this)}),this}}(window.jQuery);
\ No newline at end of file
diff --git a/docs/static/less/bootstrap/alerts.less b/docs/static/less/bootstrap/alerts.less
deleted file mode 100644
index 3eab066..0000000
--- a/docs/static/less/bootstrap/alerts.less
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Alerts
-// --------------------------------------------------
-
-
-// Base styles
-// -------------------------
-
-.alert {
-  padding: @alert-padding;
-  margin-bottom: @line-height-computed;
-  border: 1px solid transparent;
-  border-radius: @alert-border-radius;
-
-  // Headings for larger alerts
-  h4 {
-    margin-top: 0;
-    // Specified for the h4 to prevent conflicts of changing @headings-color
-    color: inherit;
-  }
-  // Provide class for links that match alerts
-  .alert-link {
-    font-weight: @alert-link-font-weight;
-  }
-
-  // Improve alignment and spacing of inner content
-  > p,
-  > ul {
-    margin-bottom: 0;
-  }
-  > p + p {
-    margin-top: 5px;
-  }
-}
-
-// Dismissable alerts
-//
-// Expand the right padding and account for the close button's positioning.
-
-.alert-dismissable {
- padding-right: (@alert-padding + 20);
-
-  // Adjust close link position
-  .close {
-    position: relative;
-    top: -2px;
-    right: -21px;
-    color: inherit;
-  }
-}
-
-// Alternate styles
-//
-// Generate contextual modifier classes for colorizing the alert.
-
-.alert-success {
-  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);
-}
-.alert-info {
-  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);
-}
-.alert-warning {
-  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);
-}
-.alert-danger {
-  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);
-}
diff --git a/docs/static/less/bootstrap/badges.less b/docs/static/less/bootstrap/badges.less
deleted file mode 100644
index 56828ca..0000000
--- a/docs/static/less/bootstrap/badges.less
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Badges
-// --------------------------------------------------
-
-
-// Base classes
-.badge {
-  display: inline-block;
-  min-width: 10px;
-  padding: 3px 7px;
-  font-size: @font-size-small;
-  font-weight: @badge-font-weight;
-  color: @badge-color;
-  line-height: @badge-line-height;
-  vertical-align: baseline;
-  white-space: nowrap;
-  text-align: center;
-  background-color: @badge-bg;
-  border-radius: @badge-border-radius;
-
-  // Empty badges collapse automatically (not available in IE8)
-  &:empty {
-    display: none;
-  }
-
-  // Quick fix for badges in buttons
-  .btn & {
-    position: relative;
-    top: -1px;
-  }
-  .btn-xs & {
-    top: 0;
-    padding: 1px 5px;
-  }
-}
-
-// Hover state, but only for links
-a.badge {
-  &:hover,
-  &:focus {
-    color: @badge-link-hover-color;
-    text-decoration: none;
-    cursor: pointer;
-  }
-}
-
-// Account for counters in navs
-a.list-group-item.active > .badge,
-.nav-pills > .active > a > .badge {
-  color: @badge-active-color;
-  background-color: @badge-active-bg;
-}
-.nav-pills > li > a > .badge {
-  margin-left: 3px;
-}
diff --git a/docs/static/less/bootstrap/bootstrap.less b/docs/static/less/bootstrap/bootstrap.less
deleted file mode 100644
index b368b87..0000000
--- a/docs/static/less/bootstrap/bootstrap.less
+++ /dev/null
@@ -1,49 +0,0 @@
-// Core variables and mixins
-@import "variables.less";
-@import "mixins.less";
-
-// Reset
-@import "normalize.less";
-@import "print.less";
-
-// Core CSS
-@import "scaffolding.less";
-@import "type.less";
-@import "code.less";
-@import "grid.less";
-@import "tables.less";
-@import "forms.less";
-@import "buttons.less";
-
-// Components
-@import "component-animations.less";
-@import "glyphicons.less";
-@import "dropdowns.less";
-@import "button-groups.less";
-@import "input-groups.less";
-@import "navs.less";
-@import "navbar.less";
-@import "breadcrumbs.less";
-@import "pagination.less";
-@import "pager.less";
-@import "labels.less";
-@import "badges.less";
-@import "jumbotron.less";
-@import "thumbnails.less";
-@import "alerts.less";
-@import "progress-bars.less";
-@import "media.less";
-@import "list-group.less";
-@import "panels.less";
-@import "wells.less";
-@import "close.less";
-
-// Components w/ JavaScript
-@import "modals.less";
-@import "tooltip.less";
-@import "popovers.less";
-@import "carousel.less";
-
-// Utility classes
-@import "utilities.less";
-@import "responsive-utilities.less";
diff --git a/docs/static/less/bootstrap/breadcrumbs.less b/docs/static/less/bootstrap/breadcrumbs.less
deleted file mode 100644
index cb01d50..0000000
--- a/docs/static/less/bootstrap/breadcrumbs.less
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Breadcrumbs
-// --------------------------------------------------
-
-
-.breadcrumb {
-  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;
-  margin-bottom: @line-height-computed;
-  list-style: none;
-  background-color: @breadcrumb-bg;
-  border-radius: @border-radius-base;
-
-  > li {
-    display: inline-block;
-
-    + li:before {
-      content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space
-      padding: 0 5px;
-      color: @breadcrumb-color;
-    }
-  }
-
-  > .active {
-    color: @breadcrumb-active-color;
-  }
-}
diff --git a/docs/static/less/bootstrap/button-groups.less b/docs/static/less/bootstrap/button-groups.less
deleted file mode 100644
index 27eb796..0000000
--- a/docs/static/less/bootstrap/button-groups.less
+++ /dev/null
@@ -1,226 +0,0 @@
-//
-// Button groups
-// --------------------------------------------------
-
-// Make the div behave like a button
-.btn-group,
-.btn-group-vertical {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle; // match .btn alignment given font-size hack above
-  > .btn {
-    position: relative;
-    float: left;
-    // Bring the "active" button to the front
-    &:hover,
-    &:focus,
-    &:active,
-    &.active {
-      z-index: 2;
-    }
-    &:focus {
-      // Remove focus outline when dropdown JS adds it after closing the menu
-      outline: none;
-    }
-  }
-}
-
-// Prevent double borders when buttons are next to each other
-.btn-group {
-  .btn + .btn,
-  .btn + .btn-group,
-  .btn-group + .btn,
-  .btn-group + .btn-group {
-    margin-left: -1px;
-  }
-}
-
-// Optional: Group multiple button groups together for a toolbar
-.btn-toolbar {
-  margin-left: -5px; // Offset the first child's margin
-  &:extend(.clearfix all);
-
-  .btn-group,
-  .input-group {
-    float: left;
-  }
-  > .btn,
-  > .btn-group,
-  > .input-group {
-    margin-left: 5px;
-  }
-}
-
-.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
-  border-radius: 0;
-}
-
-// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
-.btn-group > .btn:first-child {
-  margin-left: 0;
-  &:not(:last-child):not(.dropdown-toggle) {
-    .border-right-radius(0);
-  }
-}
-// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
-.btn-group > .btn:last-child:not(:first-child),
-.btn-group > .dropdown-toggle:not(:first-child) {
-  .border-left-radius(0);
-}
-
-// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
-.btn-group > .btn-group {
-  float: left;
-}
-.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
-  border-radius: 0;
-}
-.btn-group > .btn-group:first-child {
-  > .btn:last-child,
-  > .dropdown-toggle {
-    .border-right-radius(0);
-  }
-}
-.btn-group > .btn-group:last-child > .btn:first-child {
-  .border-left-radius(0);
-}
-
-// On active and open, don't show outline
-.btn-group .dropdown-toggle:active,
-.btn-group.open .dropdown-toggle {
-  outline: 0;
-}
-
-
-// Sizing
-//
-// Remix the default button sizing classes into new ones for easier manipulation.
-
-.btn-group-xs > .btn { &:extend(.btn-xs); }
-.btn-group-sm > .btn { &:extend(.btn-sm); }
-.btn-group-lg > .btn { &:extend(.btn-lg); }
-
-
-// Split button dropdowns
-// ----------------------
-
-// Give the line between buttons some depth
-.btn-group > .btn + .dropdown-toggle {
-  padding-left: 8px;
-  padding-right: 8px;
-}
-.btn-group > .btn-lg + .dropdown-toggle {
-  padding-left: 12px;
-  padding-right: 12px;
-}
-
-// The clickable button for toggling the menu
-// Remove the gradient and set the same inset shadow as the :active state
-.btn-group.open .dropdown-toggle {
-  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
-
-  // Show no shadow for `.btn-link` since it has no other button styles.
-  &.btn-link {
-    .box-shadow(none);
-  }
-}
-
-
-// Reposition the caret
-.btn .caret {
-  margin-left: 0;
-}
-// Carets in other button sizes
-.btn-lg .caret {
-  border-width: @caret-width-large @caret-width-large 0;
-  border-bottom-width: 0;
-}
-// Upside down carets for .dropup
-.dropup .btn-lg .caret {
-  border-width: 0 @caret-width-large @caret-width-large;
-}
-
-
-// Vertical button groups
-// ----------------------
-
-.btn-group-vertical {
-  > .btn,
-  > .btn-group,
-  > .btn-group > .btn {
-    display: block;
-    float: none;
-    width: 100%;
-    max-width: 100%;
-  }
-
-  // Clear floats so dropdown menus can be properly placed
-  > .btn-group {
-    &:extend(.clearfix all);
-    > .btn {
-      float: none;
-    }
-  }
-
-  > .btn + .btn,
-  > .btn + .btn-group,
-  > .btn-group + .btn,
-  > .btn-group + .btn-group {
-    margin-top: -1px;
-    margin-left: 0;
-  }
-}
-
-.btn-group-vertical > .btn {
-  &:not(:first-child):not(:last-child) {
-    border-radius: 0;
-  }
-  &:first-child:not(:last-child) {
-    border-top-right-radius: @border-radius-base;
-    .border-bottom-radius(0);
-  }
-  &:last-child:not(:first-child) {
-    border-bottom-left-radius: @border-radius-base;
-    .border-top-radius(0);
-  }
-}
-.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
-  border-radius: 0;
-}
-.btn-group-vertical > .btn-group:first-child:not(:last-child) {
-  > .btn:last-child,
-  > .dropdown-toggle {
-    .border-bottom-radius(0);
-  }
-}
-.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
-  .border-top-radius(0);
-}
-
-
-
-// Justified button groups
-// ----------------------
-
-.btn-group-justified {
-  display: table;
-  width: 100%;
-  table-layout: fixed;
-  border-collapse: separate;
-  > .btn,
-  > .btn-group {
-    float: none;
-    display: table-cell;
-    width: 1%;
-  }
-  > .btn-group .btn {
-    width: 100%;
-  }
-}
-
-
-// Checkbox and radio options
-[data-toggle="buttons"] > .btn > input[type="radio"],
-[data-toggle="buttons"] > .btn > input[type="checkbox"] {
-  display: none;
-}
diff --git a/docs/static/less/bootstrap/buttons.less b/docs/static/less/bootstrap/buttons.less
deleted file mode 100644
index d4fc156..0000000
--- a/docs/static/less/bootstrap/buttons.less
+++ /dev/null
@@ -1,159 +0,0 @@
-//
-// Buttons
-// --------------------------------------------------
-
-
-// Base styles
-// --------------------------------------------------
-
-.btn {
-  display: inline-block;
-  margin-bottom: 0; // For input.btn
-  font-weight: @btn-font-weight;
-  text-align: center;
-  vertical-align: middle;
-  cursor: pointer;
-  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-  border: 1px solid transparent;
-  white-space: nowrap;
-  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
-  .user-select(none);
-
-  &,
-  &:active,
-  &.active {
-    &:focus {
-      .tab-focus();
-    }
-  }
-
-  &:hover,
-  &:focus {
-    color: @btn-default-color;
-    text-decoration: none;
-  }
-
-  &:active,
-  &.active {
-    outline: 0;
-    background-image: none;
-    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
-  }
-
-  &.disabled,
-  &[disabled],
-  fieldset[disabled] & {
-    cursor: not-allowed;
-    pointer-events: none; // Future-proof disabling of clicks
-    .opacity(.65);
-    .box-shadow(none);
-  }
-}
-
-
-// Alternate buttons
-// --------------------------------------------------
-
-.btn-default {
-  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
-}
-.btn-primary {
-  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
-}
-// Success appears as green
-.btn-success {
-  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);
-}
-// Info appears as blue-green
-.btn-info {
-  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);
-}
-// Warning appears as orange
-.btn-warning {
-  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);
-}
-// Danger and error appear as red
-.btn-danger {
-  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);
-}
-
-
-// Link buttons
-// -------------------------
-
-// Make a button look and behave like a link
-.btn-link {
-  color: @link-color;
-  font-weight: normal;
-  cursor: pointer;
-  border-radius: 0;
-
-  &,
-  &:active,
-  &[disabled],
-  fieldset[disabled] & {
-    background-color: transparent;
-    .box-shadow(none);
-  }
-  &,
-  &:hover,
-  &:focus,
-  &:active {
-    border-color: transparent;
-  }
-  &:hover,
-  &:focus {
-    color: @link-hover-color;
-    text-decoration: underline;
-    background-color: transparent;
-  }
-  &[disabled],
-  fieldset[disabled] & {
-    &:hover,
-    &:focus {
-      color: @btn-link-disabled-color;
-      text-decoration: none;
-    }
-  }
-}
-
-
-// Button Sizes
-// --------------------------------------------------
-
-.btn-lg {
-  // line-height: ensure even-numbered height of button next to large input
-  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
-}
-.btn-sm {
-  // line-height: ensure proper height of button next to small input
-  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
-}
-.btn-xs {
-  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
-}
-
-
-// Block button
-// --------------------------------------------------
-
-.btn-block {
-  display: block;
-  width: 100%;
-  padding-left: 0;
-  padding-right: 0;
-}
-
-// Vertically space out multiple block buttons
-.btn-block + .btn-block {
-  margin-top: 5px;
-}
-
-// Specificity overrides
-input[type="submit"],
-input[type="reset"],
-input[type="button"] {
-  &.btn-block {
-    width: 100%;
-  }
-}
diff --git a/docs/static/less/bootstrap/carousel.less b/docs/static/less/bootstrap/carousel.less
deleted file mode 100644
index e3fb8a2..0000000
--- a/docs/static/less/bootstrap/carousel.less
+++ /dev/null
@@ -1,232 +0,0 @@
-//
-// Carousel
-// --------------------------------------------------
-
-
-// Wrapper for the slide container and indicators
-.carousel {
-  position: relative;
-}
-
-.carousel-inner {
-  position: relative;
-  overflow: hidden;
-  width: 100%;
-
-  > .item {
-    display: none;
-    position: relative;
-    .transition(.6s ease-in-out left);
-
-    // Account for jankitude on images
-    > img,
-    > a > img {
-      &:extend(.img-responsive);
-      line-height: 1;
-    }
-  }
-
-  > .active,
-  > .next,
-  > .prev { display: block; }
-
-  > .active {
-    left: 0;
-  }
-
-  > .next,
-  > .prev {
-    position: absolute;
-    top: 0;
-    width: 100%;
-  }
-
-  > .next {
-    left: 100%;
-  }
-  > .prev {
-    left: -100%;
-  }
-  > .next.left,
-  > .prev.right {
-    left: 0;
-  }
-
-  > .active.left {
-    left: -100%;
-  }
-  > .active.right {
-    left: 100%;
-  }
-
-}
-
-// Left/right controls for nav
-// ---------------------------
-
-.carousel-control {
-  position: absolute;
-  top: 0;
-  left: 0;
-  bottom: 0;
-  width: @carousel-control-width;
-  .opacity(@carousel-control-opacity);
-  font-size: @carousel-control-font-size;
-  color: @carousel-control-color;
-  text-align: center;
-  text-shadow: @carousel-text-shadow;
-  // We can't have this transition here because WebKit cancels the carousel
-  // animation if you trip this while in the middle of another animation.
-
-  // Set gradients for backgrounds
-  &.left {
-    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));
-  }
-  &.right {
-    left: auto;
-    right: 0;
-    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));
-  }
-
-  // Hover/focus state
-  &:hover,
-  &:focus {
-    outline: none;
-    color: @carousel-control-color;
-    text-decoration: none;
-    .opacity(.9);
-  }
-
-  // Toggles
-  .icon-prev,
-  .icon-next,
-  .glyphicon-chevron-left,
-  .glyphicon-chevron-right {
-    position: absolute;
-    top: 50%;
-    z-index: 5;
-    display: inline-block;
-  }
-  .icon-prev,
-  .glyphicon-chevron-left {
-    left: 50%;
-  }
-  .icon-next,
-  .glyphicon-chevron-right {
-    right: 50%;
-  }
-  .icon-prev,
-  .icon-next {
-    width:  20px;
-    height: 20px;
-    margin-top: -10px;
-    margin-left: -10px;
-    font-family: serif;
-  }
-
-  .icon-prev {
-    &:before {
-      content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
-    }
-  }
-  .icon-next {
-    &:before {
-      content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
-    }
-  }
-}
-
-// Optional indicator pips
-//
-// Add an unordered list with the following class and add a list item for each
-// slide your carousel holds.
-
-.carousel-indicators {
-  position: absolute;
-  bottom: 10px;
-  left: 50%;
-  z-index: 15;
-  width: 60%;
-  margin-left: -30%;
-  padding-left: 0;
-  list-style: none;
-  text-align: center;
-
-  li {
-    display: inline-block;
-    width:  10px;
-    height: 10px;
-    margin: 1px;
-    text-indent: -999px;
-    border: 1px solid @carousel-indicator-border-color;
-    border-radius: 10px;
-    cursor: pointer;
-
-    // IE8-9 hack for event handling
-    //
-    // Internet Explorer 8-9 does not support clicks on elements without a set
-    // `background-color`. We cannot use `filter` since that's not viewed as a
-    // background color by the browser. Thus, a hack is needed.
-    //
-    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
-    // set alpha transparency for the best results possible.
-    background-color: #000 \9; // IE8
-    background-color: rgba(0,0,0,0); // IE9
-  }
-  .active {
-    margin: 0;
-    width:  12px;
-    height: 12px;
-    background-color: @carousel-indicator-active-bg;
-  }
-}
-
-// Optional captions
-// -----------------------------
-// Hidden by default for smaller viewports
-.carousel-caption {
-  position: absolute;
-  left: 15%;
-  right: 15%;
-  bottom: 20px;
-  z-index: 10;
-  padding-top: 20px;
-  padding-bottom: 20px;
-  color: @carousel-caption-color;
-  text-align: center;
-  text-shadow: @carousel-text-shadow;
-  & .btn {
-    text-shadow: none; // No shadow for button elements in carousel-caption
-  }
-}
-
-
-// Scale up controls for tablets and up
-@media screen and (min-width: @screen-sm-min) {
-
-  // Scale up the controls a smidge
-  .carousel-control {
-    .glyphicon-chevron-left,
-    .glyphicon-chevron-right,
-    .icon-prev,
-    .icon-next {
-      width: 30px;
-      height: 30px;
-      margin-top: -15px;
-      margin-left: -15px;
-      font-size: 30px;
-    }
-  }
-
-  // Show and left align the captions
-  .carousel-caption {
-    left: 20%;
-    right: 20%;
-    padding-bottom: 30px;
-  }
-
-  // Move up the indicators
-  .carousel-indicators {
-    bottom: 20px;
-  }
-}
diff --git a/docs/static/less/bootstrap/close.less b/docs/static/less/bootstrap/close.less
deleted file mode 100644
index 9b4e74f..0000000
--- a/docs/static/less/bootstrap/close.less
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Close icons
-// --------------------------------------------------
-
-
-.close {
-  float: right;
-  font-size: (@font-size-base * 1.5);
-  font-weight: @close-font-weight;
-  line-height: 1;
-  color: @close-color;
-  text-shadow: @close-text-shadow;
-  .opacity(.2);
-
-  &:hover,
-  &:focus {
-    color: @close-color;
-    text-decoration: none;
-    cursor: pointer;
-    .opacity(.5);
-  }
-
-  // Additional properties for button version
-  // iOS requires the button element instead of an anchor tag.
-  // If you want the anchor version, it requires `href="#"`.
-  button& {
-    padding: 0;
-    cursor: pointer;
-    background: transparent;
-    border: 0;
-    -webkit-appearance: none;
-  }
-}
diff --git a/docs/static/less/bootstrap/code.less b/docs/static/less/bootstrap/code.less
deleted file mode 100644
index 3eed26c..0000000
--- a/docs/static/less/bootstrap/code.less
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Code (inline and block)
-// --------------------------------------------------
-
-
-// Inline and block code styles
-code,
-kbd,
-pre,
-samp {
-  font-family: @font-family-monospace;
-}
-
-// Inline code
-code {
-  padding: 2px 4px;
-  font-size: 90%;
-  color: @code-color;
-  background-color: @code-bg;
-  white-space: nowrap;
-  border-radius: @border-radius-base;
-}
-
-// User input typically entered via keyboard
-kbd {
-  padding: 2px 4px;
-  font-size: 90%;
-  color: @kbd-color;
-  background-color: @kbd-bg;
-  border-radius: @border-radius-small;
-  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
-}
-
-// Blocks of code
-pre {
-  display: block;
-  padding: ((@line-height-computed - 1) / 2);
-  margin: 0 0 (@line-height-computed / 2);
-  font-size: (@font-size-base - 1); // 14px to 13px
-  line-height: @line-height-base;
-  word-break: break-all;
-  word-wrap: break-word;
-  color: @pre-color;
-  background-color: @pre-bg;
-  border: 1px solid @pre-border-color;
-  border-radius: @border-radius-base;
-
-  // Account for some code outputs that place code tags in pre tags
-  code {
-    padding: 0;
-    font-size: inherit;
-    color: inherit;
-    white-space: pre-wrap;
-    background-color: transparent;
-    border-radius: 0;
-  }
-}
-
-// Enable scrollable blocks of code
-.pre-scrollable {
-  max-height: @pre-scrollable-max-height;
-  overflow-y: scroll;
-}
diff --git a/docs/static/less/bootstrap/component-animations.less b/docs/static/less/bootstrap/component-animations.less
deleted file mode 100644
index 1efe45e..0000000
--- a/docs/static/less/bootstrap/component-animations.less
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Component animations
-// --------------------------------------------------
-
-// Heads up!
-//
-// We don't use the `.opacity()` mixin here since it causes a bug with text
-// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.
-
-.fade {
-  opacity: 0;
-  .transition(opacity .15s linear);
-  &.in {
-    opacity: 1;
-  }
-}
-
-.collapse {
-  display: none;
-  &.in {
-    display: block;
-  }
-}
-.collapsing {
-  position: relative;
-  height: 0;
-  overflow: hidden;
-  .transition(height .35s ease);
-}
diff --git a/docs/static/less/bootstrap/dropdowns.less b/docs/static/less/bootstrap/dropdowns.less
deleted file mode 100644
index f165165..0000000
--- a/docs/static/less/bootstrap/dropdowns.less
+++ /dev/null
@@ -1,213 +0,0 @@
-//
-// Dropdown menus
-// --------------------------------------------------
-
-
-// Dropdown arrow/caret
-.caret {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 2px;
-  vertical-align: middle;
-  border-top:   @caret-width-base solid;
-  border-right: @caret-width-base solid transparent;
-  border-left:  @caret-width-base solid transparent;
-}
-
-// The dropdown wrapper (div)
-.dropdown {
-  position: relative;
-}
-
-// Prevent the focus on the dropdown toggle when closing dropdowns
-.dropdown-toggle:focus {
-  outline: 0;
-}
-
-// The dropdown menu (ul)
-.dropdown-menu {
-  position: absolute;
-  top: 100%;
-  left: 0;
-  z-index: @zindex-dropdown;
-  display: none; // none by default, but block on "open" of the menu
-  float: left;
-  min-width: 160px;
-  padding: 5px 0;
-  margin: 2px 0 0; // override default ul
-  list-style: none;
-  font-size: @font-size-base;
-  background-color: @dropdown-bg;
-  border: 1px solid @dropdown-fallback-border; // IE8 fallback
-  border: 1px solid @dropdown-border;
-  border-radius: @border-radius-base;
-  .box-shadow(0 6px 12px rgba(0,0,0,.175));
-  background-clip: padding-box;
-
-  // Aligns the dropdown menu to right
-  //
-  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
-  &.pull-right {
-    right: 0;
-    left: auto;
-  }
-
-  // Dividers (basically an hr) within the dropdown
-  .divider {
-    .nav-divider(@dropdown-divider-bg);
-  }
-
-  // Links within the dropdown menu
-  > li > a {
-    display: block;
-    padding: 3px 20px;
-    clear: both;
-    font-weight: normal;
-    line-height: @line-height-base;
-    color: @dropdown-link-color;
-    white-space: nowrap; // prevent links from randomly breaking onto new lines
-  }
-}
-
-// Hover/Focus state
-.dropdown-menu > li > a {
-  &:hover,
-  &:focus {
-    text-decoration: none;
-    color: @dropdown-link-hover-color;
-    background-color: @dropdown-link-hover-bg;
-  }
-}
-
-// Active state
-.dropdown-menu > .active > a {
-  &,
-  &:hover,
-  &:focus {
-    color: @dropdown-link-active-color;
-    text-decoration: none;
-    outline: 0;
-    background-color: @dropdown-link-active-bg;
-  }
-}
-
-// Disabled state
-//
-// Gray out text and ensure the hover/focus state remains gray
-
-.dropdown-menu > .disabled > a {
-  &,
-  &:hover,
-  &:focus {
-    color: @dropdown-link-disabled-color;
-  }
-}
-// Nuke hover/focus effects
-.dropdown-menu > .disabled > a {
-  &:hover,
-  &:focus {
-    text-decoration: none;
-    background-color: transparent;
-    background-image: none; // Remove CSS gradient
-    .reset-filter();
-    cursor: not-allowed;
-  }
-}
-
-// Open state for the dropdown
-.open {
-  // Show the menu
-  > .dropdown-menu {
-    display: block;
-  }
-
-  // Remove the outline when :focus is triggered
-  > a {
-    outline: 0;
-  }
-}
-
-// Menu positioning
-//
-// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
-// menu with the parent.
-.dropdown-menu-right {
-  left: auto; // Reset the default from `.dropdown-menu`
-  right: 0;
-}
-// With v3, we enabled auto-flipping if you have a dropdown within a right
-// aligned nav component. To enable the undoing of that, we provide an override
-// to restore the default dropdown menu alignment.
-//
-// This is only for left-aligning a dropdown menu within a `.navbar-right` or
-// `.pull-right` nav component.
-.dropdown-menu-left {
-  left: 0;
-  right: auto;
-}
-
-// Dropdown section headers
-.dropdown-header {
-  display: block;
-  padding: 3px 20px;
-  font-size: @font-size-small;
-  line-height: @line-height-base;
-  color: @dropdown-header-color;
-}
-
-// Backdrop to catch body clicks on mobile, etc.
-.dropdown-backdrop {
-  position: fixed;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  top: 0;
-  z-index: (@zindex-dropdown - 10);
-}
-
-// Right aligned dropdowns
-.pull-right > .dropdown-menu {
-  right: 0;
-  left: auto;
-}
-
-// Allow for dropdowns to go bottom up (aka, dropup-menu)
-//
-// Just add .dropup after the standard .dropdown class and you're set, bro.
-// TODO: abstract this so that the navbar fixed styles are not placed here?
-
-.dropup,
-.navbar-fixed-bottom .dropdown {
-  // Reverse the caret
-  .caret {
-    border-top: 0;
-    border-bottom: @caret-width-base solid;
-    content: "";
-  }
-  // Different positioning for bottom up menu
-  .dropdown-menu {
-    top: auto;
-    bottom: 100%;
-    margin-bottom: 1px;
-  }
-}
-
-
-// Component alignment
-//
-// Reiterate per navbar.less and the modified component alignment there.
-
-@media (min-width: @grid-float-breakpoint) {
-  .navbar-right {
-    .dropdown-menu {
-      .dropdown-menu-right();
-    }
-    // Necessary for overrides of the default right aligned menu.
-    // Will remove come v4 in all likelihood.
-    .dropdown-menu-left {
-      .dropdown-menu-left();
-    }
-  }
-}
-
diff --git a/docs/static/less/bootstrap/forms.less b/docs/static/less/bootstrap/forms.less
deleted file mode 100644
index f607b85..0000000
--- a/docs/static/less/bootstrap/forms.less
+++ /dev/null
@@ -1,438 +0,0 @@
-//
-// Forms
-// --------------------------------------------------
-
-
-// Normalize non-controls
-//
-// Restyle and baseline non-control form elements.
-
-fieldset {
-  padding: 0;
-  margin: 0;
-  border: 0;
-  // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,
-  // so we reset that to ensure it behaves more like a standard block element.
-  // See https://github.com/twbs/bootstrap/issues/12359.
-  min-width: 0;
-}
-
-legend {
-  display: block;
-  width: 100%;
-  padding: 0;
-  margin-bottom: @line-height-computed;
-  font-size: (@font-size-base * 1.5);
-  line-height: inherit;
-  color: @legend-color;
-  border: 0;
-  border-bottom: 1px solid @legend-border-color;
-}
-
-label {
-  display: inline-block;
-  margin-bottom: 5px;
-  font-weight: bold;
-}
-
-
-// Normalize form controls
-//
-// While most of our form styles require extra classes, some basic normalization
-// is required to ensure optimum display with or without those classes to better
-// address browser inconsistencies.
-
-// Override content-box in Normalize (* isn't specific enough)
-input[type="search"] {
-  .box-sizing(border-box);
-}
-
-// Position radios and checkboxes better
-input[type="radio"],
-input[type="checkbox"] {
-  margin: 4px 0 0;
-  margin-top: 1px \9; /* IE8-9 */
-  line-height: normal;
-}
-
-// Set the height of file controls to match text inputs
-input[type="file"] {
-  display: block;
-}
-
-// Make range inputs behave like textual form controls
-input[type="range"] {
-  display: block;
-  width: 100%;
-}
-
-// Make multiple select elements height not fixed
-select[multiple],
-select[size] {
-  height: auto;
-}
-
-// Focus for file, radio, and checkbox
-input[type="file"]:focus,
-input[type="radio"]:focus,
-input[type="checkbox"]:focus {
-  .tab-focus();
-}
-
-// Adjust output element
-output {
-  display: block;
-  padding-top: (@padding-base-vertical + 1);
-  font-size: @font-size-base;
-  line-height: @line-height-base;
-  color: @input-color;
-}
-
-
-// Common form controls
-//
-// Shared size and type resets for form controls. Apply `.form-control` to any
-// of the following form controls:
-//
-// select
-// textarea
-// input[type="text"]
-// input[type="password"]
-// input[type="datetime"]
-// input[type="datetime-local"]
-// input[type="date"]
-// input[type="month"]
-// input[type="time"]
-// input[type="week"]
-// input[type="number"]
-// input[type="email"]
-// input[type="url"]
-// input[type="search"]
-// input[type="tel"]
-// input[type="color"]
-
-.form-control {
-  display: block;
-  width: 100%;
-  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
-  padding: @padding-base-vertical @padding-base-horizontal;
-  font-size: @font-size-base;
-  line-height: @line-height-base;
-  color: @input-color;
-  background-color: @input-bg;
-  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-  border: 1px solid @input-border;
-  border-radius: @input-border-radius;
-  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
-  .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");
-
-  // Customize the `:focus` state to imitate native WebKit styles.
-  .form-control-focus();
-
-  // Placeholder
-  .placeholder();
-
-  // Disabled and read-only inputs
-  //
-  // HTML5 says that controls under a fieldset > legend:first-child won't be
-  // disabled if the fieldset is disabled. Due to implementation difficulty, we
-  // don't honor that edge case; we style them as disabled anyway.
-  &[disabled],
-  &[readonly],
-  fieldset[disabled] & {
-    cursor: not-allowed;
-    background-color: @input-bg-disabled;
-    opacity: 1; // iOS fix for unreadable disabled content
-  }
-
-  // Reset height for `textarea`s
-  textarea& {
-    height: auto;
-  }
-}
-
-
-// Search inputs in iOS
-//
-// This overrides the extra rounded corners on search inputs in iOS so that our
-// `.form-control` class can properly style them. Note that this cannot simply
-// be added to `.form-control` as it's not specific enough. For details, see
-// https://github.com/twbs/bootstrap/issues/11586.
-
-input[type="search"] {
-  -webkit-appearance: none;
-}
-
-
-// Special styles for iOS date input
-//
-// In Mobile Safari, date inputs require a pixel line-height that matches the
-// given height of the input.
-
-input[type="date"] {
-  line-height: @input-height-base;
-}
-
-
-// Form groups
-//
-// Designed to help with the organization and spacing of vertical forms. For
-// horizontal forms, use the predefined grid classes.
-
-.form-group {
-  margin-bottom: 15px;
-}
-
-
-// Checkboxes and radios
-//
-// Indent the labels to position radios/checkboxes as hanging controls.
-
-.radio,
-.checkbox {
-  display: block;
-  min-height: @line-height-computed; // clear the floating input if there is no label text
-  margin-top: 10px;
-  margin-bottom: 10px;
-  padding-left: 20px;
-  label {
-    display: inline;
-    font-weight: normal;
-    cursor: pointer;
-  }
-}
-.radio input[type="radio"],
-.radio-inline input[type="radio"],
-.checkbox input[type="checkbox"],
-.checkbox-inline input[type="checkbox"] {
-  float: left;
-  margin-left: -20px;
-}
-.radio + .radio,
-.checkbox + .checkbox {
-  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
-}
-
-// Radios and checkboxes on same line
-.radio-inline,
-.checkbox-inline {
-  display: inline-block;
-  padding-left: 20px;
-  margin-bottom: 0;
-  vertical-align: middle;
-  font-weight: normal;
-  cursor: pointer;
-}
-.radio-inline + .radio-inline,
-.checkbox-inline + .checkbox-inline {
-  margin-top: 0;
-  margin-left: 10px; // space out consecutive inline controls
-}
-
-// Apply same disabled cursor tweak as for inputs
-//
-// Note: Neither radios nor checkboxes can be readonly.
-input[type="radio"],
-input[type="checkbox"],
-.radio,
-.radio-inline,
-.checkbox,
-.checkbox-inline {
-  &[disabled],
-  fieldset[disabled] & {
-    cursor: not-allowed;
-  }
-}
-
-
-// Form control sizing
-//
-// Build on `.form-control` with modifier classes to decrease or increase the
-// height and font-size of form controls.
-
-.input-sm {
-  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
-}
-
-.input-lg {
-  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
-}
-
-
-// Form control feedback states
-//
-// Apply contextual and semantic states to individual form controls.
-
-.has-feedback {
-  // Enable absolute positioning
-  position: relative;
-
-  // Ensure icons don't overlap text
-  .form-control {
-    padding-right: (@input-height-base * 1.25);
-  }
-
-  // Feedback icon (requires .glyphicon classes)
-  .form-control-feedback {
-    position: absolute;
-    top: (@line-height-computed + 5); // Height of the `label` and its margin
-    right: 0;
-    display: block;
-    width: @input-height-base;
-    height: @input-height-base;
-    line-height: @input-height-base;
-    text-align: center;
-  }
-}
-
-// Feedback states
-.has-success {
-  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
-}
-.has-warning {
-  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
-}
-.has-error {
-  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
-}
-
-
-// Static form control text
-//
-// Apply class to a `p` element to make any string of text align with labels in
-// a horizontal form layout.
-
-.form-control-static {
-  margin-bottom: 0; // Remove default margin from `p`
-}
-
-
-// Help text
-//
-// Apply to any element you wish to create light text for placement immediately
-// below a form control. Use for general help, formatting, or instructional text.
-
-.help-block {
-  display: block; // account for any element using help-block
-  margin-top: 5px;
-  margin-bottom: 10px;
-  color: lighten(@text-color, 25%); // lighten the text some for contrast
-}
-
-
-
-// Inline forms
-//
-// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
-// forms begin stacked on extra small (mobile) devices and then go inline when
-// viewports reach <768px.
-//
-// Requires wrapping inputs and labels with `.form-group` for proper display of
-// default HTML form controls and our custom form controls (e.g., input groups).
-//
-// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
-
-.form-inline {
-
-  // Kick in the inline
-  @media (min-width: @screen-sm-min) {
-    // Inline-block all the things for "inline"
-    .form-group {
-      display: inline-block;
-      margin-bottom: 0;
-      vertical-align: middle;
-    }
-
-    // In navbar-form, allow folks to *not* use `.form-group`
-    .form-control {
-      display: inline-block;
-      width: auto; // Prevent labels from stacking above inputs in `.form-group`
-      vertical-align: middle;
-    }
-    // Input groups need that 100% width though
-    .input-group > .form-control {
-      width: 100%;
-    }
-
-    .control-label {
-      margin-bottom: 0;
-      vertical-align: middle;
-    }
-
-    // Remove default margin on radios/checkboxes that were used for stacking, and
-    // then undo the floating of radios and checkboxes to match (which also avoids
-    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
-    .radio,
-    .checkbox {
-      display: inline-block;
-      margin-top: 0;
-      margin-bottom: 0;
-      padding-left: 0;
-      vertical-align: middle;
-    }
-    .radio input[type="radio"],
-    .checkbox input[type="checkbox"] {
-      float: none;
-      margin-left: 0;
-    }
-
-    // Validation states
-    //
-    // Reposition the icon because it's now within a grid column and columns have
-    // `position: relative;` on them. Also accounts for the grid gutter padding.
-    .has-feedback .form-control-feedback {
-      top: 0;
-    }
-  }
-}
-
-
-// Horizontal forms
-//
-// Horizontal forms are built on grid classes and allow you to create forms with
-// labels on the left and inputs on the right.
-
-.form-horizontal {
-
-  // Consistent vertical alignment of labels, radios, and checkboxes
-  .control-label,
-  .radio,
-  .checkbox,
-  .radio-inline,
-  .checkbox-inline {
-    margin-top: 0;
-    margin-bottom: 0;
-    padding-top: (@padding-base-vertical + 1); // Default padding plus a border
-  }
-  // Account for padding we're adding to ensure the alignment and of help text
-  // and other content below items
-  .radio,
-  .checkbox {
-    min-height: (@line-height-computed + (@padding-base-vertical + 1));
-  }
-
-  // Make form groups behave like rows
-  .form-group {
-    .make-row();
-  }
-
-  .form-control-static {
-    padding-top: (@padding-base-vertical + 1);
-  }
-
-  // Only right align form labels here when the columns stop stacking
-  @media (min-width: @screen-sm-min) {
-    .control-label {
-      text-align: right;
-    }
-  }
-
-  // Validation states
-  //
-  // Reposition the icon because it's now within a grid column and columns have
-  // `position: relative;` on them. Also accounts for the grid gutter padding.
-  .has-feedback .form-control-feedback {
-    top: 0;
-    right: (@grid-gutter-width / 2);
-  }
-}
diff --git a/docs/static/less/bootstrap/glyphicons.less b/docs/static/less/bootstrap/glyphicons.less
deleted file mode 100644
index 789c5e7..0000000
--- a/docs/static/less/bootstrap/glyphicons.less
+++ /dev/null
@@ -1,233 +0,0 @@
-//
-// Glyphicons for Bootstrap
-//
-// Since icons are fonts, they can be placed anywhere text is placed and are
-// thus automatically sized to match the surrounding child. To use, create an
-// inline element with the appropriate classes, like so:
-//
-// <a href="#"><span class="glyphicon glyphicon-star"></span> Star</a>
-
-// Import the fonts
-@font-face {
-  font-family: 'Glyphicons Halflings';
-  src: ~"url('@{icon-font-path}@{icon-font-name}.eot')";
-  src: ~"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')",
-       ~"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')",
-       ~"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')",
-       ~"url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg')";
-}
-
-// Catchall baseclass
-.glyphicon {
-  position: relative;
-  top: 1px;
-  display: inline-block;
-  font-family: 'Glyphicons Halflings';
-  font-style: normal;
-  font-weight: normal;
-  line-height: 1;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-
-// Individual icons
-.glyphicon-asterisk               { &:before { content: "\2a"; } }
-.glyphicon-plus                   { &:before { content: "\2b"; } }
-.glyphicon-euro                   { &:before { content: "\20ac"; } }
-.glyphicon-minus                  { &:before { content: "\2212"; } }
-.glyphicon-cloud                  { &:before { content: "\2601"; } }
-.glyphicon-envelope               { &:before { content: "\2709"; } }
-.glyphicon-pencil                 { &:before { content: "\270f"; } }
-.glyphicon-glass                  { &:before { content: "\e001"; } }
-.glyphicon-music                  { &:before { content: "\e002"; } }
-.glyphicon-search                 { &:before { content: "\e003"; } }
-.glyphicon-heart                  { &:before { content: "\e005"; } }
-.glyphicon-star                   { &:before { content: "\e006"; } }
-.glyphicon-star-empty             { &:before { content: "\e007"; } }
-.glyphicon-user                   { &:before { content: "\e008"; } }
-.glyphicon-film                   { &:before { content: "\e009"; } }
-.glyphicon-th-large               { &:before { content: "\e010"; } }
-.glyphicon-th                     { &:before { content: "\e011"; } }
-.glyphicon-th-list                { &:before { content: "\e012"; } }
-.glyphicon-ok                     { &:before { content: "\e013"; } }
-.glyphicon-remove                 { &:before { content: "\e014"; } }
-.glyphicon-zoom-in                { &:before { content: "\e015"; } }
-.glyphicon-zoom-out               { &:before { content: "\e016"; } }
-.glyphicon-off                    { &:before { content: "\e017"; } }
-.glyphicon-signal                 { &:before { content: "\e018"; } }
-.glyphicon-cog                    { &:before { content: "\e019"; } }
-.glyphicon-trash                  { &:before { content: "\e020"; } }
-.glyphicon-home                   { &:before { content: "\e021"; } }
-.glyphicon-file                   { &:before { content: "\e022"; } }
-.glyphicon-time                   { &:before { content: "\e023"; } }
-.glyphicon-road                   { &:before { content: "\e024"; } }
-.glyphicon-download-alt           { &:before { content: "\e025"; } }
-.glyphicon-download               { &:before { content: "\e026"; } }
-.glyphicon-upload                 { &:before { content: "\e027"; } }
-.glyphicon-inbox                  { &:before { content: "\e028"; } }
-.glyphicon-play-circle            { &:before { content: "\e029"; } }
-.glyphicon-repeat                 { &:before { content: "\e030"; } }
-.glyphicon-refresh                { &:before { content: "\e031"; } }
-.glyphicon-list-alt               { &:before { content: "\e032"; } }
-.glyphicon-lock                   { &:before { content: "\e033"; } }
-.glyphicon-flag                   { &:before { content: "\e034"; } }
-.glyphicon-headphones             { &:before { content: "\e035"; } }
-.glyphicon-volume-off             { &:before { content: "\e036"; } }
-.glyphicon-volume-down            { &:before { content: "\e037"; } }
-.glyphicon-volume-up              { &:before { content: "\e038"; } }
-.glyphicon-qrcode                 { &:before { content: "\e039"; } }
-.glyphicon-barcode                { &:before { content: "\e040"; } }
-.glyphicon-tag                    { &:before { content: "\e041"; } }
-.glyphicon-tags                   { &:before { content: "\e042"; } }
-.glyphicon-book                   { &:before { content: "\e043"; } }
-.glyphicon-bookmark               { &:before { content: "\e044"; } }
-.glyphicon-print                  { &:before { content: "\e045"; } }
-.glyphicon-camera                 { &:before { content: "\e046"; } }
-.glyphicon-font                   { &:before { content: "\e047"; } }
-.glyphicon-bold                   { &:before { content: "\e048"; } }
-.glyphicon-italic                 { &:before { content: "\e049"; } }
-.glyphicon-text-height            { &:before { content: "\e050"; } }
-.glyphicon-text-width             { &:before { content: "\e051"; } }
-.glyphicon-align-left             { &:before { content: "\e052"; } }
-.glyphicon-align-center           { &:before { content: "\e053"; } }
-.glyphicon-align-right            { &:before { content: "\e054"; } }
-.glyphicon-align-justify          { &:before { content: "\e055"; } }
-.glyphicon-list                   { &:before { content: "\e056"; } }
-.glyphicon-indent-left            { &:before { content: "\e057"; } }
-.glyphicon-indent-right           { &:before { content: "\e058"; } }
-.glyphicon-facetime-video         { &:before { content: "\e059"; } }
-.glyphicon-picture                { &:before { content: "\e060"; } }
-.glyphicon-map-marker             { &:before { content: "\e062"; } }
-.glyphicon-adjust                 { &:before { content: "\e063"; } }
-.glyphicon-tint                   { &:before { content: "\e064"; } }
-.glyphicon-edit                   { &:before { content: "\e065"; } }
-.glyphicon-share                  { &:before { content: "\e066"; } }
-.glyphicon-check                  { &:before { content: "\e067"; } }
-.glyphicon-move                   { &:before { content: "\e068"; } }
-.glyphicon-step-backward          { &:before { content: "\e069"; } }
-.glyphicon-fast-backward          { &:before { content: "\e070"; } }
-.glyphicon-backward               { &:before { content: "\e071"; } }
-.glyphicon-play                   { &:before { content: "\e072"; } }
-.glyphicon-pause                  { &:before { content: "\e073"; } }
-.glyphicon-stop                   { &:before { content: "\e074"; } }
-.glyphicon-forward                { &:before { content: "\e075"; } }
-.glyphicon-fast-forward           { &:before { content: "\e076"; } }
-.glyphicon-step-forward           { &:before { content: "\e077"; } }
-.glyphicon-eject                  { &:before { content: "\e078"; } }
-.glyphicon-chevron-left           { &:before { content: "\e079"; } }
-.glyphicon-chevron-right          { &:before { content: "\e080"; } }
-.glyphicon-plus-sign              { &:before { content: "\e081"; } }
-.glyphicon-minus-sign             { &:before { content: "\e082"; } }
-.glyphicon-remove-sign            { &:before { content: "\e083"; } }
-.glyphicon-ok-sign                { &:before { content: "\e084"; } }
-.glyphicon-question-sign          { &:before { content: "\e085"; } }
-.glyphicon-info-sign              { &:before { content: "\e086"; } }
-.glyphicon-screenshot             { &:before { content: "\e087"; } }
-.glyphicon-remove-circle          { &:before { content: "\e088"; } }
-.glyphicon-ok-circle              { &:before { content: "\e089"; } }
-.glyphicon-ban-circle             { &:before { content: "\e090"; } }
-.glyphicon-arrow-left             { &:before { content: "\e091"; } }
-.glyphicon-arrow-right            { &:before { content: "\e092"; } }
-.glyphicon-arrow-up               { &:before { content: "\e093"; } }
-.glyphicon-arrow-down             { &:before { content: "\e094"; } }
-.glyphicon-share-alt              { &:before { content: "\e095"; } }
-.glyphicon-resize-full            { &:before { content: "\e096"; } }
-.glyphicon-resize-small           { &:before { content: "\e097"; } }
-.glyphicon-exclamation-sign       { &:before { content: "\e101"; } }
-.glyphicon-gift                   { &:before { content: "\e102"; } }
-.glyphicon-leaf                   { &:before { content: "\e103"; } }
-.glyphicon-fire                   { &:before { content: "\e104"; } }
-.glyphicon-eye-open               { &:before { content: "\e105"; } }
-.glyphicon-eye-close              { &:before { content: "\e106"; } }
-.glyphicon-warning-sign           { &:before { content: "\e107"; } }
-.glyphicon-plane                  { &:before { content: "\e108"; } }
-.glyphicon-calendar               { &:before { content: "\e109"; } }
-.glyphicon-random                 { &:before { content: "\e110"; } }
-.glyphicon-comment                { &:before { content: "\e111"; } }
-.glyphicon-magnet                 { &:before { content: "\e112"; } }
-.glyphicon-chevron-up             { &:before { content: "\e113"; } }
-.glyphicon-chevron-down           { &:before { content: "\e114"; } }
-.glyphicon-retweet                { &:before { content: "\e115"; } }
-.glyphicon-shopping-cart          { &:before { content: "\e116"; } }
-.glyphicon-folder-close           { &:before { content: "\e117"; } }
-.glyphicon-folder-open            { &:before { content: "\e118"; } }
-.glyphicon-resize-vertical        { &:before { content: "\e119"; } }
-.glyphicon-resize-horizontal      { &:before { content: "\e120"; } }
-.glyphicon-hdd                    { &:before { content: "\e121"; } }
-.glyphicon-bullhorn               { &:before { content: "\e122"; } }
-.glyphicon-bell                   { &:before { content: "\e123"; } }
-.glyphicon-certificate            { &:before { content: "\e124"; } }
-.glyphicon-thumbs-up              { &:before { content: "\e125"; } }
-.glyphicon-thumbs-down            { &:before { content: "\e126"; } }
-.glyphicon-hand-right             { &:before { content: "\e127"; } }
-.glyphicon-hand-left              { &:before { content: "\e128"; } }
-.glyphicon-hand-up                { &:before { content: "\e129"; } }
-.glyphicon-hand-down              { &:before { content: "\e130"; } }
-.glyphicon-circle-arrow-right     { &:before { content: "\e131"; } }
-.glyphicon-circle-arrow-left      { &:before { content: "\e132"; } }
-.glyphicon-circle-arrow-up        { &:before { content: "\e133"; } }
-.glyphicon-circle-arrow-down      { &:before { content: "\e134"; } }
-.glyphicon-globe                  { &:before { content: "\e135"; } }
-.glyphicon-wrench                 { &:before { content: "\e136"; } }
-.glyphicon-tasks                  { &:before { content: "\e137"; } }
-.glyphicon-filter                 { &:before { content: "\e138"; } }
-.glyphicon-briefcase              { &:before { content: "\e139"; } }
-.glyphicon-fullscreen             { &:before { content: "\e140"; } }
-.glyphicon-dashboard              { &:before { content: "\e141"; } }
-.glyphicon-paperclip              { &:before { content: "\e142"; } }
-.glyphicon-heart-empty            { &:before { content: "\e143"; } }
-.glyphicon-link                   { &:before { content: "\e144"; } }
-.glyphicon-phone                  { &:before { content: "\e145"; } }
-.glyphicon-pushpin                { &:before { content: "\e146"; } }
-.glyphicon-usd                    { &:before { content: "\e148"; } }
-.glyphicon-gbp                    { &:before { content: "\e149"; } }
-.glyphicon-sort                   { &:before { content: "\e150"; } }
-.glyphicon-sort-by-alphabet       { &:before { content: "\e151"; } }
-.glyphicon-sort-by-alphabet-alt   { &:before { content: "\e152"; } }
-.glyphicon-sort-by-order          { &:before { content: "\e153"; } }
-.glyphicon-sort-by-order-alt      { &:before { content: "\e154"; } }
-.glyphicon-sort-by-attributes     { &:before { content: "\e155"; } }
-.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } }
-.glyphicon-unchecked              { &:before { content: "\e157"; } }
-.glyphicon-expand                 { &:before { content: "\e158"; } }
-.glyphicon-collapse-down          { &:before { content: "\e159"; } }
-.glyphicon-collapse-up            { &:before { content: "\e160"; } }
-.glyphicon-log-in                 { &:before { content: "\e161"; } }
-.glyphicon-flash                  { &:before { content: "\e162"; } }
-.glyphicon-log-out                { &:before { content: "\e163"; } }
-.glyphicon-new-window             { &:before { content: "\e164"; } }
-.glyphicon-record                 { &:before { content: "\e165"; } }
-.glyphicon-save                   { &:before { content: "\e166"; } }
-.glyphicon-open                   { &:before { content: "\e167"; } }
-.glyphicon-saved                  { &:before { content: "\e168"; } }
-.glyphicon-import                 { &:before { content: "\e169"; } }
-.glyphicon-export                 { &:before { content: "\e170"; } }
-.glyphicon-send                   { &:before { content: "\e171"; } }
-.glyphicon-floppy-disk            { &:before { content: "\e172"; } }
-.glyphicon-floppy-saved           { &:before { content: "\e173"; } }
-.glyphicon-floppy-remove          { &:before { content: "\e174"; } }
-.glyphicon-floppy-save            { &:before { content: "\e175"; } }
-.glyphicon-floppy-open            { &:before { content: "\e176"; } }
-.glyphicon-credit-card            { &:before { content: "\e177"; } }
-.glyphicon-transfer               { &:before { content: "\e178"; } }
-.glyphicon-cutlery                { &:before { content: "\e179"; } }
-.glyphicon-header                 { &:before { content: "\e180"; } }
-.glyphicon-compressed             { &:before { content: "\e181"; } }
-.glyphicon-earphone               { &:before { content: "\e182"; } }
-.glyphicon-phone-alt              { &:before { content: "\e183"; } }
-.glyphicon-tower                  { &:before { content: "\e184"; } }
-.glyphicon-stats                  { &:before { content: "\e185"; } }
-.glyphicon-sd-video               { &:before { content: "\e186"; } }
-.glyphicon-hd-video               { &:before { content: "\e187"; } }
-.glyphicon-subtitles              { &:before { content: "\e188"; } }
-.glyphicon-sound-stereo           { &:before { content: "\e189"; } }
-.glyphicon-sound-dolby            { &:before { content: "\e190"; } }
-.glyphicon-sound-5-1              { &:before { content: "\e191"; } }
-.glyphicon-sound-6-1              { &:before { content: "\e192"; } }
-.glyphicon-sound-7-1              { &:before { content: "\e193"; } }
-.glyphicon-copyright-mark         { &:before { content: "\e194"; } }
-.glyphicon-registration-mark      { &:before { content: "\e195"; } }
-.glyphicon-cloud-download         { &:before { content: "\e197"; } }
-.glyphicon-cloud-upload           { &:before { content: "\e198"; } }
-.glyphicon-tree-conifer           { &:before { content: "\e199"; } }
-.glyphicon-tree-deciduous         { &:before { content: "\e200"; } }
diff --git a/docs/static/less/bootstrap/grid.less b/docs/static/less/bootstrap/grid.less
deleted file mode 100644
index e100655..0000000
--- a/docs/static/less/bootstrap/grid.less
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Grid system
-// --------------------------------------------------
-
-
-// Container widths
-//
-// Set the container width, and override it for fixed navbars in media queries.
-
-.container {
-  .container-fixed();
-
-  @media (min-width: @screen-sm-min) {
-    width: @container-sm;
-  }
-  @media (min-width: @screen-md-min) {
-    width: @container-md;
-  }
-  @media (min-width: @screen-lg-min) {
-    width: @container-lg;
-  }
-}
-
-
-// Fluid container
-//
-// Utilizes the mixin meant for fixed width containers, but without any defined
-// width for fluid, full width layouts.
-
-.container-fluid {
-  .container-fixed();
-}
-
-
-// Row
-//
-// Rows contain and clear the floats of your columns.
-
-.row {
-  .make-row();
-}
-
-
-// Columns
-//
-// Common styles for small and large grid columns
-
-.make-grid-columns();
-
-
-// Extra small grid
-//
-// Columns, offsets, pushes, and pulls for extra small devices like
-// smartphones.
-
-.make-grid(xs);
-
-
-// Small grid
-//
-// Columns, offsets, pushes, and pulls for the small device range, from phones
-// to tablets.
-
-@media (min-width: @screen-sm-min) {
-  .make-grid(sm);
-}
-
-
-// Medium grid
-//
-// Columns, offsets, pushes, and pulls for the desktop device range.
-
-@media (min-width: @screen-md-min) {
-  .make-grid(md);
-}
-
-
-// Large grid
-//
-// Columns, offsets, pushes, and pulls for the large desktop device range.
-
-@media (min-width: @screen-lg-min) {
-  .make-grid(lg);
-}
diff --git a/docs/static/less/bootstrap/input-groups.less b/docs/static/less/bootstrap/input-groups.less
deleted file mode 100644
index a111474..0000000
--- a/docs/static/less/bootstrap/input-groups.less
+++ /dev/null
@@ -1,162 +0,0 @@
-//
-// Input groups
-// --------------------------------------------------
-
-// Base styles
-// -------------------------
-.input-group {
-  position: relative; // For dropdowns
-  display: table;
-  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table
-
-  // Undo padding and float of grid classes
-  &[class*="col-"] {
-    float: none;
-    padding-left: 0;
-    padding-right: 0;
-  }
-
-  .form-control {
-    // Ensure that the input is always above the *appended* addon button for
-    // proper border colors.
-    position: relative;
-    z-index: 2;
-
-    // IE9 fubars the placeholder attribute in text inputs and the arrows on
-    // select elements in input groups. To fix it, we float the input. Details:
-    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855
-    float: left;
-
-    width: 100%;
-    margin-bottom: 0;
-  }
-}
-
-// Sizing options
-//
-// Remix the default form control sizing classes into new ones for easier
-// manipulation.
-
-.input-group-lg > .form-control,
-.input-group-lg > .input-group-addon,
-.input-group-lg > .input-group-btn > .btn { .input-lg(); }
-.input-group-sm > .form-control,
-.input-group-sm > .input-group-addon,
-.input-group-sm > .input-group-btn > .btn { .input-sm(); }
-
-
-// Display as table-cell
-// -------------------------
-.input-group-addon,
-.input-group-btn,
-.input-group .form-control {
-  display: table-cell;
-
-  &:not(:first-child):not(:last-child) {
-    border-radius: 0;
-  }
-}
-// Addon and addon wrapper for buttons
-.input-group-addon,
-.input-group-btn {
-  width: 1%;
-  white-space: nowrap;
-  vertical-align: middle; // Match the inputs
-}
-
-// Text input groups
-// -------------------------
-.input-group-addon {
-  padding: @padding-base-vertical @padding-base-horizontal;
-  font-size: @font-size-base;
-  font-weight: normal;
-  line-height: 1;
-  color: @input-color;
-  text-align: center;
-  background-color: @input-group-addon-bg;
-  border: 1px solid @input-group-addon-border-color;
-  border-radius: @border-radius-base;
-
-  // Sizing
-  &.input-sm {
-    padding: @padding-small-vertical @padding-small-horizontal;
-    font-size: @font-size-small;
-    border-radius: @border-radius-small;
-  }
-  &.input-lg {
-    padding: @padding-large-vertical @padding-large-horizontal;
-    font-size: @font-size-large;
-    border-radius: @border-radius-large;
-  }
-
-  // Nuke default margins from checkboxes and radios to vertically center within.
-  input[type="radio"],
-  input[type="checkbox"] {
-    margin-top: 0;
-  }
-}
-
-// Reset rounded corners
-.input-group .form-control:first-child,
-.input-group-addon:first-child,
-.input-group-btn:first-child > .btn,
-.input-group-btn:first-child > .btn-group > .btn,
-.input-group-btn:first-child > .dropdown-toggle,
-.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
-.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
-  .border-right-radius(0);
-}
-.input-group-addon:first-child {
-  border-right: 0;
-}
-.input-group .form-control:last-child,
-.input-group-addon:last-child,
-.input-group-btn:last-child > .btn,
-.input-group-btn:last-child > .btn-group > .btn,
-.input-group-btn:last-child > .dropdown-toggle,
-.input-group-btn:first-child > .btn:not(:first-child),
-.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
-  .border-left-radius(0);
-}
-.input-group-addon:last-child {
-  border-left: 0;
-}
-
-// Button input groups
-// -------------------------
-.input-group-btn {
-  position: relative;
-  // Jankily prevent input button groups from wrapping with `white-space` and
-  // `font-size` in combination with `inline-block` on buttons.
-  font-size: 0;
-  white-space: nowrap;
-
-  // Negative margin for spacing, position for bringing hovered/focused/actived
-  // element above the siblings.
-  > .btn {
-    position: relative;
-    + .btn {
-      margin-left: -1px;
-    }
-    // Bring the "active" button to the front
-    &:hover,
-    &:focus,
-    &:active {
-      z-index: 2;
-    }
-  }
-
-  // Negative margin to only have a 1px border between the two
-  &:first-child {
-    > .btn,
-    > .btn-group {
-      margin-right: -1px;
-    }
-  }
-  &:last-child {
-    > .btn,
-    > .btn-group {
-      margin-left: -1px;
-    }
-  }
-}
diff --git a/docs/static/less/bootstrap/jumbotron.less b/docs/static/less/bootstrap/jumbotron.less
deleted file mode 100644
index a15e169..0000000
--- a/docs/static/less/bootstrap/jumbotron.less
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Jumbotron
-// --------------------------------------------------
-
-
-.jumbotron {
-  padding: @jumbotron-padding;
-  margin-bottom: @jumbotron-padding;
-  color: @jumbotron-color;
-  background-color: @jumbotron-bg;
-
-  h1,
-  .h1 {
-    color: @jumbotron-heading-color;
-  }
-  p {
-    margin-bottom: (@jumbotron-padding / 2);
-    font-size: @jumbotron-font-size;
-    font-weight: 200;
-  }
-
-  .container & {
-    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container
-  }
-
-  .container {
-    max-width: 100%;
-  }
-
-  @media screen and (min-width: @screen-sm-min) {
-    padding-top:    (@jumbotron-padding * 1.6);
-    padding-bottom: (@jumbotron-padding * 1.6);
-
-    .container & {
-      padding-left:  (@jumbotron-padding * 2);
-      padding-right: (@jumbotron-padding * 2);
-    }
-
-    h1,
-    .h1 {
-      font-size: (@font-size-base * 4.5);
-    }
-  }
-}
diff --git a/docs/static/less/bootstrap/labels.less b/docs/static/less/bootstrap/labels.less
deleted file mode 100644
index 5db1ed1..0000000
--- a/docs/static/less/bootstrap/labels.less
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Labels
-// --------------------------------------------------
-
-.label {
-  display: inline;
-  padding: .2em .6em .3em;
-  font-size: 75%;
-  font-weight: bold;
-  line-height: 1;
-  color: @label-color;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: baseline;
-  border-radius: .25em;
-
-  // Add hover effects, but only for links
-  &[href] {
-    &:hover,
-    &:focus {
-      color: @label-link-hover-color;
-      text-decoration: none;
-      cursor: pointer;
-    }
-  }
-
-  // Empty labels collapse automatically (not available in IE8)
-  &:empty {
-    display: none;
-  }
-
-  // Quick fix for labels in buttons
-  .btn & {
-    position: relative;
-    top: -1px;
-  }
-}
-
-// Colors
-// Contextual variations (linked labels get darker on :hover)
-
-.label-default {
-  .label-variant(@label-default-bg);
-}
-
-.label-primary {
-  .label-variant(@label-primary-bg);
-}
-
-.label-success {
-  .label-variant(@label-success-bg);
-}
-
-.label-info {
-  .label-variant(@label-info-bg);
-}
-
-.label-warning {
-  .label-variant(@label-warning-bg);
-}
-
-.label-danger {
-  .label-variant(@label-danger-bg);
-}
diff --git a/docs/static/less/bootstrap/list-group.less b/docs/static/less/bootstrap/list-group.less
deleted file mode 100644
index 3343f8e..0000000
--- a/docs/static/less/bootstrap/list-group.less
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// List groups
-// --------------------------------------------------
-
-
-// Base class
-//
-// Easily usable on <ul>, <ol>, or <div>.
-
-.list-group {
-  // No need to set list-style: none; since .list-group-item is block level
-  margin-bottom: 20px;
-  padding-left: 0; // reset padding because ul and ol
-}
-
-
-// Individual list items
-//
-// Use on `li`s or `div`s within the `.list-group` parent.
-
-.list-group-item {
-  position: relative;
-  display: block;
-  padding: 10px 15px;
-  // Place the border on the list items and negative margin up for better styling
-  margin-bottom: -1px;
-  background-color: @list-group-bg;
-  border: 1px solid @list-group-border;
-
-  // Round the first and last items
-  &:first-child {
-    .border-top-radius(@list-group-border-radius);
-  }
-  &:last-child {
-    margin-bottom: 0;
-    .border-bottom-radius(@list-group-border-radius);
-  }
-
-  // Align badges within list items
-  > .badge {
-    float: right;
-  }
-  > .badge + .badge {
-    margin-right: 5px;
-  }
-}
-
-
-// Linked list items
-//
-// Use anchor elements instead of `li`s or `div`s to create linked list items.
-// Includes an extra `.active` modifier class for showing selected items.
-
-a.list-group-item {
-  color: @list-group-link-color;
-
-  .list-group-item-heading {
-    color: @list-group-link-heading-color;
-  }
-
-  // Hover state
-  &:hover,
-  &:focus {
-    text-decoration: none;
-    background-color: @list-group-hover-bg;
-  }
-
-  // Active class on item itself, not parent
-  &.active,
-  &.active:hover,
-  &.active:focus {
-    z-index: 2; // Place active items above their siblings for proper border styling
-    color: @list-group-active-color;
-    background-color: @list-group-active-bg;
-    border-color: @list-group-active-border;
-
-    // Force color to inherit for custom content
-    .list-group-item-heading {
-      color: inherit;
-    }
-    .list-group-item-text {
-      color: @list-group-active-text-color;
-    }
-  }
-}
-
-
-// Contextual variants
-//
-// Add modifier classes to change text and background color on individual items.
-// Organizationally, this must come after the `:hover` states.
-
-.list-group-item-variant(success; @state-success-bg; @state-success-text);
-.list-group-item-variant(info; @state-info-bg; @state-info-text);
-.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);
-.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);
-
-
-// Custom content options
-//
-// Extra classes for creating well-formatted content within `.list-group-item`s.
-
-.list-group-item-heading {
-  margin-top: 0;
-  margin-bottom: 5px;
-}
-.list-group-item-text {
-  margin-bottom: 0;
-  line-height: 1.3;
-}
diff --git a/docs/static/less/bootstrap/media.less b/docs/static/less/bootstrap/media.less
deleted file mode 100644
index 5ad22cd..0000000
--- a/docs/static/less/bootstrap/media.less
+++ /dev/null
@@ -1,56 +0,0 @@
-// Media objects
-// Source: http://stubbornella.org/content/?p=497
-// --------------------------------------------------
-
-
-// Common styles
-// -------------------------
-
-// Clear the floats
-.media,
-.media-body {
-  overflow: hidden;
-  zoom: 1;
-}
-
-// Proper spacing between instances of .media
-.media,
-.media .media {
-  margin-top: 15px;
-}
-.media:first-child {
-  margin-top: 0;
-}
-
-// For images and videos, set to block
-.media-object {
-  display: block;
-}
-
-// Reset margins on headings for tighter default spacing
-.media-heading {
-  margin: 0 0 5px;
-}
-
-
-// Media image alignment
-// -------------------------
-
-.media {
-  > .pull-left {
-    margin-right: 10px;
-  }
-  > .pull-right {
-    margin-left: 10px;
-  }
-}
-
-
-// Media list variation
-// -------------------------
-
-// Undo default ul/ol styles
-.media-list {
-  padding-left: 0;
-  list-style: none;
-}
diff --git a/docs/static/less/bootstrap/mixins.less b/docs/static/less/bootstrap/mixins.less
deleted file mode 100644
index 71723db..0000000
--- a/docs/static/less/bootstrap/mixins.less
+++ /dev/null
@@ -1,929 +0,0 @@
-//
-// Mixins
-// --------------------------------------------------
-
-
-// Utilities
-// -------------------------
-
-// Clearfix
-// Source: http://nicolasgallagher.com/micro-clearfix-hack/
-//
-// For modern browsers
-// 1. The space content is one way to avoid an Opera bug when the
-//    contenteditable attribute is included anywhere else in the document.
-//    Otherwise it causes space to appear at the top and bottom of elements
-//    that are clearfixed.
-// 2. The use of `table` rather than `block` is only necessary if using
-//    `:before` to contain the top-margins of child elements.
-.clearfix() {
-  &:before,
-  &:after {
-    content: " "; // 1
-    display: table; // 2
-  }
-  &:after {
-    clear: both;
-  }
-}
-
-// WebKit-style focus
-.tab-focus() {
-  // Default
-  outline: thin dotted;
-  // WebKit
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-
-// Center-align a block level element
-.center-block() {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-// Sizing shortcuts
-.size(@width; @height) {
-  width: @width;
-  height: @height;
-}
-.square(@size) {
-  .size(@size; @size);
-}
-
-// Placeholder text
-.placeholder(@color: @input-color-placeholder) {
-  &::-moz-placeholder           { color: @color;   // Firefox
-                                  opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526
-  &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+
-  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome
-}
-
-// Text overflow
-// Requires inline-block or block for proper styling
-.text-overflow() {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-// CSS image replacement
-//
-// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for
-// mixins being reused as classes with the same name, this doesn't hold up. As
-// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note
-// that we cannot chain the mixins together in Less, so they are repeated.
-//
-// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
-
-// Deprecated as of v3.0.1 (will be removed in v4)
-.hide-text() {
-  font: ~"0/0" a;
-  color: transparent;
-  text-shadow: none;
-  background-color: transparent;
-  border: 0;
-}
-// New mixin to use as of v3.0.1
-.text-hide() {
-  .hide-text();
-}
-
-
-
-// CSS3 PROPERTIES
-// --------------------------------------------------
-
-// Single side border-radius
-.border-top-radius(@radius) {
-  border-top-right-radius: @radius;
-   border-top-left-radius: @radius;
-}
-.border-right-radius(@radius) {
-  border-bottom-right-radius: @radius;
-     border-top-right-radius: @radius;
-}
-.border-bottom-radius(@radius) {
-  border-bottom-right-radius: @radius;
-   border-bottom-left-radius: @radius;
-}
-.border-left-radius(@radius) {
-  border-bottom-left-radius: @radius;
-     border-top-left-radius: @radius;
-}
-
-// Drop shadows
-//
-// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
-//   supported browsers that have box shadow capabilities now support the
-//   standard `box-shadow` property.
-.box-shadow(@shadow) {
-  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
-          box-shadow: @shadow;
-}
-
-// Transitions
-.transition(@transition) {
-  -webkit-transition: @transition;
-          transition: @transition;
-}
-.transition-property(@transition-property) {
-  -webkit-transition-property: @transition-property;
-          transition-property: @transition-property;
-}
-.transition-delay(@transition-delay) {
-  -webkit-transition-delay: @transition-delay;
-          transition-delay: @transition-delay;
-}
-.transition-duration(@transition-duration) {
-  -webkit-transition-duration: @transition-duration;
-          transition-duration: @transition-duration;
-}
-.transition-transform(@transition) {
-  -webkit-transition: -webkit-transform @transition;
-     -moz-transition: -moz-transform @transition;
-       -o-transition: -o-transform @transition;
-          transition: transform @transition;
-}
-
-// Transformations
-.rotate(@degrees) {
-  -webkit-transform: rotate(@degrees);
-      -ms-transform: rotate(@degrees); // IE9 only
-          transform: rotate(@degrees);
-}
-.scale(@ratio; @ratio-y...) {
-  -webkit-transform: scale(@ratio, @ratio-y);
-      -ms-transform: scale(@ratio, @ratio-y); // IE9 only
-          transform: scale(@ratio, @ratio-y);
-}
-.translate(@x; @y) {
-  -webkit-transform: translate(@x, @y);
-      -ms-transform: translate(@x, @y); // IE9 only
-          transform: translate(@x, @y);
-}
-.skew(@x; @y) {
-  -webkit-transform: skew(@x, @y);
-      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-          transform: skew(@x, @y);
-}
-.translate3d(@x; @y; @z) {
-  -webkit-transform: translate3d(@x, @y, @z);
-          transform: translate3d(@x, @y, @z);
-}
-
-.rotateX(@degrees) {
-  -webkit-transform: rotateX(@degrees);
-      -ms-transform: rotateX(@degrees); // IE9 only
-          transform: rotateX(@degrees);
-}
-.rotateY(@degrees) {
-  -webkit-transform: rotateY(@degrees);
-      -ms-transform: rotateY(@degrees); // IE9 only
-          transform: rotateY(@degrees);
-}
-.perspective(@perspective) {
-  -webkit-perspective: @perspective;
-     -moz-perspective: @perspective;
-          perspective: @perspective;
-}
-.perspective-origin(@perspective) {
-  -webkit-perspective-origin: @perspective;
-     -moz-perspective-origin: @perspective;
-          perspective-origin: @perspective;
-}
-.transform-origin(@origin) {
-  -webkit-transform-origin: @origin;
-     -moz-transform-origin: @origin;
-      -ms-transform-origin: @origin; // IE9 only
-          transform-origin: @origin;
-}
-
-// Animations
-.animation(@animation) {
-  -webkit-animation: @animation;
-          animation: @animation;
-}
-.animation-name(@name) {
-  -webkit-animation-name: @name;
-          animation-name: @name;
-}
-.animation-duration(@duration) {
-  -webkit-animation-duration: @duration;
-          animation-duration: @duration;
-}
-.animation-timing-function(@timing-function) {
-  -webkit-animation-timing-function: @timing-function;
-          animation-timing-function: @timing-function;
-}
-.animation-delay(@delay) {
-  -webkit-animation-delay: @delay;
-          animation-delay: @delay;
-}
-.animation-iteration-count(@iteration-count) {
-  -webkit-animation-iteration-count: @iteration-count;
-          animation-iteration-count: @iteration-count;
-}
-.animation-direction(@direction) {
-  -webkit-animation-direction: @direction;
-          animation-direction: @direction;
-}
-
-// Backface visibility
-// Prevent browsers from flickering when using CSS 3D transforms.
-// Default value is `visible`, but can be changed to `hidden`
-.backface-visibility(@visibility){
-  -webkit-backface-visibility: @visibility;
-     -moz-backface-visibility: @visibility;
-          backface-visibility: @visibility;
-}
-
-// Box sizing
-.box-sizing(@boxmodel) {
-  -webkit-box-sizing: @boxmodel;
-     -moz-box-sizing: @boxmodel;
-          box-sizing: @boxmodel;
-}
-
-// User select
-// For selecting text on the page
-.user-select(@select) {
-  -webkit-user-select: @select;
-     -moz-user-select: @select;
-      -ms-user-select: @select; // IE10+
-          user-select: @select;
-}
-
-// Resize anything
-.resizable(@direction) {
-  resize: @direction; // Options: horizontal, vertical, both
-  overflow: auto; // Safari fix
-}
-
-// CSS3 Content Columns
-.content-columns(@column-count; @column-gap: @grid-gutter-width) {
-  -webkit-column-count: @column-count;
-     -moz-column-count: @column-count;
-          column-count: @column-count;
-  -webkit-column-gap: @column-gap;
-     -moz-column-gap: @column-gap;
-          column-gap: @column-gap;
-}
-
-// Optional hyphenation
-.hyphens(@mode: auto) {
-  word-wrap: break-word;
-  -webkit-hyphens: @mode;
-     -moz-hyphens: @mode;
-      -ms-hyphens: @mode; // IE10+
-       -o-hyphens: @mode;
-          hyphens: @mode;
-}
-
-// Opacity
-.opacity(@opacity) {
-  opacity: @opacity;
-  // IE8 filter
-  @opacity-ie: (@opacity * 100);
-  filter: ~"alpha(opacity=@{opacity-ie})";
-}
-
-
-
-// GRADIENTS
-// --------------------------------------------------
-
-#gradient {
-
-  // Horizontal gradient, from left to right
-  //
-  // Creates two color stops, start and end, by specifying a color and position for each color stop.
-  // Color stops are not available in IE9 and below.
-  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
-    background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+
-    background-image:  linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-    background-repeat: repeat-x;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
-  }
-
-  // Vertical gradient, from top to bottom
-  //
-  // Creates two color stops, start and end, by specifying a color and position for each color stop.
-  // Color stops are not available in IE9 and below.
-  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
-    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+
-    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-    background-repeat: repeat-x;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down
-  }
-
-  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
-    background-repeat: repeat-x;
-    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
-    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-  }
-  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
-    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
-    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
-    background-repeat: no-repeat;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
-  }
-  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
-    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
-    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
-    background-repeat: no-repeat;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
-  }
-  .radial(@inner-color: #555; @outer-color: #333) {
-    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
-    background-image: radial-gradient(circle, @inner-color, @outer-color);
-    background-repeat: no-repeat;
-  }
-  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
-    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
-    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
-  }
-}
-
-// Reset filters for IE
-//
-// When you need to remove a gradient background, do not forget to use this to reset
-// the IE filter for IE9 and below.
-.reset-filter() {
-  filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
-}
-
-
-
-// Retina images
-//
-// Short retina mixin for setting background-image and -size
-
-.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
-  background-image: url("@{file-1x}");
-
-  @media
-  only screen and (-webkit-min-device-pixel-ratio: 2),
-  only screen and (   min--moz-device-pixel-ratio: 2),
-  only screen and (     -o-min-device-pixel-ratio: 2/1),
-  only screen and (        min-device-pixel-ratio: 2),
-  only screen and (                min-resolution: 192dpi),
-  only screen and (                min-resolution: 2dppx) {
-    background-image: url("@{file-2x}");
-    background-size: @width-1x @height-1x;
-  }
-}
-
-
-// Responsive image
-//
-// Keep images from scaling beyond the width of their parents.
-
-.img-responsive(@display: block) {
-  display: @display;
-  max-width: 100%; // Part 1: Set a maximum relative to the parent
-  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
-}
-
-
-// COMPONENT MIXINS
-// --------------------------------------------------
-
-// Horizontal dividers
-// -------------------------
-// Dividers (basically an hr) within dropdowns and nav lists
-.nav-divider(@color: #e5e5e5) {
-  height: 1px;
-  margin: ((@line-height-computed / 2) - 1) 0;
-  overflow: hidden;
-  background-color: @color;
-}
-
-// Panels
-// -------------------------
-.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
-  border-color: @border;
-
-  & > .panel-heading {
-    color: @heading-text-color;
-    background-color: @heading-bg-color;
-    border-color: @heading-border;
-
-    + .panel-collapse .panel-body {
-      border-top-color: @border;
-    }
-  }
-  & > .panel-footer {
-    + .panel-collapse .panel-body {
-      border-bottom-color: @border;
-    }
-  }
-}
-
-// Alerts
-// -------------------------
-.alert-variant(@background; @border; @text-color) {
-  background-color: @background;
-  border-color: @border;
-  color: @text-color;
-
-  hr {
-    border-top-color: darken(@border, 5%);
-  }
-  .alert-link {
-    color: darken(@text-color, 10%);
-  }
-}
-
-// Tables
-// -------------------------
-.table-row-variant(@state; @background) {
-  // Exact selectors below required to override `.table-striped` and prevent
-  // inheritance to nested tables.
-  .table > thead > tr,
-  .table > tbody > tr,
-  .table > tfoot > tr {
-    > td.@{state},
-    > th.@{state},
-    &.@{state} > td,
-    &.@{state} > th {
-      background-color: @background;
-    }
-  }
-
-  // Hover states for `.table-hover`
-  // Note: this is not available for cells or rows within `thead` or `tfoot`.
-  .table-hover > tbody > tr {
-    > td.@{state}:hover,
-    > th.@{state}:hover,
-    &.@{state}:hover > td,
-    &.@{state}:hover > th {
-      background-color: darken(@background, 5%);
-    }
-  }
-}
-
-// List Groups
-// -------------------------
-.list-group-item-variant(@state; @background; @color) {
-  .list-group-item-@{state} {
-    color: @color;
-    background-color: @background;
-
-    a& {
-      color: @color;
-
-      .list-group-item-heading { color: inherit; }
-
-      &:hover,
-      &:focus {
-        color: @color;
-        background-color: darken(@background, 5%);
-      }
-      &.active,
-      &.active:hover,
-      &.active:focus {
-        color: #fff;
-        background-color: @color;
-        border-color: @color;
-      }
-    }
-  }
-}
-
-// Button variants
-// -------------------------
-// Easily pump out default styles, as well as :hover, :focus, :active,
-// and disabled options for all buttons
-.button-variant(@color; @background; @border) {
-  color: @color;
-  background-color: @background;
-  border-color: @border;
-
-  &:hover,
-  &:focus,
-  &:active,
-  &.active,
-  .open .dropdown-toggle& {
-    color: @color;
-    background-color: darken(@background, 8%);
-        border-color: darken(@border, 12%);
-  }
-  &:active,
-  &.active,
-  .open .dropdown-toggle& {
-    background-image: none;
-  }
-  &.disabled,
-  &[disabled],
-  fieldset[disabled] & {
-    &,
-    &:hover,
-    &:focus,
-    &:active,
-    &.active {
-      background-color: @background;
-          border-color: @border;
-    }
-  }
-
-  .badge {
-    color: @background;
-    background-color: @color;
-  }
-}
-
-// Button sizes
-// -------------------------
-.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
-  padding: @padding-vertical @padding-horizontal;
-  font-size: @font-size;
-  line-height: @line-height;
-  border-radius: @border-radius;
-}
-
-// Pagination
-// -------------------------
-.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {
-  > li {
-    > a,
-    > span {
-      padding: @padding-vertical @padding-horizontal;
-      font-size: @font-size;
-    }
-    &:first-child {
-      > a,
-      > span {
-        .border-left-radius(@border-radius);
-      }
-    }
-    &:last-child {
-      > a,
-      > span {
-        .border-right-radius(@border-radius);
-      }
-    }
-  }
-}
-
-// Labels
-// -------------------------
-.label-variant(@color) {
-  background-color: @color;
-  &[href] {
-    &:hover,
-    &:focus {
-      background-color: darken(@color, 10%);
-    }
-  }
-}
-
-// Contextual backgrounds
-// -------------------------
-.bg-variant(@color) {
-  background-color: @color;
-  a&:hover {
-    background-color: darken(@color, 10%);
-  }
-}
-
-// Typography
-// -------------------------
-.text-emphasis-variant(@color) {
-  color: @color;
-  a&:hover {
-    color: darken(@color, 10%);
-  }
-}
-
-// Navbar vertical align
-// -------------------------
-// Vertically center elements in the navbar.
-// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
-.navbar-vertical-align(@element-height) {
-  margin-top: ((@navbar-height - @element-height) / 2);
-  margin-bottom: ((@navbar-height - @element-height) / 2);
-}
-
-// Progress bars
-// -------------------------
-.progress-bar-variant(@color) {
-  background-color: @color;
-  .progress-striped & {
-    #gradient > .striped();
-  }
-}
-
-// Responsive utilities
-// -------------------------
-// More easily include all the states for responsive-utilities.less.
-.responsive-visibility() {
-  display: block !important;
-  table&  { display: table; }
-  tr&     { display: table-row !important; }
-  th&,
-  td&     { display: table-cell !important; }
-}
-
-.responsive-invisibility() {
-  display: none !important;
-}
-
-
-// Grid System
-// -----------
-
-// Centered container element
-.container-fixed() {
-  margin-right: auto;
-  margin-left: auto;
-  padding-left:  (@grid-gutter-width / 2);
-  padding-right: (@grid-gutter-width / 2);
-  &:extend(.clearfix all);
-}
-
-// Creates a wrapper for a series of columns
-.make-row(@gutter: @grid-gutter-width) {
-  margin-left:  (@gutter / -2);
-  margin-right: (@gutter / -2);
-  &:extend(.clearfix all);
-}
-
-// Generate the extra small columns
-.make-xs-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  float: left;
-  width: percentage((@columns / @grid-columns));
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-}
-.make-xs-column-offset(@columns) {
-  @media (min-width: @screen-xs-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-xs-column-push(@columns) {
-  @media (min-width: @screen-xs-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-xs-column-pull(@columns) {
-  @media (min-width: @screen-xs-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-
-// Generate the small columns
-.make-sm-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-sm-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-offset(@columns) {
-  @media (min-width: @screen-sm-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-push(@columns) {
-  @media (min-width: @screen-sm-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-pull(@columns) {
-  @media (min-width: @screen-sm-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-
-// Generate the medium columns
-.make-md-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-md-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-offset(@columns) {
-  @media (min-width: @screen-md-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-push(@columns) {
-  @media (min-width: @screen-md-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-pull(@columns) {
-  @media (min-width: @screen-md-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-
-// Generate the large columns
-.make-lg-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-lg-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-offset(@columns) {
-  @media (min-width: @screen-lg-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-push(@columns) {
-  @media (min-width: @screen-lg-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-pull(@columns) {
-  @media (min-width: @screen-lg-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-
-// Framework grid generation
-//
-// Used only by Bootstrap to generate the correct number of grid classes given
-// any value of `@grid-columns`.
-
-.make-grid-columns() {
-  // Common styles for all sizes of grid columns, widths 1-12
-  .col(@index) when (@index = 1) { // initial
-    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
-    .col((@index + 1), @item);
-  }
-  .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
-    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
-    .col((@index + 1), ~"@{list}, @{item}");
-  }
-  .col(@index, @list) when (@index > @grid-columns) { // terminal
-    @{list} {
-      position: relative;
-      // Prevent columns from collapsing when empty
-      min-height: 1px;
-      // Inner gutter via padding
-      padding-left:  (@grid-gutter-width / 2);
-      padding-right: (@grid-gutter-width / 2);
-    }
-  }
-  .col(1); // kickstart it
-}
-
-.float-grid-columns(@class) {
-  .col(@index) when (@index = 1) { // initial
-    @item: ~".col-@{class}-@{index}";
-    .col((@index + 1), @item);
-  }
-  .col(@index, @list) when (@index =< @grid-columns) { // general
-    @item: ~".col-@{class}-@{index}";
-    .col((@index + 1), ~"@{list}, @{item}");
-  }
-  .col(@index, @list) when (@index > @grid-columns) { // terminal
-    @{list} {
-      float: left;
-    }
-  }
-  .col(1); // kickstart it
-}
-
-.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
-  .col-@{class}-@{index} {
-    width: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = push) {
-  .col-@{class}-push-@{index} {
-    left: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = pull) {
-  .col-@{class}-pull-@{index} {
-    right: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = offset) {
-  .col-@{class}-offset-@{index} {
-    margin-left: percentage((@index / @grid-columns));
-  }
-}
-
-// Basic looping in LESS
-.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
-  .calc-grid-column(@index, @class, @type);
-  // next iteration
-  .loop-grid-columns((@index - 1), @class, @type);
-}
-
-// Create grid for specific class
-.make-grid(@class) {
-  .float-grid-columns(@class);
-  .loop-grid-columns(@grid-columns, @class, width);
-  .loop-grid-columns(@grid-columns, @class, pull);
-  .loop-grid-columns(@grid-columns, @class, push);
-  .loop-grid-columns(@grid-columns, @class, offset);
-}
-
-// Form validation states
-//
-// Used in forms.less to generate the form validation CSS for warnings, errors,
-// and successes.
-
-.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
-  // Color the label and help text
-  .help-block,
-  .control-label,
-  .radio,
-  .checkbox,
-  .radio-inline,
-  .checkbox-inline  {
-    color: @text-color;
-  }
-  // Set the border and box shadow on specific inputs to match
-  .form-control {
-    border-color: @border-color;
-    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
-    &:focus {
-      border-color: darken(@border-color, 10%);
-      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);
-      .box-shadow(@shadow);
-    }
-  }
-  // Set validation states also for addons
-  .input-group-addon {
-    color: @text-color;
-    border-color: @border-color;
-    background-color: @background-color;
-  }
-  // Optional feedback icon
-  .form-control-feedback {
-    color: @text-color;
-  }
-}
-
-// Form control focus state
-//
-// Generate a customized focus state and for any input with the specified color,
-// which defaults to the `@input-focus-border` variable.
-//
-// We highly encourage you to not customize the default value, but instead use
-// this to tweak colors on an as-needed basis. This aesthetic change is based on
-// WebKit's default styles, but applicable to a wider range of browsers. Its
-// usability and accessibility should be taken into account with any change.
-//
-// Example usage: change the default blue border and shadow to white for better
-// contrast against a dark gray background.
-
-.form-control-focus(@color: @input-border-focus) {
-  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
-  &:focus {
-    border-color: @color;
-    outline: 0;
-    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
-  }
-}
-
-// Form control sizing
-//
-// Relative text size, padding, and border-radii changes for form controls. For
-// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
-// element gets special love because it's special, and that's a fact!
-
-.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
-  height: @input-height;
-  padding: @padding-vertical @padding-horizontal;
-  font-size: @font-size;
-  line-height: @line-height;
-  border-radius: @border-radius;
-
-  select& {
-    height: @input-height;
-    line-height: @input-height;
-  }
-
-  textarea&,
-  select[multiple]& {
-    height: auto;
-  }
-}
diff --git a/docs/static/less/bootstrap/modals.less b/docs/static/less/bootstrap/modals.less
deleted file mode 100644
index 21cdee0..0000000
--- a/docs/static/less/bootstrap/modals.less
+++ /dev/null
@@ -1,139 +0,0 @@
-//
-// Modals
-// --------------------------------------------------
-
-// .modal-open      - body class for killing the scroll
-// .modal           - container to scroll within
-// .modal-dialog    - positioning shell for the actual modal
-// .modal-content   - actual modal w/ bg and corners and shit
-
-// Kill the scroll on the body
-.modal-open {
-  overflow: hidden;
-}
-
-// Container that the modal scrolls within
-.modal {
-  display: none;
-  overflow: auto;
-  overflow-y: scroll;
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: @zindex-modal;
-  -webkit-overflow-scrolling: touch;
-
-  // Prevent Chrome on Windows from adding a focus outline. For details, see
-  // https://github.com/twbs/bootstrap/pull/10951.
-  outline: 0;
-
-  // When fading in the modal, animate it to slide down
-  &.fade .modal-dialog {
-    .translate(0, -25%);
-    .transition-transform(~"0.3s ease-out");
-  }
-  &.in .modal-dialog { .translate(0, 0)}
-}
-
-// Shell div to position the modal with bottom padding
-.modal-dialog {
-  position: relative;
-  width: auto;
-  margin: 10px;
-}
-
-// Actual modal
-.modal-content {
-  position: relative;
-  background-color: @modal-content-bg;
-  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
-  border: 1px solid @modal-content-border-color;
-  border-radius: @border-radius-large;
-  .box-shadow(0 3px 9px rgba(0,0,0,.5));
-  background-clip: padding-box;
-  // Remove focus outline from opened modal
-  outline: none;
-}
-
-// Modal background
-.modal-backdrop {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: @zindex-modal-background;
-  background-color: @modal-backdrop-bg;
-  // Fade for backdrop
-  &.fade { .opacity(0); }
-  &.in { .opacity(@modal-backdrop-opacity); }
-}
-
-// Modal header
-// Top section of the modal w/ title and dismiss
-.modal-header {
-  padding: @modal-title-padding;
-  border-bottom: 1px solid @modal-header-border-color;
-  min-height: (@modal-title-padding + @modal-title-line-height);
-}
-// Close icon
-.modal-header .close {
-  margin-top: -2px;
-}
-
-// Title text within header
-.modal-title {
-  margin: 0;
-  line-height: @modal-title-line-height;
-}
-
-// Modal body
-// Where all modal content resides (sibling of .modal-header and .modal-footer)
-.modal-body {
-  position: relative;
-  padding: @modal-inner-padding;
-}
-
-// Footer (for actions)
-.modal-footer {
-  margin-top: 15px;
-  padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;
-  text-align: right; // right align buttons
-  border-top: 1px solid @modal-footer-border-color;
-  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons
-
-  // Properly space out buttons
-  .btn + .btn {
-    margin-left: 5px;
-    margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
-  }
-  // but override that for button groups
-  .btn-group .btn + .btn {
-    margin-left: -1px;
-  }
-  // and override it for block buttons as well
-  .btn-block + .btn-block {
-    margin-left: 0;
-  }
-}
-
-// Scale up the modal
-@media (min-width: @screen-sm-min) {
-  // Automatically set modal's width for larger viewports
-  .modal-dialog {
-    width: @modal-md;
-    margin: 30px auto;
-  }
-  .modal-content {
-    .box-shadow(0 5px 15px rgba(0,0,0,.5));
-  }
-
-  // Modal sizes
-  .modal-sm { width: @modal-sm; }
-}
-
-@media (min-width: @screen-md-min) {
-  .modal-lg { width: @modal-lg; }
-}
diff --git a/docs/static/less/bootstrap/navbar.less b/docs/static/less/bootstrap/navbar.less
deleted file mode 100644
index 8c4c210..0000000
--- a/docs/static/less/bootstrap/navbar.less
+++ /dev/null
@@ -1,616 +0,0 @@
-//
-// Navbars
-// --------------------------------------------------
-
-
-// Wrapper and base class
-//
-// Provide a static navbar from which we expand to create full-width, fixed, and
-// other navbar variations.
-
-.navbar {
-  position: relative;
-  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)
-  margin-bottom: @navbar-margin-bottom;
-  border: 1px solid transparent;
-
-  // Prevent floats from breaking the navbar
-  &:extend(.clearfix all);
-
-  @media (min-width: @grid-float-breakpoint) {
-    border-radius: @navbar-border-radius;
-  }
-}
-
-
-// Navbar heading
-//
-// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy
-// styling of responsive aspects.
-
-.navbar-header {
-  &:extend(.clearfix all);
-
-  @media (min-width: @grid-float-breakpoint) {
-    float: left;
-  }
-}
-
-
-// Navbar collapse (body)
-//
-// Group your navbar content into this for easy collapsing and expanding across
-// various device sizes. By default, this content is collapsed when <768px, but
-// will expand past that for a horizontal display.
-//
-// To start (on mobile devices) the navbar links, forms, and buttons are stacked
-// vertically and include a `max-height` to overflow in case you have too much
-// content for the user's viewport.
-
-.navbar-collapse {
-  max-height: @navbar-collapse-max-height;
-  overflow-x: visible;
-  padding-right: @navbar-padding-horizontal;
-  padding-left:  @navbar-padding-horizontal;
-  border-top: 1px solid transparent;
-  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
-  &:extend(.clearfix all);
-  -webkit-overflow-scrolling: touch;
-
-  &.in {
-    overflow-y: auto;
-  }
-
-  @media (min-width: @grid-float-breakpoint) {
-    width: auto;
-    border-top: 0;
-    box-shadow: none;
-
-    &.collapse {
-      display: block !important;
-      height: auto !important;
-      padding-bottom: 0; // Override default setting
-      overflow: visible !important;
-    }
-
-    &.in {
-      overflow-y: visible;
-    }
-
-    // Undo the collapse side padding for navbars with containers to ensure
-    // alignment of right-aligned contents.
-    .navbar-fixed-top &,
-    .navbar-static-top &,
-    .navbar-fixed-bottom & {
-      padding-left: 0;
-      padding-right: 0;
-    }
-  }
-}
-
-
-// Both navbar header and collapse
-//
-// When a container is present, change the behavior of the header and collapse.
-
-.container,
-.container-fluid {
-  > .navbar-header,
-  > .navbar-collapse {
-    margin-right: -@navbar-padding-horizontal;
-    margin-left:  -@navbar-padding-horizontal;
-
-    @media (min-width: @grid-float-breakpoint) {
-      margin-right: 0;
-      margin-left:  0;
-    }
-  }
-}
-
-
-//
-// Navbar alignment options
-//
-// Display the navbar across the entirety of the page or fixed it to the top or
-// bottom of the page.
-
-// Static top (unfixed, but 100% wide) navbar
-.navbar-static-top {
-  z-index: @zindex-navbar;
-  border-width: 0 0 1px;
-
-  @media (min-width: @grid-float-breakpoint) {
-    border-radius: 0;
-  }
-}
-
-// Fix the top/bottom navbars when screen real estate supports it
-.navbar-fixed-top,
-.navbar-fixed-bottom {
-  position: fixed;
-  right: 0;
-  left: 0;
-  z-index: @zindex-navbar-fixed;
-
-  // Undo the rounded corners
-  @media (min-width: @grid-float-breakpoint) {
-    border-radius: 0;
-  }
-}
-.navbar-fixed-top {
-  top: 0;
-  border-width: 0 0 1px;
-}
-.navbar-fixed-bottom {
-  bottom: 0;
-  margin-bottom: 0; // override .navbar defaults
-  border-width: 1px 0 0;
-}
-
-
-// Brand/project name
-
-.navbar-brand {
-  float: left;
-  padding: @navbar-padding-vertical @navbar-padding-horizontal;
-  font-size: @font-size-large;
-  line-height: @line-height-computed;
-  height: @navbar-height;
-
-  &:hover,
-  &:focus {
-    text-decoration: none;
-  }
-
-  @media (min-width: @grid-float-breakpoint) {
-    .navbar > .container &,
-    .navbar > .container-fluid & {
-      margin-left: -@navbar-padding-horizontal;
-    }
-  }
-}
-
-
-// Navbar toggle
-//
-// Custom button for toggling the `.navbar-collapse`, powered by the collapse
-// JavaScript plugin.
-
-.navbar-toggle {
-  position: relative;
-  float: right;
-  margin-right: @navbar-padding-horizontal;
-  padding: 9px 10px;
-  .navbar-vertical-align(34px);
-  background-color: transparent;
-  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-  border: 1px solid transparent;
-  border-radius: @border-radius-base;
-
-  // We remove the `outline` here, but later compensate by attaching `:hover`
-  // styles to `:focus`.
-  &:focus {
-    outline: none;
-  }
-
-  // Bars
-  .icon-bar {
-    display: block;
-    width: 22px;
-    height: 2px;
-    border-radius: 1px;
-  }
-  .icon-bar + .icon-bar {
-    margin-top: 4px;
-  }
-
-  @media (min-width: @grid-float-breakpoint) {
-    display: none;
-  }
-}
-
-
-// Navbar nav links
-//
-// Builds on top of the `.nav` components with its own modifier class to make
-// the nav the full height of the horizontal nav (above 768px).
-
-.navbar-nav {
-  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;
-
-  > li > a {
-    padding-top:    10px;
-    padding-bottom: 10px;
-    line-height: @line-height-computed;
-  }
-
-  @media (max-width: @grid-float-breakpoint-max) {
-    // Dropdowns get custom display when collapsed
-    .open .dropdown-menu {
-      position: static;
-      float: none;
-      width: auto;
-      margin-top: 0;
-      background-color: transparent;
-      border: 0;
-      box-shadow: none;
-      > li > a,
-      .dropdown-header {
-        padding: 5px 15px 5px 25px;
-      }
-      > li > a {
-        line-height: @line-height-computed;
-        &:hover,
-        &:focus {
-          background-image: none;
-        }
-      }
-    }
-  }
-
-  // Uncollapse the nav
-  @media (min-width: @grid-float-breakpoint) {
-    float: left;
-    margin: 0;
-
-    > li {
-      float: left;
-      > a {
-        padding-top:    @navbar-padding-vertical;
-        padding-bottom: @navbar-padding-vertical;
-      }
-    }
-
-    &.navbar-right:last-child {
-      margin-right: -@navbar-padding-horizontal;
-    }
-  }
-}
-
-
-// Component alignment
-//
-// Repurpose the pull utilities as their own navbar utilities to avoid specificity
-// issues with parents and chaining. Only do this when the navbar is uncollapsed
-// though so that navbar contents properly stack and align in mobile.
-
-@media (min-width: @grid-float-breakpoint) {
-  .navbar-left  { .pull-left(); }
-  .navbar-right { .pull-right(); }
-}
-
-
-// Navbar form
-//
-// Extension of the `.form-inline` with some extra flavor for optimum display in
-// our navbars.
-
-.navbar-form {
-  margin-left: -@navbar-padding-horizontal;
-  margin-right: -@navbar-padding-horizontal;
-  padding: 10px @navbar-padding-horizontal;
-  border-top: 1px solid transparent;
-  border-bottom: 1px solid transparent;
-  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);
-  .box-shadow(@shadow);
-
-  // Mixin behavior for optimum display
-  .form-inline();
-
-  .form-group {
-    @media (max-width: @grid-float-breakpoint-max) {
-      margin-bottom: 5px;
-    }
-  }
-
-  // Vertically center in expanded, horizontal navbar
-  .navbar-vertical-align(@input-height-base);
-
-  // Undo 100% width for pull classes
-  @media (min-width: @grid-float-breakpoint) {
-    width: auto;
-    border: 0;
-    margin-left: 0;
-    margin-right: 0;
-    padding-top: 0;
-    padding-bottom: 0;
-    .box-shadow(none);
-
-    // Outdent the form if last child to line up with content down the page
-    &.navbar-right:last-child {
-      margin-right: -@navbar-padding-horizontal;
-    }
-  }
-}
-
-
-// Dropdown menus
-
-// Menu position and menu carets
-.navbar-nav > li > .dropdown-menu {
-  margin-top: 0;
-  .border-top-radius(0);
-}
-// Menu position and menu caret support for dropups via extra dropup class
-.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
-  .border-bottom-radius(0);
-}
-
-
-// Buttons in navbars
-//
-// Vertically center a button within a navbar (when *not* in a form).
-
-.navbar-btn {
-  .navbar-vertical-align(@input-height-base);
-
-  &.btn-sm {
-    .navbar-vertical-align(@input-height-small);
-  }
-  &.btn-xs {
-    .navbar-vertical-align(22);
-  }
-}
-
-
-// Text in navbars
-//
-// Add a class to make any element properly align itself vertically within the navbars.
-
-.navbar-text {
-  .navbar-vertical-align(@line-height-computed);
-
-  @media (min-width: @grid-float-breakpoint) {
-    float: left;
-    margin-left: @navbar-padding-horizontal;
-    margin-right: @navbar-padding-horizontal;
-
-    // Outdent the form if last child to line up with content down the page
-    &.navbar-right:last-child {
-      margin-right: 0;
-    }
-  }
-}
-
-// Alternate navbars
-// --------------------------------------------------
-
-// Default navbar
-.navbar-default {
-  background-color: @navbar-default-bg;
-  border-color: @navbar-default-border;
-
-  .navbar-brand {
-    color: @navbar-default-brand-color;
-    &:hover,
-    &:focus {
-      color: @navbar-default-brand-hover-color;
-      background-color: @navbar-default-brand-hover-bg;
-    }
-  }
-
-  .navbar-text {
-    color: @navbar-default-color;
-  }
-
-  .navbar-nav {
-    > li > a {
-      color: @navbar-default-link-color;
-
-      &:hover,
-      &:focus {
-        color: @navbar-default-link-hover-color;
-        background-color: @navbar-default-link-hover-bg;
-      }
-    }
-    > .active > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @navbar-default-link-active-color;
-        background-color: @navbar-default-link-active-bg;
-      }
-    }
-    > .disabled > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @navbar-default-link-disabled-color;
-        background-color: @navbar-default-link-disabled-bg;
-      }
-    }
-  }
-
-  .navbar-toggle {
-    border-color: @navbar-default-toggle-border-color;
-    &:hover,
-    &:focus {
-      background-color: @navbar-default-toggle-hover-bg;
-    }
-    .icon-bar {
-      background-color: @navbar-default-toggle-icon-bar-bg;
-    }
-  }
-
-  .navbar-collapse,
-  .navbar-form {
-    border-color: @navbar-default-border;
-  }
-
-  // Dropdown menu items
-  .navbar-nav {
-    // Remove background color from open dropdown
-    > .open > a {
-      &,
-      &:hover,
-      &:focus {
-        background-color: @navbar-default-link-active-bg;
-        color: @navbar-default-link-active-color;
-      }
-    }
-
-    @media (max-width: @grid-float-breakpoint-max) {
-      // Dropdowns get custom display when collapsed
-      .open .dropdown-menu {
-        > li > a {
-          color: @navbar-default-link-color;
-          &:hover,
-          &:focus {
-            color: @navbar-default-link-hover-color;
-            background-color: @navbar-default-link-hover-bg;
-          }
-        }
-        > .active > a {
-          &,
-          &:hover,
-          &:focus {
-            color: @navbar-default-link-active-color;
-            background-color: @navbar-default-link-active-bg;
-          }
-        }
-        > .disabled > a {
-          &,
-          &:hover,
-          &:focus {
-            color: @navbar-default-link-disabled-color;
-            background-color: @navbar-default-link-disabled-bg;
-          }
-        }
-      }
-    }
-  }
-
-
-  // Links in navbars
-  //
-  // Add a class to ensure links outside the navbar nav are colored correctly.
-
-  .navbar-link {
-    color: @navbar-default-link-color;
-    &:hover {
-      color: @navbar-default-link-hover-color;
-    }
-  }
-
-}
-
-// Inverse navbar
-
-.navbar-inverse {
-  background-color: @navbar-inverse-bg;
-  border-color: @navbar-inverse-border;
-
-  .navbar-brand {
-    color: @navbar-inverse-brand-color;
-    &:hover,
-    &:focus {
-      color: @navbar-inverse-brand-hover-color;
-      background-color: @navbar-inverse-brand-hover-bg;
-    }
-  }
-
-  .navbar-text {
-    color: @navbar-inverse-color;
-  }
-
-  .navbar-nav {
-    > li > a {
-      color: @navbar-inverse-link-color;
-
-      &:hover,
-      &:focus {
-        color: @navbar-inverse-link-hover-color;
-        background-color: @navbar-inverse-link-hover-bg;
-      }
-    }
-    > .active > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @navbar-inverse-link-active-color;
-        background-color: @navbar-inverse-link-active-bg;
-      }
-    }
-    > .disabled > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @navbar-inverse-link-disabled-color;
-        background-color: @navbar-inverse-link-disabled-bg;
-      }
-    }
-  }
-
-  // Darken the responsive nav toggle
-  .navbar-toggle {
-    border-color: @navbar-inverse-toggle-border-color;
-    &:hover,
-    &:focus {
-      background-color: @navbar-inverse-toggle-hover-bg;
-    }
-    .icon-bar {
-      background-color: @navbar-inverse-toggle-icon-bar-bg;
-    }
-  }
-
-  .navbar-collapse,
-  .navbar-form {
-    border-color: darken(@navbar-inverse-bg, 7%);
-  }
-
-  // Dropdowns
-  .navbar-nav {
-    > .open > a {
-      &,
-      &:hover,
-      &:focus {
-        background-color: @navbar-inverse-link-active-bg;
-        color: @navbar-inverse-link-active-color;
-      }
-    }
-
-    @media (max-width: @grid-float-breakpoint-max) {
-      // Dropdowns get custom display
-      .open .dropdown-menu {
-        > .dropdown-header {
-          border-color: @navbar-inverse-border;
-        }
-        .divider {
-          background-color: @navbar-inverse-border;
-        }
-        > li > a {
-          color: @navbar-inverse-link-color;
-          &:hover,
-          &:focus {
-            color: @navbar-inverse-link-hover-color;
-            background-color: @navbar-inverse-link-hover-bg;
-          }
-        }
-        > .active > a {
-          &,
-          &:hover,
-          &:focus {
-            color: @navbar-inverse-link-active-color;
-            background-color: @navbar-inverse-link-active-bg;
-          }
-        }
-        > .disabled > a {
-          &,
-          &:hover,
-          &:focus {
-            color: @navbar-inverse-link-disabled-color;
-            background-color: @navbar-inverse-link-disabled-bg;
-          }
-        }
-      }
-    }
-  }
-
-  .navbar-link {
-    color: @navbar-inverse-link-color;
-    &:hover {
-      color: @navbar-inverse-link-hover-color;
-    }
-  }
-
-}
diff --git a/docs/static/less/bootstrap/navs.less b/docs/static/less/bootstrap/navs.less
deleted file mode 100644
index 9e729b3..0000000
--- a/docs/static/less/bootstrap/navs.less
+++ /dev/null
@@ -1,242 +0,0 @@
-//
-// Navs
-// --------------------------------------------------
-
-
-// Base class
-// --------------------------------------------------
-
-.nav {
-  margin-bottom: 0;
-  padding-left: 0; // Override default ul/ol
-  list-style: none;
-  &:extend(.clearfix all);
-
-  > li {
-    position: relative;
-    display: block;
-
-    > a {
-      position: relative;
-      display: block;
-      padding: @nav-link-padding;
-      &:hover,
-      &:focus {
-        text-decoration: none;
-        background-color: @nav-link-hover-bg;
-      }
-    }
-
-    // Disabled state sets text to gray and nukes hover/tab effects
-    &.disabled > a {
-      color: @nav-disabled-link-color;
-
-      &:hover,
-      &:focus {
-        color: @nav-disabled-link-hover-color;
-        text-decoration: none;
-        background-color: transparent;
-        cursor: not-allowed;
-      }
-    }
-  }
-
-  // Open dropdowns
-  .open > a {
-    &,
-    &:hover,
-    &:focus {
-      background-color: @nav-link-hover-bg;
-      border-color: @link-color;
-    }
-  }
-
-  // Nav dividers (deprecated with v3.0.1)
-  //
-  // This should have been removed in v3 with the dropping of `.nav-list`, but
-  // we missed it. We don't currently support this anywhere, but in the interest
-  // of maintaining backward compatibility in case you use it, it's deprecated.
-  .nav-divider {
-    .nav-divider();
-  }
-
-  // Prevent IE8 from misplacing imgs
-  //
-  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989
-  > li > a > img {
-    max-width: none;
-  }
-}
-
-
-// Tabs
-// -------------------------
-
-// Give the tabs something to sit on
-.nav-tabs {
-  border-bottom: 1px solid @nav-tabs-border-color;
-  > li {
-    float: left;
-    // Make the list-items overlay the bottom border
-    margin-bottom: -1px;
-
-    // Actual tabs (as links)
-    > a {
-      margin-right: 2px;
-      line-height: @line-height-base;
-      border: 1px solid transparent;
-      border-radius: @border-radius-base @border-radius-base 0 0;
-      &:hover {
-        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;
-      }
-    }
-
-    // Active state, and its :hover to override normal :hover
-    &.active > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @nav-tabs-active-link-hover-color;
-        background-color: @nav-tabs-active-link-hover-bg;
-        border: 1px solid @nav-tabs-active-link-hover-border-color;
-        border-bottom-color: transparent;
-        cursor: default;
-      }
-    }
-  }
-  // pulling this in mainly for less shorthand
-  &.nav-justified {
-    .nav-justified();
-    .nav-tabs-justified();
-  }
-}
-
-
-// Pills
-// -------------------------
-.nav-pills {
-  > li {
-    float: left;
-
-    // Links rendered as pills
-    > a {
-      border-radius: @nav-pills-border-radius;
-    }
-    + li {
-      margin-left: 2px;
-    }
-
-    // Active state
-    &.active > a {
-      &,
-      &:hover,
-      &:focus {
-        color: @nav-pills-active-link-hover-color;
-        background-color: @nav-pills-active-link-hover-bg;
-      }
-    }
-  }
-}
-
-
-// Stacked pills
-.nav-stacked {
-  > li {
-    float: none;
-    + li {
-      margin-top: 2px;
-      margin-left: 0; // no need for this gap between nav items
-    }
-  }
-}
-
-
-// Nav variations
-// --------------------------------------------------
-
-// Justified nav links
-// -------------------------
-
-.nav-justified {
-  width: 100%;
-
-  > li {
-    float: none;
-     > a {
-      text-align: center;
-      margin-bottom: 5px;
-    }
-  }
-
-  > .dropdown .dropdown-menu {
-    top: auto;
-    left: auto;
-  }
-
-  @media (min-width: @screen-sm-min) {
-    > li {
-      display: table-cell;
-      width: 1%;
-      > a {
-        margin-bottom: 0;
-      }
-    }
-  }
-}
-
-// Move borders to anchors instead of bottom of list
-//
-// Mixin for adding on top the shared `.nav-justified` styles for our tabs
-.nav-tabs-justified {
-  border-bottom: 0;
-
-  > li > a {
-    // Override margin from .nav-tabs
-    margin-right: 0;
-    border-radius: @border-radius-base;
-  }
-
-  > .active > a,
-  > .active > a:hover,
-  > .active > a:focus {
-    border: 1px solid @nav-tabs-justified-link-border-color;
-  }
-
-  @media (min-width: @screen-sm-min) {
-    > li > a {
-      border-bottom: 1px solid @nav-tabs-justified-link-border-color;
-      border-radius: @border-radius-base @border-radius-base 0 0;
-    }
-    > .active > a,
-    > .active > a:hover,
-    > .active > a:focus {
-      border-bottom-color: @nav-tabs-justified-active-link-border-color;
-    }
-  }
-}
-
-
-// Tabbable tabs
-// -------------------------
-
-// Hide tabbable panes to start, show them when `.active`
-.tab-content {
-  > .tab-pane {
-    display: none;
-  }
-  > .active {
-    display: block;
-  }
-}
-
-
-// Dropdowns
-// -------------------------
-
-// Specific dropdowns
-.nav-tabs .dropdown-menu {
-  // make dropdown border overlap tab border
-  margin-top: -1px;
-  // Remove the top rounded corners here since there is a hard edge above the menu
-  .border-top-radius(0);
-}
diff --git a/docs/static/less/bootstrap/normalize.less b/docs/static/less/bootstrap/normalize.less
deleted file mode 100644
index 024e257..0000000
--- a/docs/static/less/bootstrap/normalize.less
+++ /dev/null
@@ -1,423 +0,0 @@
-/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
-
-//
-// 1. Set default font family to sans-serif.
-// 2. Prevent iOS text size adjust after orientation change, without disabling
-//    user zoom.
-//
-
-html {
-  font-family: sans-serif; // 1
-  -ms-text-size-adjust: 100%; // 2
-  -webkit-text-size-adjust: 100%; // 2
-}
-
-//
-// Remove default margin.
-//
-
-body {
-  margin: 0;
-}
-
-// HTML5 display definitions
-// ==========================================================================
-
-//
-// Correct `block` display not defined in IE 8/9.
-//
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
-  display: block;
-}
-
-//
-// 1. Correct `inline-block` display not defined in IE 8/9.
-// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
-//
-
-audio,
-canvas,
-progress,
-video {
-  display: inline-block; // 1
-  vertical-align: baseline; // 2
-}
-
-//
-// Prevent modern browsers from displaying `audio` without controls.
-// Remove excess height in iOS 5 devices.
-//
-
-audio:not([controls]) {
-  display: none;
-  height: 0;
-}
-
-//
-// Address `[hidden]` styling not present in IE 8/9.
-// Hide the `template` element in IE, Safari, and Firefox < 22.
-//
-
-[hidden],
-template {
-  display: none;
-}
-
-// Links
-// ==========================================================================
-
-//
-// Remove the gray background color from active links in IE 10.
-//
-
-a {
-  background: transparent;
-}
-
-//
-// Improve readability when focused and also mouse hovered in all browsers.
-//
-
-a:active,
-a:hover {
-  outline: 0;
-}
-
-// Text-level semantics
-// ==========================================================================
-
-//
-// Address styling not present in IE 8/9, Safari 5, and Chrome.
-//
-
-abbr[title] {
-  border-bottom: 1px dotted;
-}
-
-//
-// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
-//
-
-b,
-strong {
-  font-weight: bold;
-}
-
-//
-// Address styling not present in Safari 5 and Chrome.
-//
-
-dfn {
-  font-style: italic;
-}
-
-//
-// Address variable `h1` font-size and margin within `section` and `article`
-// contexts in Firefox 4+, Safari 5, and Chrome.
-//
-
-h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-
-//
-// Address styling not present in IE 8/9.
-//
-
-mark {
-  background: #ff0;
-  color: #000;
-}
-
-//
-// Address inconsistent and variable font size in all browsers.
-//
-
-small {
-  font-size: 80%;
-}
-
-//
-// Prevent `sub` and `sup` affecting `line-height` in all browsers.
-//
-
-sub,
-sup {
-  font-size: 75%;
-  line-height: 0;
-  position: relative;
-  vertical-align: baseline;
-}
-
-sup {
-  top: -0.5em;
-}
-
-sub {
-  bottom: -0.25em;
-}
-
-// Embedded content
-// ==========================================================================
-
-//
-// Remove border when inside `a` element in IE 8/9.
-//
-
-img {
-  border: 0;
-}
-
-//
-// Correct overflow displayed oddly in IE 9.
-//
-
-svg:not(:root) {
-  overflow: hidden;
-}
-
-// Grouping content
-// ==========================================================================
-
-//
-// Address margin not present in IE 8/9 and Safari 5.
-//
-
-figure {
-  margin: 1em 40px;
-}
-
-//
-// Address differences between Firefox and other browsers.
-//
-
-hr {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-  height: 0;
-}
-
-//
-// Contain overflow in all browsers.
-//
-
-pre {
-  overflow: auto;
-}
-
-//
-// Address odd `em`-unit font size rendering in all browsers.
-//
-
-code,
-kbd,
-pre,
-samp {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-
-// Forms
-// ==========================================================================
-
-//
-// Known limitation: by default, Chrome and Safari on OS X allow very limited
-// styling of `select`, unless a `border` property is set.
-//
-
-//
-// 1. Correct color not being inherited.
-//    Known issue: affects color of disabled elements.
-// 2. Correct font properties not being inherited.
-// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
-//
-
-button,
-input,
-optgroup,
-select,
-textarea {
-  color: inherit; // 1
-  font: inherit; // 2
-  margin: 0; // 3
-}
-
-//
-// Address `overflow` set to `hidden` in IE 8/9/10.
-//
-
-button {
-  overflow: visible;
-}
-
-//
-// Address inconsistent `text-transform` inheritance for `button` and `select`.
-// All other form control elements do not inherit `text-transform` values.
-// Correct `button` style inheritance in Firefox, IE 8+, and Opera
-// Correct `select` style inheritance in Firefox.
-//
-
-button,
-select {
-  text-transform: none;
-}
-
-//
-// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
-//    and `video` controls.
-// 2. Correct inability to style clickable `input` types in iOS.
-// 3. Improve usability and consistency of cursor style between image-type
-//    `input` and others.
-//
-
-button,
-html input[type="button"], // 1
-input[type="reset"],
-input[type="submit"] {
-  -webkit-appearance: button; // 2
-  cursor: pointer; // 3
-}
-
-//
-// Re-set default cursor for disabled elements.
-//
-
-button[disabled],
-html input[disabled] {
-  cursor: default;
-}
-
-//
-// Remove inner padding and border in Firefox 4+.
-//
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-  border: 0;
-  padding: 0;
-}
-
-//
-// Address Firefox 4+ setting `line-height` on `input` using `!important` in
-// the UA stylesheet.
-//
-
-input {
-  line-height: normal;
-}
-
-//
-// It's recommended that you don't attempt to style these elements.
-// Firefox's implementation doesn't respect box-sizing, padding, or width.
-//
-// 1. Address box sizing set to `content-box` in IE 8/9/10.
-// 2. Remove excess padding in IE 8/9/10.
-//
-
-input[type="checkbox"],
-input[type="radio"] {
-  box-sizing: border-box; // 1
-  padding: 0; // 2
-}
-
-//
-// Fix the cursor style for Chrome's increment/decrement buttons. For certain
-// `font-size` values of the `input`, it causes the cursor style of the
-// decrement button to change from `default` to `text`.
-//
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
-  height: auto;
-}
-
-//
-// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
-// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
-//    (include `-moz` to future-proof).
-//
-
-input[type="search"] {
-  -webkit-appearance: textfield; // 1
-  -moz-box-sizing: content-box;
-  -webkit-box-sizing: content-box; // 2
-  box-sizing: content-box;
-}
-
-//
-// Remove inner padding and search cancel button in Safari and Chrome on OS X.
-// Safari (but not Chrome) clips the cancel button when the search input has
-// padding (and `textfield` appearance).
-//
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
-
-//
-// Define consistent border, margin, and padding.
-//
-
-fieldset {
-  border: 1px solid #c0c0c0;
-  margin: 0 2px;
-  padding: 0.35em 0.625em 0.75em;
-}
-
-//
-// 1. Correct `color` not being inherited in IE 8/9.
-// 2. Remove padding so people aren't caught out if they zero out fieldsets.
-//
-
-legend {
-  border: 0; // 1
-  padding: 0; // 2
-}
-
-//
-// Remove default vertical scrollbar in IE 8/9.
-//
-
-textarea {
-  overflow: auto;
-}
-
-//
-// Don't inherit the `font-weight` (applied by a rule above).
-// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
-//
-
-optgroup {
-  font-weight: bold;
-}
-
-// Tables
-// ==========================================================================
-
-//
-// Remove most spacing between table cells.
-//
-
-table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-td,
-th {
-  padding: 0;
-}
\ No newline at end of file
diff --git a/docs/static/less/bootstrap/pager.less b/docs/static/less/bootstrap/pager.less
deleted file mode 100644
index 59103f4..0000000
--- a/docs/static/less/bootstrap/pager.less
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Pager pagination
-// --------------------------------------------------
-
-
-.pager {
-  padding-left: 0;
-  margin: @line-height-computed 0;
-  list-style: none;
-  text-align: center;
-  &:extend(.clearfix all);
-  li {
-    display: inline;
-    > a,
-    > span {
-      display: inline-block;
-      padding: 5px 14px;
-      background-color: @pager-bg;
-      border: 1px solid @pager-border;
-      border-radius: @pager-border-radius;
-    }
-
-    > a:hover,
-    > a:focus {
-      text-decoration: none;
-      background-color: @pager-hover-bg;
-    }
-  }
-
-  .next {
-    > a,
-    > span {
-      float: right;
-    }
-  }
-
-  .previous {
-    > a,
-    > span {
-      float: left;
-    }
-  }
-
-  .disabled {
-    > a,
-    > a:hover,
-    > a:focus,
-    > span {
-      color: @pager-disabled-color;
-      background-color: @pager-bg;
-      cursor: not-allowed;
-    }
-  }
-
-}
diff --git a/docs/static/less/bootstrap/pagination.less b/docs/static/less/bootstrap/pagination.less
deleted file mode 100644
index b2856ae..0000000
--- a/docs/static/less/bootstrap/pagination.less
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// Pagination (multiple pages)
-// --------------------------------------------------
-.pagination {
-  display: inline-block;
-  padding-left: 0;
-  margin: @line-height-computed 0;
-  border-radius: @border-radius-base;
-
-  > li {
-    display: inline; // Remove list-style and block-level defaults
-    > a,
-    > span {
-      position: relative;
-      float: left; // Collapse white-space
-      padding: @padding-base-vertical @padding-base-horizontal;
-      line-height: @line-height-base;
-      text-decoration: none;
-      color: @pagination-color;
-      background-color: @pagination-bg;
-      border: 1px solid @pagination-border;
-      margin-left: -1px;
-    }
-    &:first-child {
-      > a,
-      > span {
-        margin-left: 0;
-        .border-left-radius(@border-radius-base);
-      }
-    }
-    &:last-child {
-      > a,
-      > span {
-        .border-right-radius(@border-radius-base);
-      }
-    }
-  }
-
-  > li > a,
-  > li > span {
-    &:hover,
-    &:focus {
-      color: @pagination-hover-color;
-      background-color: @pagination-hover-bg;
-      border-color: @pagination-hover-border;
-    }
-  }
-
-  > .active > a,
-  > .active > span {
-    &,
-    &:hover,
-    &:focus {
-      z-index: 2;
-      color: @pagination-active-color;
-      background-color: @pagination-active-bg;
-      border-color: @pagination-active-border;
-      cursor: default;
-    }
-  }
-
-  > .disabled {
-    > span,
-    > span:hover,
-    > span:focus,
-    > a,
-    > a:hover,
-    > a:focus {
-      color: @pagination-disabled-color;
-      background-color: @pagination-disabled-bg;
-      border-color: @pagination-disabled-border;
-      cursor: not-allowed;
-    }
-  }
-}
-
-// Sizing
-// --------------------------------------------------
-
-// Large
-.pagination-lg {
-  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);
-}
-
-// Small
-.pagination-sm {
-  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);
-}
diff --git a/docs/static/less/bootstrap/panels.less b/docs/static/less/bootstrap/panels.less
deleted file mode 100644
index 20dd149..0000000
--- a/docs/static/less/bootstrap/panels.less
+++ /dev/null
@@ -1,241 +0,0 @@
-//
-// Panels
-// --------------------------------------------------
-
-
-// Base class
-.panel {
-  margin-bottom: @line-height-computed;
-  background-color: @panel-bg;
-  border: 1px solid transparent;
-  border-radius: @panel-border-radius;
-  .box-shadow(0 1px 1px rgba(0,0,0,.05));
-}
-
-// Panel contents
-.panel-body {
-  padding: @panel-body-padding;
-  &:extend(.clearfix all);
-}
-
-// Optional heading
-.panel-heading {
-  padding: 10px 15px;
-  border-bottom: 1px solid transparent;
-  .border-top-radius((@panel-border-radius - 1));
-
-  > .dropdown .dropdown-toggle {
-    color: inherit;
-  }
-}
-
-// Within heading, strip any `h*` tag of its default margins for spacing.
-.panel-title {
-  margin-top: 0;
-  margin-bottom: 0;
-  font-size: ceil((@font-size-base * 1.125));
-  color: inherit;
-
-  > a {
-    color: inherit;
-  }
-}
-
-// Optional footer (stays gray in every modifier class)
-.panel-footer {
-  padding: 10px 15px;
-  background-color: @panel-footer-bg;
-  border-top: 1px solid @panel-inner-border;
-  .border-bottom-radius((@panel-border-radius - 1));
-}
-
-
-// List groups in panels
-//
-// By default, space out list group content from panel headings to account for
-// any kind of custom content between the two.
-
-.panel {
-  > .list-group {
-    margin-bottom: 0;
-
-    .list-group-item {
-      border-width: 1px 0;
-      border-radius: 0;
-    }
-
-    // Add border top radius for first one
-    &:first-child {
-      .list-group-item:first-child {
-        border-top: 0;
-        .border-top-radius((@panel-border-radius - 1));
-      }
-    }
-    // Add border bottom radius for last one
-    &:last-child {
-      .list-group-item:last-child {
-        border-bottom: 0;
-        .border-bottom-radius((@panel-border-radius - 1));
-      }
-    }
-  }
-}
-// Collapse space between when there's no additional content.
-.panel-heading + .list-group {
-  .list-group-item:first-child {
-    border-top-width: 0;
-  }
-}
-
-
-// Tables in panels
-//
-// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
-// watch it go full width.
-
-.panel {
-  > .table,
-  > .table-responsive > .table {
-    margin-bottom: 0;
-  }
-  // Add border top radius for first one
-  > .table:first-child,
-  > .table-responsive:first-child > .table:first-child {
-    .border-top-radius((@panel-border-radius - 1));
-
-    > thead:first-child,
-    > tbody:first-child {
-      > tr:first-child {
-        td:first-child,
-        th:first-child {
-          border-top-left-radius: (@panel-border-radius - 1);
-        }
-        td:last-child,
-        th:last-child {
-          border-top-right-radius: (@panel-border-radius - 1);
-        }
-      }
-    }
-  }
-  // Add border bottom radius for last one
-  > .table:last-child,
-  > .table-responsive:last-child > .table:last-child {
-    .border-bottom-radius((@panel-border-radius - 1));
-
-    > tbody:last-child,
-    > tfoot:last-child {
-      > tr:last-child {
-        td:first-child,
-        th:first-child {
-          border-bottom-left-radius: (@panel-border-radius - 1);
-        }
-        td:last-child,
-        th:last-child {
-          border-bottom-right-radius: (@panel-border-radius - 1);
-        }
-      }
-    }
-  }
-  > .panel-body + .table,
-  > .panel-body + .table-responsive {
-    border-top: 1px solid @table-border-color;
-  }
-  > .table > tbody:first-child > tr:first-child th,
-  > .table > tbody:first-child > tr:first-child td {
-    border-top: 0;
-  }
-  > .table-bordered,
-  > .table-responsive > .table-bordered {
-    border: 0;
-    > thead,
-    > tbody,
-    > tfoot {
-      > tr {
-        > th:first-child,
-        > td:first-child {
-          border-left: 0;
-        }
-        > th:last-child,
-        > td:last-child {
-          border-right: 0;
-        }
-      }
-    }
-    > thead,
-    > tbody {
-      > tr:first-child {
-        > td,
-        > th {
-          border-bottom: 0;
-        }
-      }
-    }
-    > tbody,
-    > tfoot {
-      > tr:last-child {
-        > td,
-        > th {
-          border-bottom: 0;
-        }
-      }
-    }
-  }
-  > .table-responsive {
-    border: 0;
-    margin-bottom: 0;
-  }
-}
-
-
-// Collapsable panels (aka, accordion)
-//
-// Wrap a series of panels in `.panel-group` to turn them into an accordion with
-// the help of our collapse JavaScript plugin.
-
-.panel-group {
-  margin-bottom: @line-height-computed;
-
-  // Tighten up margin so it's only between panels
-  .panel {
-    margin-bottom: 0;
-    border-radius: @panel-border-radius;
-    overflow: hidden; // crop contents when collapsed
-    + .panel {
-      margin-top: 5px;
-    }
-  }
-
-  .panel-heading {
-    border-bottom: 0;
-    + .panel-collapse .panel-body {
-      border-top: 1px solid @panel-inner-border;
-    }
-  }
-  .panel-footer {
-    border-top: 0;
-    + .panel-collapse .panel-body {
-      border-bottom: 1px solid @panel-inner-border;
-    }
-  }
-}
-
-
-// Contextual variations
-.panel-default {
-  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);
-}
-.panel-primary {
-  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);
-}
-.panel-success {
-  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);
-}
-.panel-info {
-  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);
-}
-.panel-warning {
-  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);
-}
-.panel-danger {
-  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);
-}
diff --git a/docs/static/less/bootstrap/popovers.less b/docs/static/less/bootstrap/popovers.less
deleted file mode 100644
index 696d74c..0000000
--- a/docs/static/less/bootstrap/popovers.less
+++ /dev/null
@@ -1,133 +0,0 @@
-//
-// Popovers
-// --------------------------------------------------
-
-
-.popover {
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: @zindex-popover;
-  display: none;
-  max-width: @popover-max-width;
-  padding: 1px;
-  text-align: left; // Reset given new insertion method
-  background-color: @popover-bg;
-  background-clip: padding-box;
-  border: 1px solid @popover-fallback-border-color;
-  border: 1px solid @popover-border-color;
-  border-radius: @border-radius-large;
-  .box-shadow(0 5px 10px rgba(0,0,0,.2));
-
-  // Overrides for proper insertion
-  white-space: normal;
-
-  // Offset the popover to account for the popover arrow
-  &.top     { margin-top: -@popover-arrow-width; }
-  &.right   { margin-left: @popover-arrow-width; }
-  &.bottom  { margin-top: @popover-arrow-width; }
-  &.left    { margin-left: -@popover-arrow-width; }
-}
-
-.popover-title {
-  margin: 0; // reset heading margin
-  padding: 8px 14px;
-  font-size: @font-size-base;
-  font-weight: normal;
-  line-height: 18px;
-  background-color: @popover-title-bg;
-  border-bottom: 1px solid darken(@popover-title-bg, 5%);
-  border-radius: 5px 5px 0 0;
-}
-
-.popover-content {
-  padding: 9px 14px;
-}
-
-// Arrows
-//
-// .arrow is outer, .arrow:after is inner
-
-.popover > .arrow {
-  &,
-  &:after {
-    position: absolute;
-    display: block;
-    width: 0;
-    height: 0;
-    border-color: transparent;
-    border-style: solid;
-  }
-}
-.popover > .arrow {
-  border-width: @popover-arrow-outer-width;
-}
-.popover > .arrow:after {
-  border-width: @popover-arrow-width;
-  content: "";
-}
-
-.popover {
-  &.top > .arrow {
-    left: 50%;
-    margin-left: -@popover-arrow-outer-width;
-    border-bottom-width: 0;
-    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback
-    border-top-color: @popover-arrow-outer-color;
-    bottom: -@popover-arrow-outer-width;
-    &:after {
-      content: " ";
-      bottom: 1px;
-      margin-left: -@popover-arrow-width;
-      border-bottom-width: 0;
-      border-top-color: @popover-arrow-color;
-    }
-  }
-  &.right > .arrow {
-    top: 50%;
-    left: -@popover-arrow-outer-width;
-    margin-top: -@popover-arrow-outer-width;
-    border-left-width: 0;
-    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback
-    border-right-color: @popover-arrow-outer-color;
-    &:after {
-      content: " ";
-      left: 1px;
-      bottom: -@popover-arrow-width;
-      border-left-width: 0;
-      border-right-color: @popover-arrow-color;
-    }
-  }
-  &.bottom > .arrow {
-    left: 50%;
-    margin-left: -@popover-arrow-outer-width;
-    border-top-width: 0;
-    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback
-    border-bottom-color: @popover-arrow-outer-color;
-    top: -@popover-arrow-outer-width;
-    &:after {
-      content: " ";
-      top: 1px;
-      margin-left: -@popover-arrow-width;
-      border-top-width: 0;
-      border-bottom-color: @popover-arrow-color;
-    }
-  }
-
-  &.left > .arrow {
-    top: 50%;
-    right: -@popover-arrow-outer-width;
-    margin-top: -@popover-arrow-outer-width;
-    border-right-width: 0;
-    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback
-    border-left-color: @popover-arrow-outer-color;
-    &:after {
-      content: " ";
-      right: 1px;
-      border-right-width: 0;
-      border-left-color: @popover-arrow-color;
-      bottom: -@popover-arrow-width;
-    }
-  }
-
-}
diff --git a/docs/static/less/bootstrap/print.less b/docs/static/less/bootstrap/print.less
deleted file mode 100644
index 3655d03..0000000
--- a/docs/static/less/bootstrap/print.less
+++ /dev/null
@@ -1,101 +0,0 @@
-//
-// Basic print styles
-// --------------------------------------------------
-// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css
-
-@media print {
-
-  * {
-    text-shadow: none !important;
-    color: #000 !important; // Black prints faster: h5bp.com/s
-    background: transparent !important;
-    box-shadow: none !important;
-  }
-
-  a,
-  a:visited {
-    text-decoration: underline;
-  }
-
-  a[href]:after {
-    content: " (" attr(href) ")";
-  }
-
-  abbr[title]:after {
-    content: " (" attr(title) ")";
-  }
-
-  // Don't show links for images, or javascript/internal links
-  a[href^="javascript:"]:after,
-  a[href^="#"]:after {
-    content: "";
-  }
-
-  pre,
-  blockquote {
-    border: 1px solid #999;
-    page-break-inside: avoid;
-  }
-
-  thead {
-    display: table-header-group; // h5bp.com/t
-  }
-
-  tr,
-  img {
-    page-break-inside: avoid;
-  }
-
-  img {
-    max-width: 100% !important;
-  }
-
-  p,
-  h2,
-  h3 {
-    orphans: 3;
-    widows: 3;
-  }
-
-  h2,
-  h3 {
-    page-break-after: avoid;
-  }
-
-  // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245
-  // Once fixed, we can just straight up remove this.
-  select {
-    background: #fff !important;
-  }
-
-  // Bootstrap components
-  .navbar {
-    display: none;
-  }
-  .table {
-    td,
-    th {
-      background-color: #fff !important;
-    }
-  }
-  .btn,
-  .dropup > .btn {
-    > .caret {
-      border-top-color: #000 !important;
-    }
-  }
-  .label {
-    border: 1px solid #000;
-  }
-
-  .table {
-    border-collapse: collapse !important;
-  }
-  .table-bordered {
-    th,
-    td {
-      border: 1px solid #ddd !important;
-    }
-  }
-
-}
diff --git a/docs/static/less/bootstrap/progress-bars.less b/docs/static/less/bootstrap/progress-bars.less
deleted file mode 100644
index 76c87be..0000000
--- a/docs/static/less/bootstrap/progress-bars.less
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Progress bars
-// --------------------------------------------------
-
-
-// Bar animations
-// -------------------------
-
-// WebKit
-@-webkit-keyframes progress-bar-stripes {
-  from  { background-position: 40px 0; }
-  to    { background-position: 0 0; }
-}
-
-// Spec and IE10+
-@keyframes progress-bar-stripes {
-  from  { background-position: 40px 0; }
-  to    { background-position: 0 0; }
-}
-
-
-
-// Bar itself
-// -------------------------
-
-// Outer container
-.progress {
-  overflow: hidden;
-  height: @line-height-computed;
-  margin-bottom: @line-height-computed;
-  background-color: @progress-bg;
-  border-radius: @border-radius-base;
-  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
-}
-
-// Bar of progress
-.progress-bar {
-  float: left;
-  width: 0%;
-  height: 100%;
-  font-size: @font-size-small;
-  line-height: @line-height-computed;
-  color: @progress-bar-color;
-  text-align: center;
-  background-color: @progress-bar-bg;
-  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
-  .transition(width .6s ease);
-}
-
-// Striped bars
-.progress-striped .progress-bar {
-  #gradient > .striped();
-  background-size: 40px 40px;
-}
-
-// Call animation for the active one
-.progress.active .progress-bar {
-  .animation(progress-bar-stripes 2s linear infinite);
-}
-
-
-
-// Variations
-// -------------------------
-
-.progress-bar-success {
-  .progress-bar-variant(@progress-bar-success-bg);
-}
-
-.progress-bar-info {
-  .progress-bar-variant(@progress-bar-info-bg);
-}
-
-.progress-bar-warning {
-  .progress-bar-variant(@progress-bar-warning-bg);
-}
-
-.progress-bar-danger {
-  .progress-bar-variant(@progress-bar-danger-bg);
-}
diff --git a/docs/static/less/bootstrap/responsive-utilities.less b/docs/static/less/bootstrap/responsive-utilities.less
deleted file mode 100644
index 027a264..0000000
--- a/docs/static/less/bootstrap/responsive-utilities.less
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Responsive: Utility classes
-// --------------------------------------------------
-
-
-// IE10 in Windows (Phone) 8
-//
-// Support for responsive views via media queries is kind of borked in IE10, for
-// Surface/desktop in split view and for Windows Phone 8. This particular fix
-// must be accompanied by a snippet of JavaScript to sniff the user agent and
-// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at
-// our Getting Started page for more information on this bug.
-//
-// For more information, see the following:
-//
-// Issue: https://github.com/twbs/bootstrap/issues/10497
-// Docs: http://getbootstrap.com/getting-started/#browsers
-// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
-
-@-ms-viewport {
-  width: device-width;
-}
-
-
-// Visibility utilities
-.visible-xs,
-.visible-sm,
-.visible-md,
-.visible-lg {
-  .responsive-invisibility();
-}
-
-.visible-xs {
-  @media (max-width: @screen-xs-max) {
-    .responsive-visibility();
-  }
-}
-.visible-sm {
-  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
-    .responsive-visibility();
-  }
-}
-.visible-md {
-  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
-    .responsive-visibility();
-  }
-}
-.visible-lg {
-  @media (min-width: @screen-lg-min) {
-    .responsive-visibility();
-  }
-}
-
-.hidden-xs {
-  @media (max-width: @screen-xs-max) {
-    .responsive-invisibility();
-  }
-}
-.hidden-sm {
-  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
-    .responsive-invisibility();
-  }
-}
-.hidden-md {
-  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
-    .responsive-invisibility();
-  }
-}
-.hidden-lg {
-  @media (min-width: @screen-lg-min) {
-    .responsive-invisibility();
-  }
-}
-
-
-// Print utilities
-//
-// Media queries are placed on the inside to be mixin-friendly.
-
-.visible-print {
-  .responsive-invisibility();
-
-  @media print {
-    .responsive-visibility();
-  }
-}
-
-.hidden-print {
-  @media print {
-    .responsive-invisibility();
-  }
-}
diff --git a/docs/static/less/bootstrap/scaffolding.less b/docs/static/less/bootstrap/scaffolding.less
deleted file mode 100644
index fe29f2d..0000000
--- a/docs/static/less/bootstrap/scaffolding.less
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Scaffolding
-// --------------------------------------------------
-
-
-// Reset the box-sizing
-//
-// Heads up! This reset may cause conflicts with some third-party widgets.
-// For recommendations on resolving such conflicts, see
-// http://getbootstrap.com/getting-started/#third-box-sizing
-* {
-  .box-sizing(border-box);
-}
-*:before,
-*:after {
-  .box-sizing(border-box);
-}
-
-
-// Body reset
-
-html {
-  font-size: 62.5%;
-  -webkit-tap-highlight-color: rgba(0,0,0,0);
-}
-
-body {
-  font-family: @font-family-base;
-  font-size: @font-size-base;
-  line-height: @line-height-base;
-  color: @text-color;
-  background-color: @body-bg;
-}
-
-// Reset fonts for relevant elements
-input,
-button,
-select,
-textarea {
-  font-family: inherit;
-  font-size: inherit;
-  line-height: inherit;
-}
-
-
-// Links
-
-a {
-  color: @link-color;
-  text-decoration: none;
-
-  &:hover,
-  &:focus {
-    color: @link-hover-color;
-    text-decoration: underline;
-  }
-
-  &:focus {
-    .tab-focus();
-  }
-}
-
-
-// Figures
-//
-// We reset this here because previously Normalize had no `figure` margins. This
-// ensures we don't break anyone's use of the element.
-
-figure {
-  margin: 0;
-}
-
-
-// Images
-
-img {
-  vertical-align: middle;
-}
-
-// Responsive images (ensure images don't scale beyond their parents)
-.img-responsive {
-  .img-responsive();
-}
-
-// Rounded corners
-.img-rounded {
-  border-radius: @border-radius-large;
-}
-
-// Image thumbnails
-//
-// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
-.img-thumbnail {
-  padding: @thumbnail-padding;
-  line-height: @line-height-base;
-  background-color: @thumbnail-bg;
-  border: 1px solid @thumbnail-border;
-  border-radius: @thumbnail-border-radius;
-  .transition(all .2s ease-in-out);
-
-  // Keep them at most 100% wide
-  .img-responsive(inline-block);
-}
-
-// Perfect circle
-.img-circle {
-  border-radius: 50%; // set radius in percents
-}
-
-
-// Horizontal rules
-
-hr {
-  margin-top:    @line-height-computed;
-  margin-bottom: @line-height-computed;
-  border: 0;
-  border-top: 1px solid @hr-border;
-}
-
-
-// Only display content to screen readers
-//
-// See: http://a11yproject.com/posts/how-to-hide-content/
-
-.sr-only {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  margin: -1px;
-  padding: 0;
-  overflow: hidden;
-  clip: rect(0,0,0,0);
-  border: 0;
-}
diff --git a/docs/static/less/bootstrap/tables.less b/docs/static/less/bootstrap/tables.less
deleted file mode 100644
index c41989c..0000000
--- a/docs/static/less/bootstrap/tables.less
+++ /dev/null
@@ -1,233 +0,0 @@
-//
-// Tables
-// --------------------------------------------------
-
-
-table {
-  max-width: 100%;
-  background-color: @table-bg;
-}
-th {
-  text-align: left;
-}
-
-
-// Baseline styles
-
-.table {
-  width: 100%;
-  margin-bottom: @line-height-computed;
-  // Cells
-  > thead,
-  > tbody,
-  > tfoot {
-    > tr {
-      > th,
-      > td {
-        padding: @table-cell-padding;
-        line-height: @line-height-base;
-        vertical-align: top;
-        border-top: 1px solid @table-border-color;
-      }
-    }
-  }
-  // Bottom align for column headings
-  > thead > tr > th {
-    vertical-align: bottom;
-    border-bottom: 2px solid @table-border-color;
-  }
-  // Remove top border from thead by default
-  > caption + thead,
-  > colgroup + thead,
-  > thead:first-child {
-    > tr:first-child {
-      > th,
-      > td {
-        border-top: 0;
-      }
-    }
-  }
-  // Account for multiple tbody instances
-  > tbody + tbody {
-    border-top: 2px solid @table-border-color;
-  }
-
-  // Nesting
-  .table {
-    background-color: @body-bg;
-  }
-}
-
-
-// Condensed table w/ half padding
-
-.table-condensed {
-  > thead,
-  > tbody,
-  > tfoot {
-    > tr {
-      > th,
-      > td {
-        padding: @table-condensed-cell-padding;
-      }
-    }
-  }
-}
-
-
-// Bordered version
-//
-// Add borders all around the table and between all the columns.
-
-.table-bordered {
-  border: 1px solid @table-border-color;
-  > thead,
-  > tbody,
-  > tfoot {
-    > tr {
-      > th,
-      > td {
-        border: 1px solid @table-border-color;
-      }
-    }
-  }
-  > thead > tr {
-    > th,
-    > td {
-      border-bottom-width: 2px;
-    }
-  }
-}
-
-
-// Zebra-striping
-//
-// Default zebra-stripe styles (alternating gray and transparent backgrounds)
-
-.table-striped {
-  > tbody > tr:nth-child(odd) {
-    > td,
-    > th {
-      background-color: @table-bg-accent;
-    }
-  }
-}
-
-
-// Hover effect
-//
-// Placed here since it has to come after the potential zebra striping
-
-.table-hover {
-  > tbody > tr:hover {
-    > td,
-    > th {
-      background-color: @table-bg-hover;
-    }
-  }
-}
-
-
-// Table cell sizing
-//
-// Reset default table behavior
-
-table col[class*="col-"] {
-  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)
-  float: none;
-  display: table-column;
-}
-table {
-  td,
-  th {
-    &[class*="col-"] {
-      position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)
-      float: none;
-      display: table-cell;
-    }
-  }
-}
-
-
-// Table backgrounds
-//
-// Exact selectors below required to override `.table-striped` and prevent
-// inheritance to nested tables.
-
-// Generate the contextual variants
-.table-row-variant(active; @table-bg-active);
-.table-row-variant(success; @state-success-bg);
-.table-row-variant(info; @state-info-bg);
-.table-row-variant(warning; @state-warning-bg);
-.table-row-variant(danger; @state-danger-bg);
-
-
-// Responsive tables
-//
-// Wrap your tables in `.table-responsive` and we'll make them mobile friendly
-// by enabling horizontal scrolling. Only applies <768px. Everything above that
-// will display normally.
-
-@media (max-width: @screen-xs-max) {
-  .table-responsive {
-    width: 100%;
-    margin-bottom: (@line-height-computed * 0.75);
-    overflow-y: hidden;
-    overflow-x: scroll;
-    -ms-overflow-style: -ms-autohiding-scrollbar;
-    border: 1px solid @table-border-color;
-    -webkit-overflow-scrolling: touch;
-
-    // Tighten up spacing
-    > .table {
-      margin-bottom: 0;
-
-      // Ensure the content doesn't wrap
-      > thead,
-      > tbody,
-      > tfoot {
-        > tr {
-          > th,
-          > td {
-            white-space: nowrap;
-          }
-        }
-      }
-    }
-
-    // Special overrides for the bordered tables
-    > .table-bordered {
-      border: 0;
-
-      // Nuke the appropriate borders so that the parent can handle them
-      > thead,
-      > tbody,
-      > tfoot {
-        > tr {
-          > th:first-child,
-          > td:first-child {
-            border-left: 0;
-          }
-          > th:last-child,
-          > td:last-child {
-            border-right: 0;
-          }
-        }
-      }
-
-      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since
-      // chances are there will be only one `tr` in a `thead` and that would
-      // remove the border altogether.
-      > tbody,
-      > tfoot {
-        > tr:last-child {
-          > th,
-          > td {
-            border-bottom: 0;
-          }
-        }
-      }
-
-    }
-  }
-}
diff --git a/docs/static/less/bootstrap/theme.less b/docs/static/less/bootstrap/theme.less
deleted file mode 100644
index 6f957fb..0000000
--- a/docs/static/less/bootstrap/theme.less
+++ /dev/null
@@ -1,247 +0,0 @@
-
-//
-// Load core variables and mixins
-// --------------------------------------------------
-
-@import "variables.less";
-@import "mixins.less";
-
-
-
-//
-// Buttons
-// --------------------------------------------------
-
-// Common styles
-.btn-default,
-.btn-primary,
-.btn-success,
-.btn-info,
-.btn-warning,
-.btn-danger {
-  text-shadow: 0 -1px 0 rgba(0,0,0,.2);
-  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);
-  .box-shadow(@shadow);
-
-  // Reset the shadow
-  &:active,
-  &.active {
-    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
-  }
-}
-
-// Mixin for generating new styles
-.btn-styles(@btn-color: #555) {
-  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));
-  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners
-  background-repeat: repeat-x;
-  border-color: darken(@btn-color, 14%);
-
-  &:hover,
-  &:focus  {
-    background-color: darken(@btn-color, 12%);
-    background-position: 0 -15px;
-  }
-
-  &:active,
-  &.active {
-    background-color: darken(@btn-color, 12%);
-    border-color: darken(@btn-color, 14%);
-  }
-}
-
-// Common styles
-.btn {
-  // Remove the gradient for the pressed/active state
-  &:active,
-  &.active {
-    background-image: none;
-  }
-}
-
-// Apply the mixin to the buttons
-.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }
-.btn-primary { .btn-styles(@btn-primary-bg); }
-.btn-success { .btn-styles(@btn-success-bg); }
-.btn-info    { .btn-styles(@btn-info-bg); }
-.btn-warning { .btn-styles(@btn-warning-bg); }
-.btn-danger  { .btn-styles(@btn-danger-bg); }
-
-
-
-//
-// Images
-// --------------------------------------------------
-
-.thumbnail,
-.img-thumbnail {
-  .box-shadow(0 1px 2px rgba(0,0,0,.075));
-}
-
-
-
-//
-// Dropdowns
-// --------------------------------------------------
-
-.dropdown-menu > li > a:hover,
-.dropdown-menu > li > a:focus {
-  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));
-  background-color: darken(@dropdown-link-hover-bg, 5%);
-}
-.dropdown-menu > .active > a,
-.dropdown-menu > .active > a:hover,
-.dropdown-menu > .active > a:focus {
-  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));
-  background-color: darken(@dropdown-link-active-bg, 5%);
-}
-
-
-
-//
-// Navbar
-// --------------------------------------------------
-
-// Default navbar
-.navbar-default {
-  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);
-  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered
-  border-radius: @navbar-border-radius;
-  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);
-  .box-shadow(@shadow);
-
-  .navbar-nav > .active > a {
-    #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));
-    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));
-  }
-}
-.navbar-brand,
-.navbar-nav > li > a {
-  text-shadow: 0 1px 0 rgba(255,255,255,.25);
-}
-
-// Inverted navbar
-.navbar-inverse {
-  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);
-  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered
-
-  .navbar-nav > .active > a {
-    #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));
-    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));
-  }
-
-  .navbar-brand,
-  .navbar-nav > li > a {
-    text-shadow: 0 -1px 0 rgba(0,0,0,.25);
-  }
-}
-
-// Undo rounded corners in static and fixed navbars
-.navbar-static-top,
-.navbar-fixed-top,
-.navbar-fixed-bottom {
-  border-radius: 0;
-}
-
-
-
-//
-// Alerts
-// --------------------------------------------------
-
-// Common styles
-.alert {
-  text-shadow: 0 1px 0 rgba(255,255,255,.2);
-  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);
-  .box-shadow(@shadow);
-}
-
-// Mixin for generating new styles
-.alert-styles(@color) {
-  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));
-  border-color: darken(@color, 15%);
-}
-
-// Apply the mixin to the alerts
-.alert-success    { .alert-styles(@alert-success-bg); }
-.alert-info       { .alert-styles(@alert-info-bg); }
-.alert-warning    { .alert-styles(@alert-warning-bg); }
-.alert-danger     { .alert-styles(@alert-danger-bg); }
-
-
-
-//
-// Progress bars
-// --------------------------------------------------
-
-// Give the progress background some depth
-.progress {
-  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)
-}
-
-// Mixin for generating new styles
-.progress-bar-styles(@color) {
-  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));
-}
-
-// Apply the mixin to the progress bars
-.progress-bar            { .progress-bar-styles(@progress-bar-bg); }
-.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }
-.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }
-.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }
-.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }
-
-
-
-//
-// List groups
-// --------------------------------------------------
-
-.list-group {
-  border-radius: @border-radius-base;
-  .box-shadow(0 1px 2px rgba(0,0,0,.075));
-}
-.list-group-item.active,
-.list-group-item.active:hover,
-.list-group-item.active:focus {
-  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);
-  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));
-  border-color: darken(@list-group-active-border, 7.5%);
-}
-
-
-
-//
-// Panels
-// --------------------------------------------------
-
-// Common styles
-.panel {
-  .box-shadow(0 1px 2px rgba(0,0,0,.05));
-}
-
-// Mixin for generating new styles
-.panel-heading-styles(@color) {
-  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));
-}
-
-// Apply the mixin to the panel headings only
-.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }
-.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }
-.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }
-.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }
-.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }
-.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }
-
-
-
-//
-// Wells
-// --------------------------------------------------
-
-.well {
-  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);
-  border-color: darken(@well-bg, 10%);
-  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);
-  .box-shadow(@shadow);
-}
diff --git a/docs/static/less/bootstrap/thumbnails.less b/docs/static/less/bootstrap/thumbnails.less
deleted file mode 100644
index c428920..0000000
--- a/docs/static/less/bootstrap/thumbnails.less
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// Thumbnails
-// --------------------------------------------------
-
-
-// Mixin and adjust the regular image class
-.thumbnail {
-  display: block;
-  padding: @thumbnail-padding;
-  margin-bottom: @line-height-computed;
-  line-height: @line-height-base;
-  background-color: @thumbnail-bg;
-  border: 1px solid @thumbnail-border;
-  border-radius: @thumbnail-border-radius;
-  .transition(all .2s ease-in-out);
-
-  > img,
-  a > img {
-    &:extend(.img-responsive);
-    margin-left: auto;
-    margin-right: auto;
-  }
-
-  // Add a hover state for linked versions only
-  a&:hover,
-  a&:focus,
-  a&.active {
-    border-color: @link-color;
-  }
-
-  // Image captions
-  .caption {
-    padding: @thumbnail-caption-padding;
-    color: @thumbnail-caption-color;
-  }
-}
diff --git a/docs/static/less/bootstrap/tooltip.less b/docs/static/less/bootstrap/tooltip.less
deleted file mode 100644
index bd62699..0000000
--- a/docs/static/less/bootstrap/tooltip.less
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// Tooltips
-// --------------------------------------------------
-
-
-// Base class
-.tooltip {
-  position: absolute;
-  z-index: @zindex-tooltip;
-  display: block;
-  visibility: visible;
-  font-size: @font-size-small;
-  line-height: 1.4;
-  .opacity(0);
-
-  &.in     { .opacity(@tooltip-opacity); }
-  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }
-  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }
-  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }
-  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }
-}
-
-// Wrapper for the tooltip content
-.tooltip-inner {
-  max-width: @tooltip-max-width;
-  padding: 3px 8px;
-  color: @tooltip-color;
-  text-align: center;
-  text-decoration: none;
-  background-color: @tooltip-bg;
-  border-radius: @border-radius-base;
-}
-
-// Arrows
-.tooltip-arrow {
-  position: absolute;
-  width: 0;
-  height: 0;
-  border-color: transparent;
-  border-style: solid;
-}
-.tooltip {
-  &.top .tooltip-arrow {
-    bottom: 0;
-    left: 50%;
-    margin-left: -@tooltip-arrow-width;
-    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
-    border-top-color: @tooltip-arrow-color;
-  }
-  &.top-left .tooltip-arrow {
-    bottom: 0;
-    left: @tooltip-arrow-width;
-    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
-    border-top-color: @tooltip-arrow-color;
-  }
-  &.top-right .tooltip-arrow {
-    bottom: 0;
-    right: @tooltip-arrow-width;
-    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
-    border-top-color: @tooltip-arrow-color;
-  }
-  &.right .tooltip-arrow {
-    top: 50%;
-    left: 0;
-    margin-top: -@tooltip-arrow-width;
-    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
-    border-right-color: @tooltip-arrow-color;
-  }
-  &.left .tooltip-arrow {
-    top: 50%;
-    right: 0;
-    margin-top: -@tooltip-arrow-width;
-    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
-    border-left-color: @tooltip-arrow-color;
-  }
-  &.bottom .tooltip-arrow {
-    top: 0;
-    left: 50%;
-    margin-left: -@tooltip-arrow-width;
-    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
-    border-bottom-color: @tooltip-arrow-color;
-  }
-  &.bottom-left .tooltip-arrow {
-    top: 0;
-    left: @tooltip-arrow-width;
-    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
-    border-bottom-color: @tooltip-arrow-color;
-  }
-  &.bottom-right .tooltip-arrow {
-    top: 0;
-    right: @tooltip-arrow-width;
-    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
-    border-bottom-color: @tooltip-arrow-color;
-  }
-}
diff --git a/docs/static/less/bootstrap/type.less b/docs/static/less/bootstrap/type.less
deleted file mode 100644
index 5e2a219..0000000
--- a/docs/static/less/bootstrap/type.less
+++ /dev/null
@@ -1,293 +0,0 @@
-//
-// Typography
-// --------------------------------------------------
-
-
-// Headings
-// -------------------------
-
-h1, h2, h3, h4, h5, h6,
-.h1, .h2, .h3, .h4, .h5, .h6 {
-  font-family: @headings-font-family;
-  font-weight: @headings-font-weight;
-  line-height: @headings-line-height;
-  color: @headings-color;
-
-  small,
-  .small {
-    font-weight: normal;
-    line-height: 1;
-    color: @headings-small-color;
-  }
-}
-
-h1, .h1,
-h2, .h2,
-h3, .h3 {
-  margin-top: @line-height-computed;
-  margin-bottom: (@line-height-computed / 2);
-
-  small,
-  .small {
-    font-size: 65%;
-  }
-}
-h4, .h4,
-h5, .h5,
-h6, .h6 {
-  margin-top: (@line-height-computed / 2);
-  margin-bottom: (@line-height-computed / 2);
-
-  small,
-  .small {
-    font-size: 75%;
-  }
-}
-
-h1, .h1 { font-size: @font-size-h1; }
-h2, .h2 { font-size: @font-size-h2; }
-h3, .h3 { font-size: @font-size-h3; }
-h4, .h4 { font-size: @font-size-h4; }
-h5, .h5 { font-size: @font-size-h5; }
-h6, .h6 { font-size: @font-size-h6; }
-
-
-// Body text
-// -------------------------
-
-p {
-  margin: 0 0 (@line-height-computed / 2);
-}
-
-.lead {
-  margin-bottom: @line-height-computed;
-  font-size: floor((@font-size-base * 1.15));
-  font-weight: 200;
-  line-height: 1.4;
-
-  @media (min-width: @screen-sm-min) {
-    font-size: (@font-size-base * 1.5);
-  }
-}
-
-
-// Emphasis & misc
-// -------------------------
-
-// Ex: 14px base font * 85% = about 12px
-small,
-.small  { font-size: 85%; }
-
-// Undo browser default styling
-cite    { font-style: normal; }
-
-// Alignment
-.text-left           { text-align: left; }
-.text-right          { text-align: right; }
-.text-center         { text-align: center; }
-.text-justify        { text-align: justify; }
-
-// Contextual colors
-.text-muted {
-  color: @text-muted;
-}
-.text-primary {
-  .text-emphasis-variant(@brand-primary);
-}
-.text-success {
-  .text-emphasis-variant(@state-success-text);
-}
-.text-info {
-  .text-emphasis-variant(@state-info-text);
-}
-.text-warning {
-  .text-emphasis-variant(@state-warning-text);
-}
-.text-danger {
-  .text-emphasis-variant(@state-danger-text);
-}
-
-// Contextual backgrounds
-// For now we'll leave these alongside the text classes until v4 when we can
-// safely shift things around (per SemVer rules).
-.bg-primary {
-  // Given the contrast here, this is the only class to have its color inverted
-  // automatically.
-  color: #fff;
-  .bg-variant(@brand-primary);
-}
-.bg-success {
-  .bg-variant(@state-success-bg);
-}
-.bg-info {
-  .bg-variant(@state-info-bg);
-}
-.bg-warning {
-  .bg-variant(@state-warning-bg);
-}
-.bg-danger {
-  .bg-variant(@state-danger-bg);
-}
-
-
-// Page header
-// -------------------------
-
-.page-header {
-  padding-bottom: ((@line-height-computed / 2) - 1);
-  margin: (@line-height-computed * 2) 0 @line-height-computed;
-  border-bottom: 1px solid @page-header-border-color;
-}
-
-
-// Lists
-// --------------------------------------------------
-
-// Unordered and Ordered lists
-ul,
-ol {
-  margin-top: 0;
-  margin-bottom: (@line-height-computed / 2);
-  ul,
-  ol {
-    margin-bottom: 0;
-  }
-}
-
-// List options
-
-// Unstyled keeps list items block level, just removes default browser padding and list-style
-.list-unstyled {
-  padding-left: 0;
-  list-style: none;
-}
-
-// Inline turns list items into inline-block
-.list-inline {
-  .list-unstyled();
-  margin-left: -5px;
-
-  > li {
-    display: inline-block;
-    padding-left: 5px;
-    padding-right: 5px;
-  }
-}
-
-// Description Lists
-dl {
-  margin-top: 0; // Remove browser default
-  margin-bottom: @line-height-computed;
-}
-dt,
-dd {
-  line-height: @line-height-base;
-}
-dt {
-  font-weight: bold;
-}
-dd {
-  margin-left: 0; // Undo browser default
-}
-
-// Horizontal description lists
-//
-// Defaults to being stacked without any of the below styles applied, until the
-// grid breakpoint is reached (default of ~768px).
-
-@media (min-width: @grid-float-breakpoint) {
-  .dl-horizontal {
-    dt {
-      float: left;
-      width: (@component-offset-horizontal - 20);
-      clear: left;
-      text-align: right;
-      .text-overflow();
-    }
-    dd {
-      margin-left: @component-offset-horizontal;
-      &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present
-    }
-  }
-}
-
-// MISC
-// ----
-
-// Abbreviations and acronyms
-abbr[title],
-// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
-abbr[data-original-title] {
-  cursor: help;
-  border-bottom: 1px dotted @abbr-border-color;
-}
-.initialism {
-  font-size: 90%;
-  text-transform: uppercase;
-}
-
-// Blockquotes
-blockquote {
-  padding: (@line-height-computed / 2) @line-height-computed;
-  margin: 0 0 @line-height-computed;
-  font-size: @blockquote-font-size;
-  border-left: 5px solid @blockquote-border-color;
-
-  p,
-  ul,
-  ol {
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  // Note: Deprecated small and .small as of v3.1.0
-  // Context: https://github.com/twbs/bootstrap/issues/11660
-  footer,
-  small,
-  .small {
-    display: block;
-    font-size: 80%; // back to default font-size
-    line-height: @line-height-base;
-    color: @blockquote-small-color;
-
-    &:before {
-      content: '\2014 \00A0'; // em dash, nbsp
-    }
-  }
-}
-
-// Opposite alignment of blockquote
-//
-// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.
-.blockquote-reverse,
-blockquote.pull-right {
-  padding-right: 15px;
-  padding-left: 0;
-  border-right: 5px solid @blockquote-border-color;
-  border-left: 0;
-  text-align: right;
-
-  // Account for citation
-  footer,
-  small,
-  .small {
-    &:before { content: ''; }
-    &:after {
-      content: '\00A0 \2014'; // nbsp, em dash
-    }
-  }
-}
-
-// Quotes
-blockquote:before,
-blockquote:after {
-  content: "";
-}
-
-// Addresses
-address {
-  margin-bottom: @line-height-computed;
-  font-style: normal;
-  line-height: @line-height-base;
-}
diff --git a/docs/static/less/bootstrap/utilities.less b/docs/static/less/bootstrap/utilities.less
deleted file mode 100644
index a260312..0000000
--- a/docs/static/less/bootstrap/utilities.less
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Utility classes
-// --------------------------------------------------
-
-
-// Floats
-// -------------------------
-
-.clearfix {
-  .clearfix();
-}
-.center-block {
-  .center-block();
-}
-.pull-right {
-  float: right !important;
-}
-.pull-left {
-  float: left !important;
-}
-
-
-// Toggling content
-// -------------------------
-
-// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1
-.hide {
-  display: none !important;
-}
-.show {
-  display: block !important;
-}
-.invisible {
-  visibility: hidden;
-}
-.text-hide {
-  .text-hide();
-}
-
-
-// Hide from screenreaders and browsers
-//
-// Credit: HTML5 Boilerplate
-
-.hidden {
-  display: none !important;
-  visibility: hidden !important;
-}
-
-
-// For Affix plugin
-// -------------------------
-
-.affix {
-  position: fixed;
-}
diff --git a/docs/static/less/bootstrap/variables.less b/docs/static/less/bootstrap/variables.less
deleted file mode 100644
index 3846adc..0000000
--- a/docs/static/less/bootstrap/variables.less
+++ /dev/null
@@ -1,829 +0,0 @@
-//
-// Variables
-// --------------------------------------------------
-
-
-//== Colors
-//
-//## Gray and brand colors for use across Bootstrap.
-
-@gray-darker:            lighten(#000, 13.5%); // #222
-@gray-dark:              lighten(#000, 20%);   // #333
-@gray:                   lighten(#000, 33.5%); // #555
-@gray-light:             lighten(#000, 60%);   // #999
-@gray-lighter:           lighten(#000, 93.5%); // #eee
-
-@brand-primary:         #428bca;
-@brand-success:         #5cb85c;
-@brand-info:            #5bc0de;
-@brand-warning:         #f0ad4e;
-@brand-danger:          #d9534f;
-
-
-//== Scaffolding
-//
-// ## Settings for some of the most global styles.
-
-//** Background color for `<body>`.
-@body-bg:               #fff;
-//** Global text color on `<body>`.
-@text-color:            @gray-dark;
-
-//** Global textual link color.
-@link-color:            @brand-primary;
-//** Link hover color set via `darken()` function.
-@link-hover-color:      darken(@link-color, 15%);
-
-
-//== Typography
-//
-//## Font, line-height, and color for body text, headings, and more.
-
-@font-family-sans-serif:  "Helvetica Neue", Helvetica, Arial, sans-serif;
-@font-family-serif:       Georgia, "Times New Roman", Times, serif;
-//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
-@font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace;
-@font-family-base:        @font-family-sans-serif;
-
-@font-size-base:          14px;
-@font-size-large:         ceil((@font-size-base * 1.25)); // ~18px
-@font-size-small:         ceil((@font-size-base * 0.85)); // ~12px
-
-@font-size-h1:            floor((@font-size-base * 2.6)); // ~36px
-@font-size-h2:            floor((@font-size-base * 2.15)); // ~30px
-@font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px
-@font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px
-@font-size-h5:            @font-size-base;
-@font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px
-
-//** Unit-less `line-height` for use in components like buttons.
-@line-height-base:        1.428571429; // 20/14
-//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-@line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px
-
-//** By default, this inherits from the `<body>`.
-@headings-font-family:    inherit;
-@headings-font-weight:    500;
-@headings-line-height:    1.1;
-@headings-color:          inherit;
-
-
-//-- Iconography
-//
-//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.
-
-@icon-font-path:          "../fonts/";
-@icon-font-name:          "glyphicons-halflings-regular";
-@icon-font-svg-id:        "glyphicons_halflingsregular";
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-@padding-base-vertical:     6px;
-@padding-base-horizontal:   12px;
-
-@padding-large-vertical:    10px;
-@padding-large-horizontal:  16px;
-
-@padding-small-vertical:    5px;
-@padding-small-horizontal:  10px;
-
-@padding-xs-vertical:       1px;
-@padding-xs-horizontal:     5px;
-
-@line-height-large:         1.33;
-@line-height-small:         1.5;
-
-@border-radius-base:        4px;
-@border-radius-large:       6px;
-@border-radius-small:       3px;
-
-//** Global color for active items (e.g., navs or dropdowns).
-@component-active-color:    #fff;
-//** Global background color for active items (e.g., navs or dropdowns).
-@component-active-bg:       @brand-primary;
-
-//** Width of the `border` for generating carets that indicator dropdowns.
-@caret-width-base:          4px;
-//** Carets increase slightly in size for larger components.
-@caret-width-large:         5px;
-
-
-//== Tables
-//
-//## Customizes the `.table` component with basic values, each used across all table variations.
-
-//** Padding for `<th>`s and `<td>`s.
-@table-cell-padding:            8px;
-//** Padding for cells in `.table-condensed`.
-@table-condensed-cell-padding:  5px;
-
-//** Default background color used for all tables.
-@table-bg:                      transparent;
-//** Background color used for `.table-striped`.
-@table-bg-accent:               #f9f9f9;
-//** Background color used for `.table-hover`.
-@table-bg-hover:                #f5f5f5;
-@table-bg-active:               @table-bg-hover;
-
-//** Border color for table and cell borders.
-@table-border-color:            #ddd;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-@btn-font-weight:                normal;
-
-@btn-default-color:              #333;
-@btn-default-bg:                 #fff;
-@btn-default-border:             #ccc;
-
-@btn-primary-color:              #fff;
-@btn-primary-bg:                 @brand-primary;
-@btn-primary-border:             darken(@btn-primary-bg, 5%);
-
-@btn-success-color:              #fff;
-@btn-success-bg:                 @brand-success;
-@btn-success-border:             darken(@btn-success-bg, 5%);
-
-@btn-info-color:                 #fff;
-@btn-info-bg:                    @brand-info;
-@btn-info-border:                darken(@btn-info-bg, 5%);
-
-@btn-warning-color:              #fff;
-@btn-warning-bg:                 @brand-warning;
-@btn-warning-border:             darken(@btn-warning-bg, 5%);
-
-@btn-danger-color:               #fff;
-@btn-danger-bg:                  @brand-danger;
-@btn-danger-border:              darken(@btn-danger-bg, 5%);
-
-@btn-link-disabled-color:        @gray-light;
-
-
-//== Forms
-//
-//##
-
-//** `<input>` background color
-@input-bg:                       #fff;
-//** `<input disabled>` background color
-@input-bg-disabled:              @gray-lighter;
-
-//** Text color for `<input>`s
-@input-color:                    @gray;
-//** `<input>` border color
-@input-border:                   #ccc;
-//** `<input>` border radius
-@input-border-radius:            @border-radius-base;
-//** Border color for inputs on focus
-@input-border-focus:             #66afe9;
-
-//** Placeholder text color
-@input-color-placeholder:        @gray-light;
-
-//** Default `.form-control` height
-@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);
-//** Large `.form-control` height
-@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
-//** Small `.form-control` height
-@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
-
-@legend-color:                   @gray-dark;
-@legend-border-color:            #e5e5e5;
-
-//** Background color for textual input addons
-@input-group-addon-bg:           @gray-lighter;
-//** Border color for textual input addons
-@input-group-addon-border-color: @input-border;
-
-
-//== Dropdowns
-//
-//## Dropdown menu container and contents.
-
-//** Background for the dropdown menu.
-@dropdown-bg:                    #fff;
-//** Dropdown menu `border-color`.
-@dropdown-border:                rgba(0,0,0,.15);
-//** Dropdown menu `border-color` **for IE8**.
-@dropdown-fallback-border:       #ccc;
-//** Divider color for between dropdown items.
-@dropdown-divider-bg:            #e5e5e5;
-
-//** Dropdown link text color.
-@dropdown-link-color:            @gray-dark;
-//** Hover color for dropdown links.
-@dropdown-link-hover-color:      darken(@gray-dark, 5%);
-//** Hover background for dropdown links.
-@dropdown-link-hover-bg:         #f5f5f5;
-
-//** Active dropdown menu item text color.
-@dropdown-link-active-color:     @component-active-color;
-//** Active dropdown menu item background color.
-@dropdown-link-active-bg:        @component-active-bg;
-
-//** Disabled dropdown menu item background color.
-@dropdown-link-disabled-color:   @gray-light;
-
-//** Text color for headers within dropdown menus.
-@dropdown-header-color:          @gray-light;
-
-// Note: Deprecated @dropdown-caret-color as of v3.1.0
-@dropdown-caret-color:           #000;
-
-
-//-- Z-index master list
-//
-// Warning: Avoid customizing these values. They're used for a bird's eye view
-// of components dependent on the z-axis and are designed to all work together.
-//
-// Note: These variables are not generated into the Customizer.
-
-@zindex-navbar:            1000;
-@zindex-dropdown:          1000;
-@zindex-popover:           1010;
-@zindex-tooltip:           1030;
-@zindex-navbar-fixed:      1030;
-@zindex-modal-background:  1040;
-@zindex-modal:             1050;
-
-
-//== Media queries breakpoints
-//
-//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
-
-// Extra small screen / phone
-// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1
-@screen-xs:                  480px;
-@screen-xs-min:              @screen-xs;
-@screen-phone:               @screen-xs-min;
-
-// Small screen / tablet
-// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1
-@screen-sm:                  768px;
-@screen-sm-min:              @screen-sm;
-@screen-tablet:              @screen-sm-min;
-
-// Medium screen / desktop
-// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1
-@screen-md:                  992px;
-@screen-md-min:              @screen-md;
-@screen-desktop:             @screen-md-min;
-
-// Large screen / wide desktop
-// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1
-@screen-lg:                  1200px;
-@screen-lg-min:              @screen-lg;
-@screen-lg-desktop:          @screen-lg-min;
-
-// So media queries don't overlap when required, provide a maximum
-@screen-xs-max:              (@screen-sm-min - 1);
-@screen-sm-max:              (@screen-md-min - 1);
-@screen-md-max:              (@screen-lg-min - 1);
-
-
-//== Grid system
-//
-//## Define your custom responsive grid.
-
-//** Number of columns in the grid.
-@grid-columns:              12;
-//** Padding between columns. Gets divided in half for the left and right.
-@grid-gutter-width:         30px;
-// Navbar collapse
-//** Point at which the navbar becomes uncollapsed.
-@grid-float-breakpoint:     @screen-sm-min;
-//** Point at which the navbar begins collapsing.
-@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
-
-
-//== Container sizes
-//
-//## Define the maximum width of `.container` for different screen sizes.
-
-// Small screen / tablet
-@container-tablet:             ((720px + @grid-gutter-width));
-//** For `@screen-sm-min` and up.
-@container-sm:                 @container-tablet;
-
-// Medium screen / desktop
-@container-desktop:            ((940px + @grid-gutter-width));
-//** For `@screen-md-min` and up.
-@container-md:                 @container-desktop;
-
-// Large screen / wide desktop
-@container-large-desktop:      ((1140px + @grid-gutter-width));
-//** For `@screen-lg-min` and up.
-@container-lg:                 @container-large-desktop;
-
-
-//== Navbar
-//
-//##
-
-// Basics of a navbar
-@navbar-height:                    50px;
-@navbar-margin-bottom:             @line-height-computed;
-@navbar-border-radius:             @border-radius-base;
-@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));
-@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);
-@navbar-collapse-max-height:       340px;
-
-@navbar-default-color:             #777;
-@navbar-default-bg:                #f8f8f8;
-@navbar-default-border:            darken(@navbar-default-bg, 6.5%);
-
-// Navbar links
-@navbar-default-link-color:                #777;
-@navbar-default-link-hover-color:          #333;
-@navbar-default-link-hover-bg:             transparent;
-@navbar-default-link-active-color:         #555;
-@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);
-@navbar-default-link-disabled-color:       #ccc;
-@navbar-default-link-disabled-bg:          transparent;
-
-// Navbar brand label
-@navbar-default-brand-color:               @navbar-default-link-color;
-@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);
-@navbar-default-brand-hover-bg:            transparent;
-
-// Navbar toggle
-@navbar-default-toggle-hover-bg:           #ddd;
-@navbar-default-toggle-icon-bar-bg:        #888;
-@navbar-default-toggle-border-color:       #ddd;
-
-
-// Inverted navbar
-// Reset inverted navbar basics
-@navbar-inverse-color:                      @gray-light;
-@navbar-inverse-bg:                         #222;
-@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);
-
-// Inverted navbar links
-@navbar-inverse-link-color:                 @gray-light;
-@navbar-inverse-link-hover-color:           #fff;
-@navbar-inverse-link-hover-bg:              transparent;
-@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;
-@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);
-@navbar-inverse-link-disabled-color:        #444;
-@navbar-inverse-link-disabled-bg:           transparent;
-
-// Inverted navbar brand label
-@navbar-inverse-brand-color:                @navbar-inverse-link-color;
-@navbar-inverse-brand-hover-color:          #fff;
-@navbar-inverse-brand-hover-bg:             transparent;
-
-// Inverted navbar toggle
-@navbar-inverse-toggle-hover-bg:            #333;
-@navbar-inverse-toggle-icon-bar-bg:         #fff;
-@navbar-inverse-toggle-border-color:        #333;
-
-
-//== Navs
-//
-//##
-
-//=== Shared nav styles
-@nav-link-padding:                          10px 15px;
-@nav-link-hover-bg:                         @gray-lighter;
-
-@nav-disabled-link-color:                   @gray-light;
-@nav-disabled-link-hover-color:             @gray-light;
-
-@nav-open-link-hover-color:                 #fff;
-
-//== Tabs
-@nav-tabs-border-color:                     #ddd;
-
-@nav-tabs-link-hover-border-color:          @gray-lighter;
-
-@nav-tabs-active-link-hover-bg:             @body-bg;
-@nav-tabs-active-link-hover-color:          @gray;
-@nav-tabs-active-link-hover-border-color:   #ddd;
-
-@nav-tabs-justified-link-border-color:            #ddd;
-@nav-tabs-justified-active-link-border-color:     @body-bg;
-
-//== Pills
-@nav-pills-border-radius:                   @border-radius-base;
-@nav-pills-active-link-hover-bg:            @component-active-bg;
-@nav-pills-active-link-hover-color:         @component-active-color;
-
-
-//== Pagination
-//
-//##
-
-@pagination-color:                     @link-color;
-@pagination-bg:                        #fff;
-@pagination-border:                    #ddd;
-
-@pagination-hover-color:               @link-hover-color;
-@pagination-hover-bg:                  @gray-lighter;
-@pagination-hover-border:              #ddd;
-
-@pagination-active-color:              #fff;
-@pagination-active-bg:                 @brand-primary;
-@pagination-active-border:             @brand-primary;
-
-@pagination-disabled-color:            @gray-light;
-@pagination-disabled-bg:               #fff;
-@pagination-disabled-border:           #ddd;
-
-
-//== Pager
-//
-//##
-
-@pager-bg:                             @pagination-bg;
-@pager-border:                         @pagination-border;
-@pager-border-radius:                  15px;
-
-@pager-hover-bg:                       @pagination-hover-bg;
-
-@pager-active-bg:                      @pagination-active-bg;
-@pager-active-color:                   @pagination-active-color;
-
-@pager-disabled-color:                 @pagination-disabled-color;
-
-
-//== Jumbotron
-//
-//##
-
-@jumbotron-padding:              30px;
-@jumbotron-color:                inherit;
-@jumbotron-bg:                   @gray-lighter;
-@jumbotron-heading-color:        inherit;
-@jumbotron-font-size:            ceil((@font-size-base * 1.5));
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-@state-success-text:             #3c763d;
-@state-success-bg:               #dff0d8;
-@state-success-border:           darken(spin(@state-success-bg, -10), 5%);
-
-@state-info-text:                #31708f;
-@state-info-bg:                  #d9edf7;
-@state-info-border:              darken(spin(@state-info-bg, -10), 7%);
-
-@state-warning-text:             #8a6d3b;
-@state-warning-bg:               #fcf8e3;
-@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);
-
-@state-danger-text:              #a94442;
-@state-danger-bg:                #f2dede;
-@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);
-
-
-//== Tooltips
-//
-//##
-
-//** Tooltip max width
-@tooltip-max-width:           200px;
-//** Tooltip text color
-@tooltip-color:               #fff;
-//** Tooltip background color
-@tooltip-bg:                  #000;
-@tooltip-opacity:             .9;
-
-//** Tooltip arrow width
-@tooltip-arrow-width:         5px;
-//** Tooltip arrow color
-@tooltip-arrow-color:         @tooltip-bg;
-
-
-//== Popovers
-//
-//##
-
-//** Popover body background color
-@popover-bg:                          #fff;
-//** Popover maximum width
-@popover-max-width:                   276px;
-//** Popover border color
-@popover-border-color:                rgba(0,0,0,.2);
-//** Popover fallback border color
-@popover-fallback-border-color:       #ccc;
-
-//** Popover title background color
-@popover-title-bg:                    darken(@popover-bg, 3%);
-
-//** Popover arrow width
-@popover-arrow-width:                 10px;
-//** Popover arrow color
-@popover-arrow-color:                 #fff;
-
-//** Popover outer arrow width
-@popover-arrow-outer-width:           (@popover-arrow-width + 1);
-//** Popover outer arrow color
-@popover-arrow-outer-color:           fadein(@popover-border-color, 5%);
-//** Popover outer arrow fallback color
-@popover-arrow-outer-fallback-color:  darken(@popover-fallback-border-color, 20%);
-
-
-//== Labels
-//
-//##
-
-//** Default label background color
-@label-default-bg:            @gray-light;
-//** Primary label background color
-@label-primary-bg:            @brand-primary;
-//** Success label background color
-@label-success-bg:            @brand-success;
-//** Info label background color
-@label-info-bg:               @brand-info;
-//** Warning label background color
-@label-warning-bg:            @brand-warning;
-//** Danger label background color
-@label-danger-bg:             @brand-danger;
-
-//** Default label text color
-@label-color:                 #fff;
-//** Default text color of a linked label
-@label-link-hover-color:      #fff;
-
-
-//== Modals
-//
-//##
-
-//** Padding applied to the modal body
-@modal-inner-padding:         20px;
-
-//** Padding applied to the modal title
-@modal-title-padding:         15px;
-//** Modal title line-height
-@modal-title-line-height:     @line-height-base;
-
-//** Background color of modal content area
-@modal-content-bg:                             #fff;
-//** Modal content border color
-@modal-content-border-color:                   rgba(0,0,0,.2);
-//** Modal content border color **for IE8**
-@modal-content-fallback-border-color:          #999;
-
-//** Modal backdrop background color
-@modal-backdrop-bg:           #000;
-//** Modal backdrop opacity
-@modal-backdrop-opacity:      .5;
-//** Modal header border color
-@modal-header-border-color:   #e5e5e5;
-//** Modal footer border color
-@modal-footer-border-color:   @modal-header-border-color;
-
-@modal-lg:                    900px;
-@modal-md:                    600px;
-@modal-sm:                    300px;
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-@alert-padding:               15px;
-@alert-border-radius:         @border-radius-base;
-@alert-link-font-weight:      bold;
-
-@alert-success-bg:            @state-success-bg;
-@alert-success-text:          @state-success-text;
-@alert-success-border:        @state-success-border;
-
-@alert-info-bg:               @state-info-bg;
-@alert-info-text:             @state-info-text;
-@alert-info-border:           @state-info-border;
-
-@alert-warning-bg:            @state-warning-bg;
-@alert-warning-text:          @state-warning-text;
-@alert-warning-border:        @state-warning-border;
-
-@alert-danger-bg:             @state-danger-bg;
-@alert-danger-text:           @state-danger-text;
-@alert-danger-border:         @state-danger-border;
-
-
-//== Progress bars
-//
-//##
-
-//** Background color of the whole progress component
-@progress-bg:                 #f5f5f5;
-//** Progress bar text color
-@progress-bar-color:          #fff;
-
-//** Default progress bar color
-@progress-bar-bg:             @brand-primary;
-//** Success progress bar color
-@progress-bar-success-bg:     @brand-success;
-//** Warning progress bar color
-@progress-bar-warning-bg:     @brand-warning;
-//** Danger progress bar color
-@progress-bar-danger-bg:      @brand-danger;
-//** Info progress bar color
-@progress-bar-info-bg:        @brand-info;
-
-
-//== List group
-//
-//##
-
-//** Background color on `.list-group-item`
-@list-group-bg:                 #fff;
-//** `.list-group-item` border color
-@list-group-border:             #ddd;
-//** List group border radius
-@list-group-border-radius:      @border-radius-base;
-
-//** Background color of single list elements on hover
-@list-group-hover-bg:           #f5f5f5;
-//** Text color of active list elements
-@list-group-active-color:       @component-active-color;
-//** Background color of active list elements
-@list-group-active-bg:          @component-active-bg;
-//** Border color of active list elements
-@list-group-active-border:      @list-group-active-bg;
-@list-group-active-text-color:  lighten(@list-group-active-bg, 40%);
-
-@list-group-link-color:         #555;
-@list-group-link-heading-color: #333;
-
-
-//== Panels
-//
-//##
-
-@panel-bg:                    #fff;
-@panel-body-padding:          15px;
-@panel-border-radius:         @border-radius-base;
-
-//** Border color for elements within panels
-@panel-inner-border:          #ddd;
-@panel-footer-bg:             #f5f5f5;
-
-@panel-default-text:          @gray-dark;
-@panel-default-border:        #ddd;
-@panel-default-heading-bg:    #f5f5f5;
-
-@panel-primary-text:          #fff;
-@panel-primary-border:        @brand-primary;
-@panel-primary-heading-bg:    @brand-primary;
-
-@panel-success-text:          @state-success-text;
-@panel-success-border:        @state-success-border;
-@panel-success-heading-bg:    @state-success-bg;
-
-@panel-info-text:             @state-info-text;
-@panel-info-border:           @state-info-border;
-@panel-info-heading-bg:       @state-info-bg;
-
-@panel-warning-text:          @state-warning-text;
-@panel-warning-border:        @state-warning-border;
-@panel-warning-heading-bg:    @state-warning-bg;
-
-@panel-danger-text:           @state-danger-text;
-@panel-danger-border:         @state-danger-border;
-@panel-danger-heading-bg:     @state-danger-bg;
-
-
-//== Thumbnails
-//
-//##
-
-//** Padding around the thumbnail image
-@thumbnail-padding:           4px;
-//** Thumbnail background color
-@thumbnail-bg:                @body-bg;
-//** Thumbnail border color
-@thumbnail-border:            #ddd;
-//** Thumbnail border radius
-@thumbnail-border-radius:     @border-radius-base;
-
-//** Custom text color for thumbnail captions
-@thumbnail-caption-color:     @text-color;
-//** Padding around the thumbnail caption
-@thumbnail-caption-padding:   9px;
-
-
-//== Wells
-//
-//##
-
-@well-bg:                     #f5f5f5;
-@well-border:                 darken(@well-bg, 7%);
-
-
-//== Badges
-//
-//##
-
-@badge-color:                 #fff;
-//** Linked badge text color on hover
-@badge-link-hover-color:      #fff;
-@badge-bg:                    @gray-light;
-
-//** Badge text color in active nav link
-@badge-active-color:          @link-color;
-//** Badge background color in active nav link
-@badge-active-bg:             #fff;
-
-@badge-font-weight:           bold;
-@badge-line-height:           1;
-@badge-border-radius:         10px;
-
-
-//== Breadcrumbs
-//
-//##
-
-@breadcrumb-padding-vertical:   8px;
-@breadcrumb-padding-horizontal: 15px;
-//** Breadcrumb background color
-@breadcrumb-bg:                 #f5f5f5;
-//** Breadcrumb text color
-@breadcrumb-color:              #ccc;
-//** Text color of current page in the breadcrumb
-@breadcrumb-active-color:       @gray-light;
-//** Textual separator for between breadcrumb elements
-@breadcrumb-separator:          "/";
-
-
-//== Carousel
-//
-//##
-
-@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);
-
-@carousel-control-color:                      #fff;
-@carousel-control-width:                      15%;
-@carousel-control-opacity:                    .5;
-@carousel-control-font-size:                  20px;
-
-@carousel-indicator-active-bg:                #fff;
-@carousel-indicator-border-color:             #fff;
-
-@carousel-caption-color:                      #fff;
-
-
-//== Close
-//
-//##
-
-@close-font-weight:           bold;
-@close-color:                 #000;
-@close-text-shadow:           0 1px 0 #fff;
-
-
-//== Code
-//
-//##
-
-@code-color:                  #c7254e;
-@code-bg:                     #f9f2f4;
-
-@kbd-color:                   #fff;
-@kbd-bg:                      #333;
-
-@pre-bg:                      #f5f5f5;
-@pre-color:                   @gray-dark;
-@pre-border-color:            #ccc;
-@pre-scrollable-max-height:   340px;
-
-
-//== Type
-//
-//##
-
-//** Text muted color
-@text-muted:                  @gray-light;
-//** Abbreviations and acronyms border color
-@abbr-border-color:           @gray-light;
-//** Headings small color
-@headings-small-color:        @gray-light;
-//** Blockquote small color
-@blockquote-small-color:      @gray-light;
-//** Blockquote font size
-@blockquote-font-size:        (@font-size-base * 1.25);
-//** Blockquote border color
-@blockquote-border-color:     @gray-lighter;
-//** Page header border color
-@page-header-border-color:    @gray-lighter;
-
-
-//== Miscellaneous
-//
-//##
-
-//** Horizontal line color.
-@hr-border:                   @gray-lighter;
-
-//** Horizontal offset for forms and lists.
-@component-offset-horizontal: 180px;
diff --git a/docs/static/less/bootstrap/wells.less b/docs/static/less/bootstrap/wells.less
deleted file mode 100644
index 15d072b..0000000
--- a/docs/static/less/bootstrap/wells.less
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Wells
-// --------------------------------------------------
-
-
-// Base class
-.well {
-  min-height: 20px;
-  padding: 19px;
-  margin-bottom: 20px;
-  background-color: @well-bg;
-  border: 1px solid @well-border;
-  border-radius: @border-radius-base;
-  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
-  blockquote {
-    border-color: #ddd;
-    border-color: rgba(0,0,0,.15);
-  }
-}
-
-// Sizes
-.well-lg {
-  padding: 24px;
-  border-radius: @border-radius-large;
-}
-.well-sm {
-  padding: 9px;
-  border-radius: @border-radius-small;
-}
diff --git a/docs/static/less/pouchdb/alerts.less b/docs/static/less/pouchdb/alerts.less
deleted file mode 100644
index 2e80354..0000000
--- a/docs/static/less/pouchdb/alerts.less
+++ /dev/null
@@ -1,44 +0,0 @@
-@import "@{bootstrap}/alerts.less";
-
-.alert { .clearfix(); }
-
-.alert-text { .make-xs-column(10); }
-
-.alert:before {
-  float: left;
-  display: block;
-  content: '';
-  height: @alert-before-size;
-  width: @alert-before-size;
-  border-radius: 50%;
-  border: 1px solid;
-  font-size: @alert-before-size * .75;
-  font-family: @font-family-monospace;
-  text-align: center;
-  line-height: @alert-before-size;
-}
-
-.alert-info:before {
-  content: @alert-before-info-text;
-  border-color: @alert-info-border;
-  background-color: lighten(@alert-info-bg, 3%);
-  color: @alert-info-text;
-}
-.alert-success:before {
-  content: @alert-before-success-text;
-  border-color: @alert-success-border;
-  background-color: lighten(@alert-success-bg, 3%);
-  color: @alert-success-text;
-}
-.alert-warning:before {
-  content: @alert-before-warning-text;
-  border-color: @alert-warning-border;
-  background-color: lighten(@alert-warning-bg, 3%);
-  color: @alert-warning-text;
-}
-.alert-danger:before {
-  content: @alert-before-danger-text;
-  border-color: @alert-danger-border;
-  background-color: lighten(@alert-danger-bg, 3%);
-  color: @alert-danger-text;
-}
diff --git a/docs/static/less/pouchdb/anchors.less b/docs/static/less/pouchdb/anchors.less
deleted file mode 100644
index 57803b0..0000000
--- a/docs/static/less/pouchdb/anchors.less
+++ /dev/null
@@ -1,17 +0,0 @@
-.anchor {
-  &.h1,
-  &.h2,
-  &.h3,
-  &.h4,
-  &.h5,
-  &.h6 {
-    display: inline-block;
-    text-decoration: none;
-  }
-
-  &::before {
-    content: '# ';
-    opacity: .25;
-  }
-  &:focus { outline: none; }
-}
\ No newline at end of file
diff --git a/docs/static/less/pouchdb/block.less b/docs/static/less/pouchdb/block.less
deleted file mode 100644
index 2b734b4..0000000
--- a/docs/static/less/pouchdb/block.less
+++ /dev/null
@@ -1,13 +0,0 @@
-.block {
-  @media (max-width: @screen-md-min) {
-    > h1, > h2, > h3, > h4, > h5, > h6,
-    > .h1, > .h2, > .h3, > .h4, > .h5, > .h6,
-    > p {
-      text-align: center;
-    }
-    > p {
-      margin: 0 auto;
-      max-width: 60%;
-    }
-  }
-}
\ No newline at end of file
diff --git a/docs/static/less/pouchdb/buttons.less b/docs/static/less/pouchdb/buttons.less
deleted file mode 100644
index afb12bc..0000000
--- a/docs/static/less/pouchdb/buttons.less
+++ /dev/null
@@ -1,49 +0,0 @@
-@import "@{bootstrap}/buttons.less";
-
-.btn {
-  .button-size(@padding-base-vertical; @padding-large-horizontal*2; @font-size-base; @line-height-base; @border-radius-base);
-}
-
-.btn-lg {
-  .button-size(@padding-large-vertical; @padding-large-horizontal*2; @font-size-large; @line-height-large; @border-radius-large);
-}
-.btn-sm {
-  .button-size(@padding-small-vertical; @padding-small-horizontal*2; @font-size-small; @line-height-small; @border-radius-small);
-}
-.btn-xs {
-  .button-size(@padding-xs-vertical; @padding-xs-horizontal*2; @font-size-small; @line-height-small; @border-radius-small);
-}
-
-// Social button variants
-.btn-github {
-  .button-variant(@btn-github-color; @btn-github-bg; @btn-github-border);
-}
-.btn-twitter {
-  .button-variant(@btn-twitter-color; @btn-twitter-bg; @btn-twitter-border);
-}
-
-@media (max-width: @screen-xs-max) {
-  .btn {
-    width: 100%;
-  }
-}
-
-// Notification button-variant
-.btn-update {
-  z-index: 1000;
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  margin: auto;
-  width: 25em;
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-  text-align: center;
-  transition: opacity .5s, transform .25s;
-}
-.btn-update-hidden {
-  pointer-events: none;
-  opacity: 0;
-  transform: translateY(-100%);
-}
diff --git a/docs/static/less/pouchdb/code.less b/docs/static/less/pouchdb/code.less
deleted file mode 100644
index a5feb85..0000000
--- a/docs/static/less/pouchdb/code.less
+++ /dev/null
@@ -1,10 +0,0 @@
-@import "@{bootstrap}/code.less";
-
-code {
-  white-space: normal;
-}
-
-pre {
-  padding-left: @pre-padding;
-  padding-right: @pre-padding;
-}
diff --git a/docs/static/less/pouchdb/header.less b/docs/static/less/pouchdb/header.less
deleted file mode 100644
index 529e721..0000000
--- a/docs/static/less/pouchdb/header.less
+++ /dev/null
@@ -1,8 +0,0 @@
-header {
-  overflow-x: hidden;
-  position: relative;
-  padding: 25px 0;
-  border-bottom: 2px solid;
-  border-color: @header-border-color;
-  background-color: @header-color;
-}
\ No newline at end of file
diff --git a/docs/static/less/pouchdb/highlight.less b/docs/static/less/pouchdb/highlight.less
deleted file mode 100644
index 7b3307b..0000000
--- a/docs/static/less/pouchdb/highlight.less
+++ /dev/null
@@ -1,71 +0,0 @@
-.highlight {
-  pre {
-    background-color: #3f3f3f;
-
-    border: none;
-    border-radius: @border-radius-base;
-  }
-
-  code,
-  pre{ color: #ffffff; }
-
-  .hll { background-color: #3e403d }
-  .c { color: #75715e }
-  .err { color: #960050; background-color: #1e0010 }
-  .k { color: #66d9ef }
-  .l { color: #ae81ff }
-  .n { color: #f8f8f2 }
-  .o { color: #f92672 }
-  .p { color: #f8f8f2 }
-  .cm { color: #75715e }
-  .cp { color: #75715e }
-  .c1 { color: #75715e }
-  .cs { color: #75715e }
-  .ge { font-style: italic }
-  .gs { font-weight: bold }
-  .kc { color: #66d9ef }
-  .kd { color: #66d9ef }
-  .kn { color: #f92672 }
-  .kp { color: #66d9ef }
-  .kr { color: #66d9ef }
-  .kt { color: #66d9ef }
-  .ld { color: #e6db74 }
-  .m { color: #ae81ff }
-  .s { color: #e6db74 }
-  .na { color: #a6e22e }
-  .nb { color: #f8f8f2 }
-  .nc { color: #a6e22e }
-  .no { color: #66d9ef }
-  .nd { color: #a6e22e }
-  .ni { color: #f8f8f2 }
-  .ne { color: #a6e22e }
-  .nf { color: #a6e22e }
-  .nl { color: #f8f8f2 }
-  .nn { color: #f8f8f2 }
-  .nx { color: #6eca97 }
-  .py { color: #f8f8f2 }
-  .nt { color: #f92672 }
-  .nv { color: #f8f8f2 }
-  .ow { color: #f92672 }
-  .w { color: #f8f8f2 }
-  .mf { color: #ae81ff }
-  .mh { color: #ae81ff }
-  .mi { color: #ae81ff }
-  .mo { color: #ae81ff }
-  .sb { color: #e6db74 }
-  .sc { color: #e6db74 }
-  .sd { color: #e6db74 }
-  .s2 { color: #e6db74 }
-  .se { color: #ae81ff }
-  .sh { color: #e6db74 }
-  .si { color: #e6db74 }
-  .sx { color: #e6db74 }
-  .sr { color: #e6db74 }
-  .s1 { color: #e6db74 }
-  .ss { color: #e6db74 }
-  .bp { color: #f8f8f2 }
-  .vc { color: #f8f8f2 }
-  .vg { color: #f8f8f2 }
-  .vi { color: #f8f8f2 }
-  .il { color: #ae81ff }
-}
diff --git a/docs/static/less/pouchdb/icon-edit.less b/docs/static/less/pouchdb/icon-edit.less
deleted file mode 100644
index b5826f5..0000000
--- a/docs/static/less/pouchdb/icon-edit.less
+++ /dev/null
@@ -1,8 +0,0 @@
-.icon-edit {
-  display: inline-block;
-  height: .75em;
-  width: .75em;
-  margin-left: .2em;
-  background-size: 100%;
-  background-image: url('../img/icon-edit.svg');
-}
diff --git a/docs/static/less/pouchdb/icons.less b/docs/static/less/pouchdb/icons.less
deleted file mode 100644
index b56aa31..0000000
--- a/docs/static/less/pouchdb/icons.less
+++ /dev/null
@@ -1,94 +0,0 @@
-.icon {
-  margin: 0 auto;
-  margin-top: @grid-gutter-width;
-  background-image: url("@{img_dir}/icons.svg");
-  background-repeat: no-repeat;
-
-  & ~ * { text-align: center; }
-
-  &-twitter,
-  &-couchdb,
-  &-github,
-  &-travis,
-  &-leveldb,
-  &-saucelabs {
-    opacity: .75;
-    &:hover { opacity: 1; }
-  }
-
-  &-node {
-    background-position: 0;
-    width: 68px;
-    height: 73px;
-  }
-
-  &-light  {
-    background-position: -73px -1px;
-    width: 92px;
-    height: 85px;
-  }
-
-  &-learn {
-    background-position: -170px 0;
-    width: 92px;
-    height: 87px;
-  }
-  &-open {
-    background-position: -267px -5px;
-    width: 111px;
-    height: 77px;
-  }
-  &-twitter {
-    background-position: -388px -24px;
-    width: 46px;
-    height: 39px;
-  }
-  &-couchdb {
-    background-position: -439px -15px;
-    width: 90px;
-    height: 57px;
-  }
-  &-github {
-    background-position: -537px -22px;
-    width: 45px;
-    height: 43px;
-  }
-  &-travis {
-    background-position: -589px -20px;
-    width: 45px;
-    height: 43px;
-  }
-  &-leveldb {
-    background-position: -640px -20px;
-    width: 40px;
-    height: 43px;
-  }
-  &-saucelabs {
-    background-position: -686px -22px;
-    width: 45px;
-    height: 43px;
-  }
-
-  @media (max-width: @screen-sm-min) {
-    &-node,
-    &-light,
-    &-learn,
-    &-open {
-     height: 70px;
-     width: 67px;
-     background-size: 500px;
-     + * { margin-top: 0; }
-    }
-    &-node {
-      height: 60px;
-      width: 50px;
-      background-position: 0 0;
-    }
-    &-light { background-position: -50px 0; }
-    &-learn { background-position: -117px 0; }
-    &-open {
-      background-position: -181px 0;
-      width: 85px;
-    }
-  }
-}
diff --git a/docs/static/less/pouchdb/logo.less b/docs/static/less/pouchdb/logo.less
deleted file mode 100644
index 892e99f..0000000
--- a/docs/static/less/pouchdb/logo.less
+++ /dev/null
@@ -1,49 +0,0 @@
-.logo {
-  float: left;
-  width: @logo-width;
-  .logo-img,
-  .logo-type {
-    float: left;
-  }
-  .logo-img {
-    opacity: .9;
-    height: @logo-img-height;
-    margin-top: -@logo-img-height*.2;
-    width: @logo-img-height*@logo-img-ratio;
-    background-image: url(@logo-img);
-    background-size: 100%;
-  }
-  .logo-type {
-    margin-left: 8px;
-    font-size: 3em;
-    line-height: 1.1;
-    text-transform: lowercase;
-    letter-spacing: -1px;
-    color: @text-color;
-  }
-  &:hover .logo-img { opacity: 1; }
-  .clearfix();
-}
-/**
- * When we hit the breakpoint
- * Center the logo in the middle
- **/
-@media (max-width: @navs-breakpoint-justified) {
-  .logo {
-    float: none;
-    display: block;
-    margin: auto;
-  }
-}
-@media (max-width: @logo-breakpoint) {
-  .logo {
-    width: auto;
-    .logo-img {
-      display: block;
-      float: none;
-      margin: auto;
-    }
-    .logo-type { display: none; }
-  }
-
-}
diff --git a/docs/static/less/pouchdb/mixins.less b/docs/static/less/pouchdb/mixins.less
deleted file mode 100644
index 861a24c..0000000
--- a/docs/static/less/pouchdb/mixins.less
+++ /dev/null
@@ -1,22 +0,0 @@
-@import "@{bootstrap}/mixins.less";
-
-// Intrinsic Ratio Helper
-// https://github.com/nickcolley/intrinsic-ratio-less
-
-
-// Intrinsic ratio
-.ir(@ratio: 16/9, @width: 100%, @margin: auto) {
-	position: relative;
-	margin: @margin;
-	width: unit(@width, ~'%');
-	height: 0;
-	padding-bottom: unit(@width / @ratio, ~'%');
-	> iframe {
-		position: absolute;
-		width: 100%;
-		height: 100%;
-    border: 0;
-	}
-}
-
-.iframe-responsive { .ir(); }
diff --git a/docs/static/less/pouchdb/navs.less b/docs/static/less/pouchdb/navs.less
deleted file mode 100644
index d0b24fb..0000000
--- a/docs/static/less/pouchdb/navs.less
+++ /dev/null
@@ -1,97 +0,0 @@
-@import "@{bootstrap}/navs.less";
-
-.nav-header {
-  float: right;
-  > li { min-width: 100px; }
-}
-.nav-silent {
-  > li > a {
-    padding: .1em 0;
-    color: @text-color;
-  }
-}
-
-/**
- * Sidebar navigation used in learn.html
- **/
- @media (min-width: @screen-sm-min) {
-  .nav-sidebar-wrapper {
-   position: -webkit-sticky;
-   position: sticky;
-   top: 1em;
-  }
-}
-
-.nav-sidebar {
-  > li.active > a,
-  > li > a:hover {
-    color: darken(@brand-primary, 10%);
-    border-right: 2px solid lighten(@brand-primary, 10%);
-    padding-right: 10px;
-  }
-}
-
-@media (max-width: @navs-breakpoint-justified) {
-  .nav-header {
-     width: 100%;
-    > li {
-      float: none;
-      display: table-cell;
-      width: 1%;
-      min-width: initial;
-      > a { text-align: center; }
-    }
-  }
-}
-
-@media (max-width: @navs-breakpoint-horizontal) {
-  .nav-header > li:last-child {
-    float: left;
-    width: 100%;
-  }
-}
-
-@media (max-width: @logo-breakpoint) {
-  .nav-header > li {
-    float: left;
-    width: 100%;
-  }
-}
-
-@media (max-width: @screen-sm-min) {
-  .nav.nav-sidebar { margin-bottom: 25px; }
-  .nav-head,
-  .nav.nav-sidebar { text-align: center; }
-}
-
-
-.nav-code {
-  border-bottom: none;
-}
-.nav-code > li {
-  float: right;
-}
-.nav-code > li > a {
-  outline: 0;
-  padding: .5em .75em;
-  margin-right: 0;
-  margin-left: 1px;
-  font-size: .8em;
-  line-height: 1.3;
-}
-.nav-code > li.active > a,
-.nav-code > li.active > a:hover,
-.nav-code > li.active > a:focus {
-  border-color: #3f3f3f;
-  background: #3f3f3f;
-  color: #eee;
-  padding-bottom: 15px;
-  margin-bottom: -15px;
-}
-.nav-code > li > a:hover {
-  border-color: transparent;
-}
-.nav-code + .tab-content pre {
-  padding-top: 15px;
-  padding-bottom: 15px;
-}
diff --git a/docs/static/less/pouchdb/post.less b/docs/static/less/pouchdb/post.less
deleted file mode 100644
index 9beea5e..0000000
--- a/docs/static/less/pouchdb/post.less
+++ /dev/null
@@ -1,5 +0,0 @@
-.post {
-  margin-top: 10px;
-  margin-bottom: 40px;
-  &:last-of-type { margin-bottom: 10px; }
-}
\ No newline at end of file
diff --git a/docs/static/less/pouchdb/pouchdb.less b/docs/static/less/pouchdb/pouchdb.less
deleted file mode 100644
index 8c8e0c9..0000000
--- a/docs/static/less/pouchdb/pouchdb.less
+++ /dev/null
@@ -1,47 +0,0 @@
-@bootstrap: "../bootstrap";
-
-@import "variables.less";
-
-// Mixins
-@import "mixins.less";
-
-// Reset
-@import "@{bootstrap}/normalize.less";
-@import "@{bootstrap}/print.less";
-@import "@{bootstrap}/type.less";
-
-@import "@{bootstrap}/normalize.less";
-@import "@{bootstrap}/print.less";
-@import "alerts.less";
-
-// Core CSS
-@import "scaffolding.less";
-@import "code.less";
-@import "@{bootstrap}/grid.less";
-@import "@{bootstrap}/tables.less";
-
-
-// Components
-@import "@{bootstrap}/media.less";
-@import "@{bootstrap}/pagination.less";
-@import "@{bootstrap}/pager.less";
-@import "@{bootstrap}/tooltip.less";
-
-// Utility classes
-@import "@{bootstrap}/responsive-utilities.less";
-
-// PouchDB Overrides
-@import "navs.less";
-@import "buttons.less";
-@import "utilities.less";
-
-// PouchDB Specific
-@import "highlight.less";
-@import "header.less";
-@import "logo.less";
-@import "anchors.less";
-@import "post.less";
-@import "ribbon.less";
-@import "icons.less";
-@import "block.less";
-@import "icon-edit.less";
diff --git a/docs/static/less/pouchdb/ribbon.less b/docs/static/less/pouchdb/ribbon.less
deleted file mode 100644
index 149734f..0000000
--- a/docs/static/less/pouchdb/ribbon.less
+++ /dev/null
@@ -1,14 +0,0 @@
-.ribbon {
-    z-index: 1;
-    position: absolute;
-    top: 0; right: 0;
-    padding: .1em 3em;
-    border: 1px solid rgba(0,0,0,.1);
-    background-color: @gray-lighter;
-    color: @text-color;
-    font-weight: bold;
-    -webkit-transform: translateX(75%) rotate(45deg) translateX(-30%);
-    transform: translateX(75%) rotate(45deg) translateX(-30%);
-    -webkit-transform-origin: top left;
-    transform-origin: top left;
-}
\ No newline at end of file
diff --git a/docs/static/less/pouchdb/scaffolding.less b/docs/static/less/pouchdb/scaffolding.less
deleted file mode 100644
index 0aad31b..0000000
--- a/docs/static/less/pouchdb/scaffolding.less
+++ /dev/null
@@ -1,32 +0,0 @@
-@import "@{bootstrap}/scaffolding.less";
-
-blockquote {
-  font-size: 1.1em;
-  border-left-color: #ddf3e7;
-  cite { font-size: 1.2em; }
-}
-
-// Temporary fix for Jekyll's P tags all over the place. :/
-p:empty { display: none; }
-
-.intro,
-.infoblocks,
-.icons,
-.footer {
-  padding: 20px 0 30px;
-}
-.page-head { padding: 10px 0 20px; }
-
-article { padding: 20px 0 75px; }
-
-.page-head,
-.intro,
-.blog,
-.footer {
-  background-color: @gray-lighter;
-}
-
-.intro .highlight { margin-top: 2em; }
-.icons { border-top: 20px solid @gray-lighter; }
-
-.page-title { display: inline-block; }
diff --git a/docs/static/less/pouchdb/utilities.less b/docs/static/less/pouchdb/utilities.less
deleted file mode 100644
index 77450a8..0000000
--- a/docs/static/less/pouchdb/utilities.less
+++ /dev/null
@@ -1,21 +0,0 @@
-@import "@{bootstrap}/utilities.less";
-
-.affix {
-  padding: 1em 0;
-  position: static;
-}
-
-@media (min-width: @affix-min-width) and (min-height: @affix-min-height) {
-
-  .affix { position: fixed; }
-
-  .affix,
-  .affix-top {
-    top: 0;
-  }
-
-  .affix-top,
-  .affix-bottom {
-    position: absolute;
-  }
-}
diff --git a/docs/static/less/pouchdb/variables.less b/docs/static/less/pouchdb/variables.less
deleted file mode 100644
index 389ca8a..0000000
--- a/docs/static/less/pouchdb/variables.less
+++ /dev/null
@@ -1,69 +0,0 @@
-@import "@{bootstrap}/variables.less";
-
-// Base img dir
-@img_dir: "../img";
-
-// Color
-@brand-accent: #fa3649;
-@brand-primary: #6ccb99;
-@twitter: cornflowerblue;
-@github: darkslategray;
-
-// Social colors
-@btn-twitter-color: lighten(@twitter, 25%);
-@btn-twitter-bg: @twitter;
-@btn-twitter-border: darken(@twitter, 10%);
-@btn-github-color: lighten(@github, 50%);
-@btn-github-bg: @github;
-@btn-github-border: darken(@github, 10%);
-
-// Scaffolding
-@body-bg: #f6f6f6;
-@text-color: @gray;
-
-// Container sizes
-@container-large-desktop: ((950px + @grid-gutter-width));
-
-// Code
-@code-color: darken(@brand-primary, 30%);
-@code-bg: lighten(@brand-primary, 30%);
-
-// Type
-@font-family-sans-serif: "Open Sans", Helvetica, Arial, sans-serif;
-
-@link-color: @brand-accent;
-@nav-link-hover-bg: none;
-
-@headings-font-family: "Lato", Helvetica, Arial, sans-serif;
-@header-color: #ffffff;
-@header-border-color: #c8c8c8;
-
-// Logo
-@logo-img: '@{img_dir}/mark.svg';
-@logo-fallback-img: '@{img_dir}/mark.png';
-@logo-img-ratio: .78;
-@logo-img-height: 70px;
-@logo-width: 250px;
-// When it gets silly small display only the mark.
-@logo-breakpoint: 330px;
-
-// Navs
-
-// Switch nav into justified view
-@navs-breakpoint-justified: @screen-sm-max;
-// Switch nav into horizontal view
-@navs-breakpoint-horizontal: 510px;
-
-// Minimum width and height for fixed sidebars
-@affix-min-width: @screen-sm-min;
-@affix-min-height: 475px;
-
-// Alerts
-@alert-before-size: 35px;
-@alert-before-info-text: 'i';
-@alert-before-success-text: '\2713';
-@alert-before-warning-text: '!';
-@alert-before-danger-text: 'x';
-
-// Pre
-@pre-padding: 15px;
diff --git a/docs/users.md b/docs/users.md
deleted file mode 100644
index eb35b04..0000000
--- a/docs/users.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-layout: 2ColLeft
-title: Who's using PouchDB?
-sidebar: nav.html
----
-
-A list of known products and services that are using PouchDB.
-
-## BikeCommute
-
-[BikeCommute](https://github.com/autonome/bikecommute) is a FirefoxOS app that registers an NFC tag to track bike commuters in the Mozilla Portland office. Built using Famo.us, PouchDB, and CouchDB. See [a video of it in action](https://youtu.be/3BVZYcQ-TYA) or [read about it on Mozilla Hacks](https://hacks.mozilla.org/2014/11/nfc-in-firefox-os/).
-
-## Cloudwall
-
-{% include img.html width=200 src="cloudwall.png" alt="Cloudwall" %}
-
-[Cloudwall](http://cloudwall.me/) is an operating system for noBackend webapps, based on CouchDB and PouchDB.
-
-## Cozy Cloud
-
-{% include img.html width=125 src="cozy.png" alt="Cozy Cloud" %}
-
-[Cozy](https://cozy.io/en/) is a personal cloud that you can host, customize, and fully control. It syncs contacts, calendars, and files between your personal devices and server. Under the hood, it leverages CouchDB and PouchDB.
-
-## Delta
-[Delta](http://delta.octavore.com/) is a command-line utility for text diffs. View split diffs in the browser with syntax highlighting, or in the command-line using the --cli flag.
-
-## eHealth Africa
-
-{% include img.html width=200 src="ehealth_africa.png" alt="eHealth Africa" %}
-
-[eHealth Africa](http://ehealthafrica.org/) is an American-Nigerian NGO specialising in the development and deployment of tech for health. To tackle the Ebola outbreak, they built [mobile apps and dashboards](https://github.com/eHealthAfrica) to help track the spread of infection in the field. The combination of CouchDB and PouchDB enabled these apps to work consistently despite the extreme network unreliability of sub-saharan Africa.
-
-## Hoodie
-
-{% include img.html width=150 src="HoodieLogo.png" alt="Hoodie" href="http://hood.ie/" %}
-
-[Hoodie](http://hood.ie/) provides a complete backend solution for your frontend code. It helps you develop your web application fast and easy. Hoodie-based apps are [offline-first](http://offlinefirst.org/) so they are usable anytime. Just plug Hoodie’s API into your frontend code, and your app is ready.
-
-{% include svg/hospitalrun-logo.html %}
-
-[HospitalRun](http://hospitalrun.io/) is an open source software product designed specifically for developing world hospitals, making usability the key requirement. Using PouchDB and offline-first design, HospitalRun allows records to be carried to remote clinics, functioning when there is no Internet, and syncing when there is.
-
-## Local NPM
-
-[Local NPM](https://github.com/nolanlawson/local-npm) allows you to easily set up a local NPM server that caches data from the real NPM and updates in realtime. The goal is to cut down network request time by moving data closer to the client. Built using Node.js, LevelDB, and PouchDB.
-
-## Lullabot
-
-[Lullabot](https://www.lullabot.com) is an interactive strategy, design, and development company. We create delightful experiences using Drupal and open source technologies. Our main website is using Drupal as the back-end for content management, CouchDB with PouchDB for the API, and ReactJS for the front-end.
-
-## MBTA Alerts
-
-{% include img.html width=100 src="mbta_alerts.jpeg" alt="MBTA Alerts" %}
-
-[MBTA Alerts](https://twitter.com/MBTA_Alerts) is a Twitter bot that thousands of Bostonians depend upon to be notified of delays in the MBTA transit system. Uses Node.js, PouchDB, and CouchDB.
-
-## NPM Browser
-
-[NPM Browser](http://www.npm-browser.com/#/) is a fully offline cache of NPM packages, which runs in your browser, using Angular.js, PouchDB, and the pouchdb-load plugin.
-
-## Pokedex.org
-
-{% include img.html width=100 src="pokedexorg-logo.png" alt="Pokedex.org logo" %}
-
-[Pokedex.org](https://www.pokedex.org/) [(Github)](https://github.com/nolanlawson/pokedex.org) is a progressive web app, powered by ServiceWorker, PouchDB, virtual-dom, and web workers.
-
-## Squarespace Blog
-
-{% include img.html width=100 src="squarespace_blog.png" alt="Squarespace Blog" %}
-
-Squarespace Blog is an [Android](https://play.google.com/store/apps/details?id=com.squarespace.android.blog) and [iOS app](https://itunes.apple.com/us/app/squarespace-blog/id715084234) that gives you the tools you need to write and edit posts on multiple Squarespace websites. It uses PouchDB attachments inside a WebView for fast offline images.
-
-## Story-writer
-
-Story-writer is a free Markdown editor, with a [web version](http://markdown.xiaoshujiang.com) and [NW.js client version](http://soft.xiaoshujiang.com), built using Node.js, NW.js, LevelDB, and PouchDB.
-
-## Thali project
-
-[Thali](http://thaliproject.org/) is a Microsoft-sponsored open-source platform for creating apps that exploit the power of personal devices and put people in control of their data. It uses Cordova, PouchDB, OpenSSL, and Tor.
-
-## YLD
-
-[YLD](http://www.yld.io) is a Node.js software engineering, consulting and training company. We partner with enterprises to strengthen their software engineering culture and create the agility necessary to compete in today’s market, and are responsible for some of the largest Node.js solutions in production today. PouchDB allows us to create responsive, resilient and sync-enabled web applications.
diff --git a/package.json b/package.json
index 131f155..5574ae0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "pouchdb",
-  "version": "5.3.3-prerelease",
+  "version": "5.3.2",
   "description": "PouchDB is a pocket-sized database.",
   "main": "./lib/index.js",
   "homepage": "http://pouchdb.com/",
diff --git a/scripts/baldrick-test.sh b/scripts/baldrick-test.sh
deleted file mode 100755
index 87982d0..0000000
--- a/scripts/baldrick-test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash -x
-
-# Run PouchDB test suite, expect a global couchdb command to be installed
-#
-# Run as:
-#
-# ./scripts/baldrick-test.sh
-
-# tmp directory to store CouchDB data files
-TMP=./tmp
-COUCH_URI_FILE=$TMP/couch.uri
-
-# Install PouchDB dependancies
-npm install
-
-# Provision a CouchDB instance just for this test
-./scripts/start_standalone_couch.sh $TMP > /dev/null 2>&1 &
-COUCH_PID=$!
-
-# Wait for CouchDB to start by polling for the uri file
-# Not nasty at all :)
-while [ ! -f $COUCH_URI_FILE ]
-do
-  sleep 2
-done
-COUCH_HOST=$(cat $COUCH_URI_FILE)
-
-# Run tests
-grunt test --couch-host=$COUCH_HOST
-EXIT_STATUS=$?
-
-# Cleanup
-kill $COUCH_PID
-
-# Make sure we exit with the right status
-exit $EXIT_STATUS
\ No newline at end of file
diff --git a/scripts/bundle-browserify-test.sh b/scripts/bundle-browserify-test.sh
deleted file mode 100755
index 0496e03..0000000
--- a/scripts/bundle-browserify-test.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-echo '<!DOCTYPE html><html>' > test.html
-echo "<head><meta charset='utf-8'></head>" >> test.html
-echo "<script type=\"text/javascript\">" >> test.html
-browserify $1 >> test.html
-echo "</script></html>" >> test.html
\ No newline at end of file
diff --git a/scripts/jenkins-deploy.sh b/scripts/jenkins-deploy.sh
deleted file mode 100644
index 1c93914..0000000
--- a/scripts/jenkins-deploy.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-ROOT=$(pwd)
-
-# Build the docs
-cd $ROOT/docs
-jekyll
-
-# Publish docs
-cp -R $ROOT/docs/_site/* /home/daleharvey/www/pouchdb.com
-
-# Build
-cd $ROOT
-npm install
-
-grunt
-grunt spatial
-grunt gql
-
-cp $ROOT/dist/* /home/daleharvey/www/download.pouchdb.com
\ No newline at end of file
diff --git a/scripts/start_standalone_couch.sh b/scripts/start_standalone_couch.sh
deleted file mode 100755
index c263954..0000000
--- a/scripts/start_standalone_couch.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash -e
-
-# Start a standalone CouchDB, this is a wrapper around the $ couchdb
-# command that will create a standalone instance of CouchDB allowing
-# you to easily run serveral servers in parallel, each instance starts
-# on an ephemeral port and has a dedicated directory for its data and logs
-# use the couch.uri file to locate the host
-#
-# Run as:
-#
-# $ ./start_standalone_couch.sh ~/data/instanceId
-
-COUCH_DIR=$1
-
-# Make all the directories
-mkdir -p $COUCH_DIR/data/views
-
-# Create a standalone configuration based on the directory
-# we are passed in, CouchDB will start on a random port and couch.uri
-# will tell us where that is, data is stored within the directory
-echo "[httpd]
-bind_address = 127.0.0.1
-port = 0
-
-[log]
-level = debug
-file = $COUCH_DIR/couch.log
-
-[couchdb]
-database_dir = $COUCH_DIR/data
-view_index_dir = $COUCH_DIR/data/views
-uri_file = $COUCH_DIR/couch.uri" > $COUCH_DIR/couch.ini
-
-couchdb -a $COUCH_DIR/couch.ini
\ No newline at end of file
diff --git a/tests/capacity/index.html b/tests/capacity/index.html
deleted file mode 100644
index 5aa2726..0000000
--- a/tests/capacity/index.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<html>
-  <head>
-    <title>Pouch DB Capacity Tests</title>
-    <script src="../../dist/pouchdb.js"></script>
-  </head>
-  <body>
-
-    <div><h1>Check your console logs to see what's going on.</h1></div>
-
-    <script>
-      var db,
-          test = { iteration: 0, delay:100, docSize:500000 };
-
-      var delayedIteration = function(delay) {
-        if(!delay) delay = test.delay;
-        setTimeout(iterate, delay);
-      };
-
-      var iterate = function() {
-        console.log('iterating: ' + ++test.iteration);
-        addRandomDoc(test.docSize, delayedIteration);
-      };
-
-      var uuid = function() {
-        console.log('generating uuid...');
-        // from https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
-        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
-          var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
-          return v.toString(16);
-        });
-        console.log('uuid generated.');
-        return uuid;
-      };
-
-      var randomString = function(length) {
-        var s = '', add;
-        while(length > 0) {
-          add = Math.random().toString(36).substring(2, 2+Math.min(10, length));
-          length -= add.length;
-          s += add;
-        }
-        console.log('string generated.');
-        return s;
-      };
-
-      var addRandomDoc = function(len, successCallback) {
-        console.log('adding a random doc of len: ' + len + '...');
-        var doc = { content:randomString(len), _id:uuid() };
-        console.log('putting ...');
-        db.put(doc, function(err, res) {
-          if (err) {
-            console.error(err);
-            if (err.reason === 'QuotaExceededError') {
-              console.log('Received expected write failure, passing tests');
-              document.body.innerHTML = ':) Tests passed';
-            }
-            return;
-          }
-          console.log('Document add was successful.');
-          if(successCallback) successCallback();
-        });
-      };
-
-      console.log('dropping database...');
-      db = new PouchDB('test');
-      db.destroy(function(err, res) {
-        if(err) return console.log('[drop]' + err);
-        console.log('database dropped.  Starting puts...');
-        db = new PouchDB('test');
-        delayedIteration(0);
-     });
-    </script>
-  </body>
-</html>
diff --git a/tests/common-utils.js b/tests/common-utils.js
deleted file mode 100644
index 30948e6..0000000
--- a/tests/common-utils.js
+++ /dev/null
@@ -1,67 +0,0 @@
-'use strict';
-
-var commonUtils = {};
-
-// This is a duplicate of the function in integration/utils.js but the
-// current test set up makes it really hard to share that function. Since
-// we are apparently going to refactor the tests for now we'll just copy the
-// function in two places.
-commonUtils.params = function () {
-  if (commonUtils.isNode()) {
-    return process.env;
-  }
-  var paramStr = document.location.search.slice(1);
-  return paramStr.split('&').reduce(function (acc, val) {
-    if (!val) {
-      return acc;
-    }
-    var tmp = val.split('=');
-    acc[tmp[0]] = decodeURIComponent(tmp[1]) || true;
-    return acc;
-  }, {});
-};
-
-commonUtils.couchHost = function () {
-  if (typeof window !== 'undefined' && window.cordova) {
-    // magic route to localhost on android emulator
-    return 'http://10.0.2.2:5984';
-  }
-
-  if (typeof window !== 'undefined' && window.COUCH_HOST) {
-    return window.COUCH_HOST;
-  }
-
-  if (typeof process !== 'undefined' && process.env.COUCH_HOST) {
-    return process.env.COUCH_HOST;
-  }
-
-  if ('couchHost' in commonUtils.params()) {
-    return commonUtils.params().couchHost;
-  }
-
-  return 'http://localhost:5984';
-};
-
-commonUtils.safeRandomDBName = function () {
-  return "test" + Math.random().toString().replace('.', '_');
-};
-
-commonUtils.createDocId = function (i) {
-  var intString = i.toString();
-  while (intString.length < 10) {
-    intString = '0' + intString;
-  }
-  return 'doc_' + intString;
-};
-
-commonUtils.isNode = function () {
-  // First part taken from
-  // http://timetler.com/2012/10/13/environment-detection-in-javascript/
-  // The !process.browser check is needed to see if we are in browserify
-  // which actually will pass the first part.
-  return typeof exports !== 'undefined' &&
-          this.exports !== exports &&
-          !process.browser;
-};
-
-module.exports = commonUtils;
diff --git a/tests/component/test.auth.js b/tests/component/test.auth.js
deleted file mode 100644
index 48f0ee4..0000000
--- a/tests/component/test.auth.js
+++ /dev/null
@@ -1,50 +0,0 @@
-'use strict';
-
-var http = require('http');
-var PouchDB = require('../../lib');
-var should = require("chai").should();
-
-describe('test.auth.js', function () {
-
-  var server;
-  var headers;
-  var PORT = 9615;
-
-  before(function (done) {
-    server = http.createServer(function (req, res) {
-      headers = req.headers;
-      res.writeHead(200, {'Content-Type': 'text/plain'});
-      res.end('');
-    });
-    server.listen(PORT, done);
-  });
-
-  after(function () {
-    return server.close();
-  });
-
-  it('Test auth headers are sent correctly', function () {
-    var opts = {auth: {username: 'foo', password: 'bar'}};
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url, opts).info().then(function () {
-      should.equal(headers.authorization, 'Basic Zm9vOmJhcg==');
-    });
-  });
-
-  it('Test auth headers via url are sent correctly', function () {
-    var url = 'http://foo:bar@127.0.0.1:' + PORT;
-    return new PouchDB(url).info().then(function () {
-      should.equal(headers.authorization, 'Basic Zm9vOmJhcg==');
-    });
-  });
-
-  it('Test auth with unicode', function () {
-    var opts = {auth: {username: 'Иванов И.И.', password: 'Секрет'}};
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url, opts).info().then(function () {
-      should.equal(headers.authorization,
-                   'Basic 0JjQstCw0L3QvtCyINCYLtCYLjrQodC10LrRgNC10YI=');
-    });
-  });
-
-});
diff --git a/tests/component/test.headers.js b/tests/component/test.headers.js
deleted file mode 100644
index 41d1920..0000000
--- a/tests/component/test.headers.js
+++ /dev/null
@@ -1,100 +0,0 @@
-'use strict';
-
-var http = require('http');
-var PouchDB = require('../../lib');
-var should = require("chai").should();
-
-describe('test.headers.js', function () {
-
-  var server;
-  var headers;
-  var PORT = 9615;
-
-  before(function (done) {
-    server = http.createServer(function (req, res) {
-      headers = req.headers;
-      res.writeHead(200, {'Content-Type': 'application/json'});
-      res.end('[]');
-    });
-    server.listen(PORT, done);
-  });
-
-  after(function () {
-    return server.close();
-  });
-
-  it('Test headers are sent correctly', function () {
-    var opts = {ajax: {headers: {foo: 'bar'}}};
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url, opts).info().then(function () {
-      should.equal(headers.foo, 'bar');
-    });
-  });
-
-  it('Test auth params are sent correctly', function () {
-    var opts = {auth: {username: 'foo', password: 'bar'}};
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url, opts).info().then(function () {
-      should.equal(typeof headers.authorization, 'string');
-    });
-  });
-
-  it('Test headers are sent correctly on GET request', function () {
-    var db = new PouchDB('http://127.0.0.1:' + PORT);
-    var opts = { ajax: { headers: { ick: "slick" } } };
-    return db.get('fake', opts).then(function () {
-      should.equal(headers.ick, 'slick');
-    });
-  });
-
-  it('3491 Test headers are sent correctly on put', function () {
-    var db = new PouchDB('http://127.0.0.1:' + PORT);
-    var opts = { ajax: { headers: { ick: "slick" } } };
-    return db.post({'fake': 'obj'}, opts).then(function () {
-      should.equal(headers.ick, 'slick');
-    });
-  });
-
-  it('3491 Test headers are sent correctly on changes', function () {
-    var db = new PouchDB('http://127.0.0.1:' + PORT);
-    var opts = { ajax: { headers: { ick: "slick" } } };
-    return db.changes(opts).then(function () {
-      should.equal(headers.ick, 'slick');
-    });
-  });
-
-  it('3491 Test headers are sent correctly on destroy', function () {
-    var db = new PouchDB('http://127.0.0.1:' + PORT);
-    var opts = { ajax: { headers: { ick: "slick" } } };
-    return db.destroy(opts).then(function () {
-      should.equal(headers.ick, 'slick');
-    });
-  });
-
-  it('Test that we combine local and global ajax options', function () {
-    var opts = { ajax: { headers: { aheader: 'whyyes' } } };
-    var db = new PouchDB('http://127.0.0.1:' + PORT, opts);
-    var getOpts = {ajax: { headers: { ick: "slick", aheader: "override!" } } };
-    return db.get('fake', getOpts).then(function () {
-      should.equal(headers.ick, 'slick');
-      should.equal(headers.aheader, 'override!');
-    });
-  });
-
-  it('4450 Test headers are sent correctly on put', function () {
-    var opts = {auth: {username: 'foo', password: 'bar'}};
-    var db = new PouchDB('http://127.0.0.1:' + PORT, opts);
-    return db.put({
-      _id: 'doc',
-      _attachments: {
-        'att.txt': {
-          content_type: 'text/plain',
-          data: new Buffer(['Is there life on Mars?'], {type: 'text/plain'})
-        }
-      }
-    }).then(function () {
-      should.equal(headers.authorization, 'Basic Zm9vOmJhcg==');
-    });
-  });
-
-});
diff --git a/tests/component/test.params.js b/tests/component/test.params.js
deleted file mode 100644
index df9ef50..0000000
--- a/tests/component/test.params.js
+++ /dev/null
@@ -1,56 +0,0 @@
-'use strict';
-
-var http = require('http');
-var url = require('url');
-
-var PouchDB = require('../../lib');
-var should = require("chai").should();
-
-describe('test.params.js', function () {
-
-  var server;
-  var params;
-  var PORT = 9615;
-
-  before(function (done) {
-    server = http.createServer(function (req, res) {
-      params = url.parse(req.url,true).query;
-      res.writeHead(200, {'Content-Type': 'text/plain'});
-      res.end('');
-    });
-    server.listen(PORT, done);
-  });
-
-  after(function () {
-    return server.close();
-  });
-
-  it('Test default heartbeat', function () {
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url).changes().then(function () {
-      should.exist(params.heartbeat);
-    });
-  });
-
-  it('Test custom heartbeat', function () {
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url).changes({heartbeat: 10}).then(function () {
-      should.equal(params.heartbeat, '10');
-    });
-  });
-
-  it('Test disable heartbeat', function () {
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url).changes({heartbeat: false}).then(function () {
-      should.not.exist(params.heartbeat);
-    });
-  });
-
-  it('Test disable timeout', function () {
-    var url = 'http://127.0.0.1:' + PORT;
-    return new PouchDB(url).changes({timeout: false}).then(function () {
-      should.not.exist(params.timeout);
-    });
-  });
-
-});
diff --git a/tests/component/test.read_only_replication.js b/tests/component/test.read_only_replication.js
deleted file mode 100644
index 4256d56..0000000
--- a/tests/component/test.read_only_replication.js
+++ /dev/null
@@ -1,76 +0,0 @@
-'use strict';
-
-var PouchDB = require('../../lib');
-var Checkpointer = require('../../lib/extras/checkpointer');
-
-var express = require('express');
-var bodyParser = require('body-parser');
-
-var app = express();
-
-app.use(bodyParser.json());
-
-var replicationDoc;
-
-function reject(req, res) {
-  replicationDoc = req.body.docs[0];
-  res.status(403).send({error: true, message: 'Unauthorized'});
-}
-
-app.post('*', reject);
-app.delete('*', reject);
-app.put('*', reject);
-app.use(require('pouchdb-express-router')(PouchDB));
-
-require('chai').should();
-
-describe('test.read_only_replication.js', function () {
-  var server;
-
-  before(function () {
-    server = app.listen(0);
-  });
-
-  after(function () {
-    return server.close();
-  });
-
-  it('Test checkpointer handles error codes', function () {
-    var db = new PouchDB('test');
-
-    // These are the same, but one goes over HTTP so that we have the
-    // above access control
-    var remote = new PouchDB('remote');
-    var remoteHTTP = new PouchDB('http://127.0.0.1:' + server.address().port +
-                                 '/remote');
-
-    var expectedLastSeq;
-    var checkpointer;
-
-    return remote.bulkDocs([{_id: 'foo'}, {_id: 'bar'}]).then(function () {
-      return db.replicate.from(remoteHTTP);
-    }).then(function (replicationResult) {
-      expectedLastSeq = replicationResult.last_seq;
-      checkpointer = new Checkpointer(remoteHTTP, db, replicationDoc._id,
-                                      replicationResult);
-
-      return checkpointer.getCheckpoint().then(function (actualLastSeq) {
-        actualLastSeq.should.equal(expectedLastSeq);
-      });
-    }).then(function () {
-      return remote.destroy();
-    }).then(function () {
-      // By now, the checkpointer should have marked the source database
-      // read-only, and make no other request to read or write a
-      // replication log from or rather to it. We therefore expect
-      // `checkpointer.getCheckpoint()` to resolve with the same result
-      // as previously, even though the source database has now been
-      // destroyed.
-      return checkpointer.getCheckpoint().then(function (actualLastSeq) {
-        actualLastSeq.should.equal(expectedLastSeq);
-      });
-    }).then(function () {
-      return db.destroy();
-    });
-  });
-});
diff --git a/tests/extras/test.extras.js b/tests/extras/test.extras.js
deleted file mode 100644
index 0d57b03..0000000
--- a/tests/extras/test.extras.js
+++ /dev/null
@@ -1,41 +0,0 @@
-'use strict';
-
-var should = require('chai').should();
-
-describe('test.extras.js', function () {
-
-  it('extras/ajax should exist', function () {
-    var ajax = require('../../extras/ajax');
-    should.exist(ajax);
-    ajax.should.be.a('function');
-    ajax.name.should.equal('ajax');
-  });
-
-  it('extras/checkpointer should exist', function () {
-    var checkpointer = require('../../extras/checkpointer');
-    should.exist(checkpointer);
-    checkpointer.should.be.a('function');
-    checkpointer.name.should.equal('Checkpointer');
-  });
-
-  it('extras/promise should exist', function () {
-    var promise = require('../../extras/promise');
-    should.exist(promise);
-    promise.should.be.a('function');
-    promise.name.should.equal('Promise');
-  });
-
-  it('extras/generateReplicationId should exist', function () {
-    var genReplicationId = require('../../extras/generateReplicationId');
-    should.exist(genReplicationId);
-    genReplicationId.should.be.a('function');
-    genReplicationId.name.should.equal('generateReplicationId');
-  });
-
-  it('plugin extras should exist', function () {
-    require('../../extras/memory').should.be.a('object');
-    require('../../extras/localstorage').should.be.a('object');
-    require('../../extras/fruitdown').should.be.a('object');
-  });
-
-});
\ No newline at end of file
diff --git a/tests/fuzzy/index.html b/tests/fuzzy/index.html
deleted file mode 100644
index 472d31e..0000000
--- a/tests/fuzzy/index.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Mocha</title>
-    <link rel="stylesheet" type="text/css" href="../../node_modules/mocha/mocha.css">
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script src="../../node_modules/mocha/mocha.js"></script>
-    <script src="../../node_modules/chai/chai.js"></script>
-    <script>
-      mocha.setup({ui: 'bdd'});
-      var should = chai.should();
-    </script>
-    <script src="../integration/utils.js"></script>
-    <script src="./seedrandom.min.js"></script>
-    <script src="./test.fuzzy.js"></script>
-    <script type="text/javascript" src="../integration/webrunner.js"></script>
-  </body>
-</html>
diff --git a/tests/fuzzy/seedrandom.min.js b/tests/fuzzy/seedrandom.min.js
deleted file mode 100644
index 0f938c1..0000000
--- a/tests/fuzzy/seedrandom.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(a,b){function c(c,j,k){var n=[];j=1==j?{entropy:!0}:j||{};var s=g(f(j.entropy?[c,i(a)]:null==c?h():c,3),n),t=new d(n),u=function(){for(var a=t.g(m),b=p,c=0;q>a;)a=(a+c)*l,b*=l,c=t.g(1);for(;a>=r;)a/=2,b/=2,c>>>=1;return(a+c)/b};return u.int32=function(){return 0|t.g(4)},u.quick=function(){return t.g(4)/(4*(1<<30))},u["double"]=u,g(i(t.S),a),(j.pass||k||function(a,c,d,f){return f&&(f.S&&e(f,t),a.state=function(){return e(t,{})}),d?(b[o]=a,c):a})(u,s,"global"in j?j.global:this==b,j.state)}function d(a){var b,c=a.length,d=this,e=0,f=d.i=d.j=0,g=d.S=[];for(c||(a=[c++]);l>e;)g[e]=e++;for(e=0;l>e;e++)g[e]=g[f=s&f+a[e%c]+(b=g[e])],g[f]=b;(d.g=function(a){for(var b,c=0,e=d.i,f=d.j,g=d.S;a--;)b=g[e=s&e+1],c=c*l+g[s&(g[e]=g[f=s&f+b])+(g[f]=b)];return d.i=e,d.j=f,c})(l)}function e(a,b){return b.i=a.i,b.j=a.j,b.S=a.S.slice(),b}function f(a,b){var c,d=[],e=typeof a;if(b&&"object"==e)for(c in a)try{d.push(f(a[c],b-1))}catch(g){}return d.length?d:"string"==e?a:a+"\0"}function g(a,b){for(var c,d=a+"",e=0;e<d.length;)b[s&e]=s&(c^=19*b[s&e])+d.charCodeAt(e++);return i(b)}function h(){try{if(j)return i(j.randomBytes(l));var b=new Uint8Array(l);return(k.crypto||k.msCrypto).getRandomValues(b),i(b)}catch(c){var d=k.navigator,e=d&&d.plugins;return[+new Date,k,e,k.screen,i(a)]}}function i(a){return String.fromCharCode.apply(0,a)}var j,k=this,l=256,m=6,n=52,o="random",p=b.pow(l,m),q=b.pow(2,n),r=2*q,s=l-1;if(b["seed"+o]=c,g(b.random(),a),"object"==typeof module&&module.exports){module.exports=c;try{j=require("crypto")}catch(t){}}else"function"==typeof define&&define.amd&&define(function(){return c})}([],Math);
\ No newline at end of file
diff --git a/tests/fuzzy/test.fuzzy.js b/tests/fuzzy/test.fuzzy.js
deleted file mode 100644
index f2dece7..0000000
--- a/tests/fuzzy/test.fuzzy.js
+++ /dev/null
@@ -1,167 +0,0 @@
-'use strict';
-
-// This is my idea of something between a property test and chaos monkey
-// We are testing the one basic property of PouchDB which is whatever we
-// do to databases, locally or remotely after they have synced they should
-// end up with the same data.
-
-// To do this we define a set of 'actions' that represent what an end user
-// could do to a database, create / update / delete documents, perform
-// replications or queries etc. We pick a number (actionCount) and randomly
-// perform those actions on a random database. Once we have run enough actions
-// we sync the 2 databases together and assert that they have the same contents
-
-// We can take an optional seed from the url (?seed=hello) otherwise we just
-// generate an arbitrary one. With any given seed the 'random' generations
-// are deteministic so if we find a seed that fails the test we can provide
-// that seed again to rerun the same actions and generate the same failure
-var seed = testUtils.params().seed || Date.now();
-if (Math.seedrandom) {
-  Math.seedrandom(seed);
-}
-
-// This is the amount of random actions we do
-var actionCount = 100;
-
-// We pick an action from this list at random, it gets given a
-// db to operate on if it only uses one database
-var actions = {
-
-  // Create a random document
-  'create': function (a) {
-    return a.post({'a': 'newdoc'});
-  },
-
-  // Pick from an existing document and updated it
-  'update': function (a) {
-    return randomDoc(a).then(function (doc) {
-      if (doc) {
-        doc.updated = Date.now();
-        return a.put(doc);
-      }
-    });
-  },
-
-  // Remove a random document
-  'remove': function (a) {
-    return randomDoc(a).then(function (doc) {
-      if (doc) {
-        return a.remove(doc);
-      }
-    });
-  },
-
-  // Generate a conflict by writing a document with the same id to
-  // both databases
-  'conflict': function (a, b) {
-    var doc = {
-      _id: 'random-' + Date.now(),
-      foo: 'bar'
-    };
-    return a.put(doc).then(function () {
-      doc.baz = 'fubar';
-      return b.put(doc);
-    });
-  },
-
-  // Perform a one off replication
-  'replicate': function (a, b) {
-    return a.replicate.to(b);
-  }
-};
-
-// Utilities
-
-function randomDoc(db) {
-  return db.allDocs({include_docs: true}).then(function (res) {
-    var row = arrayRandom(res.rows);
-    if (row) {
-      return row.doc;
-    }
-  });
-}
-
-function randomNumber(min, max) {
-  min = parseInt(min, 10);
-  max = parseInt(max, 10);
-  if (min !== min) {
-    min = 0;
-  }
-  if (max !== max || max <= min) {
-    max = (min || 1) << 1; //doubling
-  } else {
-    max = max + 1;
-  }
-  var ratio = Math.random();
-  var range = max - min;
-
-  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
-}
-
-function arrayRandom(arr) {
-  var keys = Object.keys(arr);
-  var i = randomNumber(0, keys.length - 1);
-  return arr[i];
-}
-
-describe('chaos-monkey', function () {
-
-  var Promise;
-  var a, b;
-
-  beforeEach(function (done) {
-    Promise = PouchDB.utils.Promise;
-    var aname = testUtils.adapterUrl('local', 'testdb');
-    var bname = testUtils.adapterUrl('http', 'test_repl_remote');
-    testUtils.cleanup([aname, bname], function () {
-      a = new PouchDB(aname);
-      b = new PouchDB(bname);
-      done();
-    });
-  });
-
-  after(function () {
-    return a.destroy().then(function () {
-      return b.destroy();
-    });
-  });
-
-  function dbActions() {
-    return new Promise(function doit(resolve) {
-      if (!actionCount) {
-        return resolve();
-      }
-      var action = arrayRandom(Object.keys(actions));
-      actionCount--;
-      // Give the databases in random order
-      var dbs = Math.round(Math.random()) ? [a, b] : [b, a];
-      var called = actions[action].apply(null, dbs);
-      // This is probably making a big stack, should fix
-      called.then(function () {
-        doit(resolve);
-      });
-    });
-  }
-
-  // Sync the databases up
-  function finish() {
-    return a.sync(b);
-  }
-
-  function compare() {
-    return Promise.all([
-      a.allDocs({include_docs: true}),
-      b.allDocs({include_docs: true})
-    ]).then(function (res) {
-      res[0].should.deep.equal(res[1]);
-    });
-  }
-
-  it('Do a fuzzy replication run', function () {
-    // This gives us 100ms for each action, should hopefully be enough
-    this.timeout(actionCount * 1000);
-    return dbActions()
-      .then(finish)
-      .then(compare);
-  });
-});
diff --git a/tests/integration/browser.info.js b/tests/integration/browser.info.js
deleted file mode 100644
index 7640467..0000000
--- a/tests/integration/browser.info.js
+++ /dev/null
@@ -1,39 +0,0 @@
-'use strict';
-
-var adapters = ['local'];
-
-adapters.forEach(function (adapter) {
-  describe('browser.info.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    it('adapter-specific info', function () {
-      var db = new PouchDB(dbs.name);
-      return db.info().then(function (info) {
-        switch (db.adapter) {
-          case 'websql':
-            info.sqlite_plugin.should.be.a('boolean');
-            info.websql_encoding.should.be.a('string');
-            info.adapter.should.equal('websql');
-            break;
-          case 'idb':
-            info.idb_attachment_format.should.be.a('string');
-            info.adapter.should.equal('idb');
-            break;
-          default:
-            should.exist(info); // can't make any guarantees
-            break;
-        }
-      });
-    });
-  });
-});
diff --git a/tests/integration/browser.migration.js b/tests/integration/browser.migration.js
deleted file mode 100644
index acdf85c..0000000
--- a/tests/integration/browser.migration.js
+++ /dev/null
@@ -1,1234 +0,0 @@
-/* global PouchDB, PouchDBVersion110, PouchDBVersion200,
-   PouchDBVersion220, PouchDBVersion306, PouchDBVersion320,
-   PouchDBVersion360 */
-'use strict';
-
-var scenarios = [
-  'PouchDB v1.1.0',
-  'PouchDB v2.0.0',
-  'PouchDB v2.2.0',
-  'PouchDB v3.0.6',
-  'PouchDB v3.2.0',
-  'PouchDB v3.6.0',
-  'websql'
-];
-
-describe('migration', function () {
-
-  function usingDefaultPreferredAdapters() {
-    var defaults = ['idb', 'websql'];
-    return !(PouchDB.preferredAdapters < defaults ||
-      PouchDB.preferredAdapters > defaults);
-  }
-
-  scenarios.forEach(function (scenario) {
-
-    describe('migrate from ' + scenario, function () {
-
-      var dbs = {};
-      var constructors = {};
-      var skip = false;
-
-      var post220 = [
-            'PouchDB v2.2.0',
-            'PouchDB v3.0.6',
-            'PouchDB v3.2.0',
-            'PouchDB v3.6.0'
-          ].indexOf(scenario) !== -1;
-      var post306 = [
-            'PouchDB v3.0.6',
-            'PouchDB v3.2.0',
-            'PouchDB v3.6.0'
-          ].indexOf(scenario) !== -1;
-      var post320 = [
-            'PouchDB v3.2.0',
-            'PouchDB v3.6.0'
-          ].indexOf(scenario) !== -1;
-      var post360 = [
-            'PouchDB v3.6.0'
-          ].indexOf(scenario) !== -1;
-
-      beforeEach(function (done) {
-
-        var isNodeWebkit = typeof window !== 'undefined' &&
-          typeof process !== 'undefined';
-
-        var skipMigration = 'SKIP_MIGRATION' in testUtils.params() &&
-          testUtils.params().SKIP_MIGRATION;
-
-        if (!usingDefaultPreferredAdapters() || window.msIndexedDB ||
-            isNodeWebkit || skipMigration) {
-          skip = true;
-          done();
-          return;
-        }
-
-        constructors = {
-          'PouchDB v1.1.0': PouchDBVersion110,
-          'PouchDB v2.0.0': PouchDBVersion200,
-          'PouchDB v2.2.0': PouchDBVersion220,
-          'PouchDB v3.0.6': PouchDBVersion306,
-          'PouchDB v3.2.0': PouchDBVersion320,
-          'PouchDB v3.6.0': PouchDBVersion360,
-          PouchDB: PouchDB
-        };
-
-        // need actual unique db names for these tests
-        var localName = testUtils.adapterUrl('local', 'test_migration_local');
-        var remoteName = testUtils.adapterUrl('http', 'test_migration_remote');
-
-        dbs.first = {
-          pouch : constructors[scenario] || PouchDB,
-          local : localName,
-          remote : remoteName,
-          localOpts : {}
-        };
-
-        dbs.second = {
-          pouch : PouchDB,
-          local : localName,
-          remote : remoteName
-        };
-
-        if (scenario in PouchDB.adapters) {
-          dbs.first.localOpts.adapter = scenario;
-        }
-        // else scenario might not make sense for this browser, so just use 
-        // same adapter for both
-
-        testUtils.cleanup([dbs.first.local, dbs.second.local], done);
-
-      });
-
-      afterEach(function (done) {
-        if (skip) {
-          done();
-          return;
-        }
-        testUtils.cleanup([dbs.first.local, dbs.second.local], done);
-      });
-
-      var origDocs = [
-        {_id: '0', a: 1, b: 1},
-        {_id: '3', a: 4, b: 16},
-        {_id: '1', a: 2, b: 4},
-        {_id: '2', a: 3, b: 9}
-      ];
-
-      it('Testing basic migration integrity', function (done) {
-        if (skip) { return done(); }
-        var oldPouch =
-          new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-          function (err) {
-          should.not.exist(err, 'got error: ' + JSON.stringify(err));
-          if (err) {
-            done();
-          }
-        });
-        oldPouch.bulkDocs({docs: origDocs}, function (err, res) {
-          var removedDoc = {_deleted: true, _rev: res[0].rev, _id: res[0].id};
-          oldPouch.remove(removedDoc, function () {
-            oldPouch.close(function (err) {
-              should.not.exist(err, 'got error: ' + JSON.stringify(err));
-              var newPouch = new dbs.second.pouch(dbs.second.local);
-              newPouch.then(function (newPouch) {
-                return newPouch.allDocs({key: '2'});
-              }).then(function (res) {
-                  res.total_rows.should.equal(3);
-                  res.rows.should.have.length(1);
-                  return newPouch.allDocs({key: '0'});
-                }).then(function (res) {
-                  res.total_rows.should.equal(3);
-                  res.rows.should.have.length(0);
-                  done();
-                }).catch(function (err) {
-                  should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                  done();
-                });
-            });
-          });
-        });
-      });
-
-      it("Test basic replication with migration", function (done) {
-        if (skip) { return done(); }
-        var docs = [
-          {_id: "0", integer: 0, string: '0'},
-          {_id: "1", integer: 1, string: '1'},
-          {_id: "2", integer: 2, string: '2'},
-          {_id: "3", integer: 3, string: '3', _deleted : true},
-          {_id: "4", integer: 4, string: '4', _deleted : true}
-        ];
-
-        new dbs.first.pouch(dbs.first.remote, function (err, oldPouch) {
-          should.not.exist(err, 'got error in constructor: ' +
-            JSON.stringify(err));
-          if (err) {
-            done();
-          }
-          oldPouch.bulkDocs({docs: docs}, {}, function (err) {
-            should.not.exist(err, 'got error in bulkDocs: ' +
-              JSON.stringify(err));
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err, oldLocalPouch) {
-              oldPouch.replicate.to(oldLocalPouch, function (err, result) {
-                should.not.exist(err, 'got error in replicate: ' +
-                  JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-                should.exist(result.ok, 'replication was ok');
-                oldPouch.close(function (err) {
-                  should.not.exist(err, 'got error in close: ' +
-                    JSON.stringify(err));
-                  if (err) {
-                    done();
-                  }
-                  should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                  if (err) {
-                    done();
-                  }
-                  oldLocalPouch.close(function (err) {
-                    should.not.exist(err, 'got error in close: ' +
-                      JSON.stringify(err));
-                    if (err) {
-                      done();
-                    }
-                    new dbs.second.pouch(dbs.second.local,
-                      function (err, newPouch) {
-                      should.not.exist(err, 'got error in 2nd constructor: ' +
-                        JSON.stringify(err));
-                      if (err) {
-                        done();
-                      }
-                      newPouch.allDocs({}, function (err, res) {
-                        should.not.exist(err, 'got error in allDocs: ' +
-                          JSON.stringify(err));
-                        res.rows.should.have.length(3, 'unexpected rows: ' +
-                          JSON.stringify(res.rows));
-                        res.total_rows.should.equal(3);
-                        done();
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-
-      it("Test basic replication with migration + changes()", function (done) {
-        if (skip) { return done(); }
-        var docs = [
-          {_id: "0", integer: 0, string: '0'},
-          {_id: "1", integer: 1, string: '1'},
-          {_id: "2", integer: 2, string: '2'},
-          {_id: "3", integer: 3, string: '3', _deleted : true},
-          {_id: "4", integer: 4, string: '4', _deleted : true}
-        ];
-
-        new dbs.first.pouch(dbs.first.remote, function (err, oldPouch) {
-          should.not.exist(err, 'got error in constructor: ' +
-            JSON.stringify(err));
-          if (err) {
-            done();
-          }
-          oldPouch.bulkDocs({docs: docs}, {}, function (err) {
-            should.not.exist(err, 'got error in bulkDocs: ' +
-              JSON.stringify(err));
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-            function (err, oldLocalPouch) {
-              oldPouch.replicate.to(oldLocalPouch, function (err, result) {
-                should.not.exist(err, 'got error in replicate: ' +
-                  JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-                should.exist(result.ok, 'replication was ok');
-                oldPouch.close(function (err) {
-                  should.not.exist(err, 'got error in close: ' +
-                    JSON.stringify(err));
-                  if (err) {
-                    done();
-                  }
-                  should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                  if (err) {
-                    done();
-                  }
-                  oldLocalPouch.close(function (err) {
-                    should.not.exist(err, 'got error in close: ' +
-                      JSON.stringify(err));
-                    if (err) {
-                      done();
-                    }
-                    new dbs.second.pouch(dbs.second.local,
-                      function (err, newPouch) {
-                        should.not.exist(err, 'got error in 2nd constructor: ' +
-                          JSON.stringify(err));
-                        if (err) {
-                          done();
-                        }
-                        newPouch.changes({include_docs: true})
-                        .on('complete', function (complete) {
-                          complete.results.should.have.length(5,
-                            'no _local docs in changes()');
-                          done();
-                        }).on('error', done);
-                      });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-
-      if (post220) {
-        it("Test persistent views don't require update", function (done) {
-          if (skip) { return done(); }
-          var oldPouch =
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err) {
-                should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-              });
-          var docs = origDocs.slice().concat([{
-            _id: '_design/myview',
-            views: {
-              myview: {
-                map: function (doc) {
-                  emit(doc.a);
-                }.toString()
-              }
-            }
-          }]);
-          var expectedRows = [
-            { key: 1, id: '0', value: null },
-            { key: 2, id: '1', value: null },
-            { key: 3, id: '2', value: null },
-            { key: 4, id: '3', value: null }
-          ];
-          oldPouch.bulkDocs({docs: docs}, function (err) {
-            should.not.exist(err, 'bulkDocs');
-            oldPouch.query('myview', function (err, res) {
-              should.not.exist(err, 'query');
-              res.rows.should.deep.equal(expectedRows);
-              oldPouch.close(function (err) {
-                should.not.exist(err, 'close');
-                var newPouch = new dbs.second.pouch(dbs.second.local);
-                newPouch.then(function (newPouch) {
-                  return newPouch.query('myview', {stale: 'ok'});
-                }).then(function (res) {
-                  res.rows.should.deep.equal(expectedRows);
-                  done();
-                }).catch(function (err) {
-                  should.not.exist(err, 'catch');
-                  done();
-                });
-              });
-            });
-          });
-        });
-
-        it("Test persistent views don't require update, with a value",
-            function (done) {
-          if (skip) { return done(); }
-          var oldPouch =
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err) {
-                should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-              });
-          var docs = origDocs.slice().concat([{
-            _id: '_design/myview',
-            views: {
-              myview: {
-                map: function (doc) {
-                  emit(doc.a, doc.b);
-                }.toString()
-              }
-            }
-          }]);
-          var expectedRows = [
-            { key: 1, id: '0', value: 1 },
-            { key: 2, id: '1', value: 4 },
-            { key: 3, id: '2', value: 9 },
-            { key: 4, id: '3', value: 16 }
-          ];
-          oldPouch.bulkDocs({docs: docs}, function (err) {
-            should.not.exist(err, 'bulkDocs');
-            oldPouch.query('myview', function (err, res) {
-              should.not.exist(err, 'query');
-              res.rows.should.deep.equal(expectedRows);
-              oldPouch.close(function (err) {
-                should.not.exist(err, 'close');
-                var newPouch = new dbs.second.pouch(dbs.second.local);
-                newPouch.then(function (newPouch) {
-                  return newPouch.query('myview', {stale: 'ok'});
-                }).then(function (res) {
-                  res.rows.should.deep.equal(expectedRows);
-                  done();
-                }).catch(function (err) {
-                  should.not.exist(err, 'catch');
-                  done();
-                });
-              });
-            });
-          });
-        });
-
-        it('Returns ok for viewCleanup after modifying view', function (done) {
-          if (skip) { return done(); }
-          var oldPouch =
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err) {
-                should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-              });
-          var ddoc = {
-            _id: '_design/myview',
-            views: {
-              myview: {
-                map: function (doc) {
-                  emit(doc.firstName);
-                }.toString()
-              }
-            }
-          };
-          var doc = {
-            _id: 'foo',
-            firstName: 'Foobar',
-            lastName: 'Bazman'
-          };
-          oldPouch.bulkDocs({docs: [ddoc, doc]}).then(function (info) {
-            ddoc._rev = info[0].rev;
-            return oldPouch.query('myview');
-          }).then(function (res) {
-            res.rows.should.deep.equal([
-              {id: 'foo', key: 'Foobar', value: null}
-            ]);
-            ddoc.views.myview.map = function (doc) {
-              emit(doc.lastName);
-            }.toString();
-            return oldPouch.put(ddoc);
-          }).then(function () {
-            return oldPouch.query('myview');
-          }).then(function (res) {
-            res.rows.should.deep.equal([
-              {id: 'foo', key: 'Bazman', value: null}
-            ]);
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local);
-            newPouch.viewCleanup().then(function () {
-              done();
-            }, done);
-          }, done);
-        });
-        it('Remembers local docs', function (done) {
-          if (skip) { return done(); }
-          var oldPouch =
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err) {
-                should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-              });
-          var docs = [
-            { _id: '_local/foo' },
-            { _id: '_local/bar' }
-          ];
-          oldPouch.bulkDocs({docs: docs}).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local);
-            newPouch.get('_local/foo').then(function () {
-              return newPouch.get('_local/bar');
-            }).then(function () {
-              done();
-            }, done);
-          }, done);
-        });
-
-        it('Testing migration with weird doc ids', function (done) {
-          if (skip) { return done(); }
-
-          var origDocs = [
-            {_id: 'foo::bar::baz'},
-            {_id: '\u0000foo\u0000'}
-          ];
-
-          var oldPouch =
-            new dbs.first.pouch(dbs.first.local, dbs.first.localOpts,
-              function (err) {
-                should.not.exist(err, 'got error: ' + JSON.stringify(err));
-                if (err) {
-                  done();
-                }
-              });
-          oldPouch.bulkDocs({docs: origDocs}, function (err) {
-            should.not.exist(err, 'got error: ' + JSON.stringify(err));
-            oldPouch.close(function (err) {
-              should.not.exist(err, 'got error: ' + JSON.stringify(err));
-              var newPouch = new dbs.second.pouch(dbs.second.local);
-              newPouch.then(function (newPouch) {
-                return newPouch.allDocs();
-              }).then(function (res) {
-                res.total_rows.should.equal(2);
-                res.rows.should.have.length(2);
-                res.rows[1].id.should.equal(origDocs[0]._id);
-                res.rows[0].id.should.equal(origDocs[1]._id);
-                done();
-              });
-            });
-          });
-        });
-      }
-
-      if (post306) {
-        // attachments didn't really work until this release
-        it('#2818 Testing attachments with compaction of dups', function () {
-          if (skip) { return; }
-
-          var docs = [
-            {
-              _id: 'doc1',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            },
-            {
-              _id: 'doc2',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            }
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.get('doc1').then(function (doc1) {
-              return newPouch.remove(doc1);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc2', {attachments: true});
-            }).then(function (doc2) {
-              doc2._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-            });
-          });
-        });
-
-        it('#2818 Testing attachments with compaction of dups 2', function () {
-          if (skip) { return; }
-
-          var docs = [
-            {
-              _id: 'doc1',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            }
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.put({
-              _id: 'doc2',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              return newPouch.get('doc2');
-            }).then(function (doc2) {
-              return newPouch.remove(doc2);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc1', {attachments: true});
-            }).then(function (doc1) {
-              doc1._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-            });
-          });
-        });
-
-        it('#2818 Testing attachments with compaction of dups 3', function () {
-          if (skip) { return; }
-
-          var docs = [
-            {
-              _id: 'doc1',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            },
-            {
-              _id: 'doc_deleted',
-              _deleted: true
-            },
-            {
-              _id: 'doc_no_attachments'
-            }
-          ];
-
-          for (var i = 0; i < 25; i++) {
-            // test paging in the migration
-            docs.push({
-              _id: 'some_other_doc_' + i
-            });
-          }
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.put({
-              _id: 'doc2',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              return newPouch.get('doc2');
-            }).then(function (doc2) {
-              return newPouch.remove(doc2);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc1', {attachments: true});
-            }).then(function (doc1) {
-              doc1._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-            });
-          });
-        });
-
-        it('#2818 Testing attachments with compaction of dups 4', function () {
-          if (skip) { return; }
-
-          var docs = [
-            {
-              _id: 'doc1',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                },
-                'att2.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                },
-                'att3.txt': {
-                  data: 'Zm9v', // 'foo'
-                  content_type: 'text/plain'
-                }
-              }
-            }
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.put({
-              _id: 'doc2',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              return newPouch.get('doc2');
-            }).then(function (doc2) {
-              return newPouch.remove(doc2);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc1', {attachments: true});
-            }).then(function (doc1) {
-              doc1._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-              doc1._attachments['att2.txt'].data.should.equal('Zm9vYmFy');
-              doc1._attachments['att3.txt'].data.should.equal('Zm9v');
-            });
-          });
-        });
-
-        it('#2818 Testing attachments with compaction of dups 5', function () {
-          if (skip) { return; }
-
-          var docs = [
-            {
-              _id: 'doc1',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                },
-                'att2.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                },
-                'att3.txt': {
-                  data: 'Zm9v', // 'foo'
-                  content_type: 'text/plain'
-                }
-              }
-            }, {
-              _id: 'doc3',
-              _attachments: {
-                'att-a.txt': {
-                  data: 'Zm9vYmFy', // 'foobar'
-                  content_type: 'text/plain'
-                },
-                'att-b.txt': {
-                  data: 'Zm9v', // 'foo'
-                  content_type: 'text/plain'
-                },
-                'att-c.txt': {
-                  data: 'YmFy', // 'bar'
-                  content_type: 'text/plain'
-                }
-              }
-            }
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.put({
-              _id: 'doc2',
-              _attachments: {
-                'att.txt': {
-                  data: 'YmFy', // 'bar'
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              return newPouch.get('doc2');
-            }).then(function (doc2) {
-              return newPouch.remove(doc2);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc1', {attachments: true});
-            }).then(function (doc1) {
-              doc1._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-              doc1._attachments['att2.txt'].data.should.equal('Zm9vYmFy');
-              doc1._attachments['att3.txt'].data.should.equal('Zm9v');
-              return newPouch.get('doc3', {attachments: true});
-            }).then(function (doc3) {
-              doc3._attachments['att-a.txt'].data.should.equal('Zm9vYmFy');
-              doc3._attachments['att-b.txt'].data.should.equal('Zm9v');
-              doc3._attachments['att-c.txt'].data.should.equal('YmFy');
-            });
-          });
-        });
-
-        it('#2818 Testing attachments with compaction of dups 6', function () {
-          if (skip) { return; }
-
-          var docs = [];
-
-          for (var i = 0; i < 40; i++) {
-            docs.push({
-              _id: 'doc' + i,
-              _attachments: {
-                'att.txt' : {
-                  data: PouchDB.utils.btoa(Math.random().toString()),
-                  content_type: 'text/plain'
-                }
-              }
-            });
-          }
-          docs.push({
-            _id: 'doc_a',
-            _attachments: {
-              'att.txt': {
-                data: 'Zm9vYmFy', // 'foobar'
-                content_type: 'text/plain'
-              },
-              'att2.txt': {
-                data: 'Zm9vYmFy', // 'foobar'
-                content_type: 'text/plain'
-              },
-              'att3.txt': {
-                data: 'Zm9v', // 'foo'
-                content_type: 'text/plain'
-              }
-            }
-          });
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          return oldPouch.bulkDocs(docs).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.put({
-              _id: 'doc_b',
-              _attachments: {
-                'att.txt': {
-                  data: 'Zm9v', // 'foo'
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              return newPouch.get('doc_b');
-            }).then(function (doc) {
-              return newPouch.remove(doc);
-            }).then(function () {
-              return newPouch.compact();
-            }).then(function () {
-              return newPouch.get('doc_a', {attachments: true});
-            }).then(function (doc) {
-              doc._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-              doc._attachments['att2.txt'].data.should.equal('Zm9vYmFy');
-              doc._attachments['att3.txt'].data.should.equal('Zm9v');
-            });
-          });
-        });
-
-        it('#2818 compaction of atts after many revs', function () {
-          if (skip) { return; }
-          
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-
-          return oldPouch.put({_id: 'foo'}).then(function (res) {
-            return oldPouch.putAttachment('foo', 'att', res.rev, 'Zm9v',
-              'text/plain');
-          }).then(function () {
-            return oldPouch.get('foo', {attachments: true});
-          }).then(function (doc) {
-            doc._attachments['att'].content_type.should.equal('text/plain');
-            should.exist(doc._attachments['att'].data);
-            return oldPouch.get('foo');
-          }).then(function (doc) {
-            return oldPouch.put(doc);
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.compact().then(function () {
-              return newPouch.get('foo', {attachments: true});
-            }).then(function (doc) {
-              doc._attachments['att'].content_type.should.equal('text/plain');
-              doc._attachments['att'].data.length.should.be.above(0,
-                'attachment exists');
-            });
-          });
-        });
-
-        it('#2890 PNG content after migration', function () {
-          if (skip) { return; }
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-
-          var transparent1x1Png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HA' +
-              'wCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEA' +
-              'AAAASUVORK5CYII=';
-          var black1x1Png =
-            'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACkl' +
-              'EQVR4nGNiAAAABgADNjd8qAAA' +
-              'AABJRU5ErkJggg==';
-
-          return oldPouch.put({_id: 'foo'}).then(function (res) {
-            return oldPouch.putAttachment('foo', 'att', res.rev,
-              transparent1x1Png, 'image/png');
-          }).then(function () {
-            return oldPouch.get('foo', {attachments: true});
-          }).then(function (doc) {
-            doc._attachments['att'].content_type.should.equal('image/png');
-            should.exist(doc._attachments['att'].data);
-            return oldPouch.get('foo');
-          }).then(function (doc) {
-            return oldPouch.put(doc);
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.compact().then(function () {
-              return newPouch.get('foo', {attachments: true});
-            }).then(function (doc) {
-              doc._attachments['att'].content_type.should.equal('image/png');
-              doc._attachments['att'].data.should.equal(transparent1x1Png);
-              return newPouch.putAttachment('bar', 'att', null,
-                black1x1Png, 'image/png');
-            }).then(function () {
-              return newPouch.get('bar', {attachments: true});
-            }).then(function (doc) {
-              doc._attachments['att'].content_type.should.equal('image/png');
-              doc._attachments['att'].data.should.equal(black1x1Png);
-            });
-          });
-        });
-      }
-
-      if (post320) {
-        it('#3136 Testing later winningSeqs', function () {
-          if (skip) {
-            return;
-          }
-
-          var tree = [
-            [
-              {
-                _id: 'foo',
-                _rev: '1-a',
-                _revisions: {start: 1, ids: ['a']}
-              }
-            ], [
-              {
-                _id: 'foo',
-                _rev: '2-b',
-                _revisions: {start: 2, ids: ['b', 'a']}
-              }
-            ], [
-              {
-                _id: 'bar',
-                _rev: '1-x',
-                _revisions: {start: 1, ids: ['x']}
-              }
-            ], [
-              {
-                _id: 'foo',
-                _rev: '2-c',
-                _deleted: true,
-                _revisions: {start: 2, ids: ['c', 'a']}
-              }
-            ]
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-            dbs.first.local, dbs.first.localOpts);
-          var chain = PouchDB.utils.Promise.resolve();
-          tree.forEach(function (docs) {
-            chain = chain.then(function () {
-              return oldPouch.bulkDocs(docs, {new_edits: false});
-            });
-          });
-
-          return chain.then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            var newPouch = new dbs.second.pouch(dbs.second.local,
-              {auto_compaction: false});
-            return newPouch.changes({
-              include_docs: true,
-              style: 'all_docs'
-            });
-          }).then(function (result) {
-            // order don't matter
-            result.results.forEach(function (ch) {
-              ch.changes = ch.changes.sort(function (a, b) {
-                return a.rev < b.rev ? -1 : 1;
-              });
-            });
-            var expected = {
-              "results": [
-                {
-                  "seq": 3,
-                  "id": "bar",
-                  "changes": [{"rev": "1-x"}],
-                  "doc": {"_id": "bar", "_rev": "1-x"}
-                },
-                {
-                  "seq": 4,
-                  "id": "foo",
-                  "changes": [{"rev": "2-b"}, {"rev": "2-c"}],
-                  "doc": {"_id": "foo", "_rev": "2-b"}
-                }
-              ],
-              "last_seq": 4
-            };
-            result.should.deep.equal(expected);
-          });
-        });
-      }
-
-      if (post360) {
-        it('#3646 - Should finish with 0 documents', function () {
-          if (skip) {
-            return;
-          }
-
-          var data = [
-            {
-              "docs": [
-                {
-                  "_revisions": {
-                    "start": 2,
-                    "ids": [
-                      "4e16ac64356d4358bf1bdb4857fc299f",
-                      "aed67b17ea5ba6b78e704ad65d3fb5db"
-                    ]
-                  },
-                  "_rev": "2-4e16ac64356d4358bf1bdb4857fc299f",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 2,
-                    "ids": [
-                      "3757f03a178b34284361c89303cf8c35",
-                      "0593f4c87b24f0f9b620526433929bb0"
-                    ]
-                  },
-                  "_rev": "2-3757f03a178b34284361c89303cf8c35",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 3,
-                    "ids": [
-                      "f28d17ab990dcadd20ad38860fde9f11",
-                      "6cf4b9e2115d7e884292b97aa8765285",
-                      "dcfdf66ab61873ee512a9ccf3e3731a1"
-                    ]
-                  },
-                  "_rev": "3-f28d17ab990dcadd20ad38860fde9f11",
-                  "_id": "b74e3b45"
-                },
-                {
-                  "_revisions": {
-                    "start": 3,
-                    "ids": [
-                      "4d93920c00a4a7269095b22ff4329b3c",
-                      "7190eca51acb2b302a89ed1204ac2813",
-                      "017eba7ef1e4f529143f463779822627"
-                    ]
-                  },
-                  "_rev": "3-4d93920c00a4a7269095b22ff4329b3c",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 3,
-                    "ids": [
-                      "91b47d7b889feb36eaf9336c071f00cc",
-                      "0e3379b8f9128e6062d13eeb98ec538e",
-                      "1c006ce18b663e2a031ced4669797c28"
-                    ]
-                  },
-                  "_rev": "3-91b47d7b889feb36eaf9336c071f00cc",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 4,
-                    "ids": [
-                      "2c3c860d421fc9f6cc82e4fb811dc8e2",
-                      "4473170dcffa850aca381b4f644b2947",
-                      "3524a871600080f5e30e59a292b02a3f",
-                      "89eb0b5131800963bb7caf1fc83b6242"
-                    ]
-                  },
-                  "_rev": "4-2c3c860d421fc9f6cc82e4fb811dc8e2",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 6,
-                    "ids": [
-                      "441f43a31c89dc68a7cc934ce5779bf8",
-                      "4c7f8b00508144d049d18668d17e552a",
-                      "e8431fb3b448f3457c5b2d77012fa8b4",
-                      "f2e7dc8102123e13ca792a0a05ca6235",
-                      "37a13a5c1e2ce5926a3ffcda7e669106",
-                      "78739468c87b30f76d067a2d7f373803"
-                    ]
-                  },
-                  "_rev": "6-441f43a31c89dc68a7cc934ce5779bf8",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                }
-              ]
-            },
-            {
-              "docs": [
-                {
-                  "_revisions": {
-                    "start": 2,
-                    "ids": [
-                      "3757f03a178b34284361c89303cf8c35",
-                      "0593f4c87b24f0f9b620526433929bb0"
-                    ]
-                  },
-                  "_rev": "2-3757f03a178b34284361c89303cf8c35",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 2,
-                    "ids": [
-                      "4e16ac64356d4358bf1bdb4857fc299f",
-                      "aed67b17ea5ba6b78e704ad65d3fb5db"
-                    ]
-                  },
-                  "_rev": "2-4e16ac64356d4358bf1bdb4857fc299f",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 3,
-                    "ids": [
-                      "91b47d7b889feb36eaf9336c071f00cc",
-                      "0e3379b8f9128e6062d13eeb98ec538e",
-                      "1c006ce18b663e2a031ced4669797c28"
-                    ]
-                  },
-                  "_rev": "3-91b47d7b889feb36eaf9336c071f00cc",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 3,
-                    "ids": [
-                      "4d93920c00a4a7269095b22ff4329b3c",
-                      "7190eca51acb2b302a89ed1204ac2813",
-                      "017eba7ef1e4f529143f463779822627"
-                    ]
-                  },
-                  "_rev": "3-4d93920c00a4a7269095b22ff4329b3c",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 4,
-                    "ids": [
-                      "2c3c860d421fc9f6cc82e4fb811dc8e2",
-                      "4473170dcffa850aca381b4f644b2947",
-                      "3524a871600080f5e30e59a292b02a3f",
-                      "89eb0b5131800963bb7caf1fc83b6242"
-                    ]
-                  },
-                  "_rev": "4-2c3c860d421fc9f6cc82e4fb811dc8e2",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 4,
-                    "ids": [
-                      "dbaa7e6c02381c2c0ec5259572387d7c",
-                      "f28d17ab990dcadd20ad38860fde9f11",
-                      "6cf4b9e2115d7e884292b97aa8765285",
-                      "dcfdf66ab61873ee512a9ccf3e3731a1"
-                    ]
-                  },
-                  "_rev": "4-dbaa7e6c02381c2c0ec5259572387d7c",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                },
-                {
-                  "_revisions": {
-                    "start": 6,
-                    "ids": [
-                      "441f43a31c89dc68a7cc934ce5779bf8",
-                      "4c7f8b00508144d049d18668d17e552a",
-                      "e8431fb3b448f3457c5b2d77012fa8b4",
-                      "f2e7dc8102123e13ca792a0a05ca6235",
-                      "37a13a5c1e2ce5926a3ffcda7e669106",
-                      "78739468c87b30f76d067a2d7f373803"
-                    ]
-                  },
-                  "_rev": "6-441f43a31c89dc68a7cc934ce5779bf8",
-                  "_id": "b74e3b45",
-                  "_deleted": true
-                }
-              ]
-            }
-          ];
-
-          var oldPouch = new dbs.first.pouch(
-              dbs.first.local, dbs.first.localOpts);
-          var newPouch;
-
-          return oldPouch.bulkDocs(data[0], {
-            new_edits: false
-          }).then(function () {
-            return oldPouch.bulkDocs(data[1], {new_edits: false});
-          }).then(function () {
-            return oldPouch.close();
-          }).then(function () {
-            newPouch = new dbs.second.pouch(dbs.second.local,
-                {auto_compaction: false});
-            return newPouch.allDocs();
-          }).then(function (res) {
-            res.rows.should.have.length(0, 'all docs length is 0');
-            res.total_rows.should.equal(0);
-            return newPouch.allDocs({keys: ['b74e3b45'], include_docs: true});
-          }).then(function (res) {
-            var first = res.rows[0];
-            should.equal(first.value.deleted, true, 'all docs value.deleted');
-            first.value.rev.should.equal('6-441f43a31c89dc68a7cc934ce5779bf8');
-            res.total_rows.should.equal(0);
-            return newPouch.info();
-          }).then(function (info) {
-            info.doc_count.should.equal(0, 'doc_count is 0');
-            return newPouch.changes({include_docs: true});
-          }).then(function (changes) {
-            changes.results.should.have.length(1);
-            var first = changes.results[0];
-            first.doc._rev.should.equal('6-441f43a31c89dc68a7cc934ce5779bf8');
-            should.equal(first.deleted, true, 'changes metadata.deleted');
-            should.equal(first.doc._deleted, true, 'changes doc._deleted');
-          });
-        });
-      }
-    });
-  });
-});
diff --git a/tests/integration/browser.worker.js b/tests/integration/browser.worker.js
deleted file mode 100644
index 5bc5f68..0000000
--- a/tests/integration/browser.worker.js
+++ /dev/null
@@ -1,97 +0,0 @@
-'use strict';
-
-var sourceFile = window.location.search.match(/[?&]sourceFile=([^&]+)/);
-
-if (!sourceFile) {
-  sourceFile = '../../dist/pouchdb.js';
-} else {
-  sourceFile = '../../dist/' + sourceFile[1];
-}
-
-// only running in Chrome and Firefox due to various bugs.
-// IE: https://connect.microsoft.com/IE/feedback/details/866495
-// Safari: doesn't have IndexedDB or WebSQL in a WW
-// NodeWebkit: not sure what the issue is
-
-var isNodeWebkit = typeof window !== 'undefined' &&
-  typeof process !== 'undefined';
-
-if (typeof window.Worker === 'function' &&
-    !isNodeWebkit &&
-    (window.chrome || /Firefox/.test(navigator.userAgent))) {
-  runTests();
-}
-
-function runTests() {
-
-  function workerPromise(message) {
-    return new Promise(function (resolve, reject) {
-      var worker = new Worker('worker.js');
-      worker.addEventListener('error', function (e) {
-        worker.terminate();
-        reject(new Error(e.message + ": " + e.filename + ': ' + e.lineno));
-      });
-      worker.addEventListener('message', function (e) {
-        worker.terminate();
-        resolve(e.data);
-      });
-      worker.postMessage(['source', sourceFile]);
-      worker.postMessage(message);
-    });
-  }
-
-  describe('browser.worker.js', function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl('local', 'testdb');
-      dbs.remote = testUtils.adapterUrl('http', 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('create it', function () {
-      return workerPromise('ping').then(function (data) {
-        data.should.equal('pong');
-      });
-    });
-
-    it('check pouch version', function () {
-      return workerPromise('version').then(function (data) {
-        PouchDB.version.should.equal(data);
-      });
-    });
-
-    it('create remote db', function () {
-      return workerPromise(['create', dbs.remote]).then(function (data) {
-        data.should.equal('lala');
-      });
-    });
-
-    it('create local db', function () {
-      return workerPromise(['create', dbs.name]).then(function (data) {
-        data.should.equal('lala');
-      });
-    });
-
-    it('add doc with blob attachment', function () {
-      return workerPromise(['allDocs', dbs.name]).then(function (data) {
-        data.title.should.equal('lalaa');
-      });
-    });
-
-    it('put an attachment', function () {
-      var blob = new Blob(['foobar'], {type: 'text/plain'});
-      var message = ['putAttachment', dbs.name, 'doc', 'att.txt', blob,
-        'text/plain'];
-      return workerPromise(message).then(function (blob) {
-        blob.type.should.equal('text/plain');
-        blob.size.should.equal(6);
-      });
-    });
-  });
-}
diff --git a/tests/integration/cordova/.cordova/config.json b/tests/integration/cordova/.cordova/config.json
deleted file mode 100644
index 33fd5c2..0000000
--- a/tests/integration/cordova/.cordova/config.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "id": "com.pouchdb.tests",
-    "name": "PouchDB Test Runner"
-}
\ No newline at end of file
diff --git a/tests/integration/cordova/config.xml b/tests/integration/cordova/config.xml
deleted file mode 100644
index 7f8f3dc..0000000
--- a/tests/integration/cordova/config.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="com.pouchdb.tests" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
-    <name>PouchDB Test Runner</name>
-    <description>
-      Runs the unit tests suite for the PouchDB project on Cordova.
-    </description>
-    <author email="daleharvey@arandomurl.com" href="http://pouchdb.com">
-      The PouchDB Team
-    </author>
-    <content src="tests/integration/index.html" />
-    <access origin="*" />
-    <preference name="websecurity" value="disable" gap:platform="blackberry10" />
-</widget>
diff --git a/tests/integration/cordova/merges/firefoxos/icons/icon-128x128.png b/tests/integration/cordova/merges/firefoxos/icons/icon-128x128.png
deleted file mode 100644
index 8973954..0000000
--- a/tests/integration/cordova/merges/firefoxos/icons/icon-128x128.png
+++ /dev/null
Binary files differ
diff --git a/tests/integration/cordova/merges/firefoxos/icons/icon-60x60.png b/tests/integration/cordova/merges/firefoxos/icons/icon-60x60.png
deleted file mode 100644
index 5adb4a6..0000000
--- a/tests/integration/cordova/merges/firefoxos/icons/icon-60x60.png
+++ /dev/null
Binary files differ
diff --git a/tests/integration/cordova/merges/firefoxos/manifest.webapp b/tests/integration/cordova/merges/firefoxos/manifest.webapp
deleted file mode 100644
index a230a9a..0000000
--- a/tests/integration/cordova/merges/firefoxos/manifest.webapp
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "launch_path": "/tests/integration/index.html",
-    "installs_allowed_from": [
-        "*"
-    ],
-    "version": "0.0.1",
-    "name": "PouchDB Test Runner",
-    "pkgName": "com.pouchdb.tests",
-    "description": "Runs the unit tests suite for the PouchDB project on Cordova.",
-    "developer": {
-        "name": "The PouchDB Team",
-        "url": "http://pouchdb.com"
-    },
-    "icons": {
-      "128": "./icons/icon-128x128.png",
-      "60": "./icons/icon-60x60.png"
-    }
-}
diff --git a/tests/integration/cordova/platforms/.gitignore b/tests/integration/cordova/platforms/.gitignore
deleted file mode 100644
index 5e7d273..0000000
--- a/tests/integration/cordova/platforms/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore
diff --git a/tests/integration/cordova/plugins/.gitignore b/tests/integration/cordova/plugins/.gitignore
deleted file mode 100644
index 5e7d273..0000000
--- a/tests/integration/cordova/plugins/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore
diff --git a/tests/integration/deps/bigimage.js b/tests/integration/deps/bigimage.js
deleted file mode 100644
index 16cc623..0000000
--- a/tests/integration/deps/bigimage.js
+++ /dev/null
@@ -1,12 +0,0 @@
-(function () {
-  'use strict';
-
-  var bigimage = "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yza2iXhidiYKdrPxJO9Y9+6JeBqzm8xE955Yimv8IbsoWUeRbqxd/w+/397yd3e0D/3u2WHPLMKP9xTHnOJqt213fb695Sd2tz//q0+3n1v99fajF76+/drZn2n/7XuPaPfd+YX2ln97Xbv4b/6+XfS0o9ttH/+19r0//+X2kStvac/efH/73R9+SXvZ2za2L//3723Lo9rH+5PHZ1a0733zb7XT/uS17bXv/mz7V+cd3w6Z/ad22Ze/0v5lFApj2u3euyLuT+1pf/6BT7f/uOqG9r+/6HXtV8/+XPvv37Oq/dG//3/aay/5cnvzRZuj8AhGMeeE0frTX9ne8wvnt/93z8+1d73xOfFakjvaW579g+22/+OP2q3v+8529+cvbs985TPb5igYX7hxd/vG59/dfuS+n2ifufKadtzmw3sYtbZu75faT7/zgvaxK69tk199T3vea1/cvuPZ32wvWf6p9oxXvKm978pb20Xrb2o/evbL2weec3175Zt/s532/72uve7dn27/+vwT2rrlz28/c+4H2hde8o72p2++oG1YvrX97Atf147+7b9r215xWPujH7mgveX9z2m//YNntL0P3dp+/z/9VnvLH3+s3fD2KCTHhZvilwvkU1yTN/30G9vH/uZv2lWXXdGWx1PFeyKfd2/fG/I3t//26/+1HXfiye2TH//b9tb/9Nb2X3/9v7Xbb9vaPvl3H28/9aafiXcOz7b/+eH/GQs2vjjGdX8g3kN8y423tnPPf1aLRdO+efft7Zgjjom1GeuFLOOJ7JxHkWvxBon23POfGzk+0b7whc93tegLX/CC9qxnP6ftjsI1frwvO9x6eRT9yOk9e2bb2c84u1119VXdP31x7fDLla1bt7ZN8S8TKJXzWhSeOp7klyzxBDsl2Ol40phfrozxPmbWXIwxHpjEiHFKe2MtTMaTyPwSIgq04dutGV6xwg0tjul47/POXXtifW/pXmnBP72huYbdY6DsPewTrF0O9w/slWVfZAutf26o7A3ZH5lydeLBHDiIS8POfQUZfSg2Nnjj6cs5wKtTbgzlxvI8ieP+i03e1+y7j2Zf/NB7Hs5HylzxE1vk+NucLzLHd/8nLs3x4fHnQMaBX54XOovD2Of933HxE1vOk35d/7r+5ih54rogh+j3c4d+rf/Y/efWYq3/+X2Z3AAX93jzB5lydeKW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1+tFawJyD08m9hs6NWlbTCQBEiABEiABEiABEiABEiABuwRUdPzlhKPsZmc+EiABEiCBdiZAdxbtDJTVkUC6Ejh8p+nIzsxK2D2XDVcWZuHWFtg7cPi+ZlZuSYAESIAESIAESIAESIAESIAESIAESIAEOjkBisidfALZfRJIhcDeO+yZMLvDaf/nQF1aJAo9swsxuvcOiZIZTwIkQAIkQAIkQAIkQAIkQAIkQAIkQAIk0MkI2FeNOtnA2F0SIIGWBHYvmYje+b1aJkiMA/YWzIsUju8T+ZgxMyNZOnIv6LPU7vFYDnlAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiTQTgToE7mdQLIaEugsBA4ffTCe+PhZY0Vcs88ul1Mk5PiisJkndhuQlXWdMdbLgwsHoyAzNzZrhxzvfNIteOrYpnDdGRkZ4X3ukAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJtB8BWiK3H0vWRAKdgsDgggEYVjzU0leH02U5tnMQ69LC6XDiuLEz7BRttzwqHJufdquUFZEACZAACZAACZAACZAACZAACZAACZAACVgIUES24OABCXQPAoePPgiuKOHY4UjVlQXEktnKatKACdYIHpEACZAACZAACZAACZAACZAACZAACZAACXQJAhSRu8Q0chAkkBqBwsw8TCgZZxRyuMQbcjA1VxaR1kJKcg9PJvYbOjUSzT0SIAESIAESIAESIAESIAESIAESIAESIIEuQ4AicpeZSg6EBFIjcPhO0+Fxe+ASNxRtDT6f3yh64PB921oFy5EACZAACZAACZAACZAACZAACZAACZAACaQ5gbarR2k+MHaPBEigdQIHjNwHjpjF8VovFckRCATRK7cXRvfeIRLJPRIgARIgARIgARIgARIgARIgARIgARIggS5FwN2lRsPBkEA3JfC3r+fhhJ2PSHn0u5dMhH62R1i26UfU+7ZgYt/R26N5tkkCJEACJEACJEACJEACJEACJEACJEACJGCTAEVkm6CYjQTSmUBbBOTtPZ6RvYZt7y6wfRIgARIgARIgARIgARIgARIgARIgARIgARsE6M7CBiRmIQESIAESIAESIAESIAESIAESIAESIAESIAESIIHuSoAicnedeY6bBEiABEiABEiABEiABEiABEiABEiABEiABEiABGwQoIhsAxKzkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEB3JUARubvOPMdNAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAjYIUES2AYlZSIAESIAESIAESIAESIAESIAESIAESIAESIAESKC7EqCI3F1nnuMmARIgARIgARIgARIgARIgARIgARIgARIgARIgARsEKCLbgMQsJEACJEACJEACJEACJEACJEACJEACJEACJEACJNBdCVBE7q4zz3GTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgA0CFJFtQGIWEiABEiABEiABEiABEiABEiABEiABEiABEiABEuiuBCgid9eZ57hJgARIgARIgARIgARIgARIgARIgARIgARIgARIwAYBisg2IDELCZAACZAACZAACZAACZAACZAACZAACZAACZAACXRXAhSRu+vMc9wkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkYIMARWQbkJiFBEiABEiABEiABEiABEiABEiABEiABEiABEiABLorAYrI3XXmOW4SIAESIAESIAESIAESIAESIAESIAESIAESIAESsEGAIrINSMxCAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAt2VAEXk7jrzHDcJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJ2CBAEdkGJGYhARIgARIgARIgARIgARIgARIgARIgARIgARIgge5KgCJyd515jpsESIAESIAESIAESIAESIAESIAESIAESIAESIAEbBCgiGwDErOQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQHclQBG5u848x00CJEACJEACJEACJEACJEACJEACJEACJEACJEACNghQRLYBiVlIgARIgARIgARIgARIgARIgARIgARIgARIgARIoLsSoIjcXWee4yYBEiABEiABEiABEiABEiABEiABEiABEiABEiABGwQoItuAxCwkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIk0F0JUETurjPPcZMACZAACZAACZAACZAACZAACZAACZAACZAACZCADQJuG3k6fZZFixZ1+jFwACRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSwPQjQEnl7UGebJEACJEACJEACJEACJEACJEACJEACJEACJEACJNBJCHQLS+SRI0d2kulgN0mABEiABEiABEiABEiABEiABEiABEiABEiABEggvQjQEjm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABbRCEcwAAIABJREFUEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IkAROb3mg70hARIgARIgARIgARIgARIgARIgARIgARIgARIggbQiQBE5raaDnSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB9CJAETm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IkAROb3mg70hARIgARIgARIgARIgARIgARIgARIgARIgARIggbQiQBE5raaDnSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB9CJAETm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IkAROb3mg70hARIgARIgARIgARIgARIgARIgARIgARIgARIggbQiQBE5raaDnSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB9CJAETm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IkAROb3mg70hARIgARIgARIgARIgARIgARIgARIgARIgARIggbQiQBE5raaDnSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB9CJAETm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IkAROb3mg70hARIgARIgARIgARIgARIgARIgARIgARIgARIggbQiQBE5raaDnSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCB9CJAETm95oO9IQESIAESIAESIAESIAESIAESIAESIAESIAESIIG0IkAROa2mg50hARIgARIgARIgARIgARIgARIgARIgARIgARIggfQiQBE5veaDvSEBEiABEiABEiABEiABEiABEiABEiABEiABEiCBtCJAETmtpoOdIQESIAESIAESIAESIAESIAESIAESIAESIAESIIH0IuBOr+6wNyRAAiRAAiTQ+Ql4vd7mQXjg8XT+8XAE6UkgKOeZzzzTeKK1yyTxu9suGDu8Es5ThyNmAyRAAiRAAv/P3nkAOFFtb/xL3V7oSxVQpAoqAiJFRAUsWBGx9+7zj71XbKiABZ/6bE99IopdVBCl96L0pQnILrBLWbaXJJv8z51s6ia7STZbgG/eG2fmzi3n/u7NLPnm5FwSIAESqESAInIlJEwggSOIgOUg0jdmoFw+6eWIQ+cenREbQfeK8rKwa8sObNy+HeWmJjBYD8KQ0hqdOhyLjh3bIo4iWQRUIyjiyMe8L6bhj03/IKVZN1x07eU4NkUXQUUNs0jhgUxsWLNC5lkGCkrERl0cmnfqhfOH90XiYdTNzb++jInf73BDvujhCTinY6L7mickEBUCZVvw+P9NxEGHQ6uuxVlj8dxlXaNSdYOvpJaehenfjsPrMzO17jv0zfHIa8+hY0LtPXwKs3Zgd56lStw6eTmQkpyM5JSm/FtbQSrq4+Qoxu6tmSis+CxVOSBy0xyfgmQZkyYp8dVlrXw/5LZMSEiRcU+OR3J8BO1UbpkpJEACJEACJEACJFBjAhSRa4yQFZBAwyTgKNqBtx99BevK7E4D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gARIgARIgARIgASCEqCIHBQNb5AACZAACZAACZAACZAACZAACZAACZAACZAACZAACVBE5hwgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIISoAiclA0vEECJEACJEACJEACJEACJEACJEACJEACJEACJEACJEARmXOABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggKAGKyEHR8AYJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkABFZM4BEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBoAQoIgdFwxskQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIUkTkHSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEghKgiBwUDW+QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQROYcIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESCEqAInJQNLxBAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAEZlzgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIICgBishB0fAGCZAACZAACZAACZAACZAACZAACZAACZAACZAACZAARWTOARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggaAEKCIHRcMbJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACFJE5B0iABEiABEiABEiABEiABEiABEiABEiABEiABEiABIISoIgcFA1vkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJUETmHCABEiABEiABEiABEiABEiABEiABEiABEiABEiABEghKgCJyUDS8QQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQBGZc4AESIAESIAESIAESIAESIAESIAESIAESIAESIAESCAoAYrIQdHwBgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAEVkzgESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIGgBCgiB0XDGyRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAsajAUFsbOzR0E32kQRIgARIgARIgARIgARIgARIgARIgARIgARIgASiToCeyFFHygpJgARIgARIgARIgARIgARIgARIgARIgARIgARI4MghQBH5yBlL9oQESIAESIAESIAESIAESIAESIAESIAESIAESIAEok6AInLUkbJCEiABEiABEiABEiABEiABEiABEiABEiABEiABEjhyCFBEPnLGkj0hARIgARIgARIgARIgARIgARIgARIgARIgARIggagToIgcdaSskARIgARIgARIgARIgARIgARIgARIgARIgARIgASOHAIUkY+csWRPSIAESIAESIAESIAESIAESIAESIAESIAESIAESCDqBCgiRx0pKyQBEiABEiABEiABEiABEiABEiABEiABEiABEiCBI4cAReQjZyzZExIgARIgARIgARIgARIgARIgARIgARIgARIgARKIOgGKyFFHygpJgARIgARIgARIgARIgARIgARIgARIgARIgARI4MghQBH5yBlL9oQESIAESIAESIAESIAESIAESIAESIAESIAESIAEok6AInLUkbJCEiABEiABEiABEiABEiABEiABEiABEiABEiABEjhyCFBEPnLGkj0hARIgARIgARIgARIgARIgARIgARIgARIgARIggagToIgcdaSskARIgARIgARIgARIgARIgARIgARIgARIgARIgASOHAIUkY+csWRPSIAESIAESIAESIAESIAESIAESIAESIAESIAESCDqBCgiRx0pKyQBEiABEiABEiABEiABEiABEiABEiABEiABEiCBI4cAReQjZyzZExIgARIgARIgARIgARIgARIgARIgARIgARIgARKIOgGKyFFHygpJgARIgARIgARIgARIgARIgARIgARIgARIgARI4MghQBH5yBlL9oQESIAESIAESIAESIAESIAESIAESIAESIAESIAEok6AInLUkbJCEiABEiABEiABEiABEiABEiABEiABEiABEiABEjhyCBiPnK6wJyRAAiRweBDYtSsDu/fsQXr6ZuQeygUcdixavFQ7Hso9JOmb4HDo0KNHdyQnJcFkMqJv3z7Q6XRISU1G9+7d0KpVK7Rr1+7w6DCtJAESIAESIAESIAESIAESIAESIAESOKwJUEQ+rIePxpMACRwuBNavX49pX3+HJUuXY/OmzbA7IKKwHjqHQwRju5w7UGaxip5sg9Eoj2a5t1HyodwOk1mPZctFZIYO5eXlmpis+t21axec1v80XHLpRTjh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bcJT//63Y01RWzsGFfRPrqmrRU0NI4vpbxymeNzW2gp3by9tMvy00og6nss+Rj37KT4H6Zd83HtPxPs+/P43AoPqFAEREAEREAEREAEREAEREAEREAER2MsISETey06ouiMCIvDGEziZ1hHHn3AsXl71Ml584SU8+/wLaKVnsoticZRWFwxRpl+xn4KvH92d3XDRB9nn8qGCEcevvbYRGzdscHyPA/Q/9jG5RRm3NTchGg45InJJaRlq62o4sF6R45G8ZuUKJ/r4yHceg4OWHIK58/ehZ3LpGw9CLRABERABERABERABERABERABERABEdgrCNDAM++Umia5nr5M/EbbjDgHz7Y/dZ9tJ/cl1zMtPf3pbJm+bsK35bH9tp5Mk75MplnQ3d19KdNpEgEREIE3jMBr6zdg2eNPYtXyl7BtyzbU1Y1FU0szojGLIgb6YhG8RCuLLkYXT6RXclVFKQfni9DGgoPycYC80vJSFFFUjppNBgfUs+XEqVOw7/77Yd8D9sOMWTPesL6pYhEQAREQAREQAREQAREQAREQAREYzQSCweCV7P9LnGOc+/qXtp4+R1PSJNfT8yTz2zLbzN8zDxyz9eRs6ZPrySV3OWltaftsSl+m7nMSpL8oEjmdiLZFQAREYA8QmDZjKmy2qbGhEe3tnVj7yjqEQhyAj/v+8fcHMWXWTCfSOEIbDK/Xg7qx4zCmro52F27s+/YDOG6fC8FgABMnT0ZNbTVqx9Q55elFBERABERABERABERABERABERABERABPYkAYnIe5KuyhYBERCBDATqxtZRIK7DzNnTB46+lwPgaRIBERABERABERABERABERABERABERCBNyMBs3zQJAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIZCUhEzohFO0VABERABERABERABERABERABERABERABERABERABIyARGRdByIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAlkJSETOikYHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJCLrGhABERABERABERABERABERABERABERABERABERABEchKQCJyVjQ6IAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIBFZ14AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEBWAhKRs6LRAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAYnIugZEQAREQAREQAREQAREQAREQAREQAREQAREQAREQASyEpCInBWNDoiACIiACIiACIiACIiACIiACIiACIiACIiACIiACEhE1jUgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiKQlYBE5KxodEAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAisq4BERABERABERABERABERABERABERABERABERABERCBrAQkImdFowMiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAISkXUNiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIZCUgETkrGh0QAREQAREQAREQAREQAREQAREQAREQAREQAREQARGQiKxrQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREICsBichZ0eiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiARGRdAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAlkJSETOikYHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJCLrGhABERABERABERABERABERABERABERABERABERABEchKQCJyVjQ6IAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIBFZ14AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEBWAhKRs6LRAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAYnIugZEQAREQAREQAREQAREQAREQAREQAREQAREQAREQASyEpCInBWNDoiACIiACIiACIiACIiACIiACIiACIiACIiACIiACEhE1jUgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiKQlYBE5KxodEAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAisq4BERABERABERABERABERABERABERABERABERABERCBrAQkImdFowMiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAISkXUNiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIZCUgETkrGh0QAREQAREQAREQAREQAREQAREQAREQAREQAREQARGQiKxrQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREICsBichZ0eiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiARGRdAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAlkJSETOikYHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJCLrGhABERABERABERABERABERABERABERABERABERABEchKQCJyVjQ6IAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIBFZ14AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEBWAhKRs6LRAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAYnIugZEQAREQAREQAREQAREQAREQAREQAREQAREQAREQASyEpCInBWNDoiACIiACIiACIiACIiACIiACIiACIiACIiACIiACEhE1jUgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiKQlYBE5KxodEAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAisq4BERABERABERABERABERABERABERABERABERABERCBrAQkImdFowMiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAISkXUNiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIZCUgETkrGh0QAREQAREQAREQAREQAREQAREQAREQAREQAREQARGQiKxrQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREICsBichZ0eiACIiACIiACIiACIiACIiACKHn95AAACAASURBVIiACIiACIiACIiACIiARGRdAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAlkJSETOikYHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJCLrGhABERABERABERCB3SQQ6upCd3g3C3mTZd8b+/QmQ6zmiMAbQkD39huCXZWKgAiIgAiIwFuegKeAHrhS0iTXcy3t2O7OJm5bGbZMX8+0nUyXukzmH3PppZceyXI0iYAIiECCQLwLr65Zh/rGJjQ1pc/b0NTuQl0VcNO55+D23nk4dn5NZnIs57E7b8M692RMrwtkTpNt7+7kzVbm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bdhJwdYKSTM4R3Ird93JVLu3zFVH7vNRWL9ylW8tz12HpRiZeqykbJNZJfz4x4/CPfMj2CfDr30s3+73I1vtQ98/Em0Zzv059JYOL0e+/mUrtZBnr+Udbvnp9Y5EObnOQ7byi0oq05uibREQAREQgT1IQCLyHoSrokVABERABHaDAH/ieMLZx+Gf19+Gsz9x26CC9j3pfJzUb8sx6AA3Qh1ARyT5pWr60ddn+83Qhnw9nX38FzE7XyIdF4HdIPBWuA92o3t7R9ZhPmf3js6rF4MI9P/Kx76kjbvH4cJzjsnw66VBObTxJiWgZ++b9MSoWSIgAiKwFxBI2lLk6kpqmuR6+tKsI2yy/amz7U/fTu6zZbY53cLC0iXtKmRnQRiaREAERGC0ELCfMG7ZuMkRhv3BCowfPyHnzxYb1q5GvHY6xlUOJ356ZKi+GdowMj1RKSIwfAK6D4bP7vXOOdTn7OvdPtX3ehAIo2HDJrREvJgwZQrK/ck/916PulXHSBLQs3ckaaosERABESicwGiwsyjk00FqmuR6+tJEXptsf+ps+9O3k/tsmW2WiEw4mkRABERABERABERABERABERABERABERABERABN7cBEaDiGwiriYREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERyEhAInJGLNopAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJgBCQi6zoQAREQAREQAREQAREQAREQAREQAREQAREQAREQARHISkAiclY0OiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiARWdeACIiACIiACIiACIiACIjA/2fvTOCjKLI//ptckIRTghBEbsIVEJFDEAERARfRXeUQ/COsggJGEAQCIipiMAEBlSCoqOAKqMCCXAoiyLVoVNSABJRDrnAkIIEk5CCZf1X31ExPT18zmYSArz+fpLurq9579a1X1T1vaqqJABEgAkSACBAB6JvycAAAIABJREFUIkAEiAAR0CVAQWRdNHSBCBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQAQoiEw+QASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACugQoiKyLhi4QASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAAFkckHiAARIAJEgAgQASJA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IkAEiAARIAJEgAjoEqAgsi4aukAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhREJh8gAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAFdAhRE1kVDF4gAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgILI5ANEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIqBLgILIumjoAhEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIUBCZfIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABHQJUBBZFw1dIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABCiKTDxABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIgC4BCiLroqELRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJAQWTyASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAAR0CVAQWRdNHSBCBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQAQoiEw+QASIwN+awNlDe/HNxo3YuHELkpJTcD4r7/rjYc/CjuUfY0vKBX3bWZ5FI57EpOW/6efx1xWha8Xv+hKt2KxfutRdKbx4HMl7D+GKXW1aHv5M2SP72KYdOJKWqc5A5zcSASu+X9rqWxr74vXIkbXruWMHsDclBSmOvyOpaSXX2haZuduYzGw9hPQsj4HLoy4HDh1Dhka+YqugqE8J3LPOHjqAg6l+GpvtGdi/NwUX8jyZFhsrfwgWvI3u2/7QY1VGcdkj5Or5lbheFA5WZLA8ps9tVln5K58Vu33RJeTqMfdFJpUhAkSACBCBa0Yg6JppJsVEgAgQgWtKIA/fvDMaH3+f7WbF1TLdsPDdQQi1uSWX6hOb/TzWb9iCy1daoWuTm3RtDSgL2K/qXvb5QsahXdh9qQF6tqrmlCHpys93nqsPrNqsLlcaz8/s34DYhM9gt1XES4lvoUE52XkK/9qHF8a+gdOFdtiCK8KenwEsAbqNnIFB7VysvKmTFmtvylNeYwL+4Gvm+8YWlPzV0toX/cFRqz210vxCnQVK1rw+EzuuuA+y9rLReGnWOOe44BddOkJMmenYyMVF94xBzKNt5HufQb67H5uM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9Udp5JVBpms/Ml1/rqbJo9mHRmQBh4EESIAESIAESIAESIAESIAESIAESIAESIAESKBkE7gYjMjSiMtAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAoYEaEQ2xMJEEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABSYBGZM4DEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABUwI0IpuiYQYJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkACNyJwDJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACpgRoRDZFwwwSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEakTkHSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAETAnQiGyKhhkkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAI0InMOkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJmBKgEdkUDTNIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARoROYcIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESMCVAI7IpGmaQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAnQiMw5QAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkYEqARmRTNMwgARIgARIgARIgARIgARIgARIgARIgARIgARIgARKgEZlzgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIwJQAjcimaJhBAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAIzLnAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgCkBGpFN0TCDBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiARmTOARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgAVMCNCKbomEGCZAACZAACZAACZAACZAACZAACZAACZAACZAACZAAjcicAyRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAqYEaEQ2RcMMEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABGpE5B0iABEiABEoHAXcaMtwaUcV5eqbmnNGSR4BjVvLGhBKRAAmQAAmQAAmQAAmQ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I0B3FqVvzCgxCZAACZBAERCQRlZpbD2dk4Gc3Fyxy7J0706ULizkDuTyIeE0IBfB/GATfgKVqtRCpSr+89IcqxrbuDSLT9lJgARIgARIgARIgARIgASKkQDdWRQjXDZNAiRAAqWZgDQkVwwpV5pVoOwkQAIkQAIkQAIkQAIkQAIkQAIkQAJFQEC6iWAgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgAUMCNCIbYmEiCZAACZAACZAACZAACZAACZAACZAACZAACZAACZCAJEAjMucBCZAACZAACZAACZAACZAACZAACZAACZAACZAACZCAKQEakU3RMIMESIAESIAESIAESIAESIAESIAESIAESIAESIAESIBGZM4BEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABUwI0IpuiYQYJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkACNyJwDJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACpgRoRDZFwwwSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEakTkHSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAETAnQiGyKhhkkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIhREACJEACJEACdgRy3Dk4nZOBnNxcuF1uu+LnNd/ldiE4KAjlg8MR7Ao+r7KwcxIgARIozQRK09pvx5n3BjtCzCcBEiABEiABEiABawLciWzNh7kkQAIkcNETkEaEE1mpyBbHkm5AloMlZZSySpml7AwkQAIkQAL5J1Da1n47DXlvsCPEfBIgARIgARIgARKwJkAjsjUf5pIACZDARU9A7kCGqxRiEDIrspdC0SkyCZAACZxvAqV27bcDx3uDHSHmlwICZ9PSkJ5ZCgSliCRAAiRAAhcUARqRL6jhpDIkQAL5IXB071ZsTEhAgvhsiY/Htr1HkZWfBgpT1p2Gjx99GM/M2+5pRX/upO2C1HHSrq5Mdu753c176lgyTp7J60Ij5Ugy0rLzpmvFl+43SlwQ47Zi7mwsTjhe4kSjQAYEztF1ZtDzhZ2kcp27uVj0PLJjK7YdTPW1rV3vExLixbq/A8lp1uuHr3J+I6pu6vqe3/olpPz5XvvtMFxw9wY7hZlvTkC95oppPTHv+NznuNzJ+HrsAPx34EA82v8BvLVi/7kXgj2SAAmQAAlctAToE/miHXoqTgIXOQHxD8f3YyZgRUZ2AAh3UE0MHT8KzaoU/9bboLLC9UKW32ytPw8QTJyk7FiF1adicXPLqr4suzq+ghYRo3YDihc/ioDutCfujO0Y/tYEtL5lNPq1vVSTlYXf57yIz0LvxMePX69JD4yWRPcbLvcxzF+wGKczWqJz3CWBAl9AZ7bzqhTpWhTXWSlS95yJqnANXIKLpm+5vo+dgA3XDcH0Pk3FQmu83svOmt48CIPuvgrhRbzOXRBzpoiZFM3gelq5EO8NheVzIa25BWFRbOtJQYQpxjr7l3yM7xKycd+I19E87DSCq11WjL2xaRIgARIgARIIJMCdyIE8eEYCJHAREQgLByrdPAyzZs1SPuOf74/q2I+pb/987nYk54P3+q8+xg+bkvLUcIWG5knLT4JZu/lpoyBlMw5vwPuf/opTbvPdgDt++QKpwVejV5squi5Cce1/egLJn+KPwyVwt7FOWu2pO6gWXpk2HVOlcesCDudrXl3ASC8s1VyhKOsqPitlmfJA+VB/+/r1/r23J+HeDjWw6edpGDFzbbGwLezaXCxClYJGL9Z7Q2GH5qJec4t5PSns2BRl/dTkI8iJ7IIbL78MVWMbIzrSv84VZT9siwRIgARIgASMCHAnshEVppEACVw0BMpqnP1WbdAB3dt8inc3JosXswGK/cGdgsWzpmDWkt0Kk+hmt2DEoLtwaRnvl3axw23x7OmYtdjzk2x3UAweG/0K2lYvi1N71+DjD7/Bn3sP+uoOG3AXYvL9hT8Ty955Bh9vEc7vtkxAv+VASMPeeGtYO6XdlH9W4t0xb2P11hPiPBQdeg3Cg91aiJgnmMuRZdzu8C6+ut4miuUQkrEXK7f/jFuyu6CCKqy2p6z9+GrDfrRo1wcVDIxNEXWvxi1l5uKjxRvR9t7m2prWcTFm3776OoL+fR9ciz7AvPhjqHPzcLxyTxOxY9F6vN1nk/HNtCn4Lt7z89Grej6MuocXYk9sPzx2fV3gbCKmDH4NTYdNQtdYYcWSQe6CHPc0EluOwKAbRRlxvnDaCzja5in0u76Gcl4weTKxceEnePez5UhVDPGhqHf17Rg84DZU0vISMr3++Euo0WcU+gijmRqS//4cQ97YhZfefAaxkelY8ul0fPyLZx4HVWqKQcMfRavq5ZzppDaqHE3mq5xXQnfTfgLakCcW+mXuc8T5+/GvI7V1Z5xcNAd/HJRuWUJxU7/huPfahp7e5NjYlfGU9Px1wrKcd21wUraw3IX8pnNHK7eMm7Gv5sK8l5/GPjEfh3TzcEnZ8hWeGr8Mdz8/2jeP//7yFby7pw0mD7sOvyrMbkLasjlYufeM0tOVtw3CIz3Nd/TKa+ezaZOxMP6AUr5lt3uQm6Z7AGQmo5yHMoh8s/XWU8D6r3a9LxMZjZv6j8YlYS9g2uJpWNN9BtpcKn4eYhREv/llJJuxW5st1xvRp+nY2qxT5mu+nJsW15V23TDicI7Sztu9QY6Z+MXP2HHv42CmfLgZimrVonH68GE0uPclPKms3xb3CDFmnvXE5tqwGj+LcTcfV4t7uVVf+ZwL5v171zzt/CiQHqIdhwwLvZ74+vHfH9yuKDw44nk0SFuOsdN+VO6r8l445LnB4tdpZbTa+eOiHdN7mq+PQswHf08ilol1c6fjnflHEYyf8MADP6FB9+fwfE+xbtvIYbqWqO2fi/uV2hePJEACJEACpZoAjcilevgoPAmQQGEJBOwUE1/Cd24/i+DK0QhR/ifKxK+Th+KTeDe69XsKTcP3Y+a0uRgxKgJvj/qX+PlzJhaMewJfJGShw50D0KZaDtYuS0DlCp5/No7v3IA9EQ0xaEQfRKRswOR3f8LozxvjrYdb5FPsMNTv9B/UW/shEmt2xuAelwNhNRVDb0SEC2lbl2Hn1T3wzPMNkLjqC8z5cgpCosfjobYetxdWcpi1ay1gOhbNmoCfT0SgQsY/2CX8FVepfhNGPtwDlRVw6fj1wwk4UK8fHrze8zPLHb99iDkHG+HZ3u2RtXsJnp01D65g8b4+dzaeHzsUlXAadVsPx+BbYn1dp+74HQnucnjp2lq+tMBIBNpf3xTzf5mHw1nNEKPZdRhYLu/Z6bOHsWjyOARf1h79B8QhrJLc6Wwz3kjDV6+OxA/CfnzboyNwZYXjmDPxQ6zNyUWdculKJ+6sDOw4m4nafi8lSvrJI1nYcSzNJ8jJwynYdPikOPcYdQsiD/b+homfLlPmXof6FXFi71os3xMBraFM6bBMDK6qH4LZc37Bf9o/hPLSUCTm+sovFyGoUhdcFpnlm8c3PvCUMo9/nT0Nbz7zJJ6Y+B6uDHemk085mM1X//Vi1E/LKoE/jsrYY66fU84pKWKcZ89G7PV3Y2Sfy7BtyRf45oPRyI0Yj/tbea4PJ2V8utmy1BhTbMsWDXfjueOT2BuxZh9VIQc/LF6PjFsbKm4d/vr5Z/EgLRM//m+nMCK3ENdpMpYv3Iuwjj0gfsABD7MPUUuuO729686P0/BRtfEY2MHvbscnhZhv8tpZqLt2dolrp57vm6i1jC2rZPvmqdF66+srn5HWPe5HuSVjsP9YlrkR2RWJ/DKyX5vt1hvxYtCCrFNiClqt+VbXlT06u7VfLC1nDuGHOTPwdaLnYUHzJg/gkV7tEeF9YJtzcje++2oWvvfmu8IbYES/J9E4Ogzpuxef33vDmW0Y9dr7ONv2Loy7uzWS13+PCbOXo+5Nj6B3e3kvsx8z+2vDvg3jcbceV+N7uXVfju8h3olhNa+M5k5B9JDt2DIsivUkWu1H3B8698UzfSthxf+JDQFjhymqyHtUy8rH8eUbszFp7Dd4d+LdBi5vbNYsXx9Wa6X1GAW62QlDTNOOuE74e1/0T20MeOwmVK7i+e6ifhc1vLcKOczGwjdu5+h+5euPERIgARIggVJLwPfVvdRqQMFJgARIoBAEkuJXYknVI3BnCqPeou/x5/Fs3P7ftoqBNufoWmFAzkS3kdPQK07uKm2OV4anYuC475GY1h2x6WsVA3Lb/uPR32s4ad6qg0+aOp3/i8md1dM4PL7rT0xatREZfVsohhg1x8mxRlwbxFX8GGeuaItmzfy7KNPT3Qht2hcTHu2oNNM4dhgSfx+MDduE2wuvEdlKDsN2HQh0WvycMvlUFq69dQT6Vz6JGXPew9B3KuC9x7sq7E4dOYKNlVJESx4jsjt1J3bsi1DchITXaIYhwvB0as9CTFzxJx7qPhB1y2UjqHy1gJ4PbU+A21UVERZ3qkrRNYSBaxfSs0VVo93MAS0GngTVuAXTX/P/Y5hzdJXleDdIXycMyFm48ekpuLOZx5fxCxPD0H/IdF/DLgtZ9cZd/Xl+5YlJP6X02+CKpoirLeZnXByu8UmijYSh7R0345PXxPxOvBedapdF7sntii6dBl6PsCTPPO40cDzu886ZhqNH40S/ZzHrpy1o2cscrF4HtVejeSX5ygcupv3o3HtkWunnkLM7A4ho9wheeNBDJi6uMbIPDMT8b/5Aj5biQZAQ2EkZVS/x9MaSpf4f/nPFXT93/PJ6YnIts2I/suNVcE//CwfS7kKDiH1Ytikbci4fW74KJ3o3R9SJXViXnYPbr6qtNCiZyXVnlG7d2bRPutvJa0TOOWhw7UyKRP8npyJXXrsi2MnY/OYUy/XW00oB/rqzcEbs5E85JR8EeX89YNBM03wyslub7e4vjSI9QujH1m6daiR2wlut+ZbXlYHe+iTrtT8Dc998FT9mxOCp3q+gYmo8pn47G0Nmh2BGn6uVptbPn4pv91+GEQ+9Lh46nsaWP5bjZKr4lY0wIp/ve0PKrg1IcoeIh503I0ZwjLmhN7rNX40/XdGoHBkm5qj1PUKOmd21UdBxl/CsxtVszbX6DuP8HuKZBVb9B659nvLyr37+yjTLdkS+LcMiWE9a9q6r9BPWQtwfHvDcHxoOuhcrh80MuEf17/8PRr7nWRtj1V+ZSCVEsFuz1D6s1krb+aDrs0ZcS1y9qSp+3VcPbVq18n5Xtbm3Cl1lMBoLJUP5Y31vK47vCf6+GSMBEiABEihNBCz+DStNalBWEiABEsg/AblTLGvv//DZ3A04myINnkAPYTD+l2IwBlKTDytpCyYNwcqICCWe4i33975UxLj3CyNnFG5soX3hm1JM+XMmaScW//ILlq5JwPG0dOUlekHR5gY5f02DmNfQoX0Rn1oquobYZqIJ0vdnuGZXrqUcFu1qmswTdQvPAJc0HYLb28YqeQNu+hsjfl6IfRldUU/0Lw1Q+h9/uoXPQqm9KzQatesD6UFiB82KCMQ2qYcaGnn9nWXAHdESlW2QudynsCsxDfUaeX/y7m/ANCb/SY1p3zJgZ5H9eMv5EIpmtSr52g2q1ATtwkOww5dSsEhB5GlUvx2uqrQQH704CJ/XboN7enZDx2Z1DAWIiu2I1iHz8eWijej08FVIXPMbsoTrlY5i7qbuXKrM42ub+OexO6gaul0XgSl/b0JGr/zunBciGMyr1GTP9WLaj7tpwHhE5UM/Q6W9iVFRUZrsMMQ1r4bvlnqudzXDSRlfWQuWahn1eC64G80dtX/1aMe+wm2tEZq7ChsPn0V192rsdAsj38ibMXn0+9iY9CiaJW6AdNXTup68xjy77o3WHbOHCqliR3iea6diw4Brx07G5FZiWlmst6qu+T3KX6NI9y8R4dYLTdX6VxUJI3VttltvGjUOUoxc+V2nGon7l9WaX9jrymrtr5O9H4vFE70773waLWLlXKmOx8QvJEZtmI/9WW2VdT7tjOepgSskFJVr1EXnGvV8Q3a+7w3loqWxLQt/bTuKRuKXCu7U3Vh/IhvlKnhEdDJmsqTVteGkDbNr2mpcjddc6+8w+bmHSL0s+5cFdKFAenjbsGRYBOtJhtewWjnGf38IqlADVcRaEFXB831PilIxurJYeDbpNPOc2q1Zah+Wuth8z5TXsz5kuz1rsOp2zYkcZmOhbftc3K+0/TFOAiRAAiRQOgnQiFw6x41SkwAJFAEBuVMs5uYRGHdPQ7hPb8Kgxydi5dqdwojsMZoJm6cSOt35MJpGuSD/9ZUGB2EfQ51a5eA66FlCpadVfcg5ugaPDZuOXOFP786efVCvWkX88+1YzDukL1m858UpR1nhjkIN5byGOkNbsFJI7vkMDMKThRKkUcJ4F3E4XOmbcdx9K6pqvAQEtiINSxVQr5Z3254+0+Jcb5B3Mt5uVwSEzVgTssW8kL4zA0NQQBk4eoFYfuWBeHPYoKnvYnf8Gvw4dyZmTlqDWXV74I2XuntcVmhEcouddN17XY61n3+HpIcux9JvExDRdgDqCd/egeZUTaXQwDEriE6a1syjun58BcvUMtfPW6igMon9+75uzCJmZaxY6tuyKluU3PVzRy+H6bmXfXDFergqPBjxf21FTNoysWOtO5o0uBKtQ4OxXDwECzm0QUmrJn3B553ups2rGa7QEHGd6q8doIJ4kGcbvDKqroeM1lvbNiwKpO/bJXafitEWa7tVCCpiRnbrjWqs14+tXT3bNd/qupKubhwEs7U/fX+82NUt9utr1r/oerFw/bUOmXK9F4jbduuP9R+/g/HvD/P0FNEKzz3cFw3ETmQ1nK97Q/ClLdD36mjMfHO48DjrDZU7YkKXBsqJHXt1zNSqRkenbejH3XZcDTqz7Ssf95CC9C9FKgo99KoVxXqib9Nzng3xfDkgeL+mBKTZnpjd0wwq2o6RQR3HSTo59GOhb+dc3a/0/fKcBEiABEigdBHQfM0rXYJTWhIgARIoCgJiL7LSjKt8UzzZsx5emzsFizrOQBfxk/+wcM8OlYhaTdHaYDdIRmiUcKWQArkrWb9bZPf6n5WdnqOFT+WaQZ5/zHemFl5i1ZDitCWncuS3Xdn/WY0QmWc8O2OyNAYmudNMDUfFbpug4Dj11HeUhiVhpzIM1RrGCePDaqTJ93YF2jN95U8ou1sjAowWvsx8RuzHW3j1FOMdL8Y7Vp0PwmfpjjO5UE3Y0vghRT14RPBo4N1BdHa/spstn+LYzj9Pe2Go26wDHhefg6vfwMgZi3BEuFopb7Apu3Z7kf7ZGHw651PEi92Cd3dprDQhd9+53AuwXqOX9IG7YvFxhF9VH2WzXQXWSTuv7Pox/jm0sX5SPaec1V8PqPz37jqE4PAm6qlydFJGW8GMpbaMGjcra8ejMNzVvtWjbV9BFXH1dZdh8vyZ+ED4G23Tv6V4YhaJa24UaWJN3C3WySsfvMKB6V3tMfAYGmp07ezHGuE+SP0iaidj+bAU0/U2sDfzM/2DAelmZ8bEucgNaYprGxtcNNqmxC7oomRkt96YGevt6u1Y4eTeY3xdGa0bWgRq3GztD4+JEw/MFqrFlGNy4m7lAYL6gDE8pgWeGjlD5KXj0I4tiiukd5Zch8l3Cl//mnC+7g2Zp04hrMndGNO/tbgGIhBdUV3dhXHc5juB2Zhp1CpwGwW5l9vKqwjmbC447V+rq1G8KNopivXE5CuFkcimaXZrlpM+nI2RqQhKRlHIofZQEu5Xqiw8kgAJkAAJlEwCgW+xKZkyUioSIAESOCcEGnYbiOYhweLFKp/itNiZVvayduheIxTzxw7BN79vQVJSEnZsWYk581YjQxhLw2u3w3WXBOPH8a9hyZY9SDq6F2uE+4rtSWdRpVY9uHIP4//ZOw/4KIr2j//ukgvkAgQkSIDQQw9FOoqAdEUsSBH9B7GggIiCQMCOECAgoAKir4rgK4gU4aUJiPQIoiJNAghBINQESCC93X9m7/Zub7PtUkhCnv187nZ2duaZ5/lO2btnZ2f3H/hHyLd3xUysOJsBc2l3U1Jl/zrlx87UbLqKfzkTLkfuxKlL1xAbl+Q8pZqHpdDVQ0OuswCFAJ9pFndkHvaduYnUm6ewfNOvbOmJDggU/jVZUIbZGRO1GxfjkxB7Yjv+eyEdfNao3WXvEmhmjP48eAY34uJwk6+LKdn8arVCbdNtbNp3SRIrDSbjwJ6/4Vv7cZXlMKRpc4bl3PTr+372+L0X1syah99Pszq4dgbfTZspzGIUpZv8gtCsghcOrF6F4xevIZ6l+WZaBC5n23Is7yEvX36sp0/KxUh89f1uRF+KFdrYmehYUQ3FvalMAwxsa8XBbXuRbu2M1nXtTjOvSk2Edr4h4m1sj7qIxHj2YqyF04Q1cJ9ijmZPbHIWrNCu9Mpx5nUEtOwzqhNfsiZ53xf4auvfSEiMxcH1c4V1dVs+2tG5dIaRNFwlaf2osZTbwI/V0urxMGojL0OqGz+Wb3pl8fR12vAX6CUggzlLuzmW6Glwf2d2JkN4CqNDSFU3sXplShP71lTvO+KyN3o6ao230rK0wvGXTiAqKop9jmDT0jkY+uqHOJSahdDxw4XH2JF6BuOGDsXE7/9WFJOfjPT6t6iAnLNePr0xX6tfiWVq7bXGfq/yldHM7IVla38Qxv6EmENY/cc5mO/pikDh2peBP9atwG9/n0diqjfKly8nvAjUt5TrhqNYdmFdG25etSHz0jHs+u0g9u/ZiFUbfkF0rP0OsB57UXd5nYnxfJ9bGXr1yh6TyvEbQa8sT9qCbvlSIyVhOQujcuT5JCLZb6+8jyeiPK1yxDRqe70xS8ynVYZeHYkytPb5oYcov0CvV2nnMfmF5zFs5rYcvwXF8mlPBIgAESACRZ+AOAGk6GtKGhIBIkAE8pkAdx5JN/4o34tv9sLoiE1YdaAPnmcvGXvqvRlInxeOtQsjsNaR2K95KAYKWf3wwpS3kT1zJhZHvO8UFVq/A+rX7cZeYLYHGxaGYwM7Y7qnLfo/0pjJdSYTAhXLuR7h5RHyY1dqH3Qc1A/rIn5A+KRIZPt1x38W9FOUIbXLX1cPJbmhTgebq/ycIRObdvvFtxOEE9nmenjr1X5g8w3ZsQVtej6OH5evwttz9wvLTdRlj8GfMfm6zWT0q9cDLzQ+hkWbIrCS5eJrLEtno5l8a2NQi4oIj9yMIQ+9gHKyR62TL+zHuqQMjOjJZk3mYsvBms281K5vf7w8PQw3wmZg/hT7o9iVmj6AKuZfXbOymYwnXg/FkQ8WI+Ite2VXbPgA6pbah2zZ4/Ly8uXHfCaolj5Z7G/Yns3fsI9ovAV9R34A+ct/xLN83/aRvlj023I0fvQhYR1Y4Rwrp/97U5A05wN2A4W9TI9F8rVn+70+Ez2C7bOpjdokyBO+lNuVXjmu/KzPaNpnjDNfsqZSSFucWDYLo5fap8kH9xqFkQ8FOYsykoYnltePIkunVPeAYtp85C7Xzb10dmSgrHLVW7C2vB7XanZHDT/72OhbrQVal16GA+b2bLkBe5woW16mdNwR0zj3rD3J+05A0y7sZaG7kSr2CwM6qo63lURXtLNEyPXhN+FSj6zGjCNiGguaPDgYzwzuhSCHvalxZ4WbQo+3qCEmctvnKyNmr1b/Fu8vyjnrjQu+OmO+dr9yM1f1QHXsZ9fQl0e+hlsLPhXGfi7AVK49m9XbhY399vYTH7sX3/35s1M2Pz+5a7DzmAcK69qQcvEQtlzPQJbpAn7feR3ZKcm4Gp+A9Su/x7hPvkRTNis5N3Xm1hZzWe+5vZZr6evJNUS/fLcqdB7I269ROfJ87gzzYTxhT1zwTV4Ovw8uDklCAv7FfruYc97n0B9XVcpwt0WnTTmVkAZ82dM0kmO9sVNFD4kEt2CBXa/YWnC32Q31TPYSU3E9Z7eC6YAIEAEiQASKBQH3fwTKKkvTiGH5XpzRzOOlHx4vPxbj+F7twx9u5uf4Xh7mjm/xHA+LaeR7MU2T5OTkt1k62ogAESACuSZgS09CMptGa7H4wcfd7yvITEtKEmbr+fj5uTlK7fEW+LE3u+fPlo4k5jj1Y+V4sunroS43LkO+emsyfpw5Dn82HIPwx2rhdkIGSvtzB7F4abBrZstMRiL7n6Z0zrDuGWfxzrTpaPToVDzb6l5Jtgxs/fR1rCw7BF8+314SnzMYwJYdTlZmvAAAIABJREFU8XTTq+8kVt/cWc6rYcXYkfi1zRv4eHCIWzE8jYm1F2s+VL2WPnZdmOPFQJuI/eMbjJsX6XCIuNcXV14sR96ORcM8t0m5XemVI5bH93r2qerE/jh/O3Y0oh4Iw/T+9cH7QJa8PoykkSojCeuxlCSFXlo9Hqo2SgsxGNYry6CYXCez16f2mKino9p4m2ulHBnP/fIR3llmw6dfjXPdZMmrUAP5RXvVri9qIrTy6Y35ev2Kl5nbsZ/nvc2cr3xJozJlrPxQtmUgMZEvgaR2XpZc6TC/rw1sLFjx5uvYVj0U/xnDZ+A7ttSTeHX4dHQOm4eB4jJG7JQWezGr3j43MvTqFdAec5XamJG2INqiX76YUnufX3LyYzzR1tTYWbEu1a6dRqSIMpTqyEh+nkaUkRc9CvJ6lZYUz67D5fPld5FRJpSOCBABInAnCVit1nBW3t/sw1/jke3Y87D8w5fdF9OIYfFYTCvm53u1D58lI57jYfHD48SwuGdRQlq+53F8k++lcUIC+RfNRJYToWMiQASIgAIBk48ftPzApZgDL+dcOEAtXqEIg1E+uXJI6+uhIZdfWmT+Rr72b0oaX5zCgrL+SlN0WBZvKztn0Cy1ZJbamPr+AqEc9yQW9Bj5CXpK1l12P28/MtlkiislUojTq2+nw5Y5HlL50idyQEymM42CfE+jtPQxWo4t8SQ++2w3zHWfRcPyyly0yuE6Gy3LZZ9yu9Irx5Vfv0w9ncSXCfE+oLYZSSPNa4SlmN5IWj0eejaKZRnZ65VlREZe0hixRU9H/fEsdxqmZ3qj3aDH76gDmWuqZ6+aNVr59BgZqQfhb4VsqDAy9nN9y5bXGvy581jrvJrFkvgCuDYks3Wq+CxJYbkqwe50nDwQiUQ2xvvKLnNa7CVaagZzI0OvXtnKzYq/EbTKMtQWHJbol69psvNkfskxoruW7U6F8hjIjzKKgoyCvl6V8iufR9KUnQgQASJABAqbADmRC7sGqHwiQASIQBEn4M3WuMy08Rui4mZBleBG6F4nQIwo4L3s37ujNOmL+9QU8DLzh1IKdku7zWbdSd8oWLDFeS7dMZOOO0Js5kCMG9GNuf5LxmakboykcdLyhKUnaZ0FUKAwCdTr9QbqFaYCRazswh/79YAoj2S5ujawJQF6D++BHXOWY/jQ5W4FN+07Bn0dS/u4naADInC3EKDr1d1Sk2QHESACRKDACcjmFyiWJ00jhuV78V86j5d+eLz8WIzje7WPfAkLnk5croKWs2AwaCMCRIAI3CkCWcyBfDODvVhIHPnvVMF5LYfNoK5gKQMvE798FNx29fQJ2AJqI7C80lz0givXuOR0XD13gdWhN6rWqIFyPsWtIo1bKk9ppG6MpHHJ9YSlJ2ldJVCICBQVAsV27NcDqHFt4MsBXDx/Qbgx6GP1R5UqVenRez2edP4uIEDXq7ugEskEIkAEigCBkrCchZF/ktI0Yli+505evvF46YfHy4/FOL5X+5ATmcGhjQgQASJQVAhwZ8LtrBRkZWezl66JSycVFe3c9eBLWPAZyGXZm2cK2oHsXjIdEQEiQATuLgLFaezXI0/XBj1CdJ4IEAEiQASIABHIC4GS4ESm5Szy0kIoLxEgAkSghBDgztjy3mVKiLVkJhEgAkSACHACNPZTOyACRIAIEAEiQASIABEQCfCZwLQRASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARUCRATmRFLBRJBIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAKcADmRqR0QASJABIgAEShGBNKSkpCc7q6wUpx7CjoiAkTgThOgfnmniVN5RIAIEAEiQASIABEgAgVJgJzIBUmXZBMBIlCkCVw9fQInLyXm0DE7KQ5HjkQhpWi/Py6H3vkSYUvC4hEvYtKqU+riWJo9K7/F9qgb6mnUzhiRr5bXaLxYxsq/jebI33R54aOhickWhx9nDMfLI0dixLDnMG9PDHLE7f7HeN0UkJ6qJtzp8pQUKQo6KOl1N8cx5rpjyl1mf45+yfqq25Zf7VBkmx9jXX7p5GZoHg9E+7SuR3kswkh2+W+Fa+dO4GhUFKKEzxG2P424JJ0fDHJb5LzZ8VfDX8SKqNtGVKI0RIAIEAEiQASIABEoFAL0Yr1CwU6FEgEiUOgE2B+2dTNm4VCnMVgwJMRNndvnNmP27J/x7oLFCC5jcjt3tx0knI7EvlvB6N2ystM0c2nAlpHhPJYHTLbr2LhpO26ntETXRvfIT+se68nXFWAggVBGpoGECkmUmCgkU43KKx81wTE7FuN/UZl4NmwamvvchleVaojZMdstzruyD2aNNlY3BaWnmv53ujwlPYqCDkp63U1xSv3nTvT5/GKopL+nspX6qlRGfrbDvIx1BaWTVG5ew4XeduS/Ffjx9FnYk5LzAhPSexRGPd0Gvio/G6S2KLUBb5V8eWVI+YkAESACRIAIEAEikF8EyImcXyRJDhEgAsWOQKmyQFlLzn9tJosvbCb/YmdPbhQ+uHox1ld53c2JzOWYLBZVcTZzDUyevwBmPz/VNIV6wmRBaVPOejWqkxoTo/kLik9i3FVk+XVHz8bVnKqcVIgzWjcFpadTOVngTpcnK144LAo6KOl1N8Wp9R+tMaUo2a+mvyc6KvVVaf58a4d5HOsKRCep0LskLP+t4OMLVOg8Hh8Ptt+ATmNPL+1cNhfLNs9HWPIofPpiG13LldpAps5kZl2hlIAIEAEiQASIABEgAgVMgJzIBQyYxBMBInAXEGAzj3YsW4DFW+3LI5grhGDUhBFoVcWEVR+8iQttx2JMn/qCoQnHV2PszF14+p1w9AhmXmq2HV4xGZ//2xZzxj8MXyRg+5K5WLLjrHAuoNnDCBs1CPfaohE+cipqvDIDoe1cs4Iv//FfTPjsAqbMm4Ra1lvKeUsxhynTce2H02B+4lmYtn2FVUeuo1bvCZg8uIlQTs6vdOxaOAmLj7PFdY/Pwku7Ae/6oZg3voOQNOGfvfh8+mfYd+ImO7ag48BRGNqnBQuxjZW1Zf67uMbsfumhIBaRjqNbvsPn3+9Goo3/C7agTvvHMXr4o6hgxJlrU2HC7WLbrXMHsPjrNfjz3CXhmDMbP3wQAv3s521pcfh+/hxsOXJRON+yz2BkJ2ULYfuXUf1UmEzoDotaG6haRlKOIyjnw47XzZyGxNa9kLRrKfaeSxUS3vfoKLzSXzJrTZVDBv5YuQALN16DF37Cc8/9hHp9w9DbtkUW9zbeeaqarG5YUaz87d8uwJLt9vZrMwfi1fDJaFclSyGtRl0YtiOfyst1u9KobyS725xXm6ryafsazKStI+08pr32PoKGTMGQjrzf2Le4w8sx5pNovP/pJAT7JSuPNbydsfxzR09FyPjZzrGF1+26iDdxvmUYRvWsLYp07Z32dUX8tqX47VIWO2dBr5cm4JkH7WMWT6zax7wv6OvsfFpDpf8YGVO4EkY58rR8Y7YptmuhTlTGbKG/qrWPXjjyucKYyPu/vUTXNytb8ZpQ1Uehr7J+2d/FWhDC8ruNoc560h4j9Mc6zkW9PR7fMAsz1gPvzR7neMomHbu/+hBfH6+Djz8ahD3Scd2gTnzm9oyIL3Ep3T72V6kSgNtXrqDeM+/jDYU2qdrWHOO5C7JKSJU96yMFpLOSJqVhv/7wc6X8AtBrWDju8XkX87fPx4G+X6DtvWxs0NqYrm5tQJ6WnV8/512sjmmIWXOGoRI0rv/yvHRMBIgAESACRIAIEIECIkBrIhcQWBJLBIhA8SCQwpZt4As3pKenCx8eTklPliifjk0RrwsO5J7PjcU7E19HG98ofDrpDRyM84V/uSwc2n7QuX7yX5s3I5P9id/w6xlBBl8bc/eWc/AJrM4ecU3Hz3PGMQdyDPq8NBZhrw2E6ehmhE1Zj5RS1RFS3QvbVuxwyuJ/iCPX7IJ31RBUtmao53XMXrqddgWr50RgzfWGGDb8JfS5r5LEDnnQB3W7PIk6XmZ41+qO0aNHY+RjzQRnidVqQtKJXThTvismvTMRzzJH8d4Vc/Hdb1edQuKvJODYlXjhOOXfX/DRsl1o0f8VTJw4Ea8M7oRSJiukf7KdGXMENJg47Lpx5hD+tdbHqLCJmDC8N+KP/ITw5Yftkhij1R9OZA7ka3h0RBjeDRuG+M0/4FBqFnwdt0mN66fGRKMNxEqd1S7jpHx4bELCFWz59mucr9LHwbQ2/towH99Eiky1OPggMKQzOjUsjWyvBniZ1VX/tlUU4uz17V62XXfuQO44YDjGjh6GTk2DUbFcKUFZeVrV9umoCyN28P6SH+UZrzcXdx7Sy+dus7G6UbdJq97c9UKpQLSp642fl27FbeFmCzvP2u/eFdtgrlAH1fwy1Mca1s5sGSk4nZaO27KVZuKvZuD09SRZYa5De519i+sNBrD++SaeZDeptnwVju/+FNseoNrHdHV2OdIAtf4D6I8pHnAUTNNq19r9Vb19qOvvoslDWvK9VfuluwzA43ZoYKzjumn14UZdHkPV9L8xbfZmQZ3YP5bi6z0X8MjQJ9gNv1zolHoSU6Z+icSWgxDx8UcYP6QDLl++jEo9X0boA64nJqS2q7Y1aSLVsBZ7+1isO0blQmdVdWQnWj/1fyjDbpzGXJd1Ulk68VDeBsR4Pi78NOd1djP4FkaMewaVTPrXf2deChABIkAEiAARIAJEoAAJ0EzkAoRLookAESjaBLhjI/6XuXjpFwU92WxNvmVd+x0/RGWgy8iZeNYxQ7h+eDhuvvQWlvx0HBM7t4FtwV+4mDQI9awXsOtYJkxsZL2+OxI3Q5vD/2Y0/sjMwuNtagqyvjuSjj4T52NgIz5LuTkmT0jEyIh1OJ/UF10GdcGPET/haNxAtK1kRlbs31gfk4EeozvCJ/Z3aOVt4FhZwhz0MBZMfVp1TUbBKMdXUKO2aFR+MVKbtkOzZo6ZcuzPa3KyDZaQFzBrRGchZcPg8Ti/fzQOnYwFHAz4CdFJnJ58S0hXr2kIGtVkdjVqhPuFGP0vzlfTLjbLsVbXlzGnqyirEV6L/hOzI48i5YUW8Ln0h8Co55tzMaCZfX3md2f7YdgbHyPbsWSlJ/opMcm6FqnZBlrK1tQWNRX58GNbCpv/yZhOkTE9doExRWXdttGgUUu0P1YZP1+og7atWjlmRlbIGcfqj29i2WL7bTdsJoZ1tM9wb96qo5AGDsewNK1mXbA2ZsQO3l/yo7zAXLYrzfqW2cxB5MUmI+3XDpt/+6Bdv974buo6/Hn+GXSpyW4KxJ8S2m+XkQ8JfVxrrGk5MMd8WKdosQ6dEZIAt8/a4RW8O9TeKxs1aojMiyOxcc1veKrlY8JYodXHtHSWr/2q1H+4Q0xvTPGMo2tcVmpnYptXG7M/bK0+XinqL2HJg3ryPxmi1FdlQhyH0nrTbYcGxjp9jg0waXxfjI5Yjk9/uIVLm3fBv9MoDOJjp2zs4Crq6ZQQfQixNm+8FdobgWysDuwWij4b9+FPUwAq+vkoGq3V1uTtSS5Aj33L0NoForNcD9VjWwZS2Q2ihFv8RrT9SSTVtI4T0jbAo6zeyfj165lYfiQDz384H+2qlWFtLlL3OqlXDp0nAkSACBABIkAEiEB+ECAncn5QJBlEgAgUSwLcsVGufSjGP97Y+SI5vm7nraj1mPldtGBTYlyMsD7yg03uddpoM1dBn05WzD18DOUebQ1LdiSOXklDVds+nLFVQ9jE3pgT/iWOxo5As/OHwJcPaF2nDBLPXBFkbJo9BnutViGckJAg7A9fSETDht3YzOBfsGZnFNoOaILoA5tZ3uroGlJBN2+Dhmbhz3PgAy0NOZCFQh1/eJVeohcQFCAkEb/4GpC+CutH8/P+dTugTYUt+Oa9UVhesy0G9++Dzs1qiVk194lx2kwaMGd7auwZbN+6FTsPROFGUrJQV+YAu0Mtkc3w5Y/nN6tRwVmOuXx9dGDTkE87YjzST4GJXhtIsYUYYq7EVHQgGOGQabPPkOfrZopVoRTnBMECou49W7jar/S8NKyrA2tjfNO2w95f8qW8XLYrj+rbASC3NukyE24WOQphO//gzmjtvRErth1FF7Zu6vkDvyCDjQ+dWf0kntmpOdakDGzhEuRhyN9fusa7Dxo1r4L/7bSPPVyUVh/T0jmHGgr9R0yjxFgcUzzlqNWuxXNqY7bPwPvVxysN/UU79OTz8UCvX4qy5HslRs4xwsBYZ4Sjf+OnMLbPMczZuAlZPg9g3gut5Wq4HWvpVCaAL6GSgb9OXkODVpVhSzyLgzczUaacmwi3A6225pZQ4UCXPXMi8y2/dVZQRTGK/37gSzhZfdVv+ChmdESWYr78VRFvC9c4foOkC78pyzYj9eoQQTsiQASIABEgAkSACBQoAXIiFyheEk4EiEBRJ2AtXwM1qlZ1UzMljTlQbX+7xeU4YC/f45tX+TpseQsvHPnrBAKTdsEc1BdN6t2H1hYv7GZOT+/Lh4S4Kmx93xTH/8ouA15EiL8JfKIs/9PJ/BaoVaMMcxiXxePdKuKjrZG43b8Wtq39F/4dR6Mqy3tLJy/YWq98U3IICycK8qtUDYz6+HOcPXIAG1YuwqLZB7Ck9lP45P2+KMv+UGtt7L1QwqbGJOvaAbw6fgGy2TrUA/oPQZ0q5fHP2hlYddmez2TxZo43q3PpCrGscmyWuXPLg35OGUoBRxtQOuVpnB4HT+WJ6TkfvvGVcPU2fR3sbUxLTr6Wx95mlat2pVXfWsqrnNOySZ+Zu1Abm6HZd2Bj/L78f4h9vjF2ro2Ctd1w1GF93OXSdc8DWTszy3655fYlkux5A6EgvT6mpbNM01wfespRq05UlRA55nP7cJYnyndG5G+A26w31hnlaMt0PKbBLz552LzubYEX2gdg0acT2Grtjq1iZ8zqXk88ctvrtTW3xJ4ceMDeU509USP5QjSbmc16Fruu52bzZddLXiW8i+//bhUGPDCSLWVhYr8T7NLUrpO5KYvyEAEiQASIABEgAkQgNwRkf0VyI4LyEAEiQASKLwGTsCKyu/4Zjv/XPJbPtDLZNuEgmykc7JhVyNc53rP9Bnzb1EVpc3m071SNzepahK/Y48Bth7VknmE/3N+Txa2ci7NM/n1Dmwrumixf+2xAa40QtJbNUBQ1aNajL7y2LsK69T7Yn5GFF3o3FE756OV1PKYvyvFkzx3Zed98ULtZR7zGPpf2fYKJX2zDVbZER1mF985Jy9Kz6/SezcJMzXC2lnR1s90xfCbRJcFisbL6ScARSf0gLQYHbmQKf8RdKT3TT8pErw3oPYLt0kE9pMdBPaf2GYvFX+DDZ7rzWd1am64OBtpYvpYnKOtZvbnsU8nnWPbFlU4/pGWTLjMF8TUfYP3i++lYtnQZjiRn4unu9j6u185KZ5rYizmBS1eZM7+eoy5ZW+czP/U28YkHMd256Mvw8m0iHJ49qN3HeCI1nUV58r20/8jPKR17ylGrTvQ42vurdvvQ0t+YfCUr8xZnZKwzwjHh+A+Yu+U8HnjkEURv/glvfbEPC4cbXYAopw3pt27Bp8nTmD6MzWhmN/QCyqt3MiNtLWcJrhhd9q6kmiFPdFYTJN6EEc/bEs/gi49WIts7BA821LnwiZlk+8QbNvSe+DGeDjqNl0Z9jLfnNsCCsd1hpF5louiQCBABIkAEiAARIAIFQoBerFcgWEkoESACdwsBr0pN0DfIgg3sEdPtUReRGH8Z6xdOE9Y5fsrh/KnTpoXgqMsw+aObY9mABvd3ZggyhNnGHULsM51LV+sgyNo4YwzW7D+O2NhYnD6+F0tX7XO+TM9cqTW6V/PG1tU7gIrd0bKq/QVoRvJy5qniQrdiBaSewbihQzHxe4WZ1Wx6k385Ey5H7sSpS9cQG2dfT1dRjihPshfLSrkYia++343oS7GCTWeiYyWplINiXj27KtWoA1P2Few/8I8ge++KmVhxNgPm0na5vjXvZ0tXeGHNrHn4/TSz4doZfDdtpjAbzE6OvWjNE/0UmBhpA0pWijaK5+THYjzf63GQpjUSFsvyrdkBne7xwoaZU7Hj+L+MzzkcYEuDnIpNc4oR0xrVQUzvFCAJ5Gd5mvWm0a418zl0ldsgP5aYBC2bjDKTyjOVaYCBba04uG0v0q1seYu6doeTXjsz+QWhWQUvHFi9CscvXkM8a+vfTIvA5WwbxLYuLUcM87Xfk/d9ga+2/o2ExFgcXD9XWOO75aMdhWVY9PoYl6Oms1iGc6/Qf8RzWow95ahVJ3ocNduHhv6iHXryxXRG9nIm8mOpDCNjnR5HW+JJTJ/1E3P6huLlQYMw7o3uQtuQvmRRroP8WKoTD9+8akPmpWPY9dtB7N+zEas2/ILoWMmdPkkGI21NktwZFHUwyl5M7xQgC3iisyyr8zD+0glERUWxzxFsWjoHQ1/9UHiha+j44cLsYWdCWUCum/SYL1XkxdKbyt6Hqa91Qdrh/+Kz7Wfz/fogU4kOiQARIAJEgAgQASJgmADNRDaMihISASJwtxHgzhXVzWRfroLPKu7/3hQkzfkAS2awl+mxDDbmLO73+kz0CLbPBixXvQWqmNfjWs3uqOFnl+lbrQVal16GA+b2qBfgKIfJeuq9GUifF461CyOw1lG4X/NQDBRVYWm69W2HbZ9Hom3fh1zLQejldcwSrVjO/WVGqXFnBYfq4y1qKJjqg46D+mFdxA8InxSJbL/u+M+CfkI6uRwlVmIaPpt7z+Zv2EcswoK+Iz9AMHvRktom5uV8tZj41u3G1oXcgw0Lw7GBCTPd0xb9H2mMVQccklldvDw9DDfCZmD+lPFCZEDTLuyFgbuR6phh7Zl+SkxCdduAkp1OGx0n5cduTHU42EX4stmj8pKU4tj9B7EdMLkvTHkb2TNnYnHE+87MofU7oH6A/T6yNK1WXYj3J5zpHdLkduRXeVka7So1Rr1da9a3Sj/JtU2Vymq2XydwWaDtI32x6LflaPzoQ8IaqsJpVld6Y80Tr4fiyAeLEfGWvQNUbPgA6pbah2yNpwn42u+VQtrixLJZGL3UDiC41yiMfChIKNZfr485dFfUWWYXf3lgrsYUQ+1fUphWu2Z1osUx9aLWeKWkf6j7mucG6omtIK/QVyX6O4Lydic/du9b+mOd3ni67YuPcNFUH+GvdxM0CGj+f3ix41/4av48dFo4UYiT6yA/luqUcvEQtlzPQJbpAn7feR3ZKcm4Gp+A9Su/x7hPvkTT8u7XAKNtTU7KqYMee8fLAZ3pHYLyojMXIc3Pj/nN19QjqzHjCD/imwVNHhyMZwb3QpDjN4A9Pue3XDfpsbcEV5XWz2P4Q2fw+ZJwHGj6n1yNMzlLpxgiQASIABEgAkSACOSNgOTniqogaRoxLN+LM5p5vPTD4+XHYhzfq334jXh+ju/lYe74Fs/xsJhGvhfTNElOTn6bpaONCBABIpAnArb0JCSz9Qp9/Pwcq4nmXpwoy2Lxg4+731dXqCd5z/3yEd5ZZsOnX41zOatylJCOpKQM+DG78rIlJdlnMudWjpZdaUx2JqPu56cOy16+ehrP9FNmIuqYH21AjbVYRm7ahppMHm9naKz95ocO+VWeUr0ZaddK+bT4GDmnZZMnzGL/+Abj5kUqOtq4HqIstXbGbTOxscOq3h3s5jCn2rdjRyPqgTBM719faANZKvn0+piezu78lPuPexrlI9F2o+3fSJ0ocdRuH8b0F3VVkq9sXf7E2nVXH+t4KaJuRjl6rBlrWyvefB3bqofiP2M6u7KnnsSrw6ejc9g8DFRZQkevrbmEqYdE+zxinwed1TW5s2dEuwusXu+sOVQaESACRIAIEIG7ioDVag1nBvFHgPkrabIdex6Wf/h6dGIaMSwei2nF/Hyv9uEzRMRzPCx+eJwYFvcsSkjL9zyOb/K9NE5IIP+imchyInRMBIgAEVAhYPLxg4YPUyWXcnReZHmSNz3TG+0GPa7hQOb6+Wg6Z5UtyBmbW+exKEnLrlLMwa31yD6XoVe+3nlRD/temYmWju75c39UUGUYYShqnR865Fd5SvVmpF0r5RPty+1eyyajzPiSAp99thvmus+ioWympqiXnixPbRNfuMn1V9u0bDOis7tc5f7jnkb5SM92eS4tvbVkaTM0pr+WfLme+Xmsrbu9pDuhW3IKW8riVrKwHJN9rel0nDwQiUT2cjlfjaX2terMKKfc2pdbnY3qVdDpcmt3QetF8okAESACRIAIEIGSQYCcyCWjnslKIkAESiiBer3eQL0SajuZffcSKJbt2jFDkzvYbOZAjBvRLc9PNBip4bTbwO0McZKBkRySNIWks0QDChZVAmxpid7De2DHnOUYPnS5m5ZN+45BX8dyT24nCvugOOpc2MyofCJABIgAESACRIAISAiIy1JIonIEpWnEsHzPl47gG4+Xfni8/FiM43u1j3wJC55OXK6ClrNgMGgjAkSACBABIkAEihOBdFw9dwE3M7xRtUYNlPMRf0oVrA1XT5+ALaA2AsvrzeVX0qNwdFbShOKKJgG+vMLF8xeEGxU+Vn9UqVJVf5mVQjalOOpcyMioeCJABIgAESACRMAAgZKwnIWRfzDSNGJYvudOXr7xeOmHx8uPxTi+V/uQE5nBoY0IEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQgaJNoCQ4kbkTlzYiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACigRoTWRFLBRJBIhASSCQZcvC7awUZGVnw2bK5ZqhJQEU2UgEiECRJmCymeBlNqOsly+8TPxhLtqIABEgAkSACBABIkAEiAARIAL5S4BmIucvT5JGBIhAMSHAHcg3MxKRyfbkQC4mlUZqEgEioEiAj2F8LONjGh/baCMCRIAIEAEiQASIABEgAkSACOQ3AXIi5zd5xvOxAAAgAElEQVRRkkcEiECxIMBnIAsrthcLbUlJIkAEiIABAuwtFMLYZiApJSECRIAIEAEiQASIABEgAkSACHhCgJzIntCitESACNw1BDKzabbeXVOZZAgRIAJOAnx5njxttiTsWfkttkfdUBfD0iwe8SImrTqlnobOGCdghLlxacop70QZyiVTLBEgAkSACBABIkAEiMBdQoCcyHdJRZIZRIAIeEiAzdhT26J/+wW7fzujdhq2zGTciIvD7aR01TTqJzJw63ocblxPUklil61+ns00jE9AYmKyYn6uG5efO90URXoYqWeftri0VLv+avYB+ny0Ssir/ILnq8dPz36988hj+9Vuf1rsjZ3T1z8tkfUf1v+SMnOuY65fv8a00Eql1f+08tnP6dunJ0N3fMrj+u4m23Vs3LQdq3+/5FQl4XQk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4k5Y2ogAESACJY8AHy4993EJnEzeVrbecW6RMeevY61kJQlGZGvlV5J5Z+O07dPTxYex9dFga4SPVhkFLV+rbGPntPnp2a93nutgJI2Wrlrtr5RwY0Urt/Y5I7ppla9Xv9qlGzurVb6eBCP26cnQO2+y5XJg0xMMH+b49NAz65BpYktgaGXVd6gaK1uvHC0T85JXKlfPFr3zUlla4eQU+4xhtnPMzE7HyQOR7AWNNvgqeepVhbmzLeWnMQCryqATRIAIEAEiQASIABEgAiWBADmRS0Itk41EgAjkIOBt9mKP6/KbfLQRASJABO4eAl5m/iAWbXc1AbZ8Ru/hPbBjznIMH7rczdSmfcegr2O5ELcTdEAEiAARIAJEgAgQASJABPJIgJzIeQRI2YkAESieBMp6+eJmRmKuZyMXT6tJayJABO5qAmxWallv37vaRDLOTiCw+dNY/GVfXDx/AbczbPCx+qNKlaq0DAU1ECJABIgAESACRIAIEIECI0BO5AJDS4KJABEoygS8TF6oYCmD21kpyMrOZi98EpcDKspak25EgAgQgZwE+BIWfAYydyDzsY22kkGAL8ERFNywZBhLVhIBIkAEiAARIAJEgAgUOgFyIhd6FZACRIAIFBYB7mwp712msIqncokAESACRIAIEAEiQASIABEgAkSACBABIlAsCNDCecWimkhJIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIQOEQICdy4XCnUokAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIALFggA5kYtFNZGSRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQgcIhQE7kwuFOpRIBIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASKBQFyIheLaiIliQARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAoVDgJzIhcOdSiUCRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgUCwLkRC4W1URKEgEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABAqHADmRC4c7lUoEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEoFgTIiVwsqomUJAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBQOAXIiFw53KpUIEAEiQASIABEgAkSA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IUZQlzAVh59B/olZsJcC2wee2AtRH3lqKo9TgAIUoAAFKFCwBTidRcHuP9aeAhSgAAUoQAEKUMClQABuq1IDt7k8lr2dMggrg7HxGcnIyMwUN8pTp1fLXj55lVpOYSFHIIf6i5tgFoIAsnQraH3gqa8LYx95ajOPU4ACFKAABShAgfwuwOks8nsPsX4UoAAFKEABClAgnwvIIGaEf/F8XsvCXT32QeHuX7aOAhSgAAUoQAEK3GoBOU0EFwpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKCASwEGkV2ycCcFKEABClCAAhSgAAUoQAEKUIACFKAABShAAQpIAQaReR1QgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKCArgCDyLo0PEABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIMIvMaoAAFKEABClCAAhSgAAUoQAEKUIACFKAABShAAV0BBpF1aXiAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFGETmNUABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAK6Agwi69LwAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCjCIzGuAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFdAUYRNal4QEKUIACFKAABShAAQpQgAIUoAAFKEABClCAAhRgEJnXAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCugKMIisS8MDFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAUowCAyrwEKUIACFKAABShAAQpQgAIUoAAFKEABClCAAhTQFWAQWZeGByhAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIBBZF4DFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAUooCvAILIuDQ9QgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKAAg8i8BihAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUEBXgEFkXRoeoAAFKEABClCAAhSgAAUoQAEKUIACFKAABShAAQaReQ1QgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKCArgCDyLo0PEABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIMIvMaoAAFKEABClCAAhSgAAUoQAEKUIACFKAABShAAV0BBpF1aXiAAhSg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ZHv9ZTcO3r3ts3/x5nb9vv3t1Ac/ub36Zx43JD63/dUn/6x908PPaHtvura9+q03DXmt7dt7S/ufL3lm+4FXnt4+etWn2m99z4faT//R4mszPvHmf9e+7dmXtT/92HXt6re+sD3m5M+2Kya+7vjLv+sZ7Zn3P7s977WXtvf98ve1e1z51vaoJ/9g+97XXNr27r+hveyp17VveOLPtquGA3Dme+1Lf6r9t888oX3iY3/cHnbaod+dafxln310u/yaT7U/+skd7Z989y+0Tw2H46znKT/2jnE9e275eHvCZT/XvvE5r218ecaeWy5vn7htvddNH/lgu2W4/x37P9V+5onf2V55wQ+2y6+/pV3/mU+1J150r/He77//L9r3Pe1N7aff/4n27pf/UPvJn3rt+BUfl//pC9q3/exV7W2fvK5d9db/3J70lWcO+WuHyDuGPxj1jue237/6MYetb2y69rLv029oj3rS09oX/+pb2nW33tqu+sAL2oX33LH0Htptn24v/Il/2C5/1M+0qy57XTvhN/9le+y3/WH7D5d+sv35b/zT9hM/9uZt/QqSut7oIRACIRACIRACIRACIRACIRACIRACIRACIXBnJnB3OEQuv+a6eKt2nvvI9rQzLm9ve+e72jtef2p7/Fd+VXv8F5zR3vOud7U/e+Vft+983EWtDb+x/Hlf+MD27v/xwvbz/+XV7d67dg6nwvvHBjvb4kD1QLtHO/3M81u74Jx2jx37264ThoPVE4fYjsX3OOxou1u78EfbJb/3I+3UE05qD774Ee2c04bj6eE3Zt/5R69oT/yZn2+ff+redlM7uz3l27683bjn8Ldj947T2zkX7mon3/PUdsIJ+9rH3/e61h72n9q3POq+7dprbm+P+/s/3B53/Yvbuz9267CqYb7hQPvlP/0d7Z479g2rO3SM8Qf/XPutH/+OdvL+k9rXfMe/aO2WT7Trbtvb3vf6PxzW8wvjeq67+ZT2Q//uWe3yP3ptu/zWA8O83NP62k5e02/92Pvbr33muvYf//XfayfvvrntHg6Bzzxl4DSMT9+2u73h/7y0ff4ZO9u593/w8DUVZ7Sdw5H0pW96eXvis36iXXyPPe3Wdv7wFR1f3m7wL+kdGNY/sb5rbzv0Pv56OMRv535/e9q3PqLtuemmdsJJJ7V7nbj8Htqem9sXPOst7aee+kVt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QAABBBBAAAEEEEAAgYYqQBC5oY48/UYAAQQQQAABBBBAAAEEEEAAAQQQQAABBGIQIIgcAxJFEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBhipAELmhjjz9RgABBBBAAAEEEEAAAQQQQAABBBBAAAEEYhBIiaFMnS8yd+7cOt8HOoAAAggggAACCCCAAAIIIIAAAggggAACCOwLAWYi7wt1rokAAggggAACCCCAAAIIIIAAAggggAACCNQRgQYxE7lbt251ZDhoJgIIIIAAAggggAACCCCAAAIIIIAAAgggkFwCzEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAqn1DPwAAIABJREFUAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJEEROrvGgNQgggAACCCCAAAIIIIAAAggggAACCCCAQFIJEEROquGgMQgggAACCCCAAAIIIIAAAggggAACCCCAQHIJpCRXc2gNAggkk4DL5fI3x+l0+tdZQQABBBBAAAEEEEAAAQQQQAABBBBoOAIEkRvOWNPT+ijgKZJ1K9dKgcdTTe+ckpWTLdnZmZKdmVlNWe/h4l+myZWT3vKXHfn3B2V090b+bVYQQAABBBBAAAEEEEAAAQQQQAABBBqGAEHkhjHO9LKeCniK1spDDz0UQxA5CMCWLT2PHCajRg6Rrs2zgg6ErpZJUegOthBAAAEEEEAAAQQQQAABBBBAAAEEGqQAOZEb5LDT6foiYNOvgRrZ4uyNZ6csm/2e3D/x7/Lom99LWZynUxwBBBBAAAEEEEAAAQQQQAABBBBAoGEJEERuWONNbxuAgC0lRVLCHtG6vfSzZ2TSu8uiHWY/AggggAACCCCAAAIIIIAAAggggAACQjoLXgQI1CeBpsfKI/eMkfQIfSrM3yiLZ0+V59+bF3L0948ny8LBj8tBzflOKQSGDQQQQAABBBBAAAEEEEAAAQQQQAABS4CoES8EBOqRgD1S9Liif1k5reSIEy+UJ++8RFNgBOfAKJPPvvu1HinQFQQQQAABBBBAAAEEEEAAAQQQQACBRAoQRE6k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AhSgAAUoQAEKeASOhSAyy1nwbqcABShAgWNWQP2pf5PW7Y+p8z8Wz/mYusA8WQpQgAIUoAAFKEABClCAAtUgoDKBOVGAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFggowiByUhSspQAEKUIACFKAABShAAQpQgAIUoAAFKEABClBACTCIzPuAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFQgowiByShhsoQAEKUIACFKAABShAAQpQgAIUoAAFKEABClCAQWTeAxSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKBBSgEHkkDTcQAEKUIACFKAABShAAQpQgAIUoAAFKEABClCAAgwi8x6gAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKECBkAIMIoek4QYKUIACFKAABShAAQpQgAIUoAAFKEABClCAAhRgEJn3AAUoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCoQUYBA5JA03UIACFKAABShAAQpQgAIUoAAFKEABClCAAhSgAIPIvAcoQAEKUIACFKAABShAAQpQgAIUoAAFKEABClAgpACDyCFpuIECFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAUYROY9QAEKUIACFKAABShAAQpQgAIUoAAFKEABClCAAiEFGEQOScMNFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAUowCAy7wEKUIACFKAABShAAQpQgAIUoAAFKEABClCAAhQIKcAgckgabqAABShAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEGkXkPUIACFKAABShAAQpQgAIUoAAFKEABClCAAhSgQEgBBpFD0nADBShAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKMIjMe4ACFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAVCCjCIHJKGGyhAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIBBZN4DFKAABShAAQpQgAIUoAAFKEABClCAAhSgAAUoEFKAQeSQNNxAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACDCLzHqAABShAAQpQgAIUoAAFKEABClCAAhSgAAUoQIGQAgwih6ThBgpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFGAQmfcABShAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKhBRgEDkkDTdQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKAAg8i8ByhAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUCCkAIPIIWm4gQIUoAAFKEABClCAAhSgAAUoQAEKUIACFKAABRhE5j1AAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACIQUYRA5Jww0UoAAFKEABClCAAhSgAAUoQAEKUIACFKAABSjAIDLvAQpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFAgpwCBySBpuoAAFKEABClCAAhSgAAUoQAEKUIACFKAABShAAQaReQ9QgAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKBASAEGkUPScAMFKEABClCAAhSgAAUoQAEKUIACFKAABShAAQowiMx7gAIUoAAFKEABClCAAhSgAAUoQAEKUIACFKAABUIKMIgckoYbKEABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgEFk3gMUoAAFKEABClCAAhSgAAUoQAEKUIACFKAABSgQUoBB5JA03EABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIMIvMeoAAFKEABClCAAhSgAAUoQAEKUIACFKAABShAgZACDCKHpOEGClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUYBCZ9wAFKEABClCAAhSgAAUoQAEKUIACFKAABShAAQqEFGAQOSQNN1CAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoACDyLwHKEABClCAAhSgAAUoQAEKUIACFKAABShAAQpQIKQAg8ghabiBAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFGETmPUABClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIhBRhEDknDDRSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKMAgMu8BClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUCCnAIHJIGm6gAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKEABBpF5D1CAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoEBIAQaRQ9JwAwUoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCjCIzHuAAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoAAFQgowiByShhsoQAEKUIACFKAA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KEABClCAAhSgAAUoQAEKUIACFKCAbwkwiOxb54O9oQAFKEABClCAAhSgAAUoQAEKUIACFKAABSjgUwIMIvvU6WBnKEABClCAAhSgAAUoQAEKUIACFKAABShAAQr4lgCDyL51PtgbClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAI+JcAgsk+dDnaGAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoIBvCTCI7Fvng72hAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKOBTAgwi+9TpYGcoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCviWAIPIvnU+2BsKUIACFKAABShAAQpQgAIUoAAFKEABClCAAj4lwCCyT50OdoYCFKAABShAAQpQgAIUoAAFKEABClCAAhSggG8JMIjsW+eDvaEABShAAQpQgAIUoAAFKEABClCAAhSgAAUo4FMCDCL71OlgZyhAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEK+JYAg8i+dT7YGwpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACPiXAILJPnQ52hgIUoAAFKEABClCAAhSgAAUoQAEKUIACFKCAbwkwiOxb54O9oQAFKEABClCAAhSgAAUoQAEKUIACFKAABSjgUwIMIvvU6WBnKEABClCAAhSgAAUoQAEKUIACFKAABShAAQr4lgCDyL51PtgbClCAAhSgAAUoQAEKUIACFKAABShAAQpQgAI+JcAgsk+dDnaGAhSgAAUoQAEKUIACFKAABShAAQpQgAIUoIBvCTCI7Fvng72hAAUoQAEKUIACFKAABShAAQpQgAIUoAAFKOBTAgwi+9TpYGcoQAEKUIACFKAABShAAQpQgAIUoAAFKEABCviWAIPIvnU+2BsKUIACFKAABShAAQpQgAIUoAAFKEABClCAAj4lwCCyT50OdoYCFKAABShAAQpQgAIUoAAFKEABClCAAhSggG8JMIjsW+eDvaEABShAAQpQgAIUoAAFKEABClCAAhSgAAUo4FMCDCL71OlgZyhAAQpQgAIUoAAFKEABClCAAhSgAAUoQAEK+JYAg8i+dT7YGwpQgAIUoAAFKEABClCAAhSgAAUoQAEKUIACPiXAILJPnQ52hgIUoAAFKEABClCAAhSgAAUoQAEKUIACFKCAbwkwiOxb54O9oQAFKEABClCAAhSg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jkZEBIhAfSEQFtVYMPXnJdPx/vYbZmaXuycgQAjhw+ImK5LOORITp41Gi8buyN7xKd5L+1MhQadEgAgQASJABIgAESACRIBiItMaIAJEgAgQgTudgHsUXnx5Gq5qXREaEQEfCtNwp884jY8INDgCN4utD/m+SUnwYhF89mz4yUywkn251q1PEpqymMgB+TGsnpzIZpCogAgQASJABIgAESACRIA2Y9EaIAJEgAgQgTudgCuaRESjyZ0+TBofESACDZIAj2nct7W4E9kSAF6f0j0CuusspM+3J8xEKl3CDP8QaMuKzOqpgAgQASJABIgAESACRIAIcAIUzoLWAREgAkSACBABIkAEiAARqIcE+k19HzMGNhcsr8w7io27zcNV9H3qcUR7aLAv7SNkVUrvTzEOtuP9SQhku5Bx8zyWLdllrKAcESACRIAIEAEiQASIABGQESAnsgwGZYkAESACRIAIEAEiQASIQH0hsHP1Unya3x7l2UfwLXuhnqW0d90izNzjhL37My1VIyTYm72buwzHN3+JbWX8BeGUiAARIAJEgAgQASJABIiAOQFyIpszoRIiQASIABEgAkSACBABIlDnCdzMPIBv2MdaKj19BntPq0tsfC8VG99Tr6caIkAEiAARIAJEgAgQASLACTgRBiJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJqBMiJrEaGyokAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgHYi0xogAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAF1ArQTWZ0N1RABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQAQaPAFyIjf4JUAAiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAuoEyImszoZqiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAg2eADmRG/wSIABEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABdQLkRFZnQzVEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBCBBk+AnMgNfgkQACJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiIA6AXIiq7OhGiJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiECDJ0BO5Aa/BAgAESAC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AgQIECBAgAABAgRcIvsbIECAAAECBAgQIECAAAECBAgQIECAAIFDAZfIhzQWCBAgQIAAAQIECBAgQIAAAQIECBAgQMAlsr8BAgQIECBAgAABAgQIECBAgAABAgQIEDgUcIl8SGOBAAECBAgQIECAAAECBAgQIECAAAECBFwi+xsgQIAAAQIECBAgQIAAAQIECBAgQIAAgUMBl8iHNBYIECBAgAABAgQIECBAgAABAgQIECBAwCWyvwECBAgQIECAAAECBAgQIECAAAECBAgQOBRwiXxIY4EAAQIECBAgQIAAAQIECBAgQIAAAQIEXCL7GyBAgAABAgQIECBAgAABAgQIECBAgACBQwGXyIc0FggQIECAAAECBAgQIECAAAECBAgQIEDAJbK/AQIECBAgQIAAAQIECBAgQIAAAQIECBA4FHCJfEhjgQABAgQIECBAgAABAgQIECBAgAABAgRcIvsbIECAAAECBAgQIECAAAECBAgQIECAAIFDAZfIhzQWCBAgQIAAAQIECBAgQIAAAQIECBAgQMAlsr8BAgQIECBAgAABAgQIECBAgAABAgQIEDgUcIl8SGOBAAECBAgQIECAAAECBAgQIECAAAECBFwi+xsgQIAAAQIECBAgQIAAAQIECBAgQIAAgUMBl8iHNBYIECBAgAABAgQIECBAgAABAgQIECBAwCWyvwECBAgQIECAAAECBAgQIECAAAECBAgQOBRwiXxIY4EAAQIECBAgQIAAAQIECBAgQIAAAQIEXCL7GyBAgAABAgQIECBAgAABAgQIECBAgACBQwGXyIc0FggQIECAAAECBAgQIECAAAECBAgQIEDAJbK/AQIECBAgQIAAAQIECBAgQIAAAQIECBA4FHCJfEhjgQABAgQIECBAgAABAgQIECBAgAABAgRcIvsbIECAAAECBAgQIECAAAECBAgQIECAAIFDAZfIhzQWCBAgQIAAAQIECBAgQIAAAQIECBAgQMAlsr8BAgQIECBAgAABAgQIECBAgAABAgQIEDgUcIl8SGOBAAECBAgQIECAAAECBAgQIECAAAECBFwi+xsgQIAAAQIECBAgQIAAAQIECBAgQIAAgUMBl8iHNBYIECBAgAABAgQIECBAgAABAgQIECBAwCWyvwECBAgQIECAAAECBAgQIECAAAECBAgQOBRwiXxIY4EAAQIECBAg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z+VH/bMuJ0CAAAECBAgQIECAAAECBAgQIEDgbQTWi9Y+ddaP8vR27SiuPe1rPfNdbbe+601fxrm1rj82vvsxn9n6rta1i2IvTi9qPtO0O+eS2uxJvs77yLnWnrXWevasa+fOmWvdO+Oat79xPre1xnNr7REJECBAgAABAgQIECBAgAABAgQIEHi5wLnL0kvX2rfGvt2sN89a88TmrXc+13a19idmzP7OHxfe/egZt9Tmnmfze11yHp2z1i+Zz5413813tX7xriU2362ldrT+3Np6XuciAQIECBAgQIAAAQIECBAgQIAAAQKfVuCSi9bZM/O8eedr7LdKfbc26z3nqDbPmnnPnbXmic+tt3fta/3iuF6cXrxx03h01lq/dD771rzzGZvn1Zo37mpzbbc+a8nXse7v+lG96yIBAgQIECBAgAABAgQIECBAgAABAq8rcHRxelTP28y15o19287XOPd3rbXOZ2zenqPz1/ql86O+1q+K977w3J13S617GvOl1nydt+eoPmHa09i9s2etzd727WpdEwkQIECAAAECBAgQIECAAAECBAgQ+HwE5sVt32rWZn5ufe3rvDF7k3feuNY7T8xoX+OsPTa8+zHXW7+01v6r4r0vQc+dt1tba3PevLFfbM6Tr/P0tdZ4VEs9Y9e31h8blx9z37L0fnpJz/tmCQECBAgQIECAAAECBAgQIECAAAECVwvsLlHXQ57rmetHec/semPqzdfYtdY7T+zoWmPqM9/Nj2qpZ6z7n6o3/HyNC85zZ+7W1trRfNZ3+ayFovM1lqn12du1XW32t29X65pIgAABAgQIECBAgAABAgQIECBAgMDnI7C7VF1r6zxvP2szn2utN/Zbd94498x8rs/6ek7nu55L12bfRflrXYIenXtpfe3rvLFfbjdfa+ltrXHWetZam72zZ+aX9Mx+OQECBAgQIECAAAECBAgQIECAAAECn0ZgvajdvcXsmXl7Z615Y3sSU1vrR/Ojes9b12+td9/V8TUvQY/Ovqa+9nbe2C98NF/r6Z+1o7znNs6+c7WuiQQIECBAgAABAgQIECBAgAABAgQIfH4CuwvZXa1vPteO8rV39mXtaH5U73m7vV1b9z5X7/pNcXc5etNBm03PnX20vtbXeR7VWmMfv85n75p3z66+nrPO595z+a37zp1pjQABAgQIECBAgAABAgQIECBAgACB7wocXax+t/PjyrrvuXl3z76Z79ZTa09j++Zaa7ueXV/7G4/2df2m+NqXnM+df7S+q5+rnVtbYWbvzNe+zI/Wj+rrGZf2rfvMCRAgQIAAAQIECBAgQIAAAQIECBC4TuDSC9SjvqN632Kuz7zribt6a42X9s++o7Nnz+78uX5z/haXnM8949z6bu1cbbcWnKN64db1dd6+c/GWPefOs0aAAAECBAgQIECAAAECBAgQIECAwMsEbrlYXfes8/WNjtZbb5z7Lq11z66/a4nPrc/eq/O3vPh87llH6y+pH+0N1Lm1Qp7rObfW/SIBAgQIECBAgAABAgQIECBAgAABAp+PwLnL1nNr/QbneubazLs38V71nnl0XtfvEt/6IvSS5x31XFsP0Lpnne8QL+nZ7Wvtpft7jkiAAAECBAgQIECAAAECBAgQIECAwG0CL71cvWT/2rPO55sfrV1bv+TM2XOX/Iu7nHLdIZdcsp7ruXXt6C3PnXfPPUdnqRMgQIAAAQIECBAgQIAAAQIECBAg8HYCRxe3595gt2dXm2ecW791reef29+eu8VbLlDv9fBLnv1cz0vX+13OnXNurftFAgQIECBAgAABAgQIECBAgAABAgS+vwLnLmXPrc1v/FzfS9fzrOfOmO9zt/xTX5Be8/znep9bD9olPTvcW/ftzlIjQIAAAQIECBAgQIAAAQIECBAgQODzEbj1YvaSfc/1PLc+la7pnftenH8ul6PXvMclvZf0rHi37FnPMCdAgAABAgQIECBAgAABAgQIECBA4IcjcMvF7SV7Lump4jW93XPX+DlenF7zTtf0Bu7a/iPse51zdL46AQIECBAgQIAAAQIECBAgQIAAAQKvI3CvS9lrz7mm/5re11Eap37Ol6HXvtu1/YPhMX3p/vU8cwIECBAgQIAAAQIECBAgQIAAAQIEvt8CL73MvXb/tf1vovt9uTi99T1v3Xcp/muff+l76CNAgAABAgQIECBAgAABAgQIECBA4LzAa1/Q3nr+rfvOf9s7rn4fL0Hv9c73OueOvw5HESBAgAABAgQIECBAgAABAgQIECDwGQvc68L3Xue8CdUP4SL1rb7DWz3nTX7xHkKAAAECBAgQIECAAAECBAgQIECAwMNbXea+1XNe5Vf6Q70Y/aF+r1f5I3AoAQIECBAgQIAAAQIECBAgQIAAAQJ3E/heXxjvFH6Ml60/xu+8+92rESBAgAABAgQIECBAgAABAgQIECBwm8AP7qL4HIML1XM6+zVmexdVAgQIECBAgAABAgQIECBAgAABAt8XgR/VJfD35ZfiPQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECry3w/wE3OrlYJLDaPQAAAABJRU5ErkJggg==";
-  
-  if (typeof process !== 'undefined' && !process.browser) {
-    module.exports = bigimage;
-  } else {
-    window.bigimage = bigimage;
-  }
-
-})();
diff --git a/tests/integration/deps/pouchdb-1.1.0-postfixed.js b/tests/integration/deps/pouchdb-1.1.0-postfixed.js
deleted file mode 100644
index b832ce4..0000000
--- a/tests/integration/deps/pouchdb-1.1.0-postfixed.js
+++ /dev/null
@@ -1,5892 +0,0 @@
-!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.PouchDBVersion110=e():"undefined"!=typeof global?global.PouchDBVersion110=e():"undefined"!=typeof self&&(self.PouchDBVersion110=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/*globals cordova */
-
-"use strict";
-
-var utils = require('./utils');
-var merge = require('./merge');
-var errors = require('./deps/errors');
-var call = utils.call;
-
-/*
- * A generic pouch adapter
- */
-
-// returns first element of arr satisfying callback predicate
-function arrayFirst(arr, callback) {
-  for (var i = 0; i < arr.length; i++) {
-    if (callback(arr[i], i) === true) {
-      return arr[i];
-    }
-  }
-  return false;
-}
-
-// Wrapper for functions that call the bulkdocs api with a single doc,
-// if the first result is an error, return an error
-function yankError(callback) {
-  return function (err, results) {
-    if (err || results[0].error) {
-      call(callback, err || results[0]);
-    } else {
-      call(callback, null, results[0]);
-    }
-  };
-}
-
-// for every node in a revision tree computes its distance from the closest
-// leaf
-function computeHeight(revs) {
-  var height = {};
-  var edges = [];
-  merge.traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
-    var rev = pos + "-" + id;
-    if (isLeaf) {
-      height[rev] = 0;
-    }
-    if (prnt !== undefined) {
-      edges.push({from: prnt, to: rev});
-    }
-    return rev;
-  });
-
-  edges.reverse();
-  edges.forEach(function (edge) {
-    if (height[edge.from] === undefined) {
-      height[edge.from] = 1 + height[edge.to];
-    } else {
-      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
-    }
-  });
-  return height;
-}
-
-module.exports = function (Pouch) {
-  return function (opts, callback) {
-    var api = {};
-
-    var customApi = Pouch.adapters[opts.adapter](opts, function (err, db) {
-      if (err) {
-        if (callback) {
-          callback(err);
-        }
-        return;
-      }
-
-      for (var j in api) {
-        if (!db.hasOwnProperty(j)) {
-          db[j] = api[j];
-        }
-      }
-
-      // Don't call Pouch.open for ALL_DBS
-      // Pouch.open saves the db's name into ALL_DBS
-      if (opts.name === Pouch.prefix + Pouch.ALL_DBS) {
-        callback(err, db);
-      } else {
-        Pouch.open(opts, function (err) {
-          callback(err, db);
-        });
-      }
-    });
-
-    var auto_compaction = (opts.auto_compaction === true);
-
-    // wraps a callback with a function that runs compaction after each edit
-    function autoCompact(callback) {
-      if (!auto_compaction) {
-        return callback;
-      }
-      return function (err, res) {
-        if (err) {
-          call(callback, err);
-        } else {
-          var count = res.length;
-          var decCount = function () {
-            count--;
-            if (!count) {
-              call(callback, null, res);
-            }
-          };
-          res.forEach(function (doc) {
-            if (doc.ok) {
-              // TODO: we need better error handling
-              compactDocument(doc.id, 1, decCount);
-            } else {
-              decCount();
-            }
-          });
-        }
-      };
-    }
-
-    api.post = function (doc, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      if (typeof doc !== 'object' || Array.isArray(doc)) {
-        return call(callback, errors.NOT_AN_OBJECT);
-      }
-      return customApi.bulkDocs({docs: [doc]}, opts,
-          autoCompact(yankError(callback)));
-    };
-
-    api.put = function (doc, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      if (typeof doc !== 'object') {
-        return call(callback, errors.NOT_AN_OBJECT);
-      }
-      if (!utils.isValidId(doc._id)) {
-        return call(callback, errors.MISSING_ID);
-      }
-      return customApi.bulkDocs({docs: [doc]}, opts,
-          autoCompact(yankError(callback)));
-    };
-
-    api.putAttachment = function (docId, attachmentId, rev, blob, type, callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('putAttachment', arguments);
-        return;
-      }
-      if (typeof type === 'function') {
-        callback = type;
-        type = blob;
-        blob = rev;
-        rev = null;
-      }
-      if (typeof type === 'undefined') {
-        type = blob;
-        blob = rev;
-        rev = null;
-      }
-
-      function createAttachment(doc) {
-        doc._attachments = doc._attachments || {};
-        doc._attachments[attachmentId] = {
-          content_type: type,
-          data: blob
-        };
-        api.put(doc, callback);
-      }
-
-      api.get(docId, function (err, doc) {
-        // create new doc
-        if (err && err.error === errors.MISSING_DOC.error) {
-          createAttachment({_id: docId});
-          return;
-        }
-        if (err) {
-          call(callback, err);
-          return;
-        }
-
-        if (doc._rev !== rev) {
-          call(callback, errors.REV_CONFLICT);
-          return;
-        }
-
-        createAttachment(doc);
-      });
-    };
-
-    api.removeAttachment = function (docId, attachmentId, rev, callback) {
-      api.get(docId, function (err, obj) {
-        if (err) {
-          call(callback, err);
-          return;
-        }
-        if (obj._rev !== rev) {
-          call(callback, errors.REV_CONFLICT);
-          return;
-        }
-        if (!obj._attachments) {
-          return call(callback, null);
-        }
-        delete obj._attachments[attachmentId];
-        if (Object.keys(obj._attachments).length === 0) {
-          delete obj._attachments;
-        }
-        api.put(obj, callback);
-      });
-    };
-
-    api.remove = function (doc, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      if (opts === undefined) {
-        opts = {};
-      }
-      opts.was_delete = true;
-      var newDoc = {_id: doc._id, _rev: doc._rev};
-      newDoc._deleted = true;
-      return customApi.bulkDocs({docs: [newDoc]}, opts, yankError(callback));
-    };
-
-    api.revsDiff = function (req, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      var ids = Object.keys(req);
-      var count = 0;
-      var missing = {};
-
-      function addToMissing(id, revId) {
-        if (!missing[id]) {
-          missing[id] = {missing: []};
-        }
-        missing[id].missing.push(revId);
-      }
-
-      function processDoc(id, rev_tree) {
-        // Is this fast enough? Maybe we should switch to a set simulated by a map
-        var missingForId = req[id].slice(0);
-        merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
-          opts) {
-            var rev = pos + '-' + revHash;
-            var idx = missingForId.indexOf(rev);
-            if (idx === -1) {
-              return;
-            }
-
-            missingForId.splice(idx, 1);
-            if (opts.status !== 'available') {
-              addToMissing(id, rev);
-            }
-          });
-
-        // Traversing the tree is synchronous, so now `missingForId` contains
-        // revisions that were not found in the tree
-        missingForId.forEach(function (rev) {
-          addToMissing(id, rev);
-        });
-      }
-
-      ids.map(function (id) {
-        customApi._getRevisionTree(id, function (err, rev_tree) {
-          if (err && err.name === 'not_found' && err.message === 'missing') {
-            missing[id] = {missing: req[id]};
-          } else if (err) {
-            return call(callback, err);
-          } else {
-            processDoc(id, rev_tree);
-          }
-
-          if (++count === ids.length) {
-            return call(callback, null, missing);
-          }
-        });
-      });
-    };
-
-    // compact one document and fire callback
-    // by compacting we mean removing all revisions which
-    // are further from the leaf in revision tree than max_height
-    function compactDocument(docId, max_height, callback) {
-      customApi._getRevisionTree(docId, function (err, rev_tree) {
-        if (err) {
-          return call(callback);
-        }
-        var height = computeHeight(rev_tree);
-        var candidates = [];
-        var revs = [];
-        Object.keys(height).forEach(function (rev) {
-          if (height[rev] > max_height) {
-            candidates.push(rev);
-          }
-        });
-
-        merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, opts) {
-          var rev = pos + '-' + revHash;
-          if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
-            opts.status = 'missing';
-            revs.push(rev);
-          }
-        });
-        customApi._doCompaction(docId, rev_tree, revs, callback);
-      });
-    }
-
-    // compact the whole database using single document
-    // compaction
-    api.compact = function (opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      api.changes({complete: function (err, res) {
-        if (err) {
-          call(callback); // TODO: silently fail
-          return;
-        }
-        var count = res.results.length;
-        if (!count) {
-          call(callback);
-          return;
-        }
-        res.results.forEach(function (row) {
-          compactDocument(row.id, 0, function () {
-            count--;
-            if (!count) {
-              call(callback);
-            }
-          });
-        });
-      }});
-    };
-
-    /* Begin api wrappers. Specific functionality to storage belongs in the _[method] */
-    api.get = function (id, opts, callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('get', arguments);
-        return;
-      }
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-
-      var leaves = [];
-      function finishOpenRevs() {
-        var result = [];
-        var count = leaves.length;
-        if (!count) {
-          return call(callback, null, result);
-        }
-        // order with open_revs is unspecified
-        leaves.forEach(function (leaf) {
-          api.get(id, {rev: leaf, revs: opts.revs}, function (err, doc) {
-            if (!err) {
-              result.push({ok: doc});
-            } else {
-              result.push({missing: leaf});
-            }
-            count--;
-            if (!count) {
-              call(callback, null, result);
-            }
-          });
-        });
-      }
-
-      if (opts.open_revs) {
-        if (opts.open_revs === "all") {
-          customApi._getRevisionTree(id, function (err, rev_tree) {
-            if (err) {
-              // if there's no such document we should treat this
-              // situation the same way as if revision tree was empty
-              rev_tree = [];
-            }
-            leaves = merge.collectLeaves(rev_tree).map(function (leaf) {
-              return leaf.rev;
-            });
-            finishOpenRevs();
-          });
-        } else {
-          if (Array.isArray(opts.open_revs)) {
-            leaves = opts.open_revs;
-            for (var i = 0; i < leaves.length; i++) {
-              var l = leaves[i];
-              // looks like it's the only thing couchdb checks
-              if (!(typeof(l) === "string" && /^\d+-/.test(l))) {
-                return call(callback, errors.error(errors.BAD_REQUEST,
-                  "Invalid rev format"));
-              }
-            }
-            finishOpenRevs();
-          } else {
-            return call(callback, errors.error(errors.UNKNOWN_ERROR,
-              'function_clause'));
-          }
-        }
-        return; // open_revs does not like other options
-      }
-
-      return customApi._get(id, opts, function (err, result) {
-        if (err) {
-          return call(callback, err);
-        }
-
-        var doc = result.doc;
-        var metadata = result.metadata;
-        var ctx = result.ctx;
-
-        if (opts.conflicts) {
-          var conflicts = merge.collectConflicts(metadata);
-          if (conflicts.length) {
-            doc._conflicts = conflicts;
-          }
-        }
-
-        if (opts.revs || opts.revs_info) {
-          var paths = merge.rootToLeaf(metadata.rev_tree);
-          var path = arrayFirst(paths, function (arr) {
-            return arr.ids.map(function (x) { return x.id; })
-              .indexOf(doc._rev.split('-')[1]) !== -1;
-          });
-
-          path.ids.splice(path.ids.map(function (x) {return x.id; })
-                          .indexOf(doc._rev.split('-')[1]) + 1);
-          path.ids.reverse();
-
-          if (opts.revs) {
-            doc._revisions = {
-              start: (path.pos + path.ids.length) - 1,
-              ids: path.ids.map(function (rev) {
-                return rev.id;
-              })
-            };
-          }
-          if (opts.revs_info) {
-            var pos =  path.pos + path.ids.length;
-            doc._revs_info = path.ids.map(function (rev) {
-              pos--;
-              return {
-                rev: pos + '-' + rev.id,
-                status: rev.opts.status
-              };
-            });
-          }
-        }
-
-        if (opts.local_seq) {
-          doc._local_seq = result.metadata.seq;
-        }
-
-        if (opts.attachments && doc._attachments) {
-          var attachments = doc._attachments;
-          var count = Object.keys(attachments).length;
-          if (count === 0) {
-            return call(callback, null, doc);
-          }
-          Object.keys(attachments).forEach(function (key) {
-            customApi._getAttachment(attachments[key], {encode: true, ctx: ctx}, function (err, data) {
-              doc._attachments[key].data = data;
-              if (!--count) {
-                call(callback, null, doc);
-              }
-            });
-          });
-        } else {
-          if (doc._attachments) {
-            for (var key in doc._attachments) {
-              doc._attachments[key].stub = true;
-            }
-          }
-          call(callback, null, doc);
-        }
-      });
-    };
-
-    api.getAttachment = function (docId, attachmentId, opts, callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('getAttachment', arguments);
-        return;
-      }
-      if (opts instanceof Function) {
-        callback = opts;
-        opts = {};
-      }
-      customApi._get(docId, opts, function (err, res) {
-        if (err) {
-          return call(callback, err);
-        }
-        if (res.doc._attachments && res.doc._attachments[attachmentId]) {
-          opts.ctx = res.ctx;
-          customApi._getAttachment(res.doc._attachments[attachmentId], opts, callback);
-        } else {
-          return call(callback, errors.MISSING_DOC);
-        }
-      });
-    };
-
-    api.allDocs = function (opts, callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('allDocs', arguments);
-        return;
-      }
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      if ('keys' in opts) {
-        if ('startkey' in opts) {
-          call(callback, errors.error(errors.QUERY_PARSE_ERROR,
-            'Query parameter `start_key` is not compatible with multi-get'
-          ));
-          return;
-        }
-        if ('endkey' in opts) {
-          call(callback, errors.error(errors.QUERY_PARSE_ERROR,
-            'Query parameter `end_key` is not compatible with multi-get'
-          ));
-          return;
-        }
-      }
-      if (typeof opts.skip === 'undefined') {
-        opts.skip = 0;
-      }
-
-      return customApi._allDocs(opts, callback);
-    };
-
-    function processChange(doc, metadata, opts) {
-      var changeList = [{rev: doc._rev}];
-      if (opts.style === 'all_docs') {
-        changeList = merge.collectLeaves(metadata.rev_tree)
-        .map(function (x) { return {rev: x.rev}; });
-      }
-      var change = {
-        id: metadata.id,
-        changes: changeList,
-        doc: doc
-      };
-
-      if (utils.isDeleted(metadata, doc._rev)) {
-        change.deleted = true;
-      }
-      if (opts.conflicts) {
-        change.doc._conflicts = merge.collectConflicts(metadata);
-        if (!change.doc._conflicts.length) {
-          delete change.doc._conflicts;
-        }
-      }
-      return change;
-    }
-    api.changes = function (opts) {
-      if (!api.taskqueue.ready()) {
-        var task = api.taskqueue.addTask('changes', arguments);
-        return {
-          cancel: function () {
-            if (task.task) {
-              return task.task.cancel();
-            }
-            if (Pouch.DEBUG) {
-              //console.log('Cancel Changes Feed');
-            }
-            task.parameters[0].aborted = true;
-          }
-        };
-      }
-      opts = utils.extend(true, {}, opts);
-      opts.processChange = processChange;
-
-      if (!opts.since) {
-        opts.since = 0;
-      }
-      if (opts.since === 'latest') {
-        var changes;
-        api.info(function (err, info) {
-          if (!opts.aborted) {
-            opts.since = info.update_seq  - 1;
-            api.changes(opts);
-          }
-        });
-        // Return a method to cancel this method from processing any more
-        return {
-          cancel: function () {
-            if (changes) {
-              return changes.cancel();
-            }
-            if (Pouch.DEBUG) {
-              //console.log('Cancel Changes Feed');
-            }
-            opts.aborted = true;
-          }
-        };
-      }
-
-      if (opts.filter && typeof opts.filter === 'string') {
-        if (opts.filter === '_view') {
-          if (opts.view && typeof opts.view === 'string') {
-            // fetch a view from a design doc, make it behave like a filter
-            var viewName = opts.view.split('/');
-            api.get('_design/' + viewName[0], function (err, ddoc) {
-              if (ddoc && ddoc.views && ddoc.views[viewName[1]]) {
-                /*jshint evil: true */
-                var filter = eval('(function () {' + 
-                                  '  return function (doc) {' + 
-                                  '    var emitted = false;' + 
-                                  '    var emit = function (a, b) {' + 
-                                  '      emitted = true;' + 
-                                  '    };' + 
-                                  '    var view = ' + ddoc.views[viewName[1]].map + ';' + 
-                                  '    view(doc);' + 
-                                  '    if (emitted) {' + 
-                                  '      return true;' + 
-                                  '    }' + 
-                                  '  }' + 
-                                  '})()');
-                if (!opts.aborted) {
-                  opts.filter = filter;
-                  api.changes(opts);
-                }
-              } else {
-                var msg = ddoc.views ? 'missing json key: ' + viewName[1] :
-                  'missing json key: views';
-                err = err || errors.error(errors.MISSING_DOC, msg);
-                utils.call(opts.complete, err);
-              }
-            });
-          } else {
-            var err = errors.error(errors.BAD_REQUEST,
-                                  '`view` filter parameter is not provided.');
-            utils.call(opts.complete, err);
-          }
-        } else {
-          // fetch a filter from a design doc
-          var filterName = opts.filter.split('/');
-          api.get('_design/' + filterName[0], function (err, ddoc) {
-            if (ddoc && ddoc.filters && ddoc.filters[filterName[1]]) {
-              /*jshint evil: true */
-              var filter = eval('(function () { return ' +
-                                ddoc.filters[filterName[1]] + ' })()');
-              if (!opts.aborted) {
-                opts.filter = filter;
-                api.changes(opts);
-              }
-            } else {
-              var msg = (ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
-                : 'missing json key: filters';
-              err = err || errors.error(errors.MISSING_DOC, msg);
-              utils.call(opts.complete, err);
-            }
-          });
-        }
-        // Return a method to cancel this method from processing any more
-        return {
-          cancel: function () {
-            if (Pouch.DEBUG) {
-              console.log('Cancel Changes Feed');
-            }
-            opts.aborted = true;
-          }
-        };
-      }
-
-      if (!('descending' in opts)) {
-        opts.descending = false;
-      }
-
-      // 0 and 1 should return 1 document
-      opts.limit = opts.limit === 0 ? 1 : opts.limit;
-      return customApi._changes(opts);
-    };
-
-    api.close = function (callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('close', arguments);
-        return;
-      }
-      return customApi._close(callback);
-    };
-
-    api.info = function (callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('info', arguments);
-        return;
-      }
-      return customApi._info(callback);
-    };
-
-    api.id = function () {
-      return customApi._id();
-    };
-
-    api.type = function () {
-      return (typeof customApi._type === 'function') ? customApi._type() : opts.adapter;
-    };
-
-    api.bulkDocs = function (req, opts, callback) {
-      if (!api.taskqueue.ready()) {
-        api.taskqueue.addTask('bulkDocs', arguments);
-        return;
-      }
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      if (!opts) {
-        opts = {};
-      } else {
-        opts = utils.extend(true, {}, opts);
-      }
-
-      if (!req || !req.docs || req.docs.length < 1) {
-        return call(callback, errors.MISSING_BULK_DOCS);
-      }
-
-      if (!Array.isArray(req.docs)) {
-        return call(callback, errors.QUERY_PARSE_ERROR);
-      }
-
-      for (var i = 0; i < req.docs.length; ++i) {
-        if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
-          return call(callback, errors.NOT_AN_OBJECT);
-        }
-      }
-
-      req = utils.extend(true, {}, req);
-      if (!('new_edits' in opts)) {
-        opts.new_edits = true;
-      }
-
-      return customApi._bulkDocs(req, opts, autoCompact(callback));
-    };
-
-    /* End Wrappers */
-    var taskqueue = {};
-
-    taskqueue.ready = false;
-    taskqueue.queue = [];
-
-    api.taskqueue = {};
-
-    api.taskqueue.execute = function (db) {
-      if (taskqueue.ready) {
-        taskqueue.queue.forEach(function (d) {
-          d.task = db[d.name].apply(null, d.parameters);
-        });
-      }
-    };
-
-    api.taskqueue.ready = function () {
-      if (arguments.length === 0) {
-        return taskqueue.ready;
-      }
-      taskqueue.ready = arguments[0];
-    };
-
-    api.taskqueue.addTask = function (name, parameters) {
-      var task = { name: name, parameters: parameters };
-      taskqueue.queue.push(task);
-      return task;
-    };
-
-    api.replicate = {};
-
-    api.replicate.from = function (url, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      return Pouch.replicate(url, customApi, opts, callback);
-    };
-
-    api.replicate.to = function (dbName, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      return Pouch.replicate(customApi, dbName, opts, callback);
-    };
-
-    for (var j in api) {
-      if (!customApi.hasOwnProperty(j)) {
-        customApi[j] = api[j];
-      }
-    }
-
-    // Http adapter can skip setup so we force the db to be ready and execute any jobs
-    if (opts.skipSetup) {
-      api.taskqueue.ready(true);
-      api.taskqueue.execute(api);
-    }
-
-    if (utils.isCordova()) {
-      //to inform websql adapter that we can use api
-      cordova.fireWindowEvent(opts.name + "_pouch", {});
-    }
-    return customApi;
-  };
-};
-
-},{"./deps/errors":8,"./merge":13,"./utils":16}],2:[function(require,module,exports){
-"use strict";
-
-var utils = require('../utils');
-var errors = require('../deps/errors');
-
-// parseUri 1.2.2
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-function parseUri(str) {
-  var o = parseUri.options;
-  var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
-  var uri = {};
-  var i = 14;
-
-  while (i--) {
-    uri[o.key[i]] = m[i] || "";
-  }
-
-  uri[o.q.name] = {};
-  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
-    if ($1) {
-      uri[o.q.name][$1] = $2;
-    }
-  });
-
-  return uri;
-}
-
-function encodeDocId(id) {
-  if (/^_(design|local)/.test(id)) {
-    return id;
-  }
-  return encodeURIComponent(id);
-}
-
-parseUri.options = {
-  strictMode: false,
-  key: ["source", "protocol", "authority", "userInfo", "user", "password", "host",
-        "port", "relative", "path", "directory", "file", "query", "anchor"],
-  q:   {
-    name:   "queryKey",
-    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
-  },
-  parser: {
-    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
-    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
-  }
-};
-
-// Get all the information you possibly can about the URI given by name and
-// return it as a suitable object.
-function getHost(name, opts) {
-  // If the given name contains "http:"
-  if (/http(s?):/.test(name)) {
-    // Prase the URI into all its little bits
-    var uri = parseUri(name);
-
-    // Store the fact that it is a remote URI
-    uri.remote = true;
-
-    // Store the user and password as a separate auth object
-    if (uri.user || uri.password) {
-      uri.auth = {username: uri.user, password: uri.password};
-    }
-
-    // Split the path part of the URI into parts using '/' as the delimiter
-    // after removing any leading '/' and any trailing '/'
-    var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
-
-    // Store the first part as the database name and remove it from the parts
-    // array
-    uri.db = parts.pop();
-
-    // Restore the path by joining all the remaining parts (all the parts
-    // except for the database name) with '/'s
-    uri.path = parts.join('/');
-    opts = opts || {};
-    uri.headers = opts.headers || {};
-
-    if (opts.auth || uri.auth) {
-      var nAuth = opts.auth || uri.auth;
-      var token = utils.btoa(nAuth.username + ':' + nAuth.password);
-      uri.headers.Authorization = 'Basic ' + token;
-    }
-
-    if (opts.headers) {
-      uri.headers = opts.headers;
-    }
-
-    return uri;
-  }
-
-  // If the given name does not contain 'http:' then return a very basic object
-  // with no host, the current path, the given name as the database name and no
-  // username/password
-  return {host: '', path: '/', db: name, auth: false};
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genDBUrl(opts, path) {
-  // If the host is remote
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // Return the URL made up of all the host's information and the given path
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' +
-      opts.path + pathDel + opts.db + '/' + path;
-  }
-
-  // If the host is not remote, then return the URL made up of just the
-  // database name and the given path
-  return '/' + opts.db + '/' + path;
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genUrl(opts, path) {
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' + opts.path + pathDel + path;
-  }
-
-  return '/' + path;
-}
-
-// Implements the PouchDBVersion110 API for dealing with CouchDB instances over HTTP
-function HttpPouch(opts, callback) {
-
-  // Parse the URI given by opts.name into an easy-to-use object
-  var host = getHost(opts.name, opts);
-
-  // Generate the database URL based on the host
-  var db_url = genDBUrl(host, '');
-
-  // The functions that will be publically available for HttpPouch
-  var api = {};
-  var ajaxOpts = opts.ajax || {};
-  function ajax(options, callback) {
-    return utils.ajax(utils.extend({}, ajaxOpts, options), callback);
-  }
-  var uuids = {
-    list: [],
-    get: function (opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {count: 10};
-      }
-      var cb = function (err, body) {
-        if (err || !('uuids' in body)) {
-          utils.call(callback, err || errors.UNKNOWN_ERROR);
-        } else {
-          uuids.list = uuids.list.concat(body.uuids);
-          utils.call(callback, null, "OK");
-        }
-      };
-      var params = '?count=' + opts.count;
-      ajax({
-        headers: host.headers,
-        method: 'GET',
-        url: genUrl(host, '_uuids') + params
-      }, cb);
-    }
-  };
-
-  // Create a new CouchDB database based on the given opts
-  var createDB = function () {
-    ajax({headers: host.headers, method: 'PUT', url: db_url}, function (err, ret) {
-      // If we get an "Unauthorized" error
-      if (err && err.status === 401) {
-        // Test if the database already exists
-        ajax({headers: host.headers, method: 'HEAD', url: db_url}, function (err, ret) {
-          // If there is still an error
-          if (err) {
-            // Give the error to the callback to deal with
-            utils.call(callback, err);
-          } else {
-            // Continue as if there had been no errors
-            utils.call(callback, null, api);
-          }
-        });
-        // If there were no errros or if the only error is "Precondition Failed"
-        // (note: "Precondition Failed" occurs when we try to create a database
-        // that already exists)
-      } else if (!err || err.status === 412) {
-        // Continue as if there had been no errors
-        utils.call(callback, null, api);
-      } else {
-        utils.call(callback, errors.UNKNOWN_ERROR);
-      }
-    });
-  };
-  if (!opts.skipSetup) {
-    ajax({headers: host.headers, method: 'GET', url: db_url}, function (err, ret) {
-      //check if the db exists
-      if (err) {
-        if (err.status === 404) {
-          //if it doesn't, create it
-          createDB();
-        } else {
-          utils.call(callback, err);
-        }
-      } else {
-        //go do stuff with the db
-        utils.call(callback, null, api);
-      }
-    });
-  }
-
-  api.type = function () {
-    return 'http';
-  };
-
-  // The HttpPouch's ID is its URL
-  api.id = function () {
-    return genDBUrl(host, '');
-  };
-
-  api.request = function (options, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('request', arguments);
-      return;
-    }
-    options.headers = host.headers;
-    options.url = genDBUrl(host, options.url);
-    ajax(options, callback);
-  };
-
-  // Sends a POST request to the host calling the couchdb _compact function
-  //    version: The version of CouchDB it is running
-  api.compact = function (opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('compact', arguments);
-      return;
-    }
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    ajax({
-      headers: host.headers,
-      url: genDBUrl(host, '_compact'),
-      method: 'POST'
-    }, function () {
-      function ping() {
-        api.info(function (err, res) {
-          if (!res.compact_running) {
-            utils.call(callback, null);
-          } else {
-            setTimeout(ping, opts.interval || 200);
-          }
-        });
-      }
-      // Ping the http if it's finished compaction
-      if (typeof callback === "function") {
-        ping();
-      }
-    });
-  };
-
-  // Calls GET on the host, which gets back a JSON string containing
-  //    couchdb: A welcome string
-  //    version: The version of CouchDB it is running
-  api.info = function (callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('info', arguments);
-      return;
-    }
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, '')
-    }, callback);
-  };
-
-  // Get the document with the given id from the database given by host.
-  // The id could be solely the _id in the database, or it may be a
-  // _design/ID or _local/ID path
-  api.get = function (id, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('get', arguments);
-      return;
-    }
-    // If no options were given, set the callback to the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-
-    // List of parameters to add to the GET request
-    var params = [];
-
-    // If it exists, add the opts.revs value to the list of parameters.
-    // If revs=true then the resulting JSON will include a field
-    // _revisions containing an array of the revision IDs.
-    if (opts.revs) {
-      params.push('revs=true');
-    }
-
-    // If it exists, add the opts.revs_info value to the list of parameters.
-    // If revs_info=true then the resulting JSON will include the field
-    // _revs_info containing an array of objects in which each object
-    // representing an available revision.
-    if (opts.revs_info) {
-      params.push('revs_info=true');
-    }
-
-    if (opts.local_seq) {
-      params.push('local_seq=true');
-    }
-    // If it exists, add the opts.open_revs value to the list of parameters.
-    // If open_revs=all then the resulting JSON will include all the leaf
-    // revisions. If open_revs=["rev1", "rev2",...] then the resulting JSON
-    // will contain an array of objects containing data of all revisions
-    if (opts.open_revs) {
-      if (opts.open_revs !== "all") {
-        opts.open_revs = JSON.stringify(opts.open_revs);
-      }
-      params.push('open_revs=' + opts.open_revs);
-    }
-
-    // If it exists, add the opts.attachments value to the list of parameters.
-    // If attachments=true the resulting JSON will include the base64-encoded
-    // contents in the "data" property of each attachment.
-    if (opts.attachments) {
-      params.push('attachments=true');
-    }
-
-    // If it exists, add the opts.rev value to the list of parameters.
-    // If rev is given a revision number then get the specified revision.
-    if (opts.rev) {
-      params.push('rev=' + opts.rev);
-    }
-
-    // If it exists, add the opts.conflicts value to the list of parameters.
-    // If conflicts=true then the resulting JSON will include the field
-    // _conflicts containing all the conflicting revisions.
-    if (opts.conflicts) {
-      params.push('conflicts=' + opts.conflicts);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
-
-    if (opts.auto_encode) {
-      id = encodeDocId(id);
-    }
-
-    // Set the options for the ajax call
-    var options = {
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, id + params)
-    };
-
-    // If the given id contains at least one '/' and the part before the '/'
-    // is NOT "_design" and is NOT "_local"
-    // OR
-    // If the given id contains at least two '/' and the part before the first
-    // '/' is "_design".
-    // TODO This second condition seems strange since if parts[0] === '_design'
-    // then we already know that parts[0] !== '_local'.
-    var parts = id.split('/');
-    if ((parts.length > 1 && parts[0] !== '_design' && parts[0] !== '_local') ||
-        (parts.length > 2 && parts[0] === '_design' && parts[0] !== '_local')) {
-      // Binary is expected back from the server
-      options.binary = true;
-    }
-
-    // Get the document
-    ajax(options, function (err, doc, xhr) {
-      // If the document does not exist, send an error to the callback
-      if (err) {
-        return utils.call(callback, err);
-      }
-
-      // Send the document to the callback
-      utils.call(callback, null, doc, xhr);
-    });
-  };
-
-  // Delete the document given by doc from the database given by host.
-  api.remove = function (doc, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('remove', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Delete the document
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + doc._rev
-    }, callback);
-  };
-
-  // Get the attachment
-  api.getAttachment = function (docId, attachmentId, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-    if (opts.auto_encode) {
-      docId = encodeDocId(docId);
-    }
-    opts.auto_encode = false;
-    api.get(docId + '/' + attachmentId, opts, callback);
-  };
-
-  // Remove the attachment given by the id and rev
-  api.removeAttachment = function (docId, attachmentId, rev, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('removeAttachment', arguments);
-      return;
-    }
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(docId) + '/' + attachmentId) + '?rev=' + rev
-    }, callback);
-  };
-
-  // Add the attachment given by blob and its contentType property
-  // to the document with the given id, the revision given by rev, and
-  // add it to the database given by host.
-  api.putAttachment = function (docId, attachmentId, rev, blob, type, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('putAttachment', arguments);
-      return;
-    }
-    if (typeof type === 'function') {
-      callback = type;
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    if (typeof type === 'undefined') {
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    var id = encodeDocId(docId) + '/' + attachmentId;
-    var url = genDBUrl(host, id);
-    if (rev) {
-      url += '?rev=' + rev;
-    }
-
-    var opts = {
-      headers: host.headers,
-      method: 'PUT',
-      url: url,
-      processData: false,
-      body: blob,
-      timeout: 60000
-    };
-    opts.headers['Content-Type'] = type;
-    // Add the attachment
-    ajax(opts, callback);
-  };
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This fails if the doc has no _id field.
-  api.put = function (doc, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('put', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    if (typeof doc !== 'object') {
-      return utils.call(callback, errors.NOT_AN_OBJECT);
-    }
-    if (!utils.isValidId(doc._id)) {
-      return utils.call(callback, errors.MISSING_ID);
-    }
-
-    // List of parameter to add to the PUT request
-    var params = [];
-
-    // If it exists, add the opts.new_edits value to the list of parameters.
-    // If new_edits = false then the database will NOT assign this document a
-    // new revision number
-    if (opts && typeof opts.new_edits !== 'undefined') {
-      params.push('new_edits=' + opts.new_edits);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    // Add the document
-    ajax({
-      headers: host.headers,
-      method: 'PUT',
-      url: genDBUrl(host, encodeDocId(doc._id)) + params,
-      body: doc
-    }, callback);
-  };
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This does not assume that doc is a new document (i.e. does not
-  // have a _id or a _rev field.
-  api.post = function (doc, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('post', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    if (typeof doc !== 'object') {
-      return utils.call(callback, errors.NOT_AN_OBJECT);
-    }
-    if (! ("_id" in doc)) {
-      if (uuids.list.length > 0) {
-        doc._id = uuids.list.pop();
-        api.put(doc, opts, callback);
-      } else {
-        uuids.get(function (err, resp) {
-          if (err) {
-            return utils.call(callback, errors.UNKNOWN_ERROR);
-          }
-          doc._id = uuids.list.pop();
-          api.put(doc, opts, callback);
-        });
-      }
-    } else {
-      api.put(doc, opts, callback);
-    }
-  };
-
-  // Update/create multiple documents given by req in the database
-  // given by host.
-  api.bulkDocs = function (req, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('bulkDocs', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    if (!opts) {
-      opts = {};
-    }
-
-    // If opts.new_edits exists add it to the document data to be
-    // send to the database.
-    // If new_edits=false then it prevents the database from creating
-    // new revision numbers for the documents. Instead it just uses
-    // the old ones. This is used in database replication.
-    if (typeof opts.new_edits !== 'undefined') {
-      req.new_edits = opts.new_edits;
-    }
-
-    // Update/create the documents
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_bulk_docs'),
-      body: req
-    }, callback);
-  };
-
-  // Get a listing of the documents in the database given
-  // by host and ordered by increasing id.
-  api.allDocs = function (opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('allDocs', arguments);
-      return;
-    }
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // List of parameters to add to the GET request
-    var params = [];
-    var body;
-    var method = 'GET';
-
-    // TODO I don't see conflicts as a valid parameter for a
-    // _all_docs request (see http://wiki.apache.org/couchdb/HTTP_Document_API#all_docs)
-    if (opts.conflicts) {
-      params.push('conflicts=true');
-    }
-
-    // If opts.descending is truthy add it to params
-    if (opts.descending) {
-      params.push('descending=true');
-    }
-
-    // If opts.include_docs exists, add the include_docs value to the
-    // list of parameters.
-    // If include_docs=true then include the associated document with each
-    // result.
-    if (opts.include_docs) {
-      params.push('include_docs=true');
-    }
-
-    // If opts.startkey exists, add the startkey value to the list of
-    // parameters.
-    // If startkey is given then the returned list of documents will
-    // start with the document whose id is startkey.
-    if (opts.startkey) {
-      params.push('startkey=' +
-                  encodeURIComponent(JSON.stringify(opts.startkey)));
-    }
-
-    // If opts.endkey exists, add the endkey value to the list of parameters.
-    // If endkey is given then the returned list of docuemnts will
-    // end with the document whose id is endkey.
-    if (opts.endkey) {
-      params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
-    }
-
-    // If opts.limit exists, add the limit value to the parameter list.
-    if (opts.limit) {
-      params.push('limit=' + opts.limit);
-    }
-
-    if (typeof opts.skip !== 'undefined') {
-      params.push('skip=' + opts.skip);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    // If keys are supplied, issue a POST request to circumvent GET query string limits
-    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-    if (typeof opts.keys !== 'undefined') {
-      method = 'POST';
-      body = JSON.stringify({keys: opts.keys});
-    }
-
-    // Get the document listing
-    ajax({
-      headers: host.headers,
-      method: method,
-      url: genDBUrl(host, '_all_docs' + params),
-      body: body
-    }, callback);
-  };
-
-  // Get a list of changes made to documents in the database given by host.
-  // TODO According to the README, there should be two other methods here,
-  // api.changes.addListener and api.changes.removeListener.
-  api.changes = function (opts) {
-
-    // We internally page the results of a changes request, this means
-    // if there is a large set of changes to be returned we can start
-    // processing them quicker instead of waiting on the entire
-    // set of changes to return and attempting to process them at once
-    var CHANGES_LIMIT = 25;
-
-    if (!api.taskqueue.ready()) {
-      var task = api.taskqueue.addTask('changes', arguments);
-      return {
-        cancel: function () {
-          if (task.task) {
-            return task.task.cancel();
-          }
-          //console.log(db_url + ': Cancel Changes Feed');
-          task.parameters[0].aborted = true;
-        }
-      };
-    }
-
-    if (opts.since === 'latest') {
-      var changes;
-      api.info(function (err, info) {
-        if (!opts.aborted) {
-          opts.since = info.update_seq;
-          changes = api.changes(opts);
-        }
-      });
-      // Return a method to cancel this method from processing any more
-      return {
-        cancel: function () {
-          if (changes) {
-            return changes.cancel();
-          }
-          //console.log(db_url + ': Cancel Changes Feed');
-          opts.aborted = true;
-        }
-      };
-    }
-
-    //console.log(db_url + ': Start Changes Feed: continuous=' + opts.continuous);
-
-    var params = {};
-    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
-    if (limit === 0) {
-      limit = 1;
-    }
-    //
-    var leftToFetch = limit;
-
-    if (opts.style) {
-      params.style = opts.style;
-    }
-
-    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
-      params.include_docs = true;
-    }
-
-    if (opts.continuous) {
-      params.feed = 'longpoll';
-    }
-
-    if (opts.conflicts) {
-      params.conflicts = true;
-    }
-
-    if (opts.descending) {
-      params.descending = true;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-      if (opts.filter === '_view' && opts.view && typeof opts.view === 'string') {
-        params.view = opts.view;
-      }
-    }
-
-    // If opts.query_params exists, pass it through to the changes request.
-    // These parameters may be used by the filter on the source database.
-    if (opts.query_params && typeof opts.query_params === 'object') {
-      for (var param_name in opts.query_params) {
-        if (opts.query_params.hasOwnProperty(param_name)) {
-          params[param_name] = opts.query_params[param_name];
-        }
-      }
-    }
-
-    var xhr;
-    var lastFetchedSeq;
-    var remoteLastSeq;
-    var pagingCount;
-
-    // Get all the changes starting wtih the one immediately after the
-    // sequence number given by since.
-    var fetch = function (since, callback) {
-      params.since = since;
-      if (!opts.continuous && !pagingCount) {
-        pagingCount = remoteLastSeq;
-      }
-      params.limit = (!limit || leftToFetch > CHANGES_LIMIT) ?
-        CHANGES_LIMIT : leftToFetch;
-
-      var paramStr = '?' + Object.keys(params).map(function (k) {
-        return k + '=' + params[k];
-      }).join('&');
-
-      // Set the options for the ajax call
-      var xhrOpts = {
-        headers: host.headers,
-        method: 'GET',
-        url: genDBUrl(host, '_changes' + paramStr),
-        // _changes can take a long time to generate, especially when filtered
-        timeout: null
-      };
-      lastFetchedSeq = since;
-
-      if (opts.aborted) {
-        return;
-      }
-
-      // Get the changes
-      xhr = ajax(xhrOpts, callback);
-    };
-
-    // If opts.since exists, get all the changes from the sequence
-    // number given by opts.since. Otherwise, get all the changes
-    // from the sequence number 0.
-    var fetchTimeout = 10;
-    var fetchRetryCount = 0;
-
-    var results = {results: []};
-
-    var fetched = function (err, res) {
-      // If the result of the ajax call (res) contains changes (res.results)
-      if (res && res.results) {
-        results.last_seq = res.last_seq;
-        // For each change
-        var req = {};
-        req.query = opts.query_params;
-        res.results = res.results.filter(function (c) {
-          leftToFetch--;
-          var ret = utils.filterChange(opts)(c);
-          if (ret) {
-            results.results.push(c);
-            utils.call(opts.onChange, c);
-          }
-          return ret;
-        });
-      } else if (err) {
-        // In case of an error, stop listening for changes and call opts.complete
-        opts.aborted = true;
-        utils.call(opts.complete, err, null);
-      }
-
-      // The changes feed may have timed out with no results
-      // if so reuse last update sequence
-      if (res && res.last_seq) {
-        lastFetchedSeq = res.last_seq;
-      }
-
-      var resultsLength = res && res.results.length || 0;
-
-      pagingCount -= CHANGES_LIMIT;
-
-      var finished = (limit && leftToFetch <= 0) ||
-        (res && !resultsLength && pagingCount <= 0) ||
-        (resultsLength && res.last_seq === remoteLastSeq) ||
-        (opts.descending && lastFetchedSeq !== 0);
-
-      if (opts.continuous || !finished) {
-        // Increase retry delay exponentially as long as errors persist
-        if (err) {
-          fetchRetryCount += 1;
-        } else {
-          fetchRetryCount = 0;
-        }
-        var timeoutMultiplier = 1 << fetchRetryCount;
-        var retryWait = fetchTimeout * timeoutMultiplier;
-        var maximumWait = opts.maximumWait || 30000;
-
-        if (retryWait > maximumWait) {
-          utils.call(opts.complete, err || errors.UNKNOWN_ERROR, null);
-        }
-
-        // Queue a call to fetch again with the newest sequence number
-        setTimeout(function () { fetch(lastFetchedSeq, fetched); }, retryWait);
-      } else {
-        // We're done, call the callback
-        utils.call(opts.complete, null, results);
-      }
-    };
-
-    // If we arent doing a continuous changes request we need to know
-    // the current update_seq so we know when to stop processing the
-    // changes
-    if (opts.continuous) {
-      fetch(opts.since || 0, fetched);
-    } else {
-      api.info(function (err, res) {
-        if (err) {
-          return utils.call(opts.complete, err);
-        }
-        remoteLastSeq = res.update_seq;
-        fetch(opts.since || 0, fetched);
-      });
-    }
-
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        //console.log(db_url + ': Cancel Changes Feed');
-        opts.aborted = true;
-        xhr.abort();
-      }
-    };
-  };
-
-  // Given a set of document/revision IDs (given by req), tets the subset of
-  // those that do NOT correspond to revisions stored in the database.
-  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
-  api.revsDiff = function (req, opts, callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('revsDiff', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Get the missing document/revision IDs
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_revs_diff'),
-      body: req
-    }, function (err, res) {
-      utils.call(callback, err, res);
-    });
-  };
-
-  api.close = function (callback) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('close', arguments);
-      return;
-    }
-    utils.call(callback, null);
-  };
-
-  api.replicateOnServer = function (target, opts, promise) {
-    if (!api.taskqueue.ready()) {
-      api.taskqueue.addTask('replicateOnServer', arguments);
-      return promise;
-    }
-
-    var targetHost = getHost(target.id());
-    var params = {
-      source: host.db,
-      target: targetHost.protocol === host.protocol && targetHost.authority === host.authority ? targetHost.db : targetHost.source
-    };
-
-    if (opts.continuous) {
-      params.continuous = true;
-    }
-
-    if (opts.create_target) {
-      params.create_target = true;
-    }
-
-    if (opts.doc_ids) {
-      params.doc_ids = opts.doc_ids;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-    }
-
-    if (opts.query_params) {
-      params.query_params = opts.query_params;
-    }
-
-    var result = {};
-    var repOpts = {
-      headers: host.headers,
-      method: 'POST',
-      url: host.protocol + '://' + host.host + (host.port === 80 ? '' : (':' + host.port)) + '/_replicate',
-      body: params
-    };
-    var xhr;
-    promise.cancel = function () {
-      this.cancelled = true;
-      if (xhr && !result.ok) {
-        xhr.abort();
-      }
-      if (result._local_id) {
-        repOpts.body = {
-          replication_id: result._local_id
-        };
-      }
-      repOpts.body.cancel = true;
-      ajax(repOpts, function (err, resp, xhr) {
-        // If the replication cancel request fails, send an error to the callback
-        if (err) {
-          return utils.call(callback, err);
-        }
-        // Send the replication cancel result to the complete callback
-        utils.call(opts.complete, null, result, xhr);
-      });
-    };
-
-    if (promise.cancelled) {
-      return;
-    }
-
-    xhr = ajax(repOpts, function (err, resp, xhr) {
-      // If the replication fails, send an error to the callback
-      if (err) {
-        return utils.call(callback, err);
-      }
-
-      result.ok = true;
-
-      // Provided by CouchDB from 1.2.0 onward to cancel replication
-      if (resp._local_id) {
-        result._local_id = resp._local_id;
-      }
-
-      // Send the replication result to the complete callback
-      utils.call(opts.complete, null, resp, xhr);
-    });
-  };
-
-  return api;
-}
-
-// Delete the HttpPouch specified by the given name.
-HttpPouch.destroy = function (name, opts, callback) {
-  var host = getHost(name, opts);
-  opts = opts || {};
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts.headers = host.headers;
-  opts.method = 'DELETE';
-  opts.url = genDBUrl(host, '');
-  utils.ajax(opts, callback);
-};
-
-// HttpPouch is a valid adapter.
-HttpPouch.valid = function () {
-  return true;
-};
-
-module.exports = HttpPouch;
-
-},{"../deps/errors":8,"../utils":16}],3:[function(require,module,exports){
-'use strict';
-
-var utils = require('../utils');
-var merge = require('../merge');
-var errors = require('../deps/errors');
-function idbError(callback) {
-  return function (event) {
-    utils.call(callback, errors.error(errors.IDB_ERROR, event.target, event.type));
-  };
-}
-
-function IdbPouch(opts, callback) {
-
-  // IndexedDB requires a versioned database structure, this is going to make
-  // it hard to dynamically create object stores if we needed to for things
-  // like views
-  var POUCH_VERSION = 1;
-
-  // The object stores created for each database
-  // DOC_STORE stores the document meta data, its revision history and state
-  var DOC_STORE = 'document-store';
-  // BY_SEQ_STORE stores a particular version of a document, keyed by its
-  // sequence id
-  var BY_SEQ_STORE = 'by-sequence';
-  // Where we store attachments
-  var ATTACH_STORE = 'attach-store';
-  // Where we store meta data
-  var META_STORE = 'meta-store';
-  // Where we detect blob support
-  var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
-
-
-  var name = opts.name;
-  var req = window.indexedDB.open(name, POUCH_VERSION);
-
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.openReqList[name] = req;
-
-  var blobSupport = null;
-
-  var instanceId = null;
-  var api = {};
-  var idb = null;
-
-  req.onupgradeneeded = function (e) {
-    var db = e.target.result;
-    var currentVersion = e.oldVersion;
-    while (currentVersion !== e.newVersion) {
-      if (currentVersion === 0) {
-        createSchema(db);
-      }
-      currentVersion++;
-    }
-  };
-
-  function createSchema(db) {
-    db.createObjectStore(DOC_STORE, {keyPath : 'id'})
-      .createIndex('seq', 'seq', {unique: true});
-    db.createObjectStore(BY_SEQ_STORE, {autoIncrement : true})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
-    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
-    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
-  }
-
-  // From http://stackoverflow.com/questions/14967647/encode-decode-image-with-base64-breaks-image (2013-04-21)
-  function fixBinary(bin) {
-    var length = bin.length;
-    var buf = new ArrayBuffer(length);
-    var arr = new Uint8Array(buf);
-    for (var i = 0; i < length; i++) {
-      arr[i] = bin.charCodeAt(i);
-    }
-    return buf;
-  }
-
-  req.onsuccess = function (e) {
-
-    idb = e.target.result;
-
-    idb.onversionchange = function () {
-      idb.close();
-    };
-
-    var txn = idb.transaction([META_STORE, DETECT_BLOB_SUPPORT_STORE],
-                              'readwrite');
-
-    var req = txn.objectStore(META_STORE).get(META_STORE);
-
-    req.onsuccess = function (e) {
-      var meta = e.target.result || {id: META_STORE};
-      if (name + '_id' in meta) {
-        instanceId = meta[name + '_id'];
-      } else {
-        instanceId = utils.uuid();
-        meta[name + '_id'] = instanceId;
-        txn.objectStore(META_STORE).put(meta);
-      }
-
-      // detect blob support
-      try {
-        txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(utils.createBlob(), "key");
-        blobSupport = true;
-      } catch (err) {
-        blobSupport = false;
-      } finally {
-        utils.call(callback, null, api);
-      }
-    };
-  };
-
-  req.onerror = idbError(callback);
-
-  api.type = function () {
-    return 'idb';
-  };
-
-  // Each database needs a unique id so that we can store the sequence
-  // checkpoint without having other databases confuse itself.
-  api.id = function idb_id() {
-    return instanceId;
-  };
-
-  api._bulkDocs = function idb_bulkDocs(req, opts, callback) {
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return utils.call(callback, docInfoErrors[0]);
-    }
-
-    var results = [];
-    var docsWritten = 0;
-
-    function writeMetaData(e) {
-      var meta = e.target.result;
-      meta.updateSeq = (meta.updateSeq || 0) + docsWritten;
-      txn.objectStore(META_STORE).put(meta);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = writeMetaData;
-        return;
-      }
-      var currentDoc = docInfos.shift();
-      var req = txn.objectStore(DOC_STORE).get(currentDoc.metadata.id);
-      req.onsuccess = function process_docRead(event) {
-        var oldDoc = event.target.result;
-        if (!oldDoc) {
-          insertDoc(currentDoc);
-        } else {
-          updateDoc(oldDoc, currentDoc);
-        }
-      };
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        IdbPouch.Changes.notify(name);
-        IdbPouch.Changes.notifyLocalWindows(name);
-      });
-      utils.call(callback, null, aresults);
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        var data;
-        try {
-          data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return utils.call(callback, err);
-        }
-        att.digest = 'md5-' + utils.Crypto.MD5(data);
-        if (blobSupport) {
-          var type = att.content_type;
-          data = fixBinary(data);
-          att.data = utils.createBlob([data], {type: type});
-        }
-        return finish();
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        att.digest = 'md5-' + utils.Crypto.MD5(this.result);
-        if (!blobSupport) {
-          att.data = btoa(this.result);
-        }
-        finish();
-      };
-      reader.readAsBinaryString(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        var recv = 0;
-        function attachmentProcessed() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          preprocessAttachment(docInfo.data._attachments[key], attachmentProcessed);
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, callback) {
-      var err = null;
-      var recv = 0;
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      docsWritten++;
-
-      if (utils.isDeleted(docInfo.metadata, docInfo.metadata.rev)) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            utils.call(callback, err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      function finish() {
-        docInfo.data._doc_id_rev = docInfo.data._id + "::" + docInfo.data._rev;
-        var dataReq = txn.objectStore(BY_SEQ_STORE).put(docInfo.data);
-        dataReq.onsuccess = function (e) {
-          //console.log(name + ': Wrote Document ', docInfo.metadata.id);
-          docInfo.metadata.seq = e.target.result;
-          // Current _rev is calculated from _rev_tree on read
-          delete docInfo.metadata.rev;
-          var metaDataReq = txn.objectStore(DOC_STORE).put(docInfo.metadata);
-          metaDataReq.onsuccess = function () {
-            results.push(docInfo);
-            utils.call(callback);
-          };
-        };
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var merged = merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var wasPreviouslyDeleted = utils.isDeleted(oldDoc);
-      var inConflict = (wasPreviouslyDeleted &&
-                        utils.isDeleted(docInfo.metadata)) ||
-        (!wasPreviouslyDeleted && newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-      writeDoc(docInfo, processDocs);
-    }
-
-    function insertDoc(docInfo) {
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && utils.isDeleted(docInfo.metadata)) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-      writeDoc(docInfo, processDocs);
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var objectStore = txn.objectStore(ATTACH_STORE);
-      var getReq = objectStore.get(digest).onsuccess = function (e) {
-        var originalRefs = e.target.result && e.target.result.refs || {};
-        var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-        var newAtt = {
-          digest: digest,
-          body: data,
-          refs: originalRefs
-        };
-        newAtt.refs[ref] = true;
-        var putReq = objectStore.put(newAtt).onsuccess = function (e) {
-          utils.call(callback);
-        };
-      };
-    }
-
-    var txn;
-    preprocessAttachments(function () {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE],
-                            'readwrite');
-      txn.onerror = idbError(callback);
-      txn.ontimeout = idbError(callback);
-      txn.oncomplete = complete;
-
-      processDocs();
-    });
-  };
-
-  function sortByBulkSeq(a, b) {
-    return a._bulk_seq - b._bulk_seq;
-  }
-
-  // First we look up the metadata in the ids database, then we fetch the
-  // current revision(s) from the by sequence store
-  api._get = function idb_get(id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    var txn;
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-
-    function finish() {
-      utils.call(callback, err, {doc: doc, metadata: metadata, ctx: txn});
-    }
-
-    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
-      metadata = e.target.result;
-      // we can determine the result here if:
-      // 1. there is no such document
-      // 2. the document is deleted and we don't ask about specific rev
-      // When we ask with opts.rev we expect the answer to be either
-      // doc (possibly with _deleted=true) or missing error
-      if (!metadata) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-
-      var rev = merge.winningRev(metadata);
-      var key = metadata.id + '::' + (opts.rev ? opts.rev : rev);
-      var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-
-      index.get(key).onsuccess = function (e) {
-        doc = e.target.result;
-        if (doc && doc._doc_id_rev) {
-          delete(doc._doc_id_rev);
-        }
-        if (!doc) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        finish();
-      };
-    };
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var result;
-    var txn;
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-
-    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
-      var data = e.target.result.body;
-      if (opts.encode) {
-        if (blobSupport) {
-          var reader = new FileReader();
-          reader.onloadend = function (e) {
-            result = btoa(this.result);
-            utils.call(callback, null, result);
-          };
-          reader.readAsBinaryString(data);
-        } else {
-          result = data;
-          utils.call(callback, null, result);
-        }
-      } else {
-        if (blobSupport) {
-          result = data;
-        } else {
-          data = fixBinary(atob(data));
-          result = utils.createBlob([data], {type: type});
-        }
-        utils.call(callback, null, result);
-      }
-    };
-  };
-
-  api._allDocs = function idb_allDocs(opts, callback) {
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-
-    var descending = 'descending' in opts ? opts.descending : false;
-    descending = descending ? 'prev' : null;
-
-    var keyRange = start && end ? window.IDBKeyRange.bound(start, end)
-      : start ? window.IDBKeyRange.lowerBound(start)
-      : end ? window.IDBKeyRange.upperBound(end) : null;
-
-    var transaction = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readonly');
-    transaction.oncomplete = function () {
-      if ('keys' in opts) {
-        opts.keys.forEach(function (key) {
-          if (key in resultsMap) {
-            results.push(resultsMap[key]);
-          } else {
-            results.push({"key": key, "error": "not_found"});
-          }
-        });
-        if (opts.descending) {
-          results.reverse();
-        }
-      }
-      utils.call(callback, null, {
-        total_rows: results.length,
-        offset: opts.skip,
-        rows: ('limit' in opts) ? results.slice(opts.skip, opts.limit + opts.skip) :
-          (opts.skip > 0) ? results.slice(opts.skip) : results
-      });
-    };
-
-    var oStore = transaction.objectStore(DOC_STORE);
-    var oCursor = descending ? oStore.openCursor(keyRange, descending)
-      : oStore.openCursor(keyRange);
-    var results = [];
-    var resultsMap = {};
-    oCursor.onsuccess = function (e) {
-      if (!e.target.result) {
-        return;
-      }
-      var cursor = e.target.result;
-      var metadata = cursor.value;
-      // If opts.keys is set we want to filter here only those docs with
-      // key in opts.keys. With no performance tests it is difficult to
-      // guess if iteration with filter is faster than many single requests
-      function allDocsInner(metadata, data) {
-        if (utils.isLocalId(metadata.id)) {
-          return cursor['continue']();
-        }
-        var doc = {
-          id: metadata.id,
-          key: metadata.id,
-          value: {
-            rev: merge.winningRev(metadata)
-          }
-        };
-        if (opts.include_docs) {
-          doc.doc = data;
-          doc.doc._rev = merge.winningRev(metadata);
-          if (doc.doc._doc_id_rev) {
-            delete(doc.doc._doc_id_rev);
-          }
-          if (opts.conflicts) {
-            doc.doc._conflicts = merge.collectConflicts(metadata);
-          }
-          for (var att in doc.doc._attachments) {
-            doc.doc._attachments[att].stub = true;
-          }
-        }
-        if ('keys' in opts) {
-          if (opts.keys.indexOf(metadata.id) > -1) {
-            if (utils.isDeleted(metadata)) {
-              doc.value.deleted = true;
-              doc.doc = null;
-            }
-            resultsMap[doc.id] = doc;
-          }
-        } else {
-          if (!utils.isDeleted(metadata)) {
-            results.push(doc);
-          }
-        }
-        cursor['continue']();
-      }
-
-      if (!opts.include_docs) {
-        allDocsInner(metadata);
-      } else {
-        var index = transaction.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var mainRev = merge.winningRev(metadata);
-        var key = metadata.id + "::" + mainRev;
-        index.get(key).onsuccess = function (event) {
-          allDocsInner(cursor.value, event.target.result);
-        };
-      }
-    };
-  };
-
-  api._info = function idb_info(callback) {
-    var count = 0;
-    var update_seq = 0;
-    var txn = idb.transaction([DOC_STORE, META_STORE], 'readonly');
-
-    function fetchUpdateSeq(e) {
-      update_seq = e.target.result && e.target.result.updateSeq || 0;
-    }
-
-    function countDocs(e) {
-      var cursor = e.target.result;
-      if (!cursor) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = fetchUpdateSeq;
-        return;
-      }
-      if (cursor.value.deleted !== true) {
-        count++;
-      }
-      cursor['continue']();
-    }
-
-    txn.oncomplete = function () {
-      callback(null, {
-        db_name: name,
-        doc_count: count,
-        update_seq: update_seq
-      });
-    };
-
-    txn.objectStore(DOC_STORE).openCursor().onsuccess = countDocs;
-  };
-
-  api._changes = function idb_changes(opts) {
-    //console.log(name + ': Start Changes Feed: continuous=' + opts.continuous);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      opts.cancelled = false;
-      IdbPouch.Changes.addListener(name, id, api, opts);
-      IdbPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          //console.log(name + ': Cancel Changes Feed');
-          opts.cancelled = true;
-          IdbPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending ? 'prev' : null;
-    var last_seq = 0;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var results = [], resultIndices = {}, dedupResults = [];
-    var txn;
-
-    function fetchChanges() {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE]);
-      txn.oncomplete = onTxnComplete;
-
-      var req;
-
-      if (descending) {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(window.IDBKeyRange.lowerBound(opts.since, true), descending);
-      } else {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(window.IDBKeyRange.lowerBound(opts.since, true));
-      }
-
-      req.onsuccess = onsuccess;
-      req.onerror = onerror;
-    }
-
-    fetchChanges();
-
-    function onsuccess(event) {
-      if (!event.target.result) {
-        // Filter out null results casued by deduping
-        for (var i = 0, l = results.length; i < l; i++) {
-          var result = results[i];
-          if (result) {
-            dedupResults.push(result);
-          }
-        }
-        return false;
-      }
-
-      var cursor = event.target.result;
-
-      // Try to pre-emptively dedup to save us a bunch of idb calls
-      var changeId = cursor.value._id;
-      var changeIdIndex = resultIndices[changeId];
-      if (changeIdIndex !== undefined) {
-        results[changeIdIndex].seq = cursor.key;
-        // update so it has the later sequence number
-        results.push(results[changeIdIndex]);
-        results[changeIdIndex] = null;
-        resultIndices[changeId] = results.length - 1;
-        return cursor['continue']();
-      }
-
-      var index = txn.objectStore(DOC_STORE);
-      index.get(cursor.value._id).onsuccess = function (event) {
-        var metadata = event.target.result;
-        if (utils.isLocalId(metadata.id)) {
-          return cursor['continue']();
-        }
-
-        if (last_seq < metadata.seq) {
-          last_seq = metadata.seq;
-        }
-
-        var mainRev = merge.winningRev(metadata);
-        var key = metadata.id + "::" + mainRev;
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        index.get(key).onsuccess = function (docevent) {
-          var doc = docevent.target.result;
-          delete doc['_doc_id_rev'];
-
-          doc._rev = mainRev;
-          var change = opts.processChange(doc, metadata, opts);
-          change.seq = cursor.key;
-
-          // Dedupe the changes feed
-          var changeId = change.id, changeIdIndex = resultIndices[changeId];
-          if (changeIdIndex !== undefined) {
-            results[changeIdIndex] = null;
-          }
-          results.push(change);
-          resultIndices[changeId] = results.length - 1;
-          cursor['continue']();
-        };
-      };
-    }
-
-    function onTxnComplete() {
-      utils.processChanges(opts, dedupResults, last_seq);
-    }
-
-    function onerror(error) {
-      // TODO: shouldn't we pass some params here?
-      utils.call(opts.complete);
-    }
-  };
-
-  api._close = function (callback) {
-    if (idb === null) {
-      return utils.call(callback, errors.NOT_OPEN);
-    }
-
-    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
-    // "Returns immediately and closes the connection in a separate thread..."
-    idb.close();
-    utils.call(callback, null);
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var req = txn.objectStore(DOC_STORE).get(docId);
-    req.onsuccess = function (event) {
-      var doc = event.target.result;
-      if (!doc) {
-        utils.call(callback, errors.MISSING_DOC);
-      } else {
-        utils.call(callback, null, doc.rev_tree);
-      }
-    };
-  };
-
-  // This function removes revisions of document docId
-  // which are listed in revs and sets this document
-  // revision to to rev_tree
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    var txn = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readwrite');
-
-    var index = txn.objectStore(DOC_STORE);
-    index.get(docId).onsuccess = function (event) {
-      var metadata = event.target.result;
-      metadata.rev_tree = rev_tree;
-
-      var count = revs.length;
-      revs.forEach(function (rev) {
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = docId + "::" + rev;
-        index.getKey(key).onsuccess = function (e) {
-          var seq = e.target.result;
-          if (!seq) {
-            return;
-          }
-          var req = txn.objectStore(BY_SEQ_STORE)['delete'](seq);
-
-          count--;
-          if (!count) {
-            txn.objectStore(DOC_STORE).put(metadata);
-          }
-        };
-      });
-    };
-    txn.oncomplete = function () {
-      utils.call(callback);
-    };
-  };
-
-  return api;
-}
-
-IdbPouch.valid = function idb_valid() {
-  return typeof window !== 'undefined' && !!window.indexedDB;
-};
-
-IdbPouch.destroy = function idb_destroy(name, opts, callback) {
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.Changes.clearListeners(name);
-
-  //Close open request for "name" database to fix ie delay.
-  if (IdbPouch.openReqList[name] && IdbPouch.openReqList[name].result) {
-    IdbPouch.openReqList[name].result.close();
-  }
-  var req = window.indexedDB.deleteDatabase(name);
-
-  req.onsuccess = function () {
-    //Remove open request from the list.
-    if (IdbPouch.openReqList[name]) {
-      IdbPouch.openReqList[name] = null;
-    }
-    utils.call(callback, null);
-  };
-
-  req.onerror = idbError(callback);
-};
-
-IdbPouch.Changes = new utils.Changes();
-
-module.exports = IdbPouch;
-
-},{"../deps/errors":8,"../merge":13,"../utils":16}],4:[function(require,module,exports){
-'use strict';
-
-var utils = require('../utils');
-var merge = require('../merge');
-var errors = require('../deps/errors');
-function quote(str) {
-  return "'" + str + "'";
-}
-
-function openDB() {
-  if (typeof window !== 'undefined') {
-    if (window.navigator && window.navigator.sqlitePlugin && window.navigator.sqlitePlugin.openDatabase) {
-      return navigator.sqlitePlugin.openDatabase.apply(navigator.sqlitePlugin, arguments);
-    } else if (window.sqlitePlugin && window.sqlitePlugin.openDatabase) {
-      return window.sqlitePlugin.openDatabase.apply(window.sqlitePlugin, arguments);
-    } else {
-      return window.openDatabase.apply(window, arguments);
-    }
-  }
-}
-
-var POUCH_VERSION = 1;
-var POUCH_SIZE = 5 * 1024 * 1024;
-
-// The object stores created for each database
-// DOC_STORE stores the document meta data, its revision history and state
-var DOC_STORE = quote('document-store');
-// BY_SEQ_STORE stores a particular version of a document, keyed by its
-// sequence id
-var BY_SEQ_STORE = quote('by-sequence');
-// Where we store attachments
-var ATTACH_STORE = quote('attach-store');
-var META_STORE = quote('metadata-store');
-
-function unknownError(callback) {
-  return function (event) {
-    utils.call(callback, {
-      status: 500,
-      error: event.type,
-      reason: event.target
-    });
-  };
-}
-function idbError(callback) {
-  return function (event) {
-    utils.call(callback, errors.error(errors.WSQ_ERROR, event.target, event.type));
-  };
-}
-function webSqlPouch(opts, callback) {
-
-  var api = {};
-  var instanceId = null;
-  var name = opts.name;
-
-  var db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  if (!db) {
-    return utils.call(callback, errors.UNKNOWN_ERROR);
-  }
-
-  function dbCreated() {
-    callback(null, api);
-  }
-
-  function setup() {
-    db.transaction(function (tx) {
-      var meta = 'CREATE TABLE IF NOT EXISTS ' + META_STORE +
-        ' (update_seq, dbid)';
-      var attach = 'CREATE TABLE IF NOT EXISTS ' + ATTACH_STORE +
-        ' (digest, json, body BLOB)';
-      var doc = 'CREATE TABLE IF NOT EXISTS ' + DOC_STORE +
-        ' (id unique, seq, json, winningseq)';
-      var seq = 'CREATE TABLE IF NOT EXISTS ' + BY_SEQ_STORE +
-        ' (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, doc_id_rev UNIQUE, json)';
-
-      tx.executeSql(attach);
-      tx.executeSql(doc);
-      tx.executeSql(seq);
-      tx.executeSql(meta);
-
-      var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-      tx.executeSql(updateseq, [], function (tx, result) {
-        if (!result.rows.length) {
-          var initSeq = 'INSERT INTO ' + META_STORE + ' (update_seq) VALUES (?)';
-          tx.executeSql(initSeq, [0]);
-          return;
-        }
-      });
-
-      var dbid = 'SELECT dbid FROM ' + META_STORE + ' WHERE dbid IS NOT NULL';
-      tx.executeSql(dbid, [], function (tx, result) {
-        if (!result.rows.length) {
-          var initDb = 'UPDATE ' + META_STORE + ' SET dbid=?';
-          instanceId = utils.uuid();
-          tx.executeSql(initDb, [instanceId]);
-          return;
-        }
-        instanceId = result.rows.item(0).dbid;
-      });
-    }, unknownError(callback), dbCreated);
-  }
-  if (utils.isCordova() && typeof window !== 'undefined') {
-    //to wait until custom api is made in pouch.adapters before doing setup
-    window.addEventListener(name + '_pouch', function cordova_init() {
-      window.removeEventListener(name + '_pouch', cordova_init, false);
-      setup();
-    }, false);
-  } else {
-    setup();
-  }
-
-
-  api.type = function () {
-    return 'websql';
-  };
-
-  api.id = function () {
-    return instanceId;
-  };
-
-  api._info = function (callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT COUNT(id) AS count FROM ' + DOC_STORE;
-      tx.executeSql(sql, [], function (tx, result) {
-        var doc_count = result.rows.item(0).count;
-        var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-        tx.executeSql(updateseq, [], function (tx, result) {
-          var update_seq = result.rows.item(0).update_seq;
-          callback(null, {
-            db_name: name,
-            doc_count: doc_count,
-            update_seq: update_seq
-          });
-        });
-      });
-    });
-  };
-
-  api._bulkDocs = function (req, opts, callback) {
-
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    var docsWritten = 0;
-
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return utils.call(callback, docInfoErrors[0]);
-    }
-
-    var tx;
-    var results = [];
-    var fetchedDocs = {};
-
-    function sortByBulkSeq(a, b) {
-      return a._bulk_seq - b._bulk_seq;
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        docsWritten++;
-
-        webSqlPouch.Changes.notify(name);
-        webSqlPouch.Changes.notifyLocalWindows(name);
-      });
-
-      var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-      tx.executeSql(updateseq, [], function (tx, result) {
-        var update_seq = result.rows.item(0).update_seq + docsWritten;
-        var sql = 'UPDATE ' + META_STORE + ' SET update_seq=?';
-        tx.executeSql(sql, [update_seq], function () {
-          utils.call(callback, null, aresults);
-        });
-      });
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        try {
-          att.data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return utils.call(callback, err);
-        }
-        att.digest = 'md5-' + utils.Crypto.MD5(att.data);
-        return finish();
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        att.data = this.result;
-        att.digest = 'md5-' + utils.Crypto.MD5(this.result);
-        finish();
-      };
-      reader.readAsBinaryString(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-      var recv = 0;
-
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        function processedAttachment() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          preprocessAttachment(docInfo.data._attachments[key], processedAttachment);
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, callback, isUpdate) {
-
-      function finish() {
-        var data = docInfo.data;
-        var sql = 'INSERT INTO ' + BY_SEQ_STORE + ' (doc_id_rev, json) VALUES (?, ?);';
-        tx.executeSql(sql, [data._id + "::" + data._rev,
-                            JSON.stringify(data)], dataWritten);
-      }
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            utils.call(callback, err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      var err = null;
-      var recv = 0;
-
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      if (utils.isDeleted(docInfo.metadata, docInfo.metadata.rev)) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-
-      function dataWritten(tx, result) {
-        var seq = docInfo.metadata.seq = result.insertId;
-        delete docInfo.metadata.rev;
-
-        var mainRev = merge.winningRev(docInfo.metadata);
-
-        var sql = isUpdate ?
-          'UPDATE ' + DOC_STORE + ' SET seq=?, json=?, winningseq=(SELECT seq FROM ' +
-          BY_SEQ_STORE + ' WHERE doc_id_rev=?) WHERE id=?' :
-          'INSERT INTO ' + DOC_STORE + ' (id, seq, winningseq, json) VALUES (?, ?, ?, ?);';
-        var metadataStr = JSON.stringify(docInfo.metadata);
-        var key = docInfo.metadata.id + "::" + mainRev;
-        var params = isUpdate ?
-          [seq, metadataStr, key, docInfo.metadata.id] :
-          [docInfo.metadata.id, seq, seq, metadataStr];
-        tx.executeSql(sql, params, function (tx, result) {
-          results.push(docInfo);
-          utils.call(callback, null);
-        });
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var merged = merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var inConflict = (utils.isDeleted(oldDoc) &&
-                        utils.isDeleted(docInfo.metadata)) ||
-        (!utils.isDeleted(oldDoc) &&
-         newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-      writeDoc(docInfo, processDocs, true);
-    }
-
-    function insertDoc(docInfo) {
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && utils.isDeleted(docInfo.metadata)) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-      writeDoc(docInfo, processDocs, false);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        return complete();
-      }
-      var currentDoc = docInfos.shift();
-      var id = currentDoc.metadata.id;
-      if (id in fetchedDocs) {
-        updateDoc(fetchedDocs[id], currentDoc);
-      } else {
-        // if we have newEdits=false then we can update the same
-        // document twice in a single bulk docs call
-        fetchedDocs[id] = currentDoc.metadata;
-        insertDoc(currentDoc);
-      }
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-      var newAtt = {digest: digest};
-      var sql = 'SELECT digest, json FROM ' + ATTACH_STORE + ' WHERE digest=?';
-      tx.executeSql(sql, [digest], function (tx, result) {
-        if (!result.rows.length) {
-          newAtt.refs = {};
-          newAtt.refs[ref] = true;
-          sql = 'INSERT INTO ' + ATTACH_STORE + '(digest, json, body) VALUES (?, ?, ?)';
-          tx.executeSql(sql, [digest, JSON.stringify(newAtt), data], function () {
-            utils.call(callback, null);
-          });
-        } else {
-          newAtt.refs = JSON.parse(result.rows.item(0).json).refs;
-          sql = 'UPDATE ' + ATTACH_STORE + ' SET json=?, body=? WHERE digest=?';
-          tx.executeSql(sql, [JSON.stringify(newAtt), data, digest], function () {
-            utils.call(callback, null);
-          });
-        }
-      });
-    }
-
-    function metadataFetched(tx, results) {
-      for (var j = 0; j < results.rows.length; j++) {
-        var row = results.rows.item(j);
-        fetchedDocs[row.id] = JSON.parse(row.json);
-      }
-      processDocs();
-    }
-
-    preprocessAttachments(function () {
-      db.transaction(function (txn) {
-        tx = txn;
-        var ids = '(' + docInfos.map(function (d) {
-          return quote(d.metadata.id);
-        }).join(',') + ')';
-        var sql = 'SELECT * FROM ' + DOC_STORE + ' WHERE id IN ' + ids;
-        tx.executeSql(sql, [], metadataFetched);
-      }, unknownError(callback));
-    });
-  };
-
-  api._get = function (id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    if (!opts.ctx) {
-      db.transaction(function (txn) {
-        opts.ctx = txn;
-        api._get(id, opts, callback);
-      });
-      return;
-    }
-    var tx = opts.ctx;
-
-    function finish() {
-      utils.call(callback, err, {doc: doc, metadata: metadata, ctx: tx});
-    }
-
-    var sql = 'SELECT * FROM ' + DOC_STORE + ' WHERE id=?';
-    tx.executeSql(sql, [id], function (a, results) {
-      if (!results.rows.length) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      metadata = JSON.parse(results.rows.item(0).json);
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-
-      var rev = merge.winningRev(metadata);
-      var key = opts.rev ? opts.rev : rev;
-      key = metadata.id + '::' + key;
-      var sql = 'SELECT * FROM ' + BY_SEQ_STORE + ' WHERE doc_id_rev=?';
-      tx.executeSql(sql, [key], function (tx, results) {
-        if (!results.rows.length) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        doc = JSON.parse(results.rows.item(0).json);
-
-        finish();
-      });
-    });
-  };
-
-  function makeRevs(arr) {
-    return arr.map(function (x) { return {rev: x.rev}; });
-  }
-
-  api._allDocs = function (opts, callback) {
-    var results = [];
-    var resultsMap = {};
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var descending = 'descending' in opts ? opts.descending : false;
-    var sql = 'SELECT ' + DOC_STORE + '.id, ' + BY_SEQ_STORE + '.seq, ' +
-      BY_SEQ_STORE + '.json AS data, ' + DOC_STORE + '.json AS metadata FROM ' +
-      BY_SEQ_STORE + ' JOIN ' + DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-      DOC_STORE + '.winningseq';
-
-    var sqlArgs = [];
-    if ('keys' in opts) {
-      sql += ' WHERE ' + DOC_STORE + '.id IN (' + opts.keys.map(function () {
-        return '?';
-      }).join(',') + ')';
-      sqlArgs = sqlArgs.concat(opts.keys);
-    } else {
-      if (start) {
-        sql += ' WHERE ' + DOC_STORE + '.id >= ?';
-        sqlArgs.push(start);
-      }
-      if (end) {
-        sql += (start ? ' AND ' : ' WHERE ') + DOC_STORE + '.id <= ?';
-        sqlArgs.push(end);
-      }
-      sql += ' ORDER BY ' + DOC_STORE + '.id ' + (descending ? 'DESC' : 'ASC');
-    }
-
-    db.transaction(function (tx) {
-      tx.executeSql(sql, sqlArgs, function (tx, result) {
-        for (var i = 0, l = result.rows.length; i < l; i++) {
-          var doc = result.rows.item(i);
-          var metadata = JSON.parse(doc.metadata);
-          var data = JSON.parse(doc.data);
-          if (!(utils.isLocalId(metadata.id))) {
-            doc = {
-              id: metadata.id,
-              key: metadata.id,
-              value: {rev: merge.winningRev(metadata)}
-            };
-            if (opts.include_docs) {
-              doc.doc = data;
-              doc.doc._rev = merge.winningRev(metadata);
-              if (opts.conflicts) {
-                doc.doc._conflicts = merge.collectConflicts(metadata);
-              }
-              for (var att in doc.doc._attachments) {
-                doc.doc._attachments[att].stub = true;
-              }
-            }
-            if ('keys' in opts) {
-              if (opts.keys.indexOf(metadata.id) > -1) {
-                if (utils.isDeleted(metadata)) {
-                  doc.value.deleted = true;
-                  doc.doc = null;
-                }
-                resultsMap[doc.id] = doc;
-              }
-            } else {
-              if (!utils.isDeleted(metadata)) {
-                results.push(doc);
-              }
-            }
-          }
-        }
-      });
-    }, unknownError(callback), function () {
-      if ('keys' in opts) {
-        opts.keys.forEach(function (key) {
-          if (key in resultsMap) {
-            results.push(resultsMap[key]);
-          } else {
-            results.push({"key": key, "error": "not_found"});
-          }
-        });
-        if (opts.descending) {
-          results.reverse();
-        }
-      }
-      utils.call(callback, null, {
-        total_rows: results.length,
-        offset: opts.skip,
-        rows: ('limit' in opts) ? results.slice(opts.skip, opts.limit + opts.skip) :
-          (opts.skip > 0) ? results.slice(opts.skip) : results
-      });
-    });
-  };
-
-  api._changes = function idb_changes(opts) {
-
-
-    //console.log(name + ': Start Changes Feed: continuous=' + opts.continuous);
-
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      opts.cancelled = false;
-      webSqlPouch.Changes.addListener(name, id, api, opts);
-      webSqlPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          //console.log(name + ': Cancel Changes Feed');
-          opts.cancelled = true;
-          webSqlPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var results = [];
-    var txn;
-
-    function fetchChanges() {
-      var sql = 'SELECT ' + DOC_STORE + '.id, ' + BY_SEQ_STORE + '.seq, ' +
-        BY_SEQ_STORE + '.json AS data, ' + DOC_STORE + '.json AS metadata FROM ' +
-        BY_SEQ_STORE + ' JOIN ' + DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-        DOC_STORE + '.winningseq WHERE ' + DOC_STORE + '.seq > ' + opts.since +
-        ' ORDER BY ' + DOC_STORE + '.seq ' + (descending ? 'DESC' : 'ASC');
-
-      db.transaction(function (tx) {
-        tx.executeSql(sql, [], function (tx, result) {
-          var last_seq = 0;
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var res = result.rows.item(i);
-            var metadata = JSON.parse(res.metadata);
-            if (!utils.isLocalId(metadata.id)) {
-              if (last_seq < res.seq) {
-                last_seq = res.seq;
-              }
-              var doc = JSON.parse(res.data);
-              var change = opts.processChange(doc, metadata, opts);
-              change.seq = res.seq;
-
-              results.push(change);
-            }
-          }
-          utils.processChanges(opts, results, last_seq);
-        });
-      });
-    }
-
-    fetchChanges();
-  };
-
-  api._close = function (callback) {
-    //WebSQL databases do not need to be closed
-    utils.call(callback, null);
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var res;
-    var tx = opts.ctx;
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-    var sql = 'SELECT body FROM ' + ATTACH_STORE + ' WHERE digest=?';
-    tx.executeSql(sql, [digest], function (tx, result) {
-      var data = result.rows.item(0).body;
-      if (opts.encode) {
-        res = btoa(data);
-      } else {
-        res = utils.createBlob([data], {type: type});
-      }
-      utils.call(callback, null, res);
-    });
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          utils.call(callback, errors.MISSING_DOC);
-        } else {
-          var data = JSON.parse(result.rows.item(0).metadata);
-          utils.call(callback, null, data.rev_tree);
-        }
-      });
-    });
-  };
-
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          return utils.call(callback);
-        }
-        var metadata = JSON.parse(result.rows.item(0).metadata);
-        metadata.rev_tree = rev_tree;
-
-        var sql = 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE doc_id_rev IN (' +
-          revs.map(function (rev) {return quote(docId + '::' + rev); }).join(',') + ')';
-
-        tx.executeSql(sql, [], function (tx, result) {
-          var sql = 'UPDATE ' + DOC_STORE + ' SET json = ? WHERE id = ?';
-
-          tx.executeSql(sql, [JSON.stringify(metadata), docId], function (tx, result) {
-            callback();
-          });
-        });
-      });
-    });
-  };
-
-  return api;
-}
-
-webSqlPouch.valid = function () {
-  if (typeof window !== 'undefined') {
-    if (window.navigator && window.navigator.sqlitePlugin && window.navigator.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (window.sqlitePlugin && window.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (window.openDatabase) {
-      return true;
-    }
-  }
-  return false;
-};
-
-webSqlPouch.destroy = function (name, opts, callback) {
-  var db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  db.transaction(function (tx) {
-    tx.executeSql('DROP TABLE IF EXISTS ' + DOC_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + BY_SEQ_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + ATTACH_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + META_STORE, []);
-  }, unknownError(callback), function () {
-    utils.call(callback, null);
-  });
-};
-
-webSqlPouch.Changes = new utils.Changes();
-
-module.exports = webSqlPouch;
-
-},{"../deps/errors":8,"../merge":13,"../utils":16}],5:[function(require,module,exports){
-"use strict";
-
-var Adapter = require('./adapter')(PouchDBVersion110);
-function PouchDBVersion110(name, opts, callback) {
-
-  if (!(this instanceof PouchDBVersion110)) {
-    return new PouchDBVersion110(name, opts, callback);
-  }
-
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-
-  if (typeof callback === 'undefined') {
-    callback = function () {};
-  }
-
-  var originalName = opts.name || name;
-  var backend = PouchDBVersion110.parseAdapter(originalName);
-  
-  opts.originalName = originalName;
-  opts.name = backend.name;
-  opts.adapter = opts.adapter || backend.adapter;
-
-  if (!PouchDBVersion110.adapters[opts.adapter]) {
-    throw 'Adapter is missing';
-  }
-
-  if (!PouchDBVersion110.adapters[opts.adapter].valid()) {
-    throw 'Invalid Adapter';
-  }
-
-  var adapter = new Adapter(opts, function (err, db) {
-    if (err) {
-      if (callback) {
-        callback(err);
-      }
-      return;
-    }
-
-    for (var plugin in PouchDBVersion110.plugins) {
-      // In future these will likely need to be async to allow the plugin
-      // to initialise
-      var pluginObj = PouchDBVersion110.plugins[plugin](db);
-      for (var api in pluginObj) {
-        // We let things like the http adapter use its own implementation
-        // as it shares a lot of code
-        if (!(api in db)) {
-          db[api] = pluginObj[api];
-        }
-      }
-    }
-    db.taskqueue.ready(true);
-    db.taskqueue.execute(db);
-    callback(null, db);
-  });
-  for (var j in adapter) {
-    this[j] = adapter[j];
-  }
-  for (var plugin in PouchDBVersion110.plugins) {
-    // In future these will likely need to be async to allow the plugin
-    // to initialise
-    var pluginObj = PouchDBVersion110.plugins[plugin](this);
-    for (var api in pluginObj) {
-      // We let things like the http adapter use its own implementation
-      // as it shares a lot of code
-      if (!(api in this)) {
-        this[api] = pluginObj[api];
-      }
-    }
-  }
-}
-
-module.exports = PouchDBVersion110;
-},{"./adapter":1}],6:[function(require,module,exports){
-var process=require("__browserify_process");"use strict";
-
-var request = require('request');
-var extend = require('./extend.js');
-var createBlob = require('./blob.js');
-var errors = require('./errors');
-
-function ajax(options, callback) {
-
-  if (typeof options === "function") {
-    callback = options;
-    options = {};
-  }
-
-  function call(fun) {
-    /* jshint validthis: true */
-    var args = Array.prototype.slice.call(arguments, 1);
-    if (typeof fun === typeof Function) {
-      fun.apply(this, args);
-    }
-  }
-
-  var defaultOptions = {
-    method : "GET",
-    headers: {},
-    json: true,
-    processData: true,
-    timeout: 10000
-  };
-
-  options = extend(true, defaultOptions, options);
-
-  function onSuccess(obj, resp, cb) {
-    if (!options.binary && !options.json && options.processData &&
-      typeof obj !== 'string') {
-      obj = JSON.stringify(obj);
-    } else if (!options.binary && options.json && typeof obj === 'string') {
-      try {
-        obj = JSON.parse(obj);
-      } catch (e) {
-        // Probably a malformed JSON from server
-        call(cb, e);
-        return;
-      }
-    }
-    if (Array.isArray(obj)) {
-      obj = obj.map(function (v) {
-        var obj;
-        if (v.ok) {
-          return v;
-        } else if (v.error && v.error === 'conflict') {
-          obj = errors.REV_CONFLICT;
-          obj.id = v.id;
-          return obj;
-        } else if (v.missing) {
-          obj = errors.MISSING_DOC;
-          obj.missing = v.missing;
-          return obj;
-        }
-      });
-    }
-    call(cb, null, obj, resp);
-  }
-
-  function onError(err, cb) {
-    var errParsed, errObj, errType, key;
-    try {
-      errParsed = JSON.parse(err.responseText);
-      //would prefer not to have a try/catch clause
-      for (key in errors) {
-        if (errors[key].name === errParsed.error) {
-          errType = errors[key];
-          break;
-        }
-      }
-      errType = errType || errors.UNKNOWN_ERROR;
-      errObj = errors.error(errType, errParsed.reason);
-    } catch (e) {
-      errObj = errors.error(errors.UNKNOWN_ERROR);
-    }
-    call(cb, errObj);
-  }
-
-  if (process.browser && typeof XMLHttpRequest !== 'undefined') {
-    var timer, timedout = false;
-    var xhr = new XMLHttpRequest();
-
-    xhr.open(options.method, options.url);
-    xhr.withCredentials = true;
-
-    if (options.json) {
-      options.headers.Accept = 'application/json';
-      options.headers['Content-Type'] = options.headers['Content-Type'] ||
-        'application/json';
-      if (options.body && options.processData && typeof options.body !== "string") {
-        options.body = JSON.stringify(options.body);
-      }
-    }
-
-    if (options.binary) {
-      xhr.responseType = 'arraybuffer';
-    }
-
-    var createCookie = function (name, value, days) {
-      var expires = "";
-      if (days) {
-        var date = new Date();
-        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
-        expires = "; expires=" + date.toGMTString();
-      }
-      document.cookie = name + "=" + value + expires + "; path=/";
-    };
-
-    for (var key in options.headers) {
-      if (key === 'Cookie') {
-        var cookie = options.headers[key].split('=');
-        createCookie(cookie[0], cookie[1], 10);
-      } else {
-        xhr.setRequestHeader(key, options.headers[key]);
-      }
-    }
-
-    if (!("body" in options)) {
-      options.body = null;
-    }
-
-    var abortReq = function () {
-      timedout = true;
-      xhr.abort();
-      call(onError, xhr, callback);
-    };
-
-    xhr.onreadystatechange = function () {
-      if (xhr.readyState !== 4 || timedout) {
-        return;
-      }
-      clearTimeout(timer);
-      if (xhr.status >= 200 && xhr.status < 300) {
-        var data;
-        if (options.binary) {
-          data = createBlob([xhr.response || ''], {
-            type: xhr.getResponseHeader('Content-Type')
-          });
-        } else {
-          data = xhr.responseText;
-        }
-        call(onSuccess, data, xhr, callback);
-      } else {
-        call(onError, xhr, callback);
-      }
-    };
-
-    if (options.timeout > 0) {
-      timer = setTimeout(abortReq, options.timeout);
-      xhr.upload.onprogress = xhr.onprogress = function () {
-        clearTimeout(timer);
-        timer = setTimeout(abortReq, options.timeout);
-      };
-    }
-    xhr.send(options.body);
-    return {abort: abortReq};
-
-  } else {
-
-    if (options.json) {
-      if (!options.binary) {
-        options.headers.Accept = 'application/json';
-      }
-      options.headers['Content-Type'] = options.headers['Content-Type'] ||
-        'application/json';
-    }
-
-    if (options.binary) {
-      options.encoding = null;
-      options.json = false;
-    }
-
-    if (!options.processData) {
-      options.json = false;
-    }
-
-    return request(options, function (err, response, body) {
-      if (err) {
-        err.status = response ? response.statusCode : 400;
-        return call(onError, err, callback);
-      }
-      var error;
-      var content_type = response.headers['content-type'];
-      var data = (body || '');
-
-      // CouchDB doesn't always return the right content-type for JSON data, so
-      // we check for ^{ and }$ (ignoring leading/trailing whitespace)
-      if (!options.binary && (options.json || !options.processData) &&
-          typeof data !== 'object' &&
-          (/json/.test(content_type) ||
-           (/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
-        data = JSON.parse(data);
-      }
-
-      if (response.statusCode >= 200 && response.statusCode < 300) {
-        call(onSuccess, data, response, callback);
-      }
-      else {
-        if (options.binary) {
-          data = JSON.parse(data.toString());
-        }
-        if (data.reason === 'missing') {
-          error = errors.MISSING_DOC;
-        } else if (data.reason === 'no_db_file') {
-          error = errors.error(errors.DB_MISSING, data.reason);
-        } else if (data.error === 'conflict') {
-          error = errors.REV_CONFLICT;
-        } else {
-          error = errors.error(errors.UNKNOWN_ERROR, data.reason, data.error);
-        }
-        error.status = response.statusCode;
-        call(callback, error);
-      }
-    });
-  }
-}
-
-module.exports = ajax;
-
-},{"./blob.js":7,"./errors":8,"./extend.js":9,"__browserify_process":19,"request":18}],7:[function(require,module,exports){
-"use strict";
-
-//Abstracts constructing a Blob object, so it also works in older
-//browsers that don't support the native Blob constructor. (i.e.
-//old QtWebKit versions, at least).
-function createBlob(parts, properties) {
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var BlobBuilder = window.BlobBuilder || window.MSBlobBuilder || window.MozBlobBuilder || window.WebKitBlobBuilder;
-    var builder = new BlobBuilder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
-  }
-}
-
-module.exports = createBlob;
-
-
-},{}],8:[function(require,module,exports){
-"use strict";
-
-function PouchError(opts) {
-  this.status = opts.status;
-  this.name = opts.error;
-  this.message = opts.reason;
-  this.error = true;
-}
-PouchError.prototype = new Error();
-
-
-exports.MISSING_BULK_DOCS = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: "Missing JSON list of 'docs'"
-});
-exports.MISSING_DOC = new PouchError({ 
-  status: 404,
-  error: 'not_found',
-  reason: 'missing'
-});
-exports.REV_CONFLICT = new PouchError({
-  status: 409,
-  error: 'conflict',
-  reason: 'Document update conflict'
-});
-exports.INVALID_ID = new PouchError({
-  status: 400,
-  error: 'invalid_id',
-  reason: '_id field must contain a string'
-});
-exports.MISSING_ID = new PouchError({
-  status: 412,
-  error: 'missing_id',
-  reason: '_id is required for puts'
-});
-exports.RESERVED_ID = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Only reserved document ids may start with underscore.'
-});
-exports.NOT_OPEN = new PouchError({
-  status: 412,
-  error: 'precondition_failed',
-  reason: 'Database not open so cannot close'
-});
-exports.UNKNOWN_ERROR = new PouchError({
-  status: 500,
-  error: 'unknown_error',
-  reason: 'Database encountered an unknown error'
-});
-exports.BAD_ARG = new PouchError({
-  status: 500,
-  error: 'badarg',
-  reason: 'Some query argument is invalid'
-});
-exports.INVALID_REQUEST = new PouchError({
-  status: 400,
-  error: 'invalid_request',
-  reason: 'Request was invalid'
-});
-exports.QUERY_PARSE_ERROR = new PouchError({
-  status: 400,
-  error: 'query_parse_error',
-  reason: 'Some query parameter is invalid'
-});
-exports.DOC_VALIDATION = new PouchError({
-  status: 500,
-  error: 'doc_validation',
-  reason: 'Bad special document member'
-});
-exports.BAD_REQUEST = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Something wrong with the request'
-});
-exports.NOT_AN_OBJECT = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Document must be a JSON object'
-});
-exports.DB_MISSING = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'Database not found'
-});
-exports.IDB_ERROR = new PouchError({
-  status: 500,
-  error: 'indexed_db_went_bad',
-  reason: 'unknown'
-});
-exports.WSQ_ERROR = new PouchError({
-  status: 500,
-  error: 'web_sql_went_bad',
-  reason: 'unknown'
-});
-exports.LDB_ERROR = new PouchError({
-  status: 500,
-  error: 'levelDB_went_went_bad',
-  reason: 'unknown'
-});
-exports.error = function (error, reason, name) {
-  function CustomPouchError(msg) {
-    this.message = reason;
-    if (name) {
-      this.name = name;
-    }
-  }
-  CustomPouchError.prototype = error;
-  return new CustomPouchError(reason);
-};
-},{}],9:[function(require,module,exports){
-"use strict";
-
-// Extends method
-// (taken from http://code.jquery.com/jquery-1.9.0.js)
-// Populate the class2type map
-var class2type = {};
-
-var types = ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object", "Error"];
-for (var i = 0; i < types.length; i++) {
-  var typename = types[i];
-  class2type["[object " + typename + "]"] = typename.toLowerCase();
-}
-
-var core_toString = class2type.toString;
-var core_hasOwn = class2type.hasOwnProperty;
-
-function type(obj) {
-  if (obj === null) {
-    return String(obj);
-  }
-  return typeof obj === "object" || typeof obj === "function" ?
-    class2type[core_toString.call(obj)] || "object" :
-    typeof obj;
-}
-
-function isWindow(obj) {
-  return obj !== null && obj === obj.window;
-}
-
-function isPlainObject(obj) {
-  // Must be an Object.
-  // Because of IE, we also have to check the presence of the constructor property.
-  // Make sure that DOM nodes and window objects don't pass through, as well
-  if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
-    return false;
-  }
-
-  try {
-    // Not own constructor property must be Object
-    if (obj.constructor &&
-      !core_hasOwn.call(obj, "constructor") &&
-      !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
-      return false;
-    }
-  } catch ( e ) {
-    // IE8,9 Will throw exceptions on certain host objects #9897
-    return false;
-  }
-
-  // Own properties are enumerated firstly, so to speed up,
-  // if last one is own, then all properties are own.
-  var key;
-  for (key in obj) {}
-
-  return key === undefined || core_hasOwn.call(obj, key);
-}
-
-
-function isFunction(obj) {
-  return type(obj) === "function";
-}
-
-var isArray = Array.isArray || function (obj) {
-  return type(obj) === "array";
-};
-
-function extend() {
-  var options, name, src, copy, copyIsArray, clone,
-    target = arguments[0] || {},
-    i = 1,
-    length = arguments.length,
-    deep = false;
-
-  // Handle a deep copy situation
-  if (typeof target === "boolean") {
-    deep = target;
-    target = arguments[1] || {};
-    // skip the boolean and the target
-    i = 2;
-  }
-
-  // Handle case when target is a string or something (possible in deep copy)
-  if (typeof target !== "object" && !isFunction(target)) {
-    target = {};
-  }
-
-  // extend jQuery itself if only one argument is passed
-  if (length === i) {
-    /* jshint validthis: true */
-    target = this;
-    --i;
-  }
-
-  for (; i < length; i++) {
-    // Only deal with non-null/undefined values
-    if ((options = arguments[i]) != null) {
-      // Extend the base object
-      for (name in options) {
-        src = target[name];
-        copy = options[name];
-
-        // Prevent never-ending loop
-        if (target === copy) {
-          continue;
-        }
-
-        // Recurse if we're merging plain objects or arrays
-        if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
-          if (copyIsArray) {
-            copyIsArray = false;
-            clone = src && isArray(src) ? src : [];
-
-          } else {
-            clone = src && isPlainObject(src) ? src : {};
-          }
-
-          // Never move original objects, clone them
-          target[name] = extend(deep, clone, copy);
-
-        // Don't bring in undefined values
-        } else if (copy !== undefined) {
-          if (!(isArray(options) && isFunction(copy))) {
-            target[name] = copy;
-          }
-        }
-      }
-    }
-  }
-
-  // Return the modified object
-  return target;
-}
-
-
-module.exports = extend;
-
-
-},{}],10:[function(require,module,exports){
-var process=require("__browserify_process");"use strict";
-
-/**
-*
-*  MD5 (Message-Digest Algorithm)
-*
-*  For original source see http://www.webtoolkit.info/
-*  Download: 15.02.2009 from http://www.webtoolkit.info/javascript-md5.html
-*
-*  Licensed under CC-BY 2.0 License
-*  (http://creativecommons.org/licenses/by/2.0/uk/)
-*
-**/
-var crypto = require('crypto');
-
-exports.MD5 = function (string) {
-  if (!process.browser) {
-    return crypto.createHash('md5').update(string).digest('hex');
-  }
-  function rotateLeft(lValue, iShiftBits) {
-    return (lValue<<iShiftBits) | (lValue>>>(32 - iShiftBits));
-  }
-
-  function addUnsigned(lX, lY) {
-    var lX4, lY4, lX8, lY8, lResult;
-    lX8 = (lX & 0x80000000);
-    lY8 = (lY & 0x80000000);
-    lX4 = (lX & 0x40000000);
-    lY4 = (lY & 0x40000000);
-    lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
-    if (lX4 & lY4) {
-      return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
-    }
-    if (lX4 | lY4) {
-      if (lResult & 0x40000000) {
-        return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
-      } else {
-        return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
-      }
-    } else {
-      return (lResult ^ lX8 ^ lY8);
-    }
-  }
-
-  function f(x, y, z) { return (x & y) | ((~x) & z); }
-  function g(x, y, z) { return (x & z) | (y & (~z)); }
-  function h(x, y, z) { return (x ^ y ^ z); }
-  function i(x, y, z) { return (y ^ (x | (~z))); }
-
-  function ff(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function gg(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function hh(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function ii(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(i(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function convertToWordArray(string) {
-    var lWordCount;
-    var lMessageLength = string.length;
-    var lNumberOfWords_temp1 = lMessageLength + 8;
-    var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
-    var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
-    var lWordArray = new Array(lNumberOfWords - 1);
-    var lBytePosition = 0;
-    var lByteCount = 0;
-    while (lByteCount < lMessageLength) {
-      lWordCount = (lByteCount - (lByteCount % 4)) / 4;
-      lBytePosition = (lByteCount % 4) * 8;
-      lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
-      lByteCount++;
-    }
-    lWordCount = (lByteCount - (lByteCount % 4)) / 4;
-    lBytePosition = (lByteCount % 4) * 8;
-    lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
-    lWordArray[lNumberOfWords - 2] = lMessageLength<<3;
-    lWordArray[lNumberOfWords - 1] = lMessageLength>>>29;
-    return lWordArray;
-  }
-
-  function wordToHex(lValue) {
-    var   wordToHexValue = "",   wordToHexValue_temp = "", lByte, lCount;
-    for (lCount = 0;lCount <= 3;lCount++) {
-      lByte = (lValue>>>(lCount * 8)) & 255;
-      wordToHexValue_temp = "0" + lByte.toString(16);
-      wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
-    }
-    return   wordToHexValue;
-  }
-
-  //**  function Utf8Encode(string) removed. Aready defined in pidcrypt_utils.js
-
-  var x = [];
-  var k, AA, BB, CC, DD, a, b, c, d;
-  var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
-  var S21 = 5, S22 = 9,  S23 = 14, S24 = 20;
-  var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
-  var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
-
-  //  string = Utf8Encode(string); #function call removed
-
-  x = convertToWordArray(string);
-
-  a = 0x67452301;
-  b = 0xEFCDAB89;
-  c = 0x98BADCFE;
-  d = 0x10325476;
-
-  for (k = 0;k < x.length;k += 16) {
-    AA = a;
-    BB = b;
-    CC = c;
-    DD = d;
-    a = ff(a, b, c, d, x[k + 0],  S11, 0xD76AA478);
-    d = ff(d, a, b, c, x[k + 1],  S12, 0xE8C7B756);
-    c = ff(c, d, a, b, x[k + 2],  S13, 0x242070DB);
-    b = ff(b, c, d, a, x[k + 3],  S14, 0xC1BDCEEE);
-    a = ff(a, b, c, d, x[k + 4],  S11, 0xF57C0FAF);
-    d = ff(d, a, b, c, x[k + 5],  S12, 0x4787C62A);
-    c = ff(c, d, a, b, x[k + 6],  S13, 0xA8304613);
-    b = ff(b, c, d, a, x[k + 7],  S14, 0xFD469501);
-    a = ff(a, b, c, d, x[k + 8],  S11, 0x698098D8);
-    d = ff(d, a, b, c, x[k + 9],  S12, 0x8B44F7AF);
-    c = ff(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
-    b = ff(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
-    a = ff(a, b, c, d, x[k + 12], S11, 0x6B901122);
-    d = ff(d, a, b, c, x[k + 13], S12, 0xFD987193);
-    c = ff(c, d, a, b, x[k + 14], S13, 0xA679438E);
-    b = ff(b, c, d, a, x[k + 15], S14, 0x49B40821);
-    a = gg(a, b, c, d, x[k + 1],  S21, 0xF61E2562);
-    d = gg(d, a, b, c, x[k + 6],  S22, 0xC040B340);
-    c = gg(c, d, a, b, x[k + 11], S23, 0x265E5A51);
-    b = gg(b, c, d, a, x[k + 0],  S24, 0xE9B6C7AA);
-    a = gg(a, b, c, d, x[k + 5],  S21, 0xD62F105D);
-    d = gg(d, a, b, c, x[k + 10], S22, 0x2441453);
-    c = gg(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
-    b = gg(b, c, d, a, x[k + 4],  S24, 0xE7D3FBC8);
-    a = gg(a, b, c, d, x[k + 9],  S21, 0x21E1CDE6);
-    d = gg(d, a, b, c, x[k + 14], S22, 0xC33707D6);
-    c = gg(c, d, a, b, x[k + 3],  S23, 0xF4D50D87);
-    b = gg(b, c, d, a, x[k + 8],  S24, 0x455A14ED);
-    a = gg(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
-    d = gg(d, a, b, c, x[k + 2],  S22, 0xFCEFA3F8);
-    c = gg(c, d, a, b, x[k + 7],  S23, 0x676F02D9);
-    b = gg(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
-    a = hh(a, b, c, d, x[k + 5],  S31, 0xFFFA3942);
-    d = hh(d, a, b, c, x[k + 8],  S32, 0x8771F681);
-    c = hh(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
-    b = hh(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
-    a = hh(a, b, c, d, x[k + 1],  S31, 0xA4BEEA44);
-    d = hh(d, a, b, c, x[k + 4],  S32, 0x4BDECFA9);
-    c = hh(c, d, a, b, x[k + 7],  S33, 0xF6BB4B60);
-    b = hh(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
-    a = hh(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
-    d = hh(d, a, b, c, x[k + 0],  S32, 0xEAA127FA);
-    c = hh(c, d, a, b, x[k + 3],  S33, 0xD4EF3085);
-    b = hh(b, c, d, a, x[k + 6],  S34, 0x4881D05);
-    a = hh(a, b, c, d, x[k + 9],  S31, 0xD9D4D039);
-    d = hh(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
-    c = hh(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
-    b = hh(b, c, d, a, x[k + 2],  S34, 0xC4AC5665);
-    a = ii(a, b, c, d, x[k + 0],  S41, 0xF4292244);
-    d = ii(d, a, b, c, x[k + 7],  S42, 0x432AFF97);
-    c = ii(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
-    b = ii(b, c, d, a, x[k + 5],  S44, 0xFC93A039);
-    a = ii(a, b, c, d, x[k + 12], S41, 0x655B59C3);
-    d = ii(d, a, b, c, x[k + 3],  S42, 0x8F0CCC92);
-    c = ii(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
-    b = ii(b, c, d, a, x[k + 1],  S44, 0x85845DD1);
-    a = ii(a, b, c, d, x[k + 8],  S41, 0x6FA87E4F);
-    d = ii(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
-    c = ii(c, d, a, b, x[k + 6],  S43, 0xA3014314);
-    b = ii(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
-    a = ii(a, b, c, d, x[k + 4],  S41, 0xF7537E82);
-    d = ii(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
-    c = ii(c, d, a, b, x[k + 2],  S43, 0x2AD7D2BB);
-    b = ii(b, c, d, a, x[k + 9],  S44, 0xEB86D391);
-    a = addUnsigned(a, AA);
-    b = addUnsigned(b, BB);
-    c = addUnsigned(c, CC);
-    d = addUnsigned(d, DD);
-  }
-  var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
-  return temp.toLowerCase();
-};
-},{"__browserify_process":19,"crypto":18}],11:[function(require,module,exports){
-"use strict";
-
-// BEGIN Math.uuid.js
-
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- *   length - the desired number of characters
- *   radix  - the number of allowable values for each character.
- *
- * EXAMPLES:
- *   // No arguments  - returns RFC4122, version 4 ID
- *   >>> Math.uuid()
- *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- *   // One argument - returns ID of the specified length
- *   >>> Math.uuid(15)     // 15 character ID (default base=62)
- *   "VcydxgltxrVZSTV"
- *
- *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
- *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
- *   "01001010"
- *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
- *   "47473046"
- *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
- *   "098F4D35"
- */
-
-
-function uuid(len, radix) {
-  var chars = uuid.CHARS;
-  var uuidInner = [];
-  var i;
-
-  radix = radix || chars.length;
-
-  if (len) {
-    // Compact form
-    for (i = 0; i < len; i++) {
-      uuidInner[i] = chars[0 | Math.random() * radix];
-    }
-  } else {
-    // rfc4122, version 4 form
-    var r;
-
-    // rfc4122 requires these characters
-    uuidInner[8] = uuidInner[13] = uuidInner[18] = uuidInner[23] = '-';
-    uuidInner[14] = '4';
-
-    // Fill in random data.  At i==19 set the high bits of clock sequence as
-    // per rfc4122, sec. 4.1.5
-    for (i = 0; i < 36; i++) {
-      if (!uuidInner[i]) {
-        r = 0 | Math.random() * 16;
-        uuidInner[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
-      }
-    }
-  }
-
-  return uuidInner.join('');
-}
-
-uuid.CHARS = (
-  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
-  'abcdefghijklmnopqrstuvwxyz'
-).split('');
-
-module.exports = uuid;
-
-
-},{}],12:[function(require,module,exports){
-var process=require("__browserify_process");"use strict";
-
-var PouchDBVersion110 = require('./setup');
-
-module.exports = PouchDBVersion110;
-
-PouchDBVersion110.ajax = require('./deps/ajax');
-PouchDBVersion110.extend = require('./deps/extend');
-PouchDBVersion110.utils = require('./utils');
-PouchDBVersion110.Errors = require('./deps/errors');
-PouchDBVersion110.replicate = require('./replicate').replicate;
-PouchDBVersion110.version = require('./version');
-var httpAdapter = require('./adapters/http');
-PouchDBVersion110.adapter('http', httpAdapter);
-PouchDBVersion110.adapter('https', httpAdapter);
-
-PouchDBVersion110.adapter('idb', require('./adapters/idb'));
-PouchDBVersion110.adapter('websql', require('./adapters/websql'));
-PouchDBVersion110.plugin('mapreduce', require('pouchdb-mapreduce'));
-
-if (!process.browser) {
-  var ldbAdapter = require('./adapters/leveldb');
-  PouchDBVersion110.adapter('ldb', ldbAdapter);
-  PouchDBVersion110.adapter('leveldb', ldbAdapter);
-}
-
-},{"./adapters/http":2,"./adapters/idb":3,"./adapters/leveldb":18,"./adapters/websql":4,"./deps/ajax":6,"./deps/errors":8,"./deps/extend":9,"./replicate":14,"./setup":15,"./utils":16,"./version":17,"__browserify_process":19,"pouchdb-mapreduce":20}],13:[function(require,module,exports){
-'use strict';
-
-var extend = require('./deps/extend');
-
-
-// for a better overview of what this is doing, read:
-// https://github.com/apache/couchdb/blob/master/src/couchdb/couch_key_tree.erl
-//
-// But for a quick intro, CouchDB uses a revision tree to store a documents
-// history, A -> B -> C, when a document has conflicts, that is a branch in the
-// tree, A -> (B1 | B2 -> C), We store these as a nested array in the format
-//
-// KeyTree = [Path ... ]
-// Path = {pos: position_from_root, ids: Tree}
-// Tree = [Key, Opts, [Tree, ...]], in particular single node: [Key, []]
-
-// Turn a path as a flat array into a tree with a single branch
-function pathToTree(path) {
-  var doc = path.shift();
-  var root = [doc.id, doc.opts, []];
-  var leaf = root;
-  var nleaf;
-
-  while (path.length) {
-    doc = path.shift();
-    nleaf = [doc.id, doc.opts, []];
-    leaf[2].push(nleaf);
-    leaf = nleaf;
-  }
-  return root;
-}
-
-// Merge two trees together
-// The roots of tree1 and tree2 must be the same revision
-function mergeTree(in_tree1, in_tree2) {
-  var queue = [{tree1: in_tree1, tree2: in_tree2}];
-  var conflicts = false;
-  while (queue.length > 0) {
-    var item = queue.pop();
-    var tree1 = item.tree1;
-    var tree2 = item.tree2;
-
-    if (tree1[1].status || tree2[1].status) {
-      tree1[1].status = (tree1[1].status ===  'available' ||
-                         tree2[1].status === 'available') ? 'available' : 'missing';
-    }
-
-    for (var i = 0; i < tree2[2].length; i++) {
-      if (!tree1[2][0]) {
-        conflicts = 'new_leaf';
-        tree1[2][0] = tree2[2][i];
-        continue;
-      }
-
-      var merged = false;
-      for (var j = 0; j < tree1[2].length; j++) {
-        if (tree1[2][j][0] === tree2[2][i][0]) {
-          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
-          merged = true;
-        }
-      }
-      if (!merged) {
-        conflicts = 'new_branch';
-        tree1[2].push(tree2[2][i]);
-        tree1[2].sort();
-      }
-    }
-  }
-  return {conflicts: conflicts, tree: in_tree1};
-}
-
-function doMerge(tree, path, dontExpand) {
-  var restree = [];
-  var conflicts = false;
-  var merged = false;
-  var res, branch;
-
-  if (!tree.length) {
-    return {tree: [path], conflicts: 'new_leaf'};
-  }
-
-  tree.forEach(function (branch) {
-    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
-      // Paths start at the same position and have the same root, so they need
-      // merged
-      res = mergeTree(branch.ids, path.ids);
-      restree.push({pos: branch.pos, ids: res.tree});
-      conflicts = conflicts || res.conflicts;
-      merged = true;
-    } else if (dontExpand !== true) {
-      // The paths start at a different position, take the earliest path and
-      // traverse up until it as at the same point from root as the path we want to
-      // merge.  If the keys match we return the longer path with the other merged
-      // After stemming we dont want to expand the trees
-
-      var t1 = branch.pos < path.pos ? branch : path;
-      var t2 = branch.pos < path.pos ? path : branch;
-      var diff = t2.pos - t1.pos;
-
-      var candidateParents = [];
-
-      var trees = [];
-      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
-      while (trees.length > 0) {
-        var item = trees.pop();
-        if (item.diff === 0) {
-          if (item.ids[0] === t2.ids[0]) {
-            candidateParents.push(item);
-          }
-          continue;
-        }
-        if (!item.ids) {
-          continue;
-        }
-        /*jshint loopfunc:true */
-        item.ids[2].forEach(function (el, idx) {
-          trees.push({ids: el, diff: item.diff - 1, parent: item.ids, parentIdx: idx});
-        });
-      }
-
-      var el = candidateParents[0];
-
-      if (!el) {
-        restree.push(branch);
-      } else {
-        res = mergeTree(el.ids, t2.ids);
-        el.parent[2][el.parentIdx] = res.tree;
-        restree.push({pos: t1.pos, ids: t1.ids});
-        conflicts = conflicts || res.conflicts;
-        merged = true;
-      }
-    } else {
-      restree.push(branch);
-    }
-  });
-
-  // We didnt find
-  if (!merged) {
-    restree.push(path);
-  }
-
-  restree.sort(function (a, b) {
-    return a.pos - b.pos;
-  });
-
-  return {
-    tree: restree,
-    conflicts: conflicts || 'internal_node'
-  };
-}
-
-// To ensure we dont grow the revision tree infinitely, we stem old revisions
-function stem(tree, depth) {
-  // First we break out the tree into a complete list of root to leaf paths,
-  // we cut off the start of the path and generate a new set of flat trees
-  var stemmedPaths = PouchMerge.rootToLeaf(tree).map(function (path) {
-    var stemmed = path.ids.slice(-depth);
-    return {
-      pos: path.pos + (path.ids.length - stemmed.length),
-      ids: pathToTree(stemmed)
-    };
-  });
-  // Then we remerge all those flat trees together, ensuring that we dont
-  // connect trees that would go beyond the depth limit
-  return stemmedPaths.reduce(function (prev, current, i, arr) {
-    return doMerge(prev, current, true).tree;
-  }, [stemmedPaths.shift()]);
-}
-
-var PouchMerge = {};
-
-PouchMerge.merge = function (tree, path, depth) {
-  // Ugh, nicer way to not modify arguments in place?
-  tree = extend(true, [], tree);
-  path = extend(true, {}, path);
-  var newTree = doMerge(tree, path);
-  return {
-    tree: stem(newTree.tree, depth),
-    conflicts: newTree.conflicts
-  };
-};
-
-// We fetch all leafs of the revision tree, and sort them based on tree length
-// and whether they were deleted, undeleted documents with the longest revision
-// tree (most edits) win
-// The final sort algorithm is slightly documented in a sidebar here:
-// http://guide.couchdb.org/draft/conflicts.html
-PouchMerge.winningRev = function (metadata) {
-  var leafs = [];
-  PouchMerge.traverseRevTree(metadata.rev_tree,
-                              function (isLeaf, pos, id, something, opts) {
-    if (isLeaf) {
-      leafs.push({pos: pos, id: id, deleted: !!opts.deleted});
-    }
-  });
-  leafs.sort(function (a, b) {
-    if (a.deleted !== b.deleted) {
-      return a.deleted > b.deleted ? 1 : -1;
-    }
-    if (a.pos !== b.pos) {
-      return b.pos - a.pos;
-    }
-    return a.id < b.id ? 1 : -1;
-  });
-
-  return leafs[0].pos + '-' + leafs[0].id;
-};
-
-// Pretty much all below can be combined into a higher order function to
-// traverse revisions
-// The return value from the callback will be passed as context to all
-// children of that node
-PouchMerge.traverseRevTree = function (revs, callback) {
-  var toVisit = [];
-
-  revs.forEach(function (tree) {
-    toVisit.push({pos: tree.pos, ids: tree.ids});
-  });
-  while (toVisit.length > 0) {
-    var node = toVisit.pop();
-    var pos = node.pos;
-    var tree = node.ids;
-    var newCtx = callback(tree[2].length === 0, pos, tree[0], node.ctx, tree[1]);
-    /*jshint loopfunc: true */
-    tree[2].forEach(function (branch) {
-      toVisit.push({pos: pos + 1, ids: branch, ctx: newCtx});
-    });
-  }
-};
-
-PouchMerge.collectLeaves = function (revs) {
-  var leaves = [];
-  PouchMerge.traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
-    if (isLeaf) {
-      leaves.unshift({rev: pos + "-" + id, pos: pos, opts: opts});
-    }
-  });
-  leaves.sort(function (a, b) {
-    return b.pos - a.pos;
-  });
-  leaves.map(function (leaf) { delete leaf.pos; });
-  return leaves;
-};
-
-// returns revs of all conflicts that is leaves such that
-// 1. are not deleted and
-// 2. are different than winning revision
-PouchMerge.collectConflicts = function (metadata) {
-  var win = PouchMerge.winningRev(metadata);
-  var leaves = PouchMerge.collectLeaves(metadata.rev_tree);
-  var conflicts = [];
-  leaves.forEach(function (leaf) {
-    if (leaf.rev !== win && !leaf.opts.deleted) {
-      conflicts.push(leaf.rev);
-    }
-  });
-  return conflicts;
-};
-
-PouchMerge.rootToLeaf = function (tree) {
-  var paths = [];
-  PouchMerge.traverseRevTree(tree, function (isLeaf, pos, id, history, opts) {
-    history = history ? history.slice(0) : [];
-    history.push({id: id, opts: opts});
-    if (isLeaf) {
-      var rootPos = pos + 1 - history.length;
-      paths.unshift({pos: rootPos, ids: history});
-    }
-    return history;
-  });
-  return paths;
-};
-
-
-module.exports = PouchMerge;
-
-},{"./deps/extend":9}],14:[function(require,module,exports){
-var process=require("__browserify_process");'use strict';
-
-var PouchUtils = require('./utils');
-var Pouch = require('./index');
-
-// We create a basic promise so the caller can cancel the replication possibly
-// before we have actually started listening to changes etc
-function Promise() {
-  var that = this;
-  this.cancelled = false;
-  this.cancel = function () {
-    that.cancelled = true;
-  };
-}
-
-// The RequestManager ensures that only one database request is active at
-// at time, it ensures we dont max out simultaneous HTTP requests and makes
-// the replication process easier to reason about
-
-function RequestManager(promise) {
-  var queue = [];
-  var api = {};
-  var processing = false;
-
-  // Add a new request to the queue, if we arent currently processing anything
-  // then process it immediately
-  api.enqueue = function (fun, args) {
-    queue.push({fun: fun, args: args});
-    if (!processing) {
-      api.process();
-    }
-  };
-
-  // Process the next request
-  api.process = function () {
-    if (processing || !queue.length || promise.cancelled) {
-      return;
-    }
-    processing = true;
-    var task = queue.shift();
-    process.nextTick(function () {
-      task.fun.apply(null, task.args);
-    });
-  };
-
-  // We need to be notified whenever a request is complete to process
-  // the next request
-  api.notifyRequestComplete = function () {
-    processing = false;
-    api.process();
-  };
-
-  return api;
-}
-
-// TODO: check CouchDB's replication id generation, generate a unique id particular
-// to this replication
-
-function genReplicationId(src, target, opts) {
-  var filterFun = opts.filter ? opts.filter.toString() : '';
-  return '_local/' + PouchUtils.Crypto.MD5(src.id() + target.id() + filterFun);
-}
-
-// A checkpoint lets us restart replications from when they were last cancelled
-
-function fetchCheckpoint(src, target, id, callback) {
-  target.get(id, function (err, targetDoc) {
-    if (err && err.status === 404) {
-      callback(null, 0);
-    } else if (err) {
-      callback(err);
-    } else {
-      src.get(id, function (err, sourceDoc) {
-        if (err && err.status === 404 || (!err && (targetDoc.last_seq !== sourceDoc.last_seq))) {
-          callback(null, 0);
-        } else if (err) {
-          callback(err);
-        } else {
-          callback(null, sourceDoc.last_seq);
-        }
-      });
-    }
-  });
-}
-
-function writeCheckpoint(src, target, id, checkpoint, callback) {
-  function updateCheckpoint(db, callback) {
-    db.get(id, function (err, doc) {
-      if (err && err.status === 404) {
-        doc = {_id: id};
-      }
-      doc.last_seq = checkpoint;
-      db.put(doc, callback);
-    });
-  }
-  updateCheckpoint(target, function (err, doc) {
-    updateCheckpoint(src, function (err, doc) {
-      callback();
-    });
-  });
-}
-
-function replicate(src, target, opts, promise) {
-
-  var requests = new RequestManager(promise);
-  var writeQueue = [];
-  var repId = genReplicationId(src, target, opts);
-  var results = [];
-  var completed = false;
-  var pendingRevs = 0;
-  var last_seq = 0;
-  var continuous = opts.continuous || false;
-  var doc_ids = opts.doc_ids;
-  var result = {
-    ok: true,
-    start_time: new Date(),
-    docs_read: 0,
-    docs_written: 0
-  };
-
-  function docsWritten(err, res, len) {
-    if (opts.onChange) {
-      for (var i = 0; i < len; i++) {
-        /*jshint validthis:true */
-        opts.onChange.apply(this, [result]);
-      }
-    }
-    pendingRevs -= len;
-    result.docs_written += len;
-
-    writeCheckpoint(src, target, repId, last_seq, function (err, res) {
-      requests.notifyRequestComplete();
-      isCompleted();
-    });
-  }
-
-  function writeDocs() {
-    if (!writeQueue.length) {
-      return requests.notifyRequestComplete();
-    }
-    var len = writeQueue.length;
-    target.bulkDocs({docs: writeQueue}, {new_edits: false}, function (err, res) {
-      docsWritten(err, res, len);
-    });
-    writeQueue = [];
-  }
-
-  function eachRev(id, rev) {
-    src.get(id, {revs: true, rev: rev, attachments: true}, function (err, doc) {
-      result.docs_read++;
-      requests.notifyRequestComplete();
-      writeQueue.push(doc);
-      requests.enqueue(writeDocs);
-    });
-  }
-
-  function onRevsDiff(diffCounts) {
-    return function (err, diffs) {
-      requests.notifyRequestComplete();
-      if (err) {
-        if (continuous) {
-          promise.cancel();
-        }
-        PouchUtils.call(opts.complete, err, null);
-        return;
-      }
-
-      // We already have all diffs passed in `diffCounts`
-      if (Object.keys(diffs).length === 0) {
-        for (var docid in diffCounts) {
-          pendingRevs -= diffCounts[docid];
-        }
-        isCompleted();
-        return;
-      }
-
-      var _enqueuer = function (rev) {
-        requests.enqueue(eachRev, [id, rev]);
-      };
-
-      for (var id in diffs) {
-        var diffsAlreadyHere = diffCounts[id] - diffs[id].missing.length;
-        pendingRevs -= diffsAlreadyHere;
-        diffs[id].missing.forEach(_enqueuer);
-      }
-    };
-  }
-
-  function fetchRevsDiff(diff, diffCounts) {
-    target.revsDiff(diff, onRevsDiff(diffCounts));
-  }
-
-  function onChange(change) {
-    last_seq = change.seq;
-    results.push(change);
-    var diff = {};
-    diff[change.id] = change.changes.map(function (x) { return x.rev; });
-    var counts = {};
-    counts[change.id] = change.changes.length;
-    pendingRevs += change.changes.length;
-    requests.enqueue(fetchRevsDiff, [diff, counts]);
-  }
-
-  function complete() {
-    completed = true;
-    isCompleted();
-  }
-
-  function isCompleted() {
-    if (completed && pendingRevs === 0) {
-      result.end_time = new Date();
-      PouchUtils.call(opts.complete, null, result);
-    }
-  }
-
-  fetchCheckpoint(src, target, repId, function (err, checkpoint) {
-
-    if (err) {
-      return PouchUtils.call(opts.complete, err);
-    }
-
-    last_seq = checkpoint;
-
-    // Was the replication cancelled by the caller before it had a chance
-    // to start. Shouldnt we be calling complete?
-    if (promise.cancelled) {
-      return;
-    }
-
-    var repOpts = {
-      continuous: continuous,
-      since: last_seq,
-      style: 'all_docs',
-      onChange: onChange,
-      complete: complete,
-      doc_ids: doc_ids
-    };
-
-    if (opts.filter) {
-      repOpts.filter = opts.filter;
-    }
-
-    if (opts.query_params) {
-      repOpts.query_params = opts.query_params;
-    }
-
-    var changes = src.changes(repOpts);
-
-    if (opts.continuous) {
-      var cancel = promise.cancel;
-      promise.cancel = function () {
-        cancel();
-        changes.cancel();
-      };
-    }
-  });
-
-}
-
-function toPouch(db, callback) {
-  if (typeof db === 'string') {
-    return new Pouch(db, callback);
-  }
-  callback(null, db);
-}
-
-exports.replicate = function (src, target, opts, callback) {
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
-  }
-  if (opts === undefined) {
-    opts = {};
-  }
-  if (!opts.complete) {
-    opts.complete = callback;
-  }
-  var replicateRet = new Promise();
-  toPouch(src, function (err, src) {
-    if (err) {
-      return PouchUtils.call(callback, err);
-    }
-    toPouch(target, function (err, target) {
-      if (err) {
-        return PouchUtils.call(callback, err);
-      }
-      if (opts.server) {
-        if (typeof src.replicateOnServer !== 'function') {
-          return PouchUtils.call(callback, { error: 'Server replication not supported for ' + src.type() + ' adapter' });
-        }
-        if (src.type() !== target.type()) {
-          return PouchUtils.call(callback, { error: 'Server replication for different adapter types (' + src.type() + ' and ' + target.type() + ') is not supported' });
-        }
-        src.replicateOnServer(target, opts, replicateRet);
-      } else {
-        replicate(src, target, opts, replicateRet);
-      }
-    });
-  });
-  return replicateRet;
-};
-
-},{"./index":12,"./utils":16,"__browserify_process":19}],15:[function(require,module,exports){
-"use strict";
-
-var PouchDBVersion110 = require("./constructor");
-
-PouchDBVersion110.adapters = {};
-PouchDBVersion110.plugins = {};
-
-PouchDBVersion110.prefix = '_pouch_';
-
-PouchDBVersion110.parseAdapter = function (name) {
-  var match = name.match(/([a-z\-]*):\/\/(.*)/);
-  var adapter;
-  if (match) {
-    // the http adapter expects the fully qualified name
-    name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
-    adapter = match[1];
-    if (!PouchDBVersion110.adapters[adapter].valid()) {
-      throw 'Invalid adapter';
-    }
-    return {name: name, adapter: match[1]};
-  }
-
-  var preferredAdapters = ['idb', 'leveldb', 'websql'];
-  for (var i = 0; i < preferredAdapters.length; ++i) {
-    if (preferredAdapters[i] in PouchDBVersion110.adapters) {
-      adapter = PouchDBVersion110.adapters[preferredAdapters[i]];
-      var use_prefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-
-      return {
-        name: use_prefix ? PouchDBVersion110.prefix + name : name,
-        adapter: preferredAdapters[i]
-      };
-    }
-  }
-
-  throw 'No valid adapter found';
-};
-
-PouchDBVersion110.destroy = function (name, opts, callback) {
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-
-  if (typeof callback === 'undefined') {
-    callback = function () {};
-  }
-  var backend = PouchDBVersion110.parseAdapter(opts.name || name);
-  var dbName = backend.name;
-
-  var cb = function (err, response) {
-    if (err) {
-      callback(err);
-      return;
-    }
-
-    for (var plugin in PouchDBVersion110.plugins) {
-      PouchDBVersion110.plugins[plugin]._delete(dbName);
-    }
-    //console.log(dbName + ': Delete Database');
-
-    // call destroy method of the particular adaptor
-    PouchDBVersion110.adapters[backend.adapter].destroy(dbName, opts, callback);
-  };
-
-  // remove PouchDBVersion110 from allDBs
-  PouchDBVersion110.removeFromAllDbs(backend, cb);
-};
-
-PouchDBVersion110.removeFromAllDbs = function (opts, callback) {
-  // Only execute function if flag is enabled
-  if (!PouchDBVersion110.enableAllDbs) {
-    callback();
-    return;
-  }
-
-  // skip http and https adaptors for allDbs
-  var adapter = opts.adapter;
-  if (adapter === "http" || adapter === "https") {
-    callback();
-    return;
-  }
-
-  // remove db from PouchDBVersion110.ALL_DBS
-  new PouchDBVersion110(PouchDBVersion110.allDBName(opts.adapter), function (err, db) {
-    if (err) {
-      // don't fail when allDbs fail
-      //console.error(err);
-      callback();
-      return;
-    }
-    // check if db has been registered in PouchDBVersion110.ALL_DBS
-    var dbname = PouchDBVersion110.dbName(opts.adapter, opts.name);
-    db.get(dbname, function (err, doc) {
-      if (err) {
-        callback();
-      } else {
-        db.remove(doc, function (err, response) {
-          if (err) {
-            //console.error(err);
-          }
-          callback();
-        });
-      }
-    });
-  });
-
-};
-
-PouchDBVersion110.adapter = function (id, obj) {
-  if (obj.valid()) {
-    PouchDBVersion110.adapters[id] = obj;
-  }
-};
-
-PouchDBVersion110.plugin = function (id, obj) {
-  PouchDBVersion110.plugins[id] = obj;
-};
-
-// flag to toggle allDbs (off by default)
-PouchDBVersion110.enableAllDbs = false;
-
-// name of database used to keep track of databases
-PouchDBVersion110.ALL_DBS = "_allDbs";
-PouchDBVersion110.dbName = function (adapter, name) {
-  return [adapter, "-", name].join('');
-};
-PouchDBVersion110.realDBName = function (adapter, name) {
-  return [adapter, "://", name].join('');
-};
-PouchDBVersion110.allDBName = function (adapter) {
-  return [adapter, "://", PouchDBVersion110.prefix + PouchDBVersion110.ALL_DBS].join('');
-};
-
-PouchDBVersion110.open = function (opts, callback) {
-  // Only register pouch with allDbs if flag is enabled
-  if (!PouchDBVersion110.enableAllDbs) {
-    callback();
-    return;
-  }
-
-  var adapter = opts.adapter;
-  // skip http and https adaptors for allDbs
-  if (adapter === "http" || adapter === "https") {
-    callback();
-    return;
-  }
-
-  new PouchDBVersion110(PouchDBVersion110.allDBName(adapter), function (err, db) {
-    if (err) {
-      // don't fail when allDb registration fails
-      //console.error(err);
-      callback();
-      return;
-    }
-
-    // check if db has been registered in PouchDBVersion110.ALL_DBS
-    var dbname = PouchDBVersion110.dbName(adapter, opts.name);
-    db.get(dbname, function (err, response) {
-      if (err && err.status === 404) {
-        db.put({
-          _id: dbname,
-          dbname: opts.originalName
-        }, function (err) {
-            if (err) {
-              //console.error(err);
-            }
-
-            callback();
-          });
-      } else {
-        callback();
-      }
-    });
-  });
-};
-
-PouchDBVersion110.allDbs = function (callback) {
-  var accumulate = function (adapters, all_dbs) {
-    if (adapters.length === 0) {
-      // remove duplicates
-      var result = [];
-      all_dbs.forEach(function (doc) {
-        var exists = result.some(function (db) {
-          return db.id === doc.id;
-        });
-
-        if (!exists) {
-          result.push(doc);
-        }
-      });
-
-      // return an array of dbname
-      callback(null, result.map(function (row) {
-          return row.doc.dbname;
-        }));
-      return;
-    }
-
-    var adapter = adapters.shift();
-
-    // skip http and https adaptors for allDbs
-    if (adapter === "http" || adapter === "https") {
-      accumulate(adapters, all_dbs);
-      return;
-    }
-
-    new PouchDBVersion110(PouchDBVersion110.allDBName(adapter), function (err, db) {
-      if (err) {
-        callback(err);
-        return;
-      }
-      db.allDocs({include_docs: true}, function (err, response) {
-        if (err) {
-          callback(err);
-          return;
-        }
-
-        // append from current adapter rows
-        all_dbs.unshift.apply(all_dbs, response.rows);
-
-        // code to clear allDbs.
-        // response.rows.forEach(function (row) {
-        //   db.remove(row.doc, function () {
-        //     //console.log(arguments);
-        //   });
-        // });
-
-        // recurse
-        accumulate(adapters, all_dbs);
-      });
-    });
-  };
-  var adapters = Object.keys(PouchDBVersion110.adapters);
-  accumulate(adapters, []);
-};
-
-module.exports = PouchDBVersion110;
-
-},{"./constructor":5}],16:[function(require,module,exports){
-/*jshint strict: false */
-/*global chrome */
-
-var merge = require('./merge');
-exports.extend = require('./deps/extend');
-exports.ajax = require('./deps/ajax');
-exports.createBlob = require('./deps/blob');
-var uuid = require('./deps/uuid');
-exports.Crypto = require('./deps/md5.js');
-var buffer = require('./deps/buffer');
-var errors = require('./deps/errors');
-
-// List of top level reserved words for doc
-var reservedWords = [
-  '_id',
-  '_rev',
-  '_attachments',
-  '_deleted',
-  '_revisions',
-  '_revs_info',
-  '_conflicts',
-  '_deleted_conflicts',
-  '_local_seq',
-  '_rev_tree'
-];
-exports.uuids = function (count, options) {
-
-  if (typeof(options) !== 'object') {
-    options = {};
-  }
-
-  var length = options.length;
-  var radix = options.radix;
-  var uuids = [];
-
-  while (uuids.push(uuid(length, radix)) < count) { }
-
-  return uuids;
-};
-
-// Give back one UUID
-exports.uuid = function (options) {
-  return exports.uuids(1, options)[0];
-};
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or '_local'
-//   - any other string value is a valid id
-exports.isValidId = function (id) {
-  if (!id || (typeof id !== 'string')) {
-    return false;
-  }
-  if (/^_/.test(id)) {
-    return (/^_(design|local)/).test(id);
-  }
-  return true;
-};
-
-function isChromeApp() {
-  return (typeof chrome !== "undefined" &&
-          typeof chrome.storage !== "undefined" &&
-          typeof chrome.storage.local !== "undefined");
-}
-
-// Pretty dumb name for a function, just wraps callback calls so we dont
-// to if (callback) callback() everywhere
-exports.call = function (fun) {
-  if (typeof fun === typeof Function) {
-    var args = Array.prototype.slice.call(arguments, 1);
-    fun.apply(this, args);
-  }
-};
-
-exports.isLocalId = function (id) {
-  return (/^_local/).test(id);
-};
-
-// check if a specific revision of a doc has been deleted
-//  - metadata: the metadata object from the doc store
-//  - rev: (optional) the revision to check. defaults to winning revision
-exports.isDeleted = function (metadata, rev) {
-  if (!rev) {
-    rev = merge.winningRev(metadata);
-  }
-  if (rev.indexOf('-') >= 0) {
-    rev = rev.split('-')[1];
-  }
-  var deleted = false;
-  merge.traverseRevTree(metadata.rev_tree, function (isLeaf, pos, id, acc, opts) {
-    if (id === rev) {
-      deleted = !!opts.deleted;
-    }
-  });
-
-  return deleted;
-};
-
-exports.filterChange = function (opts) {
-  return function (change) {
-    var req = {};
-    var hasFilter = opts.filter && typeof opts.filter === 'function';
-
-    req.query = opts.query_params;
-    if (opts.filter && hasFilter && !opts.filter.call(this, change.doc, req)) {
-      return false;
-    }
-    if (opts.doc_ids && opts.doc_ids.indexOf(change.id) === -1) {
-      return false;
-    }
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else {
-      for (var att in change.doc._attachments) {
-        change.doc._attachments[att].stub = true;
-      }
-    }
-    return true;
-  };
-};
-
-exports.processChanges = function (opts, changes, last_seq) {
-  // TODO: we should try to filter and limit as soon as possible
-  changes = changes.filter(exports.filterChange(opts));
-  if (opts.limit) {
-    if (opts.limit < changes.length) {
-      changes.length = opts.limit;
-    }
-  }
-  changes.forEach(function (change) {
-    exports.call(opts.onChange, change);
-  });
-  exports.call(opts.complete, null, {results: changes, last_seq: last_seq});
-};
-
-// Preprocess documents, parse their revisions, assign an id and a
-// revision for new writes that are missing them, etc
-exports.parseDoc = function (doc, newEdits) {
-  var error = null;
-  var nRevNum;
-  var newRevId;
-  var revInfo;
-  var opts = {status: 'available'};
-  if (doc._deleted) {
-    opts.deleted = true;
-  }
-
-  if (newEdits) {
-    if (!doc._id) {
-      doc._id = exports.uuid();
-    }
-    newRevId = exports.uuid({length: 32, radix: 16}).toLowerCase();
-    if (doc._rev) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        throw "invalid value for property '_rev'";
-      }
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], {status: 'missing'}, [[newRevId, opts, []]]]
-      }];
-      nRevNum = parseInt(revInfo[1], 10) + 1;
-    } else {
-      doc._rev_tree = [{
-        pos: 1,
-        ids : [newRevId, opts, []]
-      }];
-      nRevNum = 1;
-    }
-  } else {
-    if (doc._revisions) {
-      doc._rev_tree = [{
-        pos: doc._revisions.start - doc._revisions.ids.length + 1,
-        ids: doc._revisions.ids.reduce(function (acc, x) {
-          if (acc === null) {
-            return [x, opts, []];
-          } else {
-            return [x, {status: 'missing'}, [acc]];
-          }
-        }, null)
-      }];
-      nRevNum = doc._revisions.start;
-      newRevId = doc._revisions.ids[0];
-    }
-    if (!doc._rev_tree) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        return errors.BAD_ARG;
-      }
-      nRevNum = parseInt(revInfo[1], 10);
-      newRevId = revInfo[2];
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], opts, []]
-      }];
-    }
-  }
-
-  if (typeof doc._id !== 'string') {
-    error = errors.INVALID_ID;
-  }
-  else if (!exports.isValidId(doc._id)) {
-    error = errors.RESERVED_ID;
-  }
-
-  for (var key in doc) {
-    if (doc.hasOwnProperty(key) && key[0] === '_' && reservedWords.indexOf(key) === -1) {
-      error = exports.extend({}, errors.DOC_VALIDATION);
-      error.reason += ': ' + key;
-    }
-  }
-
-  doc._id = decodeURIComponent(doc._id);
-  doc._rev = [nRevNum, newRevId].join('-');
-
-  if (error) {
-    return error;
-  }
-
-  return Object.keys(doc).reduce(function (acc, key) {
-    if (/^_/.test(key) && key !== '_attachments') {
-      acc.metadata[key.slice(1)] = doc[key];
-    } else {
-      acc.data[key] = doc[key];
-    }
-    return acc;
-  }, {metadata : {}, data : {}});
-};
-
-exports.isCordova = function () {
-  return (typeof cordova !== "undefined" ||
-          typeof PhoneGap !== "undefined" ||
-          typeof phonegap !== "undefined");
-};
-
-exports.Changes = function () {
-
-  var api = {};
-  var listeners = {};
-
-  if (isChromeApp()) {
-    chrome.storage.onChanged.addListener(function (e) {
-      // make sure it's event addressed to us
-      if (e.db_name != null) {
-        api.notify(e.db_name.newValue);//object only has oldValue, newValue members
-      }
-    });
-  } else if (typeof window !== 'undefined') {
-    window.addEventListener("storage", function (e) {
-      api.notify(e.key);
-    });
-  }
-
-  api.addListener = function (db_name, id, db, opts) {
-    if (!listeners[db_name]) {
-      listeners[db_name] = {};
-    }
-    listeners[db_name][id] = {
-      db: db,
-      opts: opts
-    };
-  };
-
-  api.removeListener = function (db_name, id) {
-    if (listeners[db_name]) {
-      delete listeners[db_name][id];
-    }
-  };
-
-  api.clearListeners = function (db_name) {
-    delete listeners[db_name];
-  };
-
-  api.notifyLocalWindows = function (db_name) {
-    //do a useless change on a storage thing
-    //in order to get other windows's listeners to activate
-    if (!isChromeApp()) {
-      localStorage[db_name] = (localStorage[db_name] === "a") ? "b" : "a";
-    } else {
-      chrome.storage.local.set({db_name: db_name});
-    }
-  };
-
-  api.notify = function (db_name) {
-    if (!listeners[db_name]) { return; }
-
-    Object.keys(listeners[db_name]).forEach(function (i) {
-      var opts = listeners[db_name][i].opts;
-      listeners[db_name][i].db.changes({
-        include_docs: opts.include_docs,
-        conflicts: opts.conflicts,
-        continuous: false,
-        descending: false,
-        filter: opts.filter,
-        view: opts.view,
-        since: opts.since,
-        query_params: opts.query_params,
-        onChange: function (c) {
-          if (c.seq > opts.since && !opts.cancelled) {
-            opts.since = c.seq;
-            exports.call(opts.onChange, c);
-          }
-        }
-      });
-    });
-  };
-
-  return api;
-};
-
-if (typeof window === 'undefined' || !('atob' in window)) {
-  exports.atob = function (str) {
-    var base64 = new buffer(str, 'base64');
-    // Node.js will just skip the characters it can't encode instead of
-    // throwing and exception
-    if (base64.toString('base64') !== str) {
-      throw ("Cannot base64 encode full string");
-    }
-    return base64.toString('binary');
-  };
-} else {
-  exports.atob = function (str) {
-    return atob(str);
-  };
-}
-
-if (typeof window === 'undefined' || !('btoa' in window)) {
-  exports.btoa = function (str) {
-    return new buffer(str, 'binary').toString('base64');
-  };
-} else {
-  exports.btoa = function (str) {
-    return btoa(str);
-  };
-}
-
-
-module.exports = exports;
-
-},{"./deps/ajax":6,"./deps/blob":7,"./deps/buffer":18,"./deps/errors":8,"./deps/extend":9,"./deps/md5.js":10,"./deps/uuid":11,"./merge":13}],17:[function(require,module,exports){
-module.exports = '1.1.0';
-
-},{}],18:[function(require,module,exports){
-
-},{}],19:[function(require,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
-    var canSetImmediate = typeof window !== 'undefined'
-    && window.setImmediate;
-    var canPost = typeof window !== 'undefined'
-    && window.postMessage && window.addEventListener
-    ;
-
-    if (canSetImmediate) {
-        return function (f) { return window.setImmediate(f) };
-    }
-
-    if (canPost) {
-        var queue = [];
-        window.addEventListener('message', function (ev) {
-            var source = ev.source;
-            if ((source === window || source === null) && ev.data === 'process-tick') {
-                ev.stopPropagation();
-                if (queue.length > 0) {
-                    var fn = queue.shift();
-                    fn();
-                }
-            }
-        }, true);
-
-        return function nextTick(fn) {
-            queue.push(fn);
-            window.postMessage('process-tick', '*');
-        };
-    }
-
-    return function nextTick(fn) {
-        setTimeout(fn, 0);
-    };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-}
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-
-},{}],20:[function(require,module,exports){
-/*global Pouch: true, pouchCollate: true */
-
-"use strict";
-
-var pouchCollate = require('pouchdb-collate');
-
-// This is the first implementation of a basic plugin, we register the
-// plugin object with pouch and it is mixin'd to each database created
-// (regardless of adapter), adapters can override plugins by providing
-// their own implementation. functions on the plugin object that start
-// with _ are reserved function that are called by pouchdb for special
-// notifications.
-
-// If we wanted to store incremental views we can do it here by listening
-// to the changes feed (keeping track of our last update_seq between page loads)
-// and storing the result of the map function (possibly using the upcoming
-// extracted adapter functions)
-
-
-
-function MapReduce(db) {
-  if(!(this instanceof MapReduce)){
-    return new MapReduce(db);
-  }
-  function viewQuery(fun, options) {
-    if (!options.complete) {
-      return;
-    }
-
-    if (!options.skip) {
-      options.skip = 0;
-    }
-
-    if (!fun.reduce) {
-      options.reduce = false;
-    }
-
-    function sum(values) {
-      return values.reduce(function (a, b) { return a + b; }, 0);
-    }
-
-    var builtInReduce = {
-      "_sum": function (keys, values){
-        return sum(values);
-      },
-
-      "_count": function (keys, values, rereduce){
-        if (rereduce){
-          return sum(values);
-        } else {
-          return values.length;
-        }
-      },
-
-      "_stats": function (keys, values, rereduce) {
-        return {
-          'sum': sum(values),
-          'min': Math.min.apply(null, values),
-          'max': Math.max.apply(null, values),
-          'count': values.length,
-          'sumsqr': (function () {
-            var _sumsqr = 0;
-            for(var idx in values) {
-              if (typeof values[idx] === 'number') {
-              _sumsqr += values[idx] * values[idx];
-              }
-            }
-            return _sumsqr;
-          })()
-        };
-      }
-    };
-
-    var results = [];
-    var current = null;
-    var num_started= 0;
-    var completed= false;
-
-    function emit(key, val) {
-      var viewRow = {
-        id: current.doc._id,
-        key: key,
-        value: val
-      };
-
-      if (options.startkey && pouchCollate(key, options.startkey) < 0) return;
-      if (options.endkey && pouchCollate(key, options.endkey) > 0) return;
-      if (typeof options.key !== 'undefined' && pouchCollate(key, options.key) !== 0) return;
-
-      num_started++;
-      if (options.include_docs) {
-        //in this special case, join on _id (issue #106)
-        if (val && typeof val === 'object' && val._id){
-          db.get(val._id,
-              function (_, joined_doc){
-                if (joined_doc) {
-                  viewRow.doc = joined_doc;
-                }
-                results.push(viewRow);
-                checkComplete();
-              });
-          return;
-        } else {
-          viewRow.doc = current.doc;
-        }
-      }
-      results.push(viewRow);
-    };
-
-    // ugly way to make sure references to 'emit' in map/reduce bind to the
-    // above emit
-    eval('fun.map = ' + fun.map.toString() + ';');
-    if (fun.reduce) {
-      if (builtInReduce[fun.reduce]) {
-        fun.reduce = builtInReduce[fun.reduce];
-      }
-
-      eval('fun.reduce = ' + fun.reduce.toString() + ';');
-    }
-
-    //only proceed once all documents are mapped and joined
-    function checkComplete() {
-      if (completed && results.length == num_started){
-        results.sort(function (a, b) {
-          return pouchCollate(a.key, b.key);
-        });
-        if (options.descending) {
-          results.reverse();
-        }
-        if (options.reduce === false) {
-          return options.complete(null, {
-            total_rows: results.length,
-            offset: options.skip,
-            rows: ('limit' in options) ? results.slice(options.skip, options.limit + options.skip) :
-              (options.skip > 0) ? results.slice(options.skip) : results
-          });
-        }
-
-        var groups = [];
-        results.forEach(function (e) {
-          var last = groups[groups.length-1] || null;
-          if (last && pouchCollate(last.key[0][0], e.key) === 0) {
-            last.key.push([e.key, e.id]);
-            last.value.push(e.value);
-            return;
-          }
-          groups.push({key: [[e.key, e.id]], value: [e.value]});
-        });
-        groups.forEach(function (e) {
-          e.value = fun.reduce(e.key, e.value);
-          e.value = (typeof e.value === 'undefined') ? null : e.value;
-          e.key = e.key[0][0];
-        });
-
-        options.complete(null, {
-          total_rows: groups.length,
-          offset: options.skip,
-          rows: ('limit' in options) ? groups.slice(options.skip, options.limit + options.skip) :
-            (options.skip > 0) ? groups.slice(options.skip) : groups
-        });
-      }
-    };
-
-    db.changes({
-      conflicts: true,
-      include_docs: true,
-      onChange: function (doc) {
-        if (!('deleted' in doc)) {
-          current = {doc: doc.doc};
-          fun.map.call(this, doc.doc);
-        }
-      },
-      complete: function () {
-        completed= true;
-        checkComplete();
-      }
-    });
-  }
-
-  function httpQuery(fun, opts, callback) {
-
-    // List of parameters to add to the PUT request
-    var params = [];
-    var body = undefined;
-    var method = 'GET';
-
-    // If opts.reduce exists and is defined, then add it to the list
-    // of parameters.
-    // If reduce=false then the results are that of only the map function
-    // not the final result of map and reduce.
-    if (typeof opts.reduce !== 'undefined') {
-      params.push('reduce=' + opts.reduce);
-    }
-    if (typeof opts.include_docs !== 'undefined') {
-      params.push('include_docs=' + opts.include_docs);
-    }
-    if (typeof opts.limit !== 'undefined') {
-      params.push('limit=' + opts.limit);
-    }
-    if (typeof opts.descending !== 'undefined') {
-      params.push('descending=' + opts.descending);
-    }
-    if (typeof opts.startkey !== 'undefined') {
-      params.push('startkey=' + encodeURIComponent(JSON.stringify(opts.startkey)));
-    }
-    if (typeof opts.endkey !== 'undefined') {
-      params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
-    }
-    if (typeof opts.key !== 'undefined') {
-      params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
-    }
-    if (typeof opts.group !== 'undefined') {
-      params.push('group=' + opts.group);
-    }
-    if (typeof opts.group_level !== 'undefined') {
-      params.push('group_level=' + opts.group_level);
-    }
-    if (typeof opts.skip !== 'undefined') {
-      params.push('skip=' + opts.skip);
-    }
-
-    // If keys are supplied, issue a POST request to circumvent GET query string limits
-    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-    if (typeof opts.keys !== 'undefined') {
-      method = 'POST';
-      body = JSON.stringify({keys:opts.keys});
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
-
-    // We are referencing a query defined in the design doc
-    if (typeof fun === 'string') {
-      var parts = fun.split('/');
-      db.request({
-        method: method,
-        url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
-        body: body
-      }, callback);
-      return;
-    }
-
-    // We are using a temporary view, terrible for performance but good for testing
-    var queryObject = JSON.parse(JSON.stringify(fun, function (key, val) {
-      if (typeof val === 'function') {
-        return val + ''; // implicitly `toString` it
-      }
-      return val;
-    }));
-
-    db.request({
-      method:'POST',
-      url: '_temp_view' + params,
-      body: queryObject
-    }, callback);
-  }
-
-  this.query = function(fun, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    if (callback) {
-      opts.complete = callback;
-    }
-
-    if (db.type() === 'http') {
-    if (typeof fun === 'function'){
-      return httpQuery({map: fun}, opts, callback);
-    }
-    return httpQuery(fun, opts, callback);
-    }
-
-    if (typeof fun === 'object') {
-      return viewQuery(fun, opts);
-    }
-
-    if (typeof fun === 'function') {
-      return viewQuery({map: fun}, opts);
-    }
-
-    var parts = fun.split('/');
-    db.get('_design/' + parts[0], function (err, doc) {
-      if (err) {
-        if (callback) callback(err);
-        return;
-      }
-
-      if (!doc.views[parts[1]]) {
-        if (callback) callback({ error: 'not_found', reason: 'missing_named_view' });
-        return;
-      }
-
-      viewQuery({
-        map: doc.views[parts[1]].map,
-        reduce: doc.views[parts[1]].reduce
-      }, opts);
-    });
-  }
-
-};
-
-// Deletion is a noop since we dont store the results of the view
-MapReduce._delete = function () { };
-module.exports = MapReduce;
-
-},{"pouchdb-collate":21}],21:[function(require,module,exports){
-'use strict';
-
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = pouchCollate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-  }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
-}
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = pouchCollate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = pouchCollate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
-    }
-
-  }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
-}
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  if (id.indexOf(typeof x) !== -1) {
-    if (x === null) {
-      return 1;
-    }
-    return id.indexOf(typeof x) + 2;
-  }
-  if (Array.isArray(x)) {
-    return 4.5;
-  }
-  if (typeof x === 'undefined') {
-    // CouchDB indexes both null/undefined as null
-    return 1;
-  }
-}
-module.exports = pouchCollate;
-function pouchCollate(a, b) {
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  if (a === null || typeof a === 'undefined') {
-    return 0;
-  }
-  if (typeof a === 'number') {
-    return a - b;
-  }
-  if (typeof a === 'boolean') {
-    return a === b ? 0 : (a < b ? -1 : 1);
-  }
-  if (typeof a === 'string') {
-    return stringCollate(a, b);
-  }
-  if (Array.isArray(a)) {
-    return arrayCollate(a, b);
-  }
-  if (typeof a === 'object') {
-    return objectCollate(a, b);
-  }
-};;
-},{}]},{},[12])
-(12)
-});
diff --git a/tests/integration/deps/pouchdb-2.0.0-postfixed.js b/tests/integration/deps/pouchdb-2.0.0-postfixed.js
deleted file mode 100644
index 716e3e1..0000000
--- a/tests/integration/deps/pouchdb-2.0.0-postfixed.js
+++ /dev/null
@@ -1,7569 +0,0 @@
-!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.PouchDBVersion200=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-"use strict";
-
-var utils = _dereq_('./utils');
-var merge = _dereq_('./merge');
-var errors = _dereq_('./deps/errors');
-var EventEmitter = _dereq_('events').EventEmitter;
-/*
- * A generic pouch adapter
- */
-
-// returns first element of arr satisfying callback predicate
-function arrayFirst(arr, callback) {
-  for (var i = 0; i < arr.length; i++) {
-    if (callback(arr[i], i) === true) {
-      return arr[i];
-    }
-  }
-  return false;
-}
-
-// Wrapper for functions that call the bulkdocs api with a single doc,
-// if the first result is an error, return an error
-function yankError(callback) {
-  return function (err, results) {
-    if (err || results[0].error) {
-      callback(err || results[0]);
-    } else {
-      callback(null, results[0]);
-    }
-  };
-}
-
-// for every node in a revision tree computes its distance from the closest
-// leaf
-function computeHeight(revs) {
-  var height = {};
-  var edges = [];
-  merge.traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
-    var rev = pos + "-" + id;
-    if (isLeaf) {
-      height[rev] = 0;
-    }
-    if (prnt !== undefined) {
-      edges.push({from: prnt, to: rev});
-    }
-    return rev;
-  });
-
-  edges.reverse();
-  edges.forEach(function (edge) {
-    if (height[edge.from] === undefined) {
-      height[edge.from] = 1 + height[edge.to];
-    } else {
-      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
-    }
-  });
-  return height;
-}
-utils.inherits(AbstractPouchDBVersion200, EventEmitter);
-module.exports = AbstractPouchDBVersion200;
-function AbstractPouchDBVersion200() {
-  var self = this;
-  EventEmitter.call(this);
-  self.autoCompact = function (callback) {
-    if (!self.auto_compaction) {
-      return callback;
-    }
-    return function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        var count = res.length;
-        var decCount = function () {
-          count--;
-          if (!count) {
-            callback(null, res);
-          }
-        };
-        res.forEach(function (doc) {
-          if (doc.ok) {
-            // TODO: we need better error handling
-            self.compactDocument(doc.id, 1, decCount);
-          } else {
-            decCount();
-          }
-        });
-      }
-    };
-  };
-  var listeners = 0, changes;
-  var eventNames = ['change', 'delete', 'create', 'update'];
-  this.on('newListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      if (listeners) {
-        listeners++;
-        return;
-      } else {
-        listeners++;
-      }
-    } else {
-      return;
-    }
-    var lastChange = 0;
-    changes = this.changes({
-      conflicts: true,
-      include_docs: true,
-      continuous: true,
-      since: 'latest',
-      onChange: function (change) {
-        if (change.seq <= lastChange) {
-          return;
-        }
-        lastChange = change.seq;
-        self.emit('change', change);
-        if (change.doc._deleted) {
-          self.emit('delete', change);
-        } else if (change.doc._rev.split('-')[0] === '1') {
-          self.emit('create', change);
-        } else {
-          self.emit('update', change);
-        }
-      }
-    });
-  });
-  this.on('removeListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      listeners--;
-      if (listeners) {
-        return;
-      }
-    } else {
-      return;
-    }
-    changes.cancel();
-  });
-}
-AbstractPouchDBVersion200.prototype.post = utils.toPromise(function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  return this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-});
-
-AbstractPouchDBVersion200.prototype.put = utils.toPromise(function () {
-  var args = Array.prototype.slice.call(arguments);
-  var temp, temptype, doc, id, opts, callback;
-  doc = args.shift();
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    callback = args.pop();
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  doc = utils.extend(true, {}, doc);
-  while (true) {
-    temp = args.shift();
-    temptype = typeof temp;
-    if (temptype === "string" && !id) {
-      doc._id = temp;
-      id = true;
-    } else if (temptype === "string" && id) {
-      doc._rev = temp;
-    } else if (temptype === "object") {
-      opts = temp;
-    } else if (temptype === "function") {
-      callback = temp;
-    }
-    if (!args.length) {
-      break;
-    }
-  }
-  opts = opts || {};
-  var error = utils.invalidIdError(doc._id);
-  if (error) {
-    return callback(error);
-  }
-  return this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-});
-
-AbstractPouchDBVersion200.prototype.putAttachment = utils.toPromise(function (docId, attachmentId, rev, blob, type, callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('putAttachment', arguments);
-    return;
-  }
-  var api = this;
-  if (typeof type === 'function') {
-    callback = type;
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-  if (typeof type === 'undefined') {
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-
-  function createAttachment(doc) {
-    doc._attachments = doc._attachments || {};
-    doc._attachments[attachmentId] = {
-      content_type: type,
-      data: blob
-    };
-    api.put(doc, callback);
-  }
-
-  api.get(docId, function (err, doc) {
-    // create new doc
-    if (err && err.error === errors.MISSING_DOC.error) {
-      createAttachment({_id: docId});
-      return;
-    }
-    if (err) {
-      callback(err);
-      return;
-    }
-
-    if (doc._rev !== rev) {
-      callback(errors.REV_CONFLICT);
-      return;
-    }
-
-    createAttachment(doc);
-  });
-});
-
-AbstractPouchDBVersion200.prototype.removeAttachment = utils.toPromise(function (docId, attachmentId, rev, callback) {
-  var self = this;
-  self.get(docId, function (err, obj) {
-    if (err) {
-      callback(err);
-      return;
-    }
-    if (obj._rev !== rev) {
-      callback(errors.REV_CONFLICT);
-      return;
-    }
-    if (!obj._attachments) {
-      return callback();
-    }
-    delete obj._attachments[attachmentId];
-    if (Object.keys(obj._attachments).length === 0) {
-      delete obj._attachments;
-    }
-    self.put(obj, callback);
-  });
-});
-
-AbstractPouchDBVersion200.prototype.remove = utils.toPromise(function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (opts === undefined) {
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-  opts.was_delete = true;
-  var newDoc = {_id: doc._id, _rev: doc._rev};
-  newDoc._deleted = true;
-  return this.bulkDocs({docs: [newDoc]}, opts, yankError(callback));
-});
-
-AbstractPouchDBVersion200.prototype.revsDiff = utils.toPromise(function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-  var ids = Object.keys(req);
-  var count = 0;
-  var missing = {};
-
-  function addToMissing(id, revId) {
-    if (!missing[id]) {
-      missing[id] = {missing: []};
-    }
-    missing[id].missing.push(revId);
-  }
-
-  function processDoc(id, rev_tree) {
-    // Is this fast enough? Maybe we should switch to a set simulated by a map
-    var missingForId = req[id].slice(0);
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
-      opts) {
-        var rev = pos + '-' + revHash;
-        var idx = missingForId.indexOf(rev);
-        if (idx === -1) {
-          return;
-        }
-
-        missingForId.splice(idx, 1);
-        if (opts.status !== 'available') {
-          addToMissing(id, rev);
-        }
-      });
-
-    // Traversing the tree is synchronous, so now `missingForId` contains
-    // revisions that were not found in the tree
-    missingForId.forEach(function (rev) {
-      addToMissing(id, rev);
-    });
-  }
-
-  ids.map(function (id) {
-    this._getRevisionTree(id, function (err, rev_tree) {
-      if (err && err.name === 'not_found' && err.message === 'missing') {
-        missing[id] = {missing: req[id]};
-      } else if (err) {
-        return callback(err);
-      } else {
-        processDoc(id, rev_tree);
-      }
-
-      if (++count === ids.length) {
-        return callback(null, missing);
-      }
-    });
-  }, this);
-});
-
-// compact one document and fire callback
-// by compacting we mean removing all revisions which
-// are further from the leaf in revision tree than max_height
-AbstractPouchDBVersion200.prototype.compactDocument = function (docId, max_height, callback) {
-  var self = this;
-  this._getRevisionTree(docId, function (err, rev_tree) {
-    if (err) {
-      return callback(err);
-    }
-    var height = computeHeight(rev_tree);
-    var candidates = [];
-    var revs = [];
-    Object.keys(height).forEach(function (rev) {
-      if (height[rev] > max_height) {
-        candidates.push(rev);
-      }
-    });
-
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, opts) {
-      var rev = pos + '-' + revHash;
-      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
-        opts.status = 'missing';
-        revs.push(rev);
-      }
-    });
-    self._doCompaction(docId, rev_tree, revs, callback);
-  });
-};
-
-// compact the whole database using single document
-// compaction
-AbstractPouchDBVersion200.prototype.compact = utils.toPromise(function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  var self = this;
-  this.changes({complete: function (err, res) {
-    if (err) {
-      callback(); // TODO: silently fail
-      return;
-    }
-    var count = res.results.length;
-    if (!count) {
-      callback();
-      return;
-    }
-    res.results.forEach(function (row) {
-      self.compactDocument(row.id, 0, function () {
-        count--;
-        if (!count) {
-          callback();
-        }
-      });
-    });
-  }});
-});
-
-/* Begin api wrappers. Specific functionality to storage belongs in the _[method] */
-AbstractPouchDBVersion200.prototype.get = utils.toPromise(function (id, opts, callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('get', arguments);
-    return;
-  }
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof id !== 'string') {
-    return callback(errors.INVALID_ID);
-  }
-  var leaves = [], self = this;
-  function finishOpenRevs() {
-    var result = [];
-    var count = leaves.length;
-    if (!count) {
-      return callback(null, result);
-    }
-    // order with open_revs is unspecified
-    leaves.forEach(function (leaf) {
-      self.get(id, {rev: leaf, revs: opts.revs, attachments: opts.attachments}, function (err, doc) {
-        if (!err) {
-          result.push({ok: doc});
-        } else {
-          result.push({missing: leaf});
-        }
-        count--;
-        if (!count) {
-          callback(null, result);
-        }
-      });
-    });
-  }
-
-  if (opts.open_revs) {
-    if (opts.open_revs === "all") {
-      this._getRevisionTree(id, function (err, rev_tree) {
-        if (err) {
-          // if there's no such document we should treat this
-          // situation the same way as if revision tree was empty
-          rev_tree = [];
-        }
-        leaves = merge.collectLeaves(rev_tree).map(function (leaf) {
-          return leaf.rev;
-        });
-        finishOpenRevs();
-      });
-    } else {
-      if (Array.isArray(opts.open_revs)) {
-        leaves = opts.open_revs;
-        for (var i = 0; i < leaves.length; i++) {
-          var l = leaves[i];
-          // looks like it's the only thing couchdb checks
-          if (!(typeof(l) === "string" && /^\d+-/.test(l))) {
-            return callback(errors.error(errors.BAD_REQUEST,
-              "Invalid rev format"));
-          }
-        }
-        finishOpenRevs();
-      } else {
-        return callback(errors.error(errors.UNKNOWN_ERROR,
-          'function_clause'));
-      }
-    }
-    return; // open_revs does not like other options
-  }
-
-  return this._get(id, opts, function (err, result) {
-    opts = utils.extend(true, {}, opts);
-    if (err) {
-      return callback(err);
-    }
-
-    var doc = result.doc;
-    var metadata = result.metadata;
-    var ctx = result.ctx;
-
-    if (opts.conflicts) {
-      var conflicts = merge.collectConflicts(metadata);
-      if (conflicts.length) {
-        doc._conflicts = conflicts;
-      }
-    }
-
-    if (opts.revs || opts.revs_info) {
-      var paths = merge.rootToLeaf(metadata.rev_tree);
-      var path = arrayFirst(paths, function (arr) {
-        return arr.ids.map(function (x) { return x.id; })
-          .indexOf(doc._rev.split('-')[1]) !== -1;
-      });
-
-      path.ids.splice(path.ids.map(function (x) {return x.id; })
-                      .indexOf(doc._rev.split('-')[1]) + 1);
-      path.ids.reverse();
-
-      if (opts.revs) {
-        doc._revisions = {
-          start: (path.pos + path.ids.length) - 1,
-          ids: path.ids.map(function (rev) {
-            return rev.id;
-          })
-        };
-      }
-      if (opts.revs_info) {
-        var pos =  path.pos + path.ids.length;
-        doc._revs_info = path.ids.map(function (rev) {
-          pos--;
-          return {
-            rev: pos + '-' + rev.id,
-            status: rev.opts.status
-          };
-        });
-      }
-    }
-
-    if (opts.local_seq) {
-      doc._local_seq = result.metadata.seq;
-    }
-
-    if (opts.attachments && doc._attachments) {
-      var attachments = doc._attachments;
-      var count = Object.keys(attachments).length;
-      if (count === 0) {
-        return callback(null, doc);
-      }
-      Object.keys(attachments).forEach(function (key) {
-        this._getAttachment(attachments[key], {encode: true, ctx: ctx}, function (err, data) {
-          doc._attachments[key].data = data;
-          if (!--count) {
-            callback(null, doc);
-          }
-        });
-      }, self);
-    } else {
-      if (doc._attachments) {
-        for (var key in doc._attachments) {
-          if (doc._attachments.hasOwnProperty(key)) {
-            doc._attachments[key].stub = true;
-          }
-        }
-      }
-      callback(null, doc);
-    }
-  });
-});
-
-AbstractPouchDBVersion200.prototype.getAttachment = utils.toPromise(function (docId, attachmentId, opts, callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('getAttachment', arguments);
-    return;
-  }
-  var self = this;
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-  this._get(docId, opts, function (err, res) {
-    if (err) {
-      return callback(err);
-    }
-    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
-      opts.ctx = res.ctx;
-      self._getAttachment(res.doc._attachments[attachmentId], opts, callback);
-    } else {
-      return callback(errors.MISSING_DOC);
-    }
-  });
-});
-
-AbstractPouchDBVersion200.prototype.allDocs = utils.toPromise(function (opts, callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('allDocs', arguments);
-    return;
-  }
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-  if ('keys' in opts) {
-    var incompatibleOpt = ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
-      return incompatibleOpt in opts;
-    })[0];
-    if (incompatibleOpt) {
-      callback(errors.error(errors.QUERY_PARSE_ERROR,
-        'Query parameter `' + incompatibleOpt + '` is not compatible with multi-get'
-      ));
-      return;
-    }
-  }
-  if (typeof opts.skip === 'undefined') {
-    opts.skip = 0;
-  }
-
-  return this._allDocs(opts, callback);
-});
-
-function processChange(doc, metadata, opts) {
-  var changeList = [{rev: doc._rev}];
-  if (opts.style === 'all_docs') {
-    changeList = merge.collectLeaves(metadata.rev_tree)
-    .map(function (x) { return {rev: x.rev}; });
-  }
-  var change = {
-    id: metadata.id,
-    changes: changeList,
-    doc: doc
-  };
-
-  if (utils.isDeleted(metadata, doc._rev)) {
-    change.deleted = true;
-  }
-  if (opts.conflicts) {
-    change.doc._conflicts = merge.collectConflicts(metadata);
-    if (!change.doc._conflicts.length) {
-      delete change.doc._conflicts;
-    }
-  }
-  return change;
-}
-AbstractPouchDBVersion200.prototype.changes = function (opts) {
-  if (!this.taskqueue.isReady) {
-    var task = this.taskqueue.addTask('changes', arguments);
-    return {
-      cancel: function () {
-        if (task.task) {
-          return task.task.cancel();
-        }
-        task.parameters[0].aborted = true;
-      }
-    };
-  }
-  var api = this;
-  opts = utils.extend(true, {}, opts);
-  opts.processChange = processChange;
-
-  if (!opts.since) {
-    opts.since = 0;
-  }
-  if (opts.since === 'latest') {
-    var changes;
-    api.info(function (err, info) {
-      if (!opts.aborted) {
-        opts.since = info.update_seq  - 1;
-        changes = api.changes(opts);
-      }
-    });
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        if (changes) {
-          return changes.cancel();
-        }
-        opts.aborted = true;
-      }
-    };
-  }
-
-  if (opts.filter && typeof opts.filter === 'string') {
-    if (opts.filter === '_view') {
-      if (opts.view && typeof opts.view === 'string') {
-        // fetch a view from a design doc, make it behave like a filter
-        var viewName = opts.view.split('/');
-        api.get('_design/' + viewName[0], function (err, ddoc) {
-          if (ddoc && ddoc.views && ddoc.views[viewName[1]]) {
-            /*jshint evil: true */
-            var filter = eval('(function () {' +
-                              '  return function (doc) {' +
-                              '    var emitted = false;' +
-                              '    var emit = function (a, b) {' +
-                              '      emitted = true;' +
-                              '    };' +
-                              '    var view = ' + ddoc.views[viewName[1]].map + ';' +
-                              '    view(doc);' +
-                              '    if (emitted) {' +
-                              '      return true;' +
-                              '    }' +
-                              '  }' +
-                              '})()');
-            if (!opts.aborted) {
-              opts.filter = filter;
-              api.changes(opts);
-            }
-          } else {
-            var msg = ddoc.views ? 'missing json key: ' + viewName[1] :
-              'missing json key: views';
-            err = err || errors.error(errors.MISSING_DOC, msg);
-            opts.complete(err);
-          }
-        });
-      } else {
-        var err = errors.error(errors.BAD_REQUEST,
-                              '`view` filter parameter is not provided.');
-        opts.complete(err);
-      }
-    } else {
-      // fetch a filter from a design doc
-      var filterName = opts.filter.split('/');
-      api.get('_design/' + filterName[0], function (err, ddoc) {
-        if (ddoc && ddoc.filters && ddoc.filters[filterName[1]]) {
-          /*jshint evil: true */
-          var filter = eval('(function () { return ' +
-                            ddoc.filters[filterName[1]] + ' })()');
-          if (!opts.aborted) {
-            opts.filter = filter;
-            api.changes(opts);
-          }
-        } else {
-          var msg = (ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
-            : 'missing json key: filters';
-          err = err || errors.error(errors.MISSING_DOC, msg);
-          opts.complete(err);
-        }
-      });
-    }
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        opts.complete(null, {status: 'cancelled'});
-        opts.complete = null;
-        opts.aborted = true;
-      }
-    };
-  }
-
-  if (!('descending' in opts)) {
-    opts.descending = false;
-  }
-
-  // 0 and 1 should return 1 document
-  opts.limit = opts.limit === 0 ? 1 : opts.limit;
-  return this._changes(opts);
-};
-
-AbstractPouchDBVersion200.prototype.close = utils.toPromise(function (callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('close', arguments);
-    return;
-  }
-  return this._close(callback);
-});
-
-AbstractPouchDBVersion200.prototype.info = utils.toPromise(function (callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('info', arguments);
-    return;
-  }
-  var self = this;
-  this._info(function (err, info) {
-    if (err) {
-      return callback(err);
-    }
-    var len = self.prefix.length;
-    if (info.db_name.length > len && info.db_name.slice(0, len) === self.prefix) {
-      info.db_name = info.db_name.slice(len);
-    }
-    callback(null, info);
-  });
-});
-
-AbstractPouchDBVersion200.prototype.id = utils.toPromise(function (callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('id', arguments);
-    return;
-  }
-  return this._id(callback);
-});
-
-AbstractPouchDBVersion200.prototype.type = function () {
-  return (typeof this._type === 'function') ? this._type() : this.adapter;
-};
-
-AbstractPouchDBVersion200.prototype.bulkDocs = utils.toPromise(function (req, opts, callback) {
-  if (!this.taskqueue.isReady) {
-    this.taskqueue.addTask('bulkDocs', arguments);
-    return;
-  }
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (!opts) {
-    opts = {};
-  } else {
-    opts = utils.extend(true, {}, opts);
-  }
-
-  if (!req || !req.docs) {
-    return callback(errors.MISSING_BULK_DOCS);
-  }
-
-  if (!Array.isArray(req.docs)) {
-    return callback(errors.QUERY_PARSE_ERROR);
-  }
-
-  for (var i = 0; i < req.docs.length; ++i) {
-    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-  }
-
-  req = utils.extend(true, {}, req);
-  if (!('new_edits' in opts)) {
-    if ('new_edits' in req) {
-      opts.new_edits = req.new_edits;
-    } else {
-      opts.new_edits = true;
-    }
-  }
-
-  return this._bulkDocs(req, opts, this.autoCompact(callback));
-});
-
-},{"./deps/errors":8,"./merge":14,"./utils":18,"events":21}],2:[function(_dereq_,module,exports){
-"use strict";
-
-var utils = _dereq_('../utils');
-var errors = _dereq_('../deps/errors');
-// parseUri 1.2.2
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-function parseUri(str) {
-  var o = parseUri.options;
-  var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
-  var uri = {};
-  var i = 14;
-
-  while (i--) {
-    uri[o.key[i]] = m[i] || "";
-  }
-
-  uri[o.q.name] = {};
-  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
-    if ($1) {
-      uri[o.q.name][$1] = $2;
-    }
-  });
-
-  return uri;
-}
-
-function encodeDocId(id) {
-  if (/^_(design|local)/.test(id)) {
-    return id;
-  }
-  return encodeURIComponent(id);
-}
-
-parseUri.options = {
-  strictMode: false,
-  key: ["source", "protocol", "authority", "userInfo", "user", "password", "host",
-        "port", "relative", "path", "directory", "file", "query", "anchor"],
-  q:   {
-    name:   "queryKey",
-    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
-  },
-  parser: {
-    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
-    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
-  }
-};
-
-// Get all the information you possibly can about the URI given by name and
-// return it as a suitable object.
-function getHost(name, opts) {
-  // If the given name contains "http:"
-  if (/http(s?):/.test(name)) {
-    // Prase the URI into all its little bits
-    var uri = parseUri(name);
-
-    // Store the fact that it is a remote URI
-    uri.remote = true;
-
-    // Store the user and password as a separate auth object
-    if (uri.user || uri.password) {
-      uri.auth = {username: uri.user, password: uri.password};
-    }
-
-    // Split the path part of the URI into parts using '/' as the delimiter
-    // after removing any leading '/' and any trailing '/'
-    var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
-
-    // Store the first part as the database name and remove it from the parts
-    // array
-    uri.db = parts.pop();
-
-    // Restore the path by joining all the remaining parts (all the parts
-    // except for the database name) with '/'s
-    uri.path = parts.join('/');
-    opts = opts || {};
-    opts = utils.extend(true, {}, opts);
-    uri.headers = opts.headers || {};
-
-    if (opts.auth || uri.auth) {
-      var nAuth = opts.auth || uri.auth;
-      var token = utils.btoa(nAuth.username + ':' + nAuth.password);
-      uri.headers.Authorization = 'Basic ' + token;
-    }
-
-    if (opts.headers) {
-      uri.headers = opts.headers;
-    }
-
-    return uri;
-  }
-
-  // If the given name does not contain 'http:' then return a very basic object
-  // with no host, the current path, the given name as the database name and no
-  // username/password
-  return {host: '', path: '/', db: name, auth: false};
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genDBUrl(opts, path) {
-  // If the host is remote
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // Return the URL made up of all the host's information and the given path
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' +
-      opts.path + pathDel + opts.db + '/' + path;
-  }
-
-  // If the host is not remote, then return the URL made up of just the
-  // database name and the given path
-  return '/' + opts.db + '/' + path;
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genUrl(opts, path) {
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' + opts.path + pathDel + path;
-  }
-
-  return '/' + path;
-}
-// Implements the PouchDBVersion200 API for dealing with CouchDB instances over HTTP
-function HttpPouch(opts, callback) {
-  // Parse the URI given by opts.name into an easy-to-use object
-  var host = getHost(opts.name, opts);
-
-  // Generate the database URL based on the host
-  var db_url = genDBUrl(host, '');
-
-  // The functions that will be publically available for HttpPouch
-  var api = this;
-  var ajaxOpts = opts.ajax || {};
-  opts = utils.extend(true, {}, opts);
-  function ajax(options, callback) {
-    return utils.ajax(utils.extend({}, ajaxOpts, options), callback);
-  }
-  var uuids = {
-    list: [],
-    get: function (opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {count: 10};
-      }
-      var cb = function (err, body) {
-        if (err || !('uuids' in body)) {
-          callback(err || errors.UNKNOWN_ERROR);
-        } else {
-          uuids.list = uuids.list.concat(body.uuids);
-          callback(null, "OK");
-        }
-      };
-      var params = '?count=' + opts.count;
-      ajax({
-        headers: host.headers,
-        method: 'GET',
-        url: genUrl(host, '_uuids') + params
-      }, cb);
-    }
-  };
-
-  // Create a new CouchDB database based on the given opts
-  var createDB = function () {
-    ajax({headers: host.headers, method: 'PUT', url: db_url}, function (err, ret) {
-      // If we get an "Unauthorized" error
-      if (err && err.status === 401) {
-        // Test if the database already exists
-        ajax({headers: host.headers, method: 'HEAD', url: db_url}, function (err, ret) {
-          // If there is still an error
-          if (err) {
-            // Give the error to the callback to deal with
-            callback(err);
-          } else {
-            // Continue as if there had been no errors
-            callback(null, api);
-          }
-        });
-        // If there were no errros or if the only error is "Precondition Failed"
-        // (note: "Precondition Failed" occurs when we try to create a database
-        // that already exists)
-      } else if (!err || err.status === 412) {
-        // Continue as if there had been no errors
-        callback(null, api);
-      } else {
-        callback(err);
-      }
-    });
-  };
-  if (!opts.skipSetup) {
-    ajax({headers: host.headers, method: 'GET', url: db_url}, function (err, ret) {
-      //check if the db exists
-      if (err) {
-        if (err.status === 404) {
-          //if it doesn't, create it
-          createDB();
-        } else {
-          callback(err);
-        }
-      } else {
-        //go do stuff with the db
-        callback(null, api);
-      }
-    });
-  }
-
-  api.type = function () {
-    return 'http';
-  };
-
-  api.id = utils.toPromise(function (callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('id', arguments);
-      return;
-    }
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genUrl(host, '')
-    }, function (err, result) {
-      callback(null, result.uuid + host.db);
-    });
-  });
-
-  api.request = utils.toPromise(function (options, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('request', arguments);
-      return;
-    }
-    options.headers = host.headers;
-    options.url = genDBUrl(host, options.url);
-    ajax(options, callback);
-  });
-
-  // Sends a POST request to the host calling the couchdb _compact function
-  //    version: The version of CouchDB it is running
-  api.compact = utils.toPromise(function (opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('compact', arguments);
-      return;
-    }
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.extend(true, {}, opts);
-    ajax({
-      headers: host.headers,
-      url: genDBUrl(host, '_compact'),
-      method: 'POST'
-    }, function () {
-      function ping() {
-        api.info(function (err, res) {
-          if (!res.compact_running) {
-            callback();
-          } else {
-            setTimeout(ping, opts.interval || 200);
-          }
-        });
-      }
-      // Ping the http if it's finished compaction
-      if (typeof callback === "function") {
-        ping();
-      }
-    });
-  });
-
-  // Calls GET on the host, which gets back a JSON string containing
-  //    couchdb: A welcome string
-  //    version: The version of CouchDB it is running
-  api._info = utils.toPromise(function (callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('info', arguments);
-      return;
-    }
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, '')
-    }, function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        res.host = genDBUrl(host, '');
-        callback(null, res);
-      }
-    });
-  });
-
-  // Get the document with the given id from the database given by host.
-  // The id could be solely the _id in the database, or it may be a
-  // _design/ID or _local/ID path
-  api.get = utils.toPromise(function (id, opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('get', arguments);
-      return;
-    }
-    // If no options were given, set the callback to the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.extend(true, {}, opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-
-    // List of parameters to add to the GET request
-    var params = [];
-
-    // If it exists, add the opts.revs value to the list of parameters.
-    // If revs=true then the resulting JSON will include a field
-    // _revisions containing an array of the revision IDs.
-    if (opts.revs) {
-      params.push('revs=true');
-    }
-
-    // If it exists, add the opts.revs_info value to the list of parameters.
-    // If revs_info=true then the resulting JSON will include the field
-    // _revs_info containing an array of objects in which each object
-    // representing an available revision.
-    if (opts.revs_info) {
-      params.push('revs_info=true');
-    }
-
-    if (opts.local_seq) {
-      params.push('local_seq=true');
-    }
-    // If it exists, add the opts.open_revs value to the list of parameters.
-    // If open_revs=all then the resulting JSON will include all the leaf
-    // revisions. If open_revs=["rev1", "rev2",...] then the resulting JSON
-    // will contain an array of objects containing data of all revisions
-    if (opts.open_revs) {
-      if (opts.open_revs !== "all") {
-        opts.open_revs = JSON.stringify(opts.open_revs);
-      }
-      params.push('open_revs=' + opts.open_revs);
-    }
-
-    // If it exists, add the opts.attachments value to the list of parameters.
-    // If attachments=true the resulting JSON will include the base64-encoded
-    // contents in the "data" property of each attachment.
-    if (opts.attachments) {
-      params.push('attachments=true');
-    }
-
-    // If it exists, add the opts.rev value to the list of parameters.
-    // If rev is given a revision number then get the specified revision.
-    if (opts.rev) {
-      params.push('rev=' + opts.rev);
-    }
-
-    // If it exists, add the opts.conflicts value to the list of parameters.
-    // If conflicts=true then the resulting JSON will include the field
-    // _conflicts containing all the conflicting revisions.
-    if (opts.conflicts) {
-      params.push('conflicts=' + opts.conflicts);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
-
-    if (opts.auto_encode) {
-      id = encodeDocId(id);
-    }
-
-    // Set the options for the ajax call
-    var options = {
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, id + params)
-    };
-
-    // If the given id contains at least one '/' and the part before the '/'
-    // is NOT "_design" and is NOT "_local"
-    // OR
-    // If the given id contains at least two '/' and the part before the first
-    // '/' is "_design".
-    // TODO This second condition seems strange since if parts[0] === '_design'
-    // then we already know that parts[0] !== '_local'.
-    var parts = id.split('/');
-    if ((parts.length > 1 && parts[0] !== '_design' && parts[0] !== '_local') ||
-        (parts.length > 2 && parts[0] === '_design' && parts[0] !== '_local')) {
-      // Binary is expected back from the server
-      options.binary = true;
-    }
-
-    // Get the document
-    ajax(options, function (err, doc, xhr) {
-      // If the document does not exist, send an error to the callback
-      if (err) {
-        return callback(err);
-      }
-
-      // Send the document to the callback
-      callback(null, doc, xhr);
-    });
-  });
-
-  // Delete the document given by doc from the database given by host.
-  api.remove = utils.toPromise(function (doc, opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('remove', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Delete the document
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + doc._rev
-    }, callback);
-  });
-
-  // Get the attachment
-  api.getAttachment = utils.toPromise(function (docId, attachmentId, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.extend(true, {}, opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-    if (opts.auto_encode) {
-      docId = encodeDocId(docId);
-    }
-    opts.auto_encode = false;
-    api.get(docId + '/' + attachmentId, opts, callback);
-  });
-
-  // Remove the attachment given by the id and rev
-  api.removeAttachment = utils.toPromise(function (docId, attachmentId, rev, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('removeAttachment', arguments);
-      return;
-    }
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(docId) + '/' + attachmentId) + '?rev=' + rev
-    }, callback);
-  });
-
-  // Add the attachment given by blob and its contentType property
-  // to the document with the given id, the revision given by rev, and
-  // add it to the database given by host.
-  api.putAttachment = utils.toPromise(function (docId, attachmentId, rev, blob, type, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('putAttachment', arguments);
-      return;
-    }
-    if (typeof type === 'function') {
-      callback = type;
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    if (typeof type === 'undefined') {
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    var id = encodeDocId(docId) + '/' + attachmentId;
-    var url = genDBUrl(host, id);
-    if (rev) {
-      url += '?rev=' + rev;
-    }
-
-    var opts = {
-      headers: host.headers,
-      method: 'PUT',
-      url: url,
-      processData: false,
-      body: blob,
-      timeout: 60000
-    };
-    opts.headers['Content-Type'] = type;
-    // Add the attachment
-    ajax(opts, callback);
-  });
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This fails if the doc has no _id field.
-  api.put = utils.toPromise(function () {
-    var args = Array.prototype.slice.call(arguments);
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('put', args);
-      return;
-    }
-    var temp, temptype, doc, id, opts, callback;
-    doc = args.shift();
-    if (typeof doc !== 'object' || Array.isArray(doc)) {
-      callback = args.pop();
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    doc = utils.extend(true, {}, doc);
-    while (true) {
-      temp = args.shift();
-      temptype = typeof temp;
-      if (temptype === "string" && !id) {
-        doc._id = temp;
-        id = true;
-      } else if (temptype === "string" && id) {
-        doc._rev = temp;
-      } else if (temptype === "object") {
-        opts = utils.extend(true, {}, temp);
-      } else if (temptype === "function") {
-        callback = temp;
-      }
-      if (!args.length) {
-        break;
-      }
-    }
-    opts = opts || {};
-    var error = utils.invalidIdError(doc._id);
-    if (error) {
-      return callback(error);
-    }
-
-    // List of parameter to add to the PUT request
-    var params = [];
-
-    // If it exists, add the opts.new_edits value to the list of parameters.
-    // If new_edits = false then the database will NOT assign this document a
-    // new revision number
-    if (opts && typeof opts.new_edits !== 'undefined') {
-      params.push('new_edits=' + opts.new_edits);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    // Add the document
-    ajax({
-      headers: host.headers,
-      method: 'PUT',
-      url: genDBUrl(host, encodeDocId(doc._id)) + params,
-      body: doc
-    }, callback);
-  });
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This does not assume that doc is a new document (i.e. does not
-  // have a _id or a _rev field.
-  api.post = utils.toPromise(function (doc, opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('post', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.extend(true, {}, opts);
-    if (typeof doc !== 'object') {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    if (! ("_id" in doc)) {
-      if (uuids.list.length > 0) {
-        doc._id = uuids.list.pop();
-        api.put(doc, opts, callback);
-      } else {
-        uuids.get(function (err, resp) {
-          if (err) {
-            return callback(errors.UNKNOWN_ERROR);
-          }
-          doc._id = uuids.list.pop();
-          api.put(doc, opts, callback);
-        });
-      }
-    } else {
-      api.put(doc, opts, callback);
-    }
-  });
-
-  // Update/create multiple documents given by req in the database
-  // given by host.
-  api.bulkDocs = utils.toPromise(function (req, opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('bulkDocs', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    if (!opts) {
-      opts = {};
-    }
-    if (!Array.isArray(req.docs)) {
-      return callback(errors.error(errors.NOT_AN_OBJECT, "Missing JSON list of 'docs'"));
-    }
-    var bad = req.docs.filter(function (doc) {
-      return typeof doc !== 'object' || Array.isArray(doc);
-    });
-    if (bad.length) {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    req = utils.extend(true, {}, req);
-    opts = utils.extend(true, {}, opts);
-    // If opts.new_edits exists add it to the document data to be
-    // send to the database.
-    // If new_edits=false then it prevents the database from creating
-    // new revision numbers for the documents. Instead it just uses
-    // the old ones. This is used in database replication.
-    if (typeof opts.new_edits !== 'undefined') {
-      req.new_edits = opts.new_edits;
-    }
-
-    // Update/create the documents
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_bulk_docs'),
-      body: req
-    }, callback);
-  });
-
-  // Get a listing of the documents in the database given
-  // by host and ordered by increasing id.
-  api.allDocs = utils.toPromise(function (opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('allDocs', arguments);
-      return;
-    }
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.extend(true, {}, opts);
-    // List of parameters to add to the GET request
-    var params = [];
-    var body;
-    var method = 'GET';
-
-    // TODO I don't see conflicts as a valid parameter for a
-    // _all_docs request (see http://wiki.apache.org/couchdb/HTTP_Document_API#all_docs)
-    if (opts.conflicts) {
-      params.push('conflicts=true');
-    }
-
-    // If opts.descending is truthy add it to params
-    if (opts.descending) {
-      params.push('descending=true');
-    }
-
-    // If opts.include_docs exists, add the include_docs value to the
-    // list of parameters.
-    // If include_docs=true then include the associated document with each
-    // result.
-    if (opts.include_docs) {
-      params.push('include_docs=true');
-    }
-
-    if (opts.key) {
-      params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
-    }
-
-    // If opts.startkey exists, add the startkey value to the list of
-    // parameters.
-    // If startkey is given then the returned list of documents will
-    // start with the document whose id is startkey.
-    if (opts.startkey) {
-      params.push('startkey=' +
-        encodeURIComponent(JSON.stringify(opts.startkey)));
-    }
-
-    // If opts.endkey exists, add the endkey value to the list of parameters.
-    // If endkey is given then the returned list of docuemnts will
-    // end with the document whose id is endkey.
-    if (opts.endkey) {
-      params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
-    }
-
-    // If opts.limit exists, add the limit value to the parameter list.
-    if (opts.limit) {
-      params.push('limit=' + opts.limit);
-    }
-
-    if (typeof opts.skip !== 'undefined') {
-      params.push('skip=' + opts.skip);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    if (typeof opts.keys !== 'undefined') {
-
-      var MAX_URL_LENGTH = 2000;
-      // according to http://stackoverflow.com/a/417184/680742,
-      // the de factor URL length limit is 2000 characters
-
-      var keysAsString = 'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-        // If the keys are short enough, do a GET. we do this to work around
-        // Safari not understanding 304s on POSTs (see issue #1239)
-        params += (params.indexOf('?') !== -1 ? '&' : '?') + keysAsString;
-      } else {
-        // If keys are too long, issue a POST request to circumvent GET query string limits
-        // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-        method = 'POST';
-        body = JSON.stringify({keys: opts.keys});
-      }
-    }
-
-    // Get the document listing
-    ajax({
-      headers: host.headers,
-      method: method,
-      url: genDBUrl(host, '_all_docs' + params),
-      body: body
-    }, callback);
-  });
-
-  // Get a list of changes made to documents in the database given by host.
-  // TODO According to the README, there should be two other methods here,
-  // api.changes.addListener and api.changes.removeListener.
-  api.changes = function (opts) {
-    // We internally page the results of a changes request, this means
-    // if there is a large set of changes to be returned we can start
-    // processing them quicker instead of waiting on the entire
-    // set of changes to return and attempting to process them at once
-    var CHANGES_LIMIT = 25;
-
-    if (!api.taskqueue.isReady) {
-      var task = api.taskqueue.addTask('changes', arguments);
-      return {
-        cancel: function () {
-          if (task.task) {
-            return task.task.cancel();
-          } else {
-            utils.call(opts.complete, null, {status: 'cancelled'});
-            opts.complete = null;
-          }
-          task.parameters[0].aborted = true;
-        }
-      };
-    }
-
-    opts = utils.extend(true, {}, opts);
-    opts.timeout = opts.timeout || 0;
-    if (opts.since === 'latest') {
-      var changes = api.changes({
-        descending: true,
-        limit: 1,
-        timeout: opts.timeout,
-        complete: function (err, info) {
-          if (err) {
-            opts.aborted = true;
-            utils.call(opts.complete, err);
-            return;
-          }
-          if (!opts.aborted) {
-            opts.since = info.last_seq;
-            changes = api.changes(opts);
-          }
-        }
-      });
-      // Return a method to cancel this method from processing any more
-      return {
-        cancel: function () {
-          utils.call(opts.complete, null, {status: 'cancelled'});
-          opts.complete = null;
-          if (changes) {
-            return changes.cancel();
-          }
-          opts.aborted = true;
-        }
-      };
-    }
-
-    var params = {};
-    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
-    if (limit === 0) {
-      limit = 1;
-    }
-    //
-    var leftToFetch = limit;
-
-    if (opts.style) {
-      params.style = opts.style;
-    }
-
-    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
-      params.include_docs = true;
-    }
-
-    if (opts.continuous) {
-      params.feed = 'longpoll';
-    }
-
-    if (opts.conflicts) {
-      params.conflicts = true;
-    }
-
-    if (opts.descending) {
-      params.descending = true;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-      if (opts.filter === '_view' && opts.view && typeof opts.view === 'string') {
-        params.view = opts.view;
-      }
-    }
-
-    // If opts.query_params exists, pass it through to the changes request.
-    // These parameters may be used by the filter on the source database.
-    if (opts.query_params && typeof opts.query_params === 'object') {
-      for (var param_name in opts.query_params) {
-        if (opts.query_params.hasOwnProperty(param_name)) {
-          params[param_name] = opts.query_params[param_name];
-        }
-      }
-    }
-
-    var xhr;
-    var lastFetchedSeq;
-
-    // Get all the changes starting wtih the one immediately after the
-    // sequence number given by since.
-    var fetch = function (since, callback) {
-      params.since = since;
-      if (opts.descending) {
-        if (limit) {
-          params.limit = leftToFetch;
-        }
-      } else {
-        params.limit = (!limit || leftToFetch > CHANGES_LIMIT) ?
-          CHANGES_LIMIT : leftToFetch;
-      }
-
-      var paramStr = '?' + Object.keys(params).map(function (k) {
-        return k + '=' + params[k];
-      }).join('&');
-
-      // Set the options for the ajax call
-      var xhrOpts = {
-        headers: host.headers,
-        method: 'GET',
-        url: genDBUrl(host, '_changes' + paramStr),
-        // _changes can take a long time to generate, especially when filtered
-        timeout: opts.timeout
-      };
-      lastFetchedSeq = since;
-
-      if (opts.aborted) {
-        return;
-      }
-
-      // Get the changes
-      xhr = ajax(xhrOpts, callback);
-    };
-
-    // If opts.since exists, get all the changes from the sequence
-    // number given by opts.since. Otherwise, get all the changes
-    // from the sequence number 0.
-    var fetchTimeout = 10;
-    var fetchRetryCount = 0;
-
-    var results = {results: []};
-
-    var fetched = function (err, res) {
-      var raw_results_length = 0;
-      // If the result of the ajax call (res) contains changes (res.results)
-      if (res && res.results) {
-        raw_results_length = res.results.length;
-        results.last_seq = res.last_seq;
-        // For each change
-        var req = {};
-        req.query = opts.query_params;
-        res.results = res.results.filter(function (c) {
-          leftToFetch--;
-          var ret = utils.filterChange(opts)(c);
-          if (ret) {
-            results.results.push(c);
-            utils.call(opts.onChange, c);
-          }
-          return ret;
-        });
-      } else if (err) {
-        // In case of an error, stop listening for changes and call opts.complete
-        opts.aborted = true;
-        utils.call(opts.complete, err);
-        return;
-      }
-
-      // The changes feed may have timed out with no results
-      // if so reuse last update sequence
-      if (res && res.last_seq) {
-        lastFetchedSeq = res.last_seq;
-      }
-
-      var finished = (limit && leftToFetch <= 0) ||
-        (res && raw_results_length < CHANGES_LIMIT) ||
-        (opts.descending);
-
-      if (opts.continuous || !finished) {
-        // Increase retry delay exponentially as long as errors persist
-        if (err) {
-          fetchRetryCount += 1;
-        } else {
-          fetchRetryCount = 0;
-        }
-        var timeoutMultiplier = 1 << fetchRetryCount;
-        var retryWait = fetchTimeout * timeoutMultiplier;
-        var maximumWait = opts.maximumWait || 30000;
-
-        if (retryWait > maximumWait) {
-          utils.call(opts.complete, err || errors.UNKNOWN_ERROR);
-          return;
-        }
-
-        // Queue a call to fetch again with the newest sequence number
-        setTimeout(function () { fetch(lastFetchedSeq, fetched); }, retryWait);
-      } else {
-        // We're done, call the callback
-        utils.call(opts.complete, null, results);
-      }
-    };
-
-    fetch(opts.since || 0, fetched);
-
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        utils.call(opts.complete, null, {status: 'cancelled'});
-        opts.complete = null;
-        opts.aborted = true;
-        xhr.abort();
-      }
-    };
-  };
-
-  // Given a set of document/revision IDs (given by req), tets the subset of
-  // those that do NOT correspond to revisions stored in the database.
-  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
-  api.revsDiff = utils.toPromise(function (req, opts, callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('revsDiff', arguments);
-      return;
-    }
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Get the missing document/revision IDs
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_revs_diff'),
-      body: req
-    }, function (err, res) {
-      callback(err, res);
-    });
-  });
-
-  api.close = utils.toPromise(function (callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('close', arguments);
-      return;
-    }
-    callback();
-  });
-
-  function replicateOnServer(target, opts, promise, targetHostUrl) {
-    opts = utils.extend(true, {}, opts);
-    var targetHost = getHost(targetHostUrl);
-    var params = {
-      source: host.db,
-      target: targetHost.protocol === host.protocol &&
-        targetHost.authority === host.authority ? targetHost.db : targetHost.source
-    };
-
-    if (opts.continuous) {
-      params.continuous = true;
-    }
-
-    if (opts.create_target) {
-      params.create_target = true;
-    }
-
-    if (opts.doc_ids) {
-      params.doc_ids = opts.doc_ids;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-    }
-
-    if (opts.query_params) {
-      params.query_params = opts.query_params;
-    }
-
-    var result = {};
-    var repOpts = {
-      headers: host.headers,
-      method: 'POST',
-      url: host.protocol + '://' + host.host +
-        (host.port === 80 ? '' : (':' + host.port)) + '/_replicate',
-      body: params
-    };
-
-    var xhr;
-    promise.cancel = function () {
-      this.cancelled = true;
-      if (xhr && !result.ok) {
-        xhr.abort();
-      }
-      if (result._local_id) {
-        repOpts.body = {
-          replication_id: result._local_id
-        };
-      }
-      repOpts.body.cancel = true;
-      ajax(repOpts, function (err, resp, xhr) {
-        // If the replication cancel request fails, send an error to the callback
-        if (err) {
-          return callback(err);
-        }
-        // Send the replication cancel result to the complete callback
-        utils.call(opts.complete, null, result, xhr);
-      });
-    };
-
-    if (promise.cancelled) {
-      return;
-    }
-
-    xhr = ajax(repOpts, function (err, resp, xhr) {
-      // If the replication fails, send an error to the callback
-      if (err) {
-        return callback(err);
-      }
-
-      result.ok = true;
-
-      // Provided by CouchDB from 1.2.0 onward to cancel replication
-      if (resp._local_id) {
-        result._local_id = resp._local_id;
-      }
-
-      // Send the replication result to the complete callback
-      utils.call(opts.complete, null, resp, xhr);
-    });
-  }
-
-  api.replicateOnServer = function (target, opts, promise) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('replicateOnServer', arguments);
-      return promise;
-    }
-    target.info(function (err, info) {
-      replicateOnServer(target, opts, promise, info.host);
-    });
-  };
-  api.destroy = utils.toPromise(function (callback) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('destroy', arguments);
-      return;
-    }
-    utils.ajax({
-      url: genDBUrl(host, ''),
-      method: 'DELETE'
-    }, function (err, resp) {
-      if (err) {
-        api.emit('error', err);
-        callback(err);
-      } else {
-        api.emit('destroyed');
-        callback(null, resp);
-      }
-    });
-  });
-}
-
-// Delete the HttpPouch specified by the given name.
-HttpPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  var host = getHost(name, opts);
-  opts = opts || {};
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-  opts.headers = host.headers;
-  opts.method = 'DELETE';
-  opts.url = genDBUrl(host, '');
-  utils.ajax(opts, callback);
-});
-
-// HttpPouch is a valid adapter.
-HttpPouch.valid = function () {
-  return true;
-};
-
-module.exports = HttpPouch;
-
-},{"../deps/errors":8,"../utils":18}],3:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-
-function idbError(callback) {
-  return function (event) {
-    callback(errors.error(errors.IDB_ERROR, event.target, event.type));
-  };
-}
-
-function isModernIdb() {
-  // check for outdated implementations of IDB
-  // that rely on the setVersion method instead of onupgradeneeded (issue #1207)
-
-  // cache based on appVersion, in case the browser is updated
-  var cacheKey = "_pouch__checkModernIdb_" +
-    (global.navigator && global.navigator.appVersion);
-  var cached = global.localStorage && global.localStorage[cacheKey];
-  if (cached) {
-    return JSON.parse(cached);
-  }
-
-  var dbName = '_pouch__checkModernIdb';
-  var result = global.indexedDB.open(dbName, 1).onupgradeneeded === null;
-
-  if (global.indexedDB.deleteDatabase) {
-    global.indexedDB.deleteDatabase(dbName); // db no longer needed
-  }
-  if (global.localStorage) {
-    global.localStorage[cacheKey] = JSON.stringify(result); // cache
-  }
-  return result;
-}
-function IdbPouch(opts, callback) {
-
-  // IndexedDB requires a versioned database structure, so we use the
-  // version here to manage migrations.
-  var ADAPTER_VERSION = 2;
-
-  // The object stores created for each database
-  // DOC_STORE stores the document meta data, its revision history and state
-  var DOC_STORE = 'document-store';
-  // BY_SEQ_STORE stores a particular version of a document, keyed by its
-  // sequence id
-  var BY_SEQ_STORE = 'by-sequence';
-  // Where we store attachments
-  var ATTACH_STORE = 'attach-store';
-  // Where we store meta data
-  var META_STORE = 'meta-store';
-  // Where we detect blob support
-  var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
-
-  var name = opts.name;
-  var req = global.indexedDB.open(name, ADAPTER_VERSION);
-
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.openReqList[name] = req;
-
-  var blobSupport = null;
-  var instanceId = null;
-  var api = this;
-  var idb = null;
-
-  req.onupgradeneeded = function (e) {
-    var db = e.target.result;
-    if (e.oldVersion < 1) {
-      // initial schema
-      createSchema(db);
-    }
-    if (e.oldVersion < 2) {
-      // version 2 adds the deletedOrLocal index
-      addDeletedOrLocalIndex(e);
-    }
-  };
-
-  function createSchema(db) {
-    db.createObjectStore(DOC_STORE, {keyPath : 'id'})
-      .createIndex('seq', 'seq', {unique: true});
-    db.createObjectStore(BY_SEQ_STORE, {autoIncrement : true})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
-    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
-    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
-  }
-
-  function addDeletedOrLocalIndex(e) {
-    var docStore = e.currentTarget.transaction.objectStore(DOC_STORE);
-
-    docStore.openCursor().onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var deleted = utils.isDeleted(metadata);
-        var local = utils.isLocalId(metadata.id);
-        metadata.deletedOrLocal = (deleted || local) ? "1" : "0";
-        docStore.put(metadata);
-        cursor['continue']();
-      } else {
-        docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
-      }
-    };
-  }
-
-  req.onsuccess = function (e) {
-
-    idb = e.target.result;
-
-    idb.onversionchange = function () {
-      idb.close();
-    };
-
-    var txn = idb.transaction([META_STORE, DETECT_BLOB_SUPPORT_STORE],
-                              'readwrite');
-
-    var req = txn.objectStore(META_STORE).get(META_STORE);
-
-    req.onsuccess = function (e) {
-
-      var idStored = false;
-      var checkSetupComplete = function () {
-        if (blobSupport === null || !idStored) {
-          return;
-        } else {
-          callback(null, api);
-        }
-      };
-
-      var meta = e.target.result || {id: META_STORE};
-      if (name  + '_id' in meta) {
-        instanceId = meta[name + '_id'];
-        idStored = true;
-        checkSetupComplete();
-      } else {
-        instanceId = utils.uuid();
-        meta[name + '_id'] = instanceId;
-        txn.objectStore(META_STORE).put(meta).onsuccess = function () {
-          idStored = true;
-          checkSetupComplete();
-        };
-      }
-
-      // detect blob support
-      try {
-        txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(utils.createBlob(), "key");
-        blobSupport = true;
-      } catch (err) {
-        blobSupport = false;
-      } finally {
-        checkSetupComplete();
-      }
-    };
-  };
-
-  req.onerror = idbError(callback);
-
-  api.type = function () {
-    return 'idb';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._bulkDocs = function idb_bulkDocs(req, opts, callback) {
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var results = [];
-    var docsWritten = 0;
-
-    function writeMetaData(e) {
-      var meta = e.target.result;
-      meta.updateSeq = (meta.updateSeq || 0) + docsWritten;
-      txn.objectStore(META_STORE).put(meta);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = writeMetaData;
-        return;
-      }
-      var currentDoc = docInfos.shift();
-      var req = txn.objectStore(DOC_STORE).get(currentDoc.metadata.id);
-      req.onsuccess = function process_docRead(event) {
-        var oldDoc = event.target.result;
-        if (!oldDoc) {
-          insertDoc(currentDoc);
-        } else {
-          updateDoc(oldDoc, currentDoc);
-        }
-      };
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        IdbPouch.Changes.notify(name);
-        IdbPouch.Changes.notifyLocalWindows(name);
-      });
-      callback(null, aresults);
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        var data;
-        try {
-          data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        att.digest = 'md5-' + utils.Crypto.MD5(data);
-        if (blobSupport) {
-          var type = att.content_type;
-          data = utils.fixBinary(data);
-          att.data = utils.createBlob([data], {type: type});
-        }
-        return finish();
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        att.digest = 'md5-' + utils.Crypto.MD5(this.result);
-        if (!blobSupport) {
-          att.data = btoa(this.result);
-        }
-        finish();
-      };
-      reader.readAsBinaryString(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        var recv = 0;
-        function attachmentProcessed() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key], attachmentProcessed);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, callback) {
-      var err = null;
-      var recv = 0;
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      docsWritten++;
-
-      if (utils.isDeleted(docInfo.metadata, docInfo.metadata.rev)) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      function finish() {
-        docInfo.data._doc_id_rev = docInfo.data._id + "::" + docInfo.data._rev;
-        var dataReq = txn.objectStore(BY_SEQ_STORE).put(docInfo.data);
-        dataReq.onsuccess = function (e) {
-          docInfo.metadata.seq = e.target.result;
-          // Current _rev is calculated from _rev_tree on read
-          delete docInfo.metadata.rev;
-          var deleted = utils.isDeleted(docInfo.metadata);
-          var local = utils.isLocalId(docInfo.metadata.id);
-          var metadata = utils.extend(true, {deletedOrLocal : (deleted || local) ? "1" : "0"}, docInfo.metadata);
-          var metaDataReq = txn.objectStore(DOC_STORE).put(metadata);
-          metaDataReq.onsuccess = function () {
-            results.push(docInfo);
-            utils.call(callback);
-          };
-        };
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var merged = merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var wasPreviouslyDeleted = utils.isDeleted(oldDoc);
-      var inConflict = (wasPreviouslyDeleted &&
-                        utils.isDeleted(docInfo.metadata)) ||
-        (!wasPreviouslyDeleted && newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-      writeDoc(docInfo, processDocs);
-    }
-
-    function insertDoc(docInfo) {
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && utils.isDeleted(docInfo.metadata)) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-      writeDoc(docInfo, processDocs);
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var objectStore = txn.objectStore(ATTACH_STORE);
-      objectStore.get(digest).onsuccess = function (e) {
-        var originalRefs = e.target.result && e.target.result.refs || {};
-        var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-        var newAtt = {
-          digest: digest,
-          body: data,
-          refs: originalRefs
-        };
-        newAtt.refs[ref] = true;
-        objectStore.put(newAtt).onsuccess = function (e) {
-          utils.call(callback);
-        };
-      };
-    }
-
-    var txn;
-    preprocessAttachments(function () {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE],
-                            'readwrite');
-      txn.onerror = idbError(callback);
-      txn.ontimeout = idbError(callback);
-      txn.oncomplete = complete;
-
-      processDocs();
-    });
-  };
-
-  function sortByBulkSeq(a, b) {
-    return a._bulk_seq - b._bulk_seq;
-  }
-
-  // First we look up the metadata in the ids database, then we fetch the
-  // current revision(s) from the by sequence store
-  api._get = function idb_get(id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    var txn;
-    opts = utils.extend(true, {}, opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: txn});
-    }
-
-    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
-      metadata = e.target.result;
-      // we can determine the result here if:
-      // 1. there is no such document
-      // 2. the document is deleted and we don't ask about specific rev
-      // When we ask with opts.rev we expect the answer to be either
-      // doc (possibly with _deleted=true) or missing error
-      if (!metadata) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-
-      var rev = merge.winningRev(metadata);
-      var key = metadata.id + '::' + (opts.rev ? opts.rev : rev);
-      var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-
-      index.get(key).onsuccess = function (e) {
-        doc = e.target.result;
-        if (doc && doc._doc_id_rev) {
-          delete(doc._doc_id_rev);
-        }
-        if (!doc) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        finish();
-      };
-    };
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var result;
-    var txn;
-    opts = utils.extend(true, {}, opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-
-    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
-      var data = e.target.result.body;
-      if (opts.encode) {
-        if (blobSupport) {
-          var reader = new FileReader();
-          reader.onloadend = function (e) {
-            result = btoa(this.result);
-            callback(null, result);
-          };
-          reader.readAsBinaryString(data);
-        } else {
-          result = data;
-          callback(null, result);
-        }
-      } else {
-        if (blobSupport) {
-          result = data;
-        } else {
-          data = utils.fixBinary(atob(data));
-          result = utils.createBlob([data], {type: type});
-        }
-        callback(null, result);
-      }
-    };
-  };
-
-  function allDocsKeysQuery(totalRows, opts, callback) {
-    var keys = opts.keys;
-    var descending = 'descending' in opts ? opts.descending : false;
-
-    if (!keys.length) { // empty list is okay
-      callback(null, {
-        offset : opts.skip,
-        rows : [],
-        total_rows : totalRows
-      });
-    } else {
-      // do a separate "key" query for each key in the keys array
-      var resultsToCollate = [];
-      keys.forEach(function (key) {
-        var subOpts = utils.extend(true, {}, opts);
-        subOpts.keys_request = true; // internal param, says this is a "keys" request
-        subOpts.key = key;
-        delete subOpts.keys;
-        delete subOpts.skip;
-        delete subOpts.limit;
-
-        allDocsNormalQuery(totalRows, subOpts, function (err, res) {
-          resultsToCollate.push({err : err, res : res, key : key});
-          if (resultsToCollate.length === keys.length) {
-            // all done, time to collate
-            var keysToResults = {};
-            for (var i = 0; i < resultsToCollate.length; i++) {
-              var result = resultsToCollate[i];
-              if (result.err) {
-                callback(err);
-                return;
-              } else {
-                keysToResults[result.key] = result;
-              }
-            }
-            var results = [];
-            keys.forEach(function (key) {
-              var result = keysToResults[key];
-              if (result.res.rows.length) {
-                results.push(result.res.rows[0]); // only one result ever
-              } else {
-                results.push({"key": key, "error": "not_found"});
-              }
-            });
-            if (descending) {
-              results = results.reverse();
-            }
-            callback(null, {
-              total_rows: totalRows,
-              offset: opts.skip,
-              rows: ('limit' in opts) ? results.slice(opts.skip, opts.limit + opts.skip) :
-                (opts.skip > 0) ? results.slice(opts.skip) : results
-            });
-          }
-        });
-      });
-    }
-  }
-
-  function allDocsNormalQuery(totalRows, opts, callback) {
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-
-    var descending = 'descending' in opts && opts.descending ? 'prev' : null;
-
-    var skipped = 0;
-
-    var manualDescEnd = false;
-    if (descending && start && end) {
-      // unfortunately IDB has a quirk where IDBKeyRange.bound is invalid if the
-      // start is less than the end, even in descending mode.  Best bet
-      // is just to handle it manually in that case.
-      manualDescEnd = end;
-      end = false;
-    }
-
-    var keyRange;
-    try {
-      keyRange = start && end ? global.IDBKeyRange.bound(start, end)
-        : start ? (descending ? global.IDBKeyRange.upperBound(start) : global.IDBKeyRange.lowerBound(start))
-        : end ? (descending ? global.IDBKeyRange.lowerBound(end) : global.IDBKeyRange.upperBound(end))
-        : key ? global.IDBKeyRange.only(key) : null;
-    } catch (e) {
-      if (e.name === "DataError" && e.code === 0) {
-        // data error, start is less than end
-        return callback(null, {total_rows : totalRows, offset : opts.skip, rows : []}); // no docs possible
-      } else {
-        return callback(errors.error(errors.IDB_ERROR, e.name, e.message));
-      }
-    }
-
-    var transaction = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readonly');
-    transaction.oncomplete = function () {
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    };
-
-    var oStore = transaction.objectStore(DOC_STORE);
-    var oCursor = descending ? oStore.openCursor(keyRange, descending)
-      : oStore.openCursor(keyRange);
-    var results = [];
-    oCursor.onsuccess = function (e) {
-      if (!e.target.result) {
-        return;
-      }
-      var cursor = e.target.result;
-      var metadata = cursor.value;
-
-      function allDocsInner(metadata, data) {
-        if (utils.isLocalId(metadata.id)) {
-          return cursor['continue']();
-        }
-        var doc = {
-          id: metadata.id,
-          key: metadata.id,
-          value: {
-            rev: merge.winningRev(metadata)
-          }
-        };
-        if (opts.include_docs) {
-          doc.doc = data;
-          doc.doc._rev = merge.winningRev(metadata);
-          if (doc.doc._doc_id_rev) {
-            delete(doc.doc._doc_id_rev);
-          }
-          if (opts.conflicts) {
-            doc.doc._conflicts = merge.collectConflicts(metadata);
-          }
-          for (var att in doc.doc._attachments) {
-            if (doc.doc._attachments.hasOwnProperty(att)) {
-              doc.doc._attachments[att].stub = true;
-            }
-          }
-        }
-        if (opts.keys_request) {
-          // deleted docs are okay with keys_requests
-          if (utils.isDeleted(metadata)) {
-            doc.value.deleted = true;
-            doc.doc = null;
-          }
-          results.push(doc);
-        } else if (!utils.isDeleted(metadata)) {
-          if (!results.length && opts.skip > 0 && skipped < opts.skip) {
-            skipped++;
-          } else if (manualDescEnd && doc.key <= manualDescEnd) {
-            if (doc.key === manualDescEnd) {
-              results.push(doc);
-            }
-            return; // done reading
-          } else if ('limit' in opts && results.length === opts.limit) {
-            return; // done reading
-          } else {
-            results.push(doc);
-          }
-        }
-        cursor['continue']();
-      }
-
-      if (!opts.include_docs) {
-        allDocsInner(metadata);
-      } else {
-        var index = transaction.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var mainRev = merge.winningRev(metadata);
-        var key = metadata.id + "::" + mainRev;
-        index.get(key).onsuccess = function (event) {
-          allDocsInner(cursor.value, event.target.result);
-        };
-      }
-    };
-  }
-
-  api._allDocs = function idb_allDocs(opts, callback) {
-
-    // first count the total_rows using the undeleted/non-local count
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-
-    var totalRows;
-    function countUndeletedNonlocalDocs(e) {
-      totalRows = e.target.result;
-    }
-
-    var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
-    index.count(global.IDBKeyRange.only("0")).onsuccess = countUndeletedNonlocalDocs;
-
-    txn.onerror = idbError(callback);
-
-    txn.oncomplete = function () {
-      if ('keys' in opts) {
-        allDocsKeysQuery(totalRows, opts, callback);
-      } else {
-        allDocsNormalQuery(totalRows, opts, callback);
-      }
-    };
-  };
-
-  api._info = function idb_info(callback) {
-    var count = 0;
-    var update_seq = 0;
-    var txn = idb.transaction([DOC_STORE, META_STORE], 'readonly');
-
-    function fetchUpdateSeq(e) {
-      update_seq = e.target.result && e.target.result.updateSeq || 0;
-    }
-
-    function countDocs(e) {
-      var cursor = e.target.result;
-      if (!cursor) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = fetchUpdateSeq;
-        return;
-      }
-      if (cursor.value.deleted !== true) {
-        count++;
-      }
-      cursor['continue']();
-    }
-
-    txn.oncomplete = function () {
-      callback(null, {
-        db_name: name,
-        doc_count: count,
-        update_seq: update_seq
-      });
-    };
-
-    txn.objectStore(DOC_STORE).openCursor().onsuccess = countDocs;
-  };
-
-  api._changes = function idb_changes(opts) {
-    opts = utils.extend(true, {}, opts);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      opts.cancelled = false;
-      IdbPouch.Changes.addListener(name, id, api, opts);
-      IdbPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          opts.complete(null, {status: 'cancelled'});
-          opts.complete = null;
-          opts.cancelled = true;
-          IdbPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending ? 'prev' : null;
-    var last_seq = 0;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var results = [], resultIndices = {}, dedupResults = [];
-    var txn;
-
-    function fetchChanges() {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE]);
-      txn.oncomplete = onTxnComplete;
-
-      var req;
-
-      if (descending) {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true), descending);
-      } else {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true));
-      }
-
-      req.onsuccess = onsuccess;
-      req.onerror = onerror;
-    }
-
-    fetchChanges();
-
-    function onsuccess(event) {
-      if (!event.target.result) {
-        // Filter out null results casued by deduping
-        for (var i = 0, l = results.length; i < l; i++) {
-          var result = results[i];
-          if (result) {
-            dedupResults.push(result);
-          }
-        }
-        return false;
-      }
-
-      var cursor = event.target.result;
-
-      // Try to pre-emptively dedup to save us a bunch of idb calls
-      var changeId = cursor.value._id;
-      var changeIdIndex = resultIndices[changeId];
-      if (changeIdIndex !== undefined) {
-        results[changeIdIndex].seq = cursor.key;
-        // update so it has the later sequence number
-        results.push(results[changeIdIndex]);
-        results[changeIdIndex] = null;
-        resultIndices[changeId] = results.length - 1;
-        return cursor['continue']();
-      }
-
-      var index = txn.objectStore(DOC_STORE);
-      index.get(cursor.value._id).onsuccess = function (event) {
-        var metadata = event.target.result;
-        if (utils.isLocalId(metadata.id)) {
-          return cursor['continue']();
-        }
-
-        if (last_seq < metadata.seq) {
-          last_seq = metadata.seq;
-        }
-
-        var mainRev = merge.winningRev(metadata);
-        var key = metadata.id + "::" + mainRev;
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        index.get(key).onsuccess = function (docevent) {
-          var doc = docevent.target.result;
-          delete doc['_doc_id_rev'];
-
-          doc._rev = mainRev;
-          var change = opts.processChange(doc, metadata, opts);
-          change.seq = cursor.key;
-
-          // Dedupe the changes feed
-          var changeId = change.id, changeIdIndex = resultIndices[changeId];
-          if (changeIdIndex !== undefined) {
-            results[changeIdIndex] = null;
-          }
-          results.push(change);
-          resultIndices[changeId] = results.length - 1;
-          cursor['continue']();
-        };
-      };
-    }
-
-    function onTxnComplete() {
-      utils.processChanges(opts, dedupResults, last_seq);
-    }
-  };
-
-  api._close = function (callback) {
-    if (idb === null) {
-      return callback(errors.NOT_OPEN);
-    }
-
-    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
-    // "Returns immediately and closes the connection in a separate thread..."
-    idb.close();
-    callback();
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var req = txn.objectStore(DOC_STORE).get(docId);
-    req.onsuccess = function (event) {
-      var doc = event.target.result;
-      if (!doc) {
-        callback(errors.MISSING_DOC);
-      } else {
-        callback(null, doc.rev_tree);
-      }
-    };
-  };
-
-  // This function removes revisions of document docId
-  // which are listed in revs and sets this document
-  // revision to to rev_tree
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    var txn = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readwrite');
-
-    var index = txn.objectStore(DOC_STORE);
-    index.get(docId).onsuccess = function (event) {
-      var metadata = event.target.result;
-      metadata.rev_tree = rev_tree;
-
-      var count = revs.length;
-      revs.forEach(function (rev) {
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = docId + "::" + rev;
-        index.getKey(key).onsuccess = function (e) {
-          var seq = e.target.result;
-          if (!seq) {
-            return;
-          }
-          txn.objectStore(BY_SEQ_STORE)['delete'](seq);
-
-          count--;
-          if (!count) {
-            if (metadata) {
-              var deleted = utils.isDeleted(metadata);
-              var local = utils.isLocalId(metadata.id);
-              metadata = utils.extend(true, {deletedOrLocal : (deleted || local) ? "1" : "0"}, metadata);
-            }
-            txn.objectStore(DOC_STORE).put(metadata);
-          }
-        };
-      });
-    };
-    txn.oncomplete = function () {
-      utils.call(callback);
-    };
-  };
-
-}
-
-IdbPouch.valid = function () {
-  return global.indexedDB && isModernIdb();
-};
-
-IdbPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.Changes.clearListeners(name);
-
-  //Close open request for "name" database to fix ie delay.
-  if (IdbPouch.openReqList[name] && IdbPouch.openReqList[name].result) {
-    IdbPouch.openReqList[name].result.close();
-  }
-  var req = global.indexedDB.deleteDatabase(name);
-
-  req.onsuccess = function () {
-    //Remove open request from the list.
-    if (IdbPouch.openReqList[name]) {
-      IdbPouch.openReqList[name] = null;
-    }
-    callback();
-  };
-
-  req.onerror = idbError(callback);
-});
-
-IdbPouch.Changes = new utils.Changes();
-
-module.exports = IdbPouch;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":8,"../merge":14,"../utils":18}],4:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-function quote(str) {
-  return "'" + str + "'";
-}
-
-function openDB() {
-  if (typeof global !== 'undefined') {
-    if (global.navigator && global.navigator.sqlitePlugin &&
-        global.navigator.sqlitePlugin.openDatabase) {
-      return navigator.sqlitePlugin.openDatabase
-        .apply(navigator.sqlitePlugin, arguments);
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return global.sqlitePlugin.openDatabase
-        .apply(global.sqlitePlugin, arguments);
-    } else {
-      return global.openDatabase.apply(global, arguments);
-    }
-  }
-}
-
-var POUCH_VERSION = 1;
-var POUCH_SIZE = 5 * 1024 * 1024;
-var ADAPTER_VERSION = 2; // used to manage migrations
-
-// The object stores created for each database
-// DOC_STORE stores the document meta data, its revision history and state
-var DOC_STORE = quote('document-store');
-// BY_SEQ_STORE stores a particular version of a document, keyed by its
-// sequence id
-var BY_SEQ_STORE = quote('by-sequence');
-// Where we store attachments
-var ATTACH_STORE = quote('attach-store');
-var META_STORE = quote('metadata-store');
-
-// these indexes cover the ground for most allDocs queries
-var BY_SEQ_STORE_DELETED_INDEX_SQL = 'CREATE INDEX IF NOT EXISTS \'by-seq-deleted-idx\' ON ' +
-  BY_SEQ_STORE + ' (seq, deleted)';
-var DOC_STORE_LOCAL_INDEX_SQL = 'CREATE INDEX IF NOT EXISTS \'doc-store-local-idx\' ON ' +
-  DOC_STORE + ' (local, id)';
-var DOC_STORE_WINNINGSEQ_INDEX_SQL = 'CREATE INDEX IF NOT EXISTS \'doc-winningseq-idx\' ON ' +
-  DOC_STORE + ' (winningseq)';
-
-
-var idRequests = [];
-var cachedDatabases = {};
-
-function unknownError(callback) {
-  return function (event) {
-    // event may actually be a SQLError object, so report is as such
-    var errorNameMatch = event && event.constructor.toString()
-      .match(/function ([^\(]+)/);
-    var errorName = (errorNameMatch && errorNameMatch[1]) || event.type;
-    var errorReason = event.target || event.message;
-    callback(errors.error(errors.WSQ_ERROR, errorReason, errorName));
-  };
-}
-
-function parseHexString(str) {
-  var result = '';
-  for (var i = 0, len = str.length; i < len; i += 2) {
-    result += String.fromCharCode(parseInt(str.substring(i, i + 2), 16));
-  }
-  return result;
-}
-
-// Safari is weird, it encodes everything with bonus \u0000 characters after
-// every character rather than user agent sniff, we test every odd
-// character for \u0000
-function isMangledUnicode(str) {
-  for (var i = 1, len = str.length; i < len; i += 2) {
-    if (str.charAt(i) !== '\u0000') {
-      return false;
-    }
-  }
-  return true;
-}
-
-// unmangle the aforementioned Safari atrocity
-function unmangleUnicode(str) {
-  var result = '';
-  for (var i = 0, len = str.length; i < len; i += 2) {
-    result += str.charAt(i);
-  }
-  return result;
-}
-
-// used to deal with utf8 encoding that occurs in most sqlite implementations
-// partially taken from
-// http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html
-function decodeUtf8(str) {
-  var result;
-  try {
-    result = decodeURIComponent(window.escape(str));
-  } catch (err) {
-    // URI error in safari, string is already escaped but still possibly mangled
-    result = str;
-  }
-  return isMangledUnicode(result) ? unmangleUnicode(result) : result;
-}
-function WebSqlPouch(opts, callback) {
-  var api = this;
-  var instanceId = null;
-  var name = opts.name;
-
-  var db = cachedDatabases[name];
-  if (!db) {
-    cachedDatabases[name] = db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  }
-  if (!db) {
-    return callback(errors.UNKNOWN_ERROR);
-  }
-
-  function dbCreated() {
-    callback(null, api);
-  }
-
-  // In this migration, we added the 'deleted' and 'local' columns to the by-seq and doc store tables.
-  // To preserve existing user data, we re-process all the existing JSON
-  // and add these values.
-  // Called migration2 because it corresponds to adapter version (db_version) #2
-  function runMigration2(tx) {
-
-    tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL); // index used for the join in the allDocs query
-
-    tx.executeSql('ALTER TABLE ' + BY_SEQ_STORE + ' ADD COLUMN deleted TINYINT(1) DEFAULT 0', [], function () {
-      tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-      tx.executeSql('ALTER TABLE ' + DOC_STORE + ' ADD COLUMN local TINYINT(1) DEFAULT 0', [], function () {
-        tx.executeSql(DOC_STORE_LOCAL_INDEX_SQL);
-
-        var sql = 'SELECT ' + DOC_STORE + '.winningseq AS seq, ' + DOC_STORE + '.json AS metadata FROM ' +
-          BY_SEQ_STORE + ' JOIN ' + DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-          DOC_STORE + '.winningseq';
-
-        tx.executeSql(sql, [], function (tx, result) {
-
-          var deleted = [];
-          var local = [];
-
-          for (var i = 0; i < result.rows.length; i++) {
-            var item = result.rows.item(i);
-            var seq = item.seq;
-            var metadata = JSON.parse(item.metadata);
-            if (utils.isDeleted(metadata)) {
-              deleted.push(seq);
-            }
-            if (utils.isLocalId(metadata.id)) {
-              local.push(metadata.id);
-            }
-          }
-
-          tx.executeSql('UPDATE ' + DOC_STORE + 'SET local = 1 WHERE id IN (' + local.map(function () {
-            return '?';
-          }).join(',') + ')', local);
-          tx.executeSql('UPDATE ' + BY_SEQ_STORE + ' SET deleted = 1 WHERE seq IN (' + deleted.map(function () {
-            return '?';
-          }).join(',') + ')', deleted);
-        });
-      });
-    });
-  }
-
-  function onGetInstanceId() {
-    while (idRequests.length > 0) {
-      var idCallback = idRequests.pop();
-      idCallback(null, instanceId);
-    }
-  }
-
-  function onGetVersion(tx, dbVersion) {
-    if (dbVersion === 0) {
-      // initial schema
-
-      var meta = 'CREATE TABLE IF NOT EXISTS ' + META_STORE +
-        ' (update_seq, dbid, db_version INTEGER)';
-      var attach = 'CREATE TABLE IF NOT EXISTS ' + ATTACH_STORE +
-        ' (digest, json, body BLOB)';
-      var doc = 'CREATE TABLE IF NOT EXISTS ' + DOC_STORE +
-        ' (id unique, seq, json, winningseq, local TINYINT(1))';
-      var seq = 'CREATE TABLE IF NOT EXISTS ' + BY_SEQ_STORE +
-        ' (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, doc_id_rev UNIQUE, json, deleted TINYINT(1))';
-
-      // creates
-      tx.executeSql(attach);
-      tx.executeSql(doc, [], function () {
-        tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
-        tx.executeSql(DOC_STORE_LOCAL_INDEX_SQL);
-      });
-      tx.executeSql(seq, [], function () {
-        tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-      });
-      tx.executeSql(meta, [], function () {
-        // mark the update_seq, db version, and new dbid
-        var initSeq = 'INSERT INTO ' + META_STORE + ' (update_seq, db_version, dbid) VALUES (?, ?, ?)';
-        instanceId = utils.uuid();
-        tx.executeSql(initSeq, [0, ADAPTER_VERSION, instanceId]);
-        onGetInstanceId();
-      });
-    } else { // version > 0
-
-      if (dbVersion === 1) {
-        runMigration2(tx);
-        // mark the db version within this transaction
-        tx.executeSql('UPDATE ' + META_STORE + ' SET db_version = ' + ADAPTER_VERSION);
-      } // in the future, add more migrations here
-
-      // notify db.id() callers
-      tx.executeSql('SELECT dbid FROM ' + META_STORE, [], function (tx, result) {
-        instanceId = result.rows.item(0).dbid;
-        onGetInstanceId();
-      });
-    }
-  }
-
-  function setup() {
-
-    db.transaction(function (tx) {
-      // first get the version
-      tx.executeSql('SELECT sql FROM sqlite_master WHERE tbl_name = ' + META_STORE, [], function (tx, result) {
-        if (!result.rows.length) {
-          // database hasn't even been created yet (version 0)
-          onGetVersion(tx, 0);
-        } else if (!/db_version/.test(result.rows.item(0).sql)) {
-          // table was created, but without the new db_version column, so add it.
-          tx.executeSql('ALTER TABLE ' + META_STORE + ' ADD COLUMN db_version INTEGER', [], function () {
-            onGetVersion(tx, 1); // before version 2, this column didn't even exist
-          });
-        } else { // column exists, we can safely get it
-          tx.executeSql('SELECT db_version FROM ' + META_STORE, [], function (tx, result) {
-            var dbVersion = result.rows.item(0).db_version;
-            onGetVersion(tx, dbVersion);
-          });
-        }
-      });
-    }, unknownError(callback), dbCreated);
-  }
-
-  if (utils.isCordova() && typeof global !== 'undefined') {
-    //to wait until custom api is made in pouch.adapters before doing setup
-    global.addEventListener(name + '_pouch', function cordova_init() {
-      global.removeEventListener(name + '_pouch', cordova_init, false);
-      setup();
-    }, false);
-  } else {
-    setup();
-  }
-
-
-  api.type = function () {
-    return 'websql';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._info = function (callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT COUNT(id) AS count FROM ' + DOC_STORE;
-      tx.executeSql(sql, [], function (tx, result) {
-        var doc_count = result.rows.item(0).count;
-        var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-        tx.executeSql(updateseq, [], function (tx, result) {
-          var update_seq = result.rows.item(0).update_seq;
-          callback(null, {
-            db_name: name,
-            doc_count: doc_count,
-            update_seq: update_seq
-          });
-        });
-      });
-    });
-  };
-
-  api._bulkDocs = function (req, opts, callback) {
-
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    var docsWritten = 0;
-
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var tx;
-    var results = [];
-    var fetchedDocs = {};
-
-    function sortByBulkSeq(a, b) {
-      return a._bulk_seq - b._bulk_seq;
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        docsWritten++;
-
-        WebSqlPouch.Changes.notify(name);
-        WebSqlPouch.Changes.notifyLocalWindows(name);
-      });
-
-      var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-      tx.executeSql(updateseq, [], function (tx, result) {
-        var update_seq = result.rows.item(0).update_seq + docsWritten;
-        var sql = 'UPDATE ' + META_STORE + ' SET update_seq=?';
-        tx.executeSql(sql, [update_seq], function () {
-          callback(null, aresults);
-        });
-      });
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        try {
-          att.data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        var data = utils.fixBinary(att.data);
-        att.data = utils.createBlob([data], {type: att.content_type});
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        att.data = this.result;
-        att.digest = 'md5-' + utils.Crypto.MD5(this.result);
-        finish();
-      };
-      reader.readAsBinaryString(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-        var recv = 0;
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        function processedAttachment() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key], processedAttachment);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, callback, isUpdate) {
-
-      function finish() {
-        var data = docInfo.data;
-        var sql = 'INSERT INTO ' + BY_SEQ_STORE + ' (doc_id_rev, json, deleted) VALUES (?, ?, ?);';
-        var sqlArgs = [
-          data._id + "::" + data._rev,
-          JSON.stringify(data),
-          utils.isDeleted(docInfo.metadata, docInfo.metadata.rev) ? 1 : 0
-        ];
-        tx.executeSql(sql, sqlArgs, dataWritten);
-      }
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      var err = null;
-      var recv = 0;
-
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      if (utils.isDeleted(docInfo.metadata, docInfo.metadata.rev)) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-
-      function dataWritten(tx, result) {
-        var seq = docInfo.metadata.seq = result.insertId;
-        delete docInfo.metadata.rev;
-
-        var mainRev = merge.winningRev(docInfo.metadata);
-
-        var sql = isUpdate ?
-          'UPDATE ' + DOC_STORE + ' SET seq=?, json=?, winningseq=(SELECT seq FROM ' +
-          BY_SEQ_STORE + ' WHERE doc_id_rev=?) WHERE id=?' :
-          'INSERT INTO ' + DOC_STORE + ' (id, seq, winningseq, json, local) VALUES (?, ?, ?, ?, ?);';
-        var metadataStr = JSON.stringify(docInfo.metadata);
-        var key = docInfo.metadata.id + "::" + mainRev;
-        var local = utils.isLocalId(docInfo.metadata.id) ? 1 : 0;
-        var params = isUpdate ?
-          [seq, metadataStr, key, docInfo.metadata.id] :
-          [docInfo.metadata.id, seq, seq, metadataStr, local];
-        tx.executeSql(sql, params, function (tx, result) {
-          results.push(docInfo);
-          callback();
-        });
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var merged = merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var inConflict = (utils.isDeleted(oldDoc) &&
-                        utils.isDeleted(docInfo.metadata)) ||
-        (!utils.isDeleted(oldDoc) &&
-         newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-      writeDoc(docInfo, processDocs, true);
-    }
-
-    function insertDoc(docInfo) {
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && utils.isDeleted(docInfo.metadata)) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-      writeDoc(docInfo, processDocs, false);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        return complete();
-      }
-      var currentDoc = docInfos.shift();
-      var id = currentDoc.metadata.id;
-      if (id in fetchedDocs) {
-        updateDoc(fetchedDocs[id], currentDoc);
-      } else {
-        // if we have newEdits=false then we can update the same
-        // document twice in a single bulk docs call
-        fetchedDocs[id] = currentDoc.metadata;
-        insertDoc(currentDoc);
-      }
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-      var newAtt = {digest: digest};
-      var sql = 'SELECT digest, json FROM ' + ATTACH_STORE + ' WHERE digest=?';
-      tx.executeSql(sql, [digest], function (tx, result) {
-        if (!result.rows.length) {
-          newAtt.refs = {};
-          newAtt.refs[ref] = true;
-          sql = 'INSERT INTO ' + ATTACH_STORE + '(digest, json, body) VALUES (?, ?, ?)';
-          tx.executeSql(sql, [digest, JSON.stringify(newAtt), data], function () {
-            callback();
-          });
-        } else {
-          newAtt.refs = JSON.parse(result.rows.item(0).json).refs;
-          sql = 'UPDATE ' + ATTACH_STORE + ' SET json=?, body=? WHERE digest=?';
-          tx.executeSql(sql, [JSON.stringify(newAtt), data, digest], function () {
-            callback();
-          });
-        }
-      });
-    }
-
-    function metadataFetched(tx, results) {
-      for (var j = 0; j < results.rows.length; j++) {
-        var row = results.rows.item(j);
-        fetchedDocs[row.id] = JSON.parse(row.json);
-      }
-      processDocs();
-    }
-
-    preprocessAttachments(function () {
-      db.transaction(function (txn) {
-        tx = txn;
-        var sql = 'SELECT * FROM ' + DOC_STORE + ' WHERE id IN ' +
-          '(' + docInfos.map(function () {return '?'; }).join(',') + ')';
-        var queryArgs = docInfos.map(function (d) { return d.metadata.id; });
-        tx.executeSql(sql, queryArgs, metadataFetched);
-      }, unknownError(callback));
-    });
-  };
-
-  api._get = function (id, opts, callback) {
-    opts = utils.extend(true, {}, opts);
-    var doc;
-    var metadata;
-    var err;
-    if (!opts.ctx) {
-      db.transaction(function (txn) {
-        opts.ctx = txn;
-        api._get(id, opts, callback);
-      });
-      return;
-    }
-    var tx = opts.ctx;
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: tx});
-    }
-
-    var sql = 'SELECT * FROM ' + DOC_STORE + ' WHERE id=?';
-    tx.executeSql(sql, [id], function (a, results) {
-      if (!results.rows.length) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      metadata = JSON.parse(results.rows.item(0).json);
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-
-      var rev = merge.winningRev(metadata);
-      var key = opts.rev ? opts.rev : rev;
-      key = metadata.id + '::' + key;
-      var sql = 'SELECT * FROM ' + BY_SEQ_STORE + ' WHERE doc_id_rev=?';
-      tx.executeSql(sql, [key], function (tx, results) {
-        if (!results.rows.length) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        doc = JSON.parse(results.rows.item(0).json);
-
-        finish();
-      });
-    });
-  };
-
-  api._allDocs = function (opts, callback) {
-    var results = [];
-    var resultsMap = {};
-    var totalRows;
-
-    var from = BY_SEQ_STORE + ' JOIN ' + DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-      DOC_STORE + '.winningseq';
-
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-    var descending = 'descending' in opts ? opts.descending : false;
-    var keys = 'keys' in opts ? opts.keys : false;
-    var limit = 'limit' in opts ? opts.limit : false;
-    var offset = 'skip' in opts ? opts.skip : false;
-
-    var sqlArgs = [];
-    var criteria = [DOC_STORE + '.local = 0'];
-
-    if (key !== false) {
-      criteria.push(DOC_STORE + '.id = ?');
-      sqlArgs.push(key);
-    } else if (keys !== false) {
-      criteria.push(DOC_STORE + '.id in (' + keys.map(function () {
-        return '?';
-      }).join(',') + ')');
-      sqlArgs = sqlArgs.concat(keys);
-    } else if (start !== false || end !== false) {
-      if (start !== false) {
-        criteria.push(DOC_STORE + '.id ' + (descending ? '<=' : '>=') + ' ?');
-        sqlArgs.push(start);
-      }
-      if (end !== false) {
-        criteria.push(DOC_STORE + '.id ' + (descending ? '>=' : '<=') + ' ?');
-        sqlArgs.push(end);
-      }
-      if (key !== false) {
-        criteria.push(DOC_STORE + '.id = ?');
-        sqlArgs.push(key);
-      }
-    }
-
-    if (keys === false) {
-      // report deleted if keys are specified
-      criteria.push(BY_SEQ_STORE + '.deleted = 0');
-    }
-
-    db.transaction(function (tx) {
-
-      // first count up the total rows
-      var sql = 'SELECT COUNT(' + DOC_STORE + '.id) AS \'num\' FROM ' +
-        from + ' WHERE ' + BY_SEQ_STORE + '.deleted = 0 AND ' +
-        // local docs are e.g. '_local_foo'
-        DOC_STORE + '.local = 0';
-
-      tx.executeSql(sql, [], function (tx, result) {
-        totalRows = result.rows.item(0).num;
-
-        // then actually fetch the documents
-
-        var sql = 'SELECT ' + DOC_STORE + '.id, ' + BY_SEQ_STORE + '.seq, ' +
-          BY_SEQ_STORE + '.json AS data, ' + DOC_STORE + '.json AS metadata FROM ' + from;
-
-        if (criteria.length) {
-          sql += ' WHERE ' + criteria.join(' AND ');
-        }
-        sql += ' ORDER BY ' + DOC_STORE + '.id ' + (descending ? 'DESC' : 'ASC');
-        if (limit !== false) {
-          sql += ' LIMIT ' + limit;
-        }
-        if (offset !== false && offset > 0) {
-          if (limit === false) {
-            // sqlite requires limit with offset, -1 acts as infinity here
-            sql += ' LIMIT -1';
-          }
-          sql += ' OFFSET ' + offset;
-        }
-
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var doc = result.rows.item(i);
-            var metadata = JSON.parse(doc.metadata);
-            var data = JSON.parse(doc.data);
-            doc = {
-              id: metadata.id,
-              key: metadata.id,
-              value: {rev: merge.winningRev(metadata)}
-            };
-            if (opts.include_docs) {
-              doc.doc = data;
-              doc.doc._rev = merge.winningRev(metadata);
-              if (opts.conflicts) {
-                doc.doc._conflicts = merge.collectConflicts(metadata);
-              }
-              for (var att in doc.doc._attachments) {
-                if (doc.doc._attachments.hasOwnProperty(att)) {
-                  doc.doc._attachments[att].stub = true;
-                }
-              }
-            }
-            if ('keys' in opts) {
-              if (opts.keys.indexOf(metadata.id) > -1) {
-                if (utils.isDeleted(metadata)) {
-                  doc.value.deleted = true;
-                  doc.doc = null;
-                }
-                resultsMap[doc.id] = doc;
-              }
-            } else {
-              results.push(doc);
-            }
-          }
-        });
-      });
-    }, unknownError(callback), function () {
-      if ('keys' in opts) {
-        opts.keys.forEach(function (key) {
-          if (key in resultsMap) {
-            results.push(resultsMap[key]);
-          } else {
-            results.push({"key": key, "error": "not_found"});
-          }
-        });
-        if (opts.descending) {
-          results.reverse();
-        }
-      }
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    });
-  };
-
-  api._changes = function idb_changes(opts) {
-    opts = utils.extend(true, {}, opts);
-
-
-    //console.log(name + ': Start Changes Feed: continuous=' + opts.continuous);
-
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      opts.cancelled = false;
-      WebSqlPouch.Changes.addListener(name, id, api, opts);
-      WebSqlPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          opts.complete(null, {status: 'cancelled'});
-          opts.complete = null;
-          opts.cancelled = true;
-          WebSqlPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var results = [];
-
-    function fetchChanges() {
-      var sql = 'SELECT ' + DOC_STORE + '.id, ' + BY_SEQ_STORE + '.seq, ' +
-        BY_SEQ_STORE + '.json AS data, ' + DOC_STORE + '.json AS metadata FROM ' +
-        BY_SEQ_STORE + ' JOIN ' + DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-        DOC_STORE + '.winningseq WHERE ' + DOC_STORE + '.seq > ' + opts.since +
-        ' ORDER BY ' + DOC_STORE + '.seq ' + (descending ? 'DESC' : 'ASC');
-
-      db.transaction(function (tx) {
-        tx.executeSql(sql, [], function (tx, result) {
-          var last_seq = 0;
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var res = result.rows.item(i);
-            var metadata = JSON.parse(res.metadata);
-            if (!utils.isLocalId(metadata.id)) {
-              if (last_seq < res.seq) {
-                last_seq = res.seq;
-              }
-              var doc = JSON.parse(res.data);
-              var change = opts.processChange(doc, metadata, opts);
-              change.seq = res.seq;
-
-              results.push(change);
-            }
-          }
-          utils.processChanges(opts, results, last_seq);
-        });
-      });
-    }
-
-    fetchChanges();
-  };
-
-  api._close = function (callback) {
-    //WebSQL databases do not need to be closed
-    callback();
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var res;
-    var tx = opts.ctx;
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-    var sql = 'SELECT hex(body) as body FROM ' + ATTACH_STORE + ' WHERE digest=?';
-    tx.executeSql(sql, [digest], function (tx, result) {
-      // TODO: sqlite normally stores data as utf8, so even the hex() function "encodes" the binary
-      // data in utf8 before returning it, and yet hex() is the only way to get the full data. so we do this.
-      var data = decodeUtf8(parseHexString(result.rows.item(0).body));
-      if (opts.encode) {
-        res = btoa(data);
-      } else {
-        data = utils.fixBinary(data);
-        res = utils.createBlob([data], {type: type});
-      }
-      callback(null, res);
-    });
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          callback(errors.MISSING_DOC);
-        } else {
-          var data = JSON.parse(result.rows.item(0).metadata);
-          callback(null, data.rev_tree);
-        }
-      });
-    });
-  };
-
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          return utils.call(callback);
-        }
-        var metadata = JSON.parse(result.rows.item(0).metadata);
-        metadata.rev_tree = rev_tree;
-
-        var sql = 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE doc_id_rev IN (' +
-          revs.map(function (rev) {return quote(docId + '::' + rev); }).join(',') + ')';
-
-        tx.executeSql(sql, [], function (tx, result) {
-          var sql = 'UPDATE ' + DOC_STORE + ' SET json = ? WHERE id = ?';
-
-          tx.executeSql(sql, [JSON.stringify(metadata), docId], function (tx, result) {
-            callback();
-          });
-        });
-      });
-    });
-  };
-}
-
-WebSqlPouch.valid = function () {
-  if (typeof global !== 'undefined') {
-    if (global.navigator && global.navigator.sqlitePlugin && global.navigator.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.openDatabase) {
-      return true;
-    }
-  }
-  return false;
-};
-
-WebSqlPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  var self = this;
-  var db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  db.transaction(function (tx) {
-    tx.executeSql('DROP TABLE IF EXISTS ' + DOC_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + BY_SEQ_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + ATTACH_STORE, []);
-    tx.executeSql('DROP TABLE IF EXISTS ' + META_STORE, []);
-  }, unknownError(callback), function () {
-    self.emit('destroyed');
-    callback();
-  });
-});
-
-WebSqlPouch.Changes = new utils.Changes();
-
-module.exports = WebSqlPouch;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":8,"../merge":14,"../utils":18}],5:[function(_dereq_,module,exports){
-(function (global){
-/*globals cordova */
-"use strict";
-
-var Adapter = _dereq_('./adapter');
-var utils = _dereq_('./utils');
-var Promise = typeof global.Promise === 'function' ? global.Promise : _dereq_('bluebird');
-var TaskQueue = _dereq_('./taskqueue');
-
-function defaultCallback(err) {
-  if (err && global.debug) {
-    console.error(err);
-  }
-}
-utils.inherits(PouchDBVersion200, Adapter);
-function PouchDBVersion200(name, opts, callback) {
-
-  if (!(this instanceof PouchDBVersion200)) {
-    return new PouchDBVersion200(name, opts, callback);
-  }
-  var self = this;
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-  if (typeof callback === 'undefined') {
-    callback = defaultCallback;
-  }
-  opts = opts || {};
-  var oldCB = callback;
-  self.auto_compaction = opts.auto_compaction;
-  self.prefix = PouchDBVersion200.prefix;
-  Adapter.call(self);
-  self.taskqueue = new TaskQueue();
-  var promise = new Promise(function (fulfill, reject) {
-    callback = function (err, resp) {
-      if (err) {
-        return reject(err);
-      }
-      delete resp.then;
-      fulfill(resp);
-    };
-  
-    opts = utils.extend(true, {}, opts);
-    var originalName = opts.name || name;
-    var backend, error;
-    (function () {
-      try {
-
-        if (typeof originalName !== 'string') {
-          error = new Error('Missing/invalid DB name');
-          error.code = 400;
-          throw error;
-        }
-
-        backend = PouchDBVersion200.parseAdapter(originalName);
-        
-        opts.originalName = originalName;
-        opts.name = backend.name;
-        opts.adapter = opts.adapter || backend.adapter;
-
-        if (!PouchDBVersion200.adapters[opts.adapter]) {
-          error = new Error('Adapter is missing');
-          error.code = 404;
-          throw error;
-        }
-
-        if (!PouchDBVersion200.adapters[opts.adapter].valid()) {
-          error = new Error('Invalid Adapter');
-          error.code = 404;
-          throw error;
-        }
-      } catch (err) {
-        self.taskqueue.fail(err);
-        self.changes = utils.toPromise(function (opts) {
-          if (opts.complete) {
-            opts.complete(err);
-          }
-        });
-      }
-    }());
-    if (error) {
-      return reject(error); // constructor error, see above
-    }
-    self.adapter = opts.adapter;
-    // needs access to PouchDBVersion200;
-    self.replicate = PouchDBVersion200.replicate.bind(self, self);
-    self.replicate.from = function (url, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      return PouchDBVersion200.replicate(url, self, opts, callback);
-    };
-
-    self.replicate.to = function (dbName, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      return self.replicate(dbName, opts, callback);
-    };
-
-    self.replicate.sync = function (dbName, opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-      return PouchDBVersion200.sync(self, dbName, opts, callback);
-    };
-    self.destroy = utils.toPromise(function (callback) {
-      var self = this;
-      if (!self.taskqueue.isReady) {
-        self.taskqueue.addTask('destroy', arguments);
-        return;
-      }
-      self.id(function (err, id) {
-        if (err) {
-          return callback(err);
-        }
-        PouchDBVersion200.destroy(id, callback);
-      });
-    });
-    PouchDBVersion200.adapters[opts.adapter].call(self, opts, function (err, db) {
-      if (err) {
-        if (callback) {
-          self.taskqueue.fail(err);
-          callback(err);
-        }
-        return;
-      }
-      function destructionListner(event) {
-        if (event === 'destroyed') {
-          self.emit('destroyed');
-          PouchDBVersion200.removeListener(opts.name, destructionListner);
-        }
-      }
-      PouchDBVersion200.on(opts.name, destructionListner);
-      self.emit('created', self);
-      PouchDBVersion200.emit('created', opts.originalName);
-      self.taskqueue.ready(self);
-      callback(null, self);
-      
-    });
-    if (opts.skipSetup) {
-      self.taskqueue.ready(self);
-    }
-
-    if (utils.isCordova()) {
-      //to inform websql adapter that we can use api
-      cordova.fireWindowEvent(opts.name + "_pouch", {});
-    }
-  });
-  promise.then(function (resp) {
-    oldCB(null, resp);
-  }, oldCB);
-  self.then = promise.then.bind(promise);
-  //prevent deoptimizing
-  (function () {
-    try {
-      self.catch = promise.catch.bind(promise);
-    } catch (e) {}
-  }());
-}
-
-module.exports = PouchDBVersion200;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./adapter":1,"./taskqueue":17,"./utils":18,"bluebird":24}],6:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-var request = _dereq_('request');
-var extend = _dereq_('./extend.js');
-var createBlob = _dereq_('./blob.js');
-var errors = _dereq_('./errors');
-var uuid = _dereq_('../deps/uuid');
-
-function ajax(options, callback) {
-
-  if (typeof options === "function") {
-    callback = options;
-    options = {};
-  }
-  options = extend(true, {}, options);
-  function call(fun) {
-    /* jshint validthis: true */
-    var args = Array.prototype.slice.call(arguments, 1);
-    if (typeof fun === typeof Function) {
-      fun.apply(this, args);
-    }
-  }
-
-  var defaultOptions = {
-    method : "GET",
-    headers: {},
-    json: true,
-    processData: true,
-    timeout: 10000,
-    cache: false
-  };
-
-  options = extend(true, defaultOptions, options);
-
-  // cache-buster, specifically designed to work around IE's aggressive caching
-  // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/
-  if (options.method === 'GET' && !options.cache) {
-    var hasArgs = options.url.indexOf('?') !== -1;
-    options.url += (hasArgs ? '&' : '?') + '_nonce=' + uuid(16);
-  }
-
-  function onSuccess(obj, resp, cb) {
-    if (!options.binary && !options.json && options.processData &&
-      typeof obj !== 'string') {
-      obj = JSON.stringify(obj);
-    } else if (!options.binary && options.json && typeof obj === 'string') {
-      try {
-        obj = JSON.parse(obj);
-      } catch (e) {
-        // Probably a malformed JSON from server
-        call(cb, e);
-        return;
-      }
-    }
-    if (Array.isArray(obj)) {
-      obj = obj.map(function (v) {
-        var obj;
-        if (v.ok) {
-          return v;
-        } else if (v.error && v.error === 'conflict') {
-          obj = errors.REV_CONFLICT;
-          obj.id = v.id;
-          return obj;
-        } else if (v.error && v.error === 'forbidden') {
-          obj = errors.FORBIDDEN;
-          obj.id = v.id;
-          obj.reason = v.reason;
-          return obj;
-        } else if (v.missing) {
-          obj = errors.MISSING_DOC;
-          obj.missing = v.missing;
-          return obj;
-        } else {
-          return v;
-        }
-      });
-    }
-    call(cb, null, obj, resp);
-  }
-
-  function onError(err, cb) {
-    var errParsed, errObj, errType, key;
-    try {
-      errParsed = JSON.parse(err.responseText);
-      //would prefer not to have a try/catch clause
-      for (key in errors) {
-        if (errors.hasOwnProperty(key) && errors[key].name === errParsed.error) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType, errParsed.reason);
-    } catch (e) {
-      for (var key in errors) {
-        if (errors.hasOwnProperty(key) && errors[key].status === err.status) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType);
-    }
-    call(cb, errObj);
-  }
-
-  if (process.browser) {
-    var timer, timedout = false;
-    var xhr;
-    if (options.xhr) {
-      xhr = new options.xhr();
-    } else {
-      xhr = new XMLHttpRequest();
-    }
-    xhr.open(options.method, options.url);
-    xhr.withCredentials = true;
-
-    if (options.json) {
-      options.headers.Accept = 'application/json';
-      options.headers['Content-Type'] = options.headers['Content-Type'] ||
-        'application/json';
-      if (options.body && options.processData && typeof options.body !== "string") {
-        options.body = JSON.stringify(options.body);
-      }
-    }
-
-    if (options.binary) {
-      xhr.responseType = 'arraybuffer';
-    }
-
-    var createCookie = function (name, value, days) {
-      var expires = "";
-      if (days) {
-        var date = new Date();
-        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
-        expires = "; expires=" + date.toGMTString();
-      }
-      document.cookie = name + "=" + value + expires + "; path=/";
-    };
-
-    for (var key in options.headers) {
-      if (key === 'Cookie') {
-        var cookie = options.headers[key].split('=');
-        createCookie(cookie[0], cookie[1], 10);
-      } else {
-        xhr.setRequestHeader(key, options.headers[key]);
-      }
-    }
-
-    if (!("body" in options)) {
-      options.body = null;
-    }
-
-    var abortReq = function () {
-      timedout = true;
-      xhr.abort();
-      call(onError, xhr, callback);
-    };
-
-    xhr.onreadystatechange = function () {
-      if (xhr.readyState !== 4 || timedout) {
-        return;
-      }
-      clearTimeout(timer);
-      if (xhr.status >= 200 && xhr.status < 300) {
-        var data;
-        if (options.binary) {
-          data = createBlob([xhr.response || ''], {
-            type: xhr.getResponseHeader('Content-Type')
-          });
-        } else {
-          data = xhr.responseText;
-        }
-        call(onSuccess, data, xhr, callback);
-      } else {
-        call(onError, xhr, callback);
-      }
-    };
-
-    if (options.timeout > 0) {
-      timer = setTimeout(abortReq, options.timeout);
-      xhr.onprogress = function () {
-        clearTimeout(timer);
-        timer = setTimeout(abortReq, options.timeout);
-      };
-      if (xhr.upload) { // does not exist in ie9
-        xhr.upload.onprogress = xhr.onprogress;
-      }
-    }
-    xhr.send(options.body);
-    return {abort: abortReq};
-
-  } else {
-
-    if (options.json) {
-      if (!options.binary) {
-        options.headers.Accept = 'application/json';
-      }
-      options.headers['Content-Type'] = options.headers['Content-Type'] ||
-        'application/json';
-    }
-
-    if (options.binary) {
-      options.encoding = null;
-      options.json = false;
-    }
-
-    if (!options.processData) {
-      options.json = false;
-    }
-
-    return request(options, function (err, response, body) {
-      if (err) {
-        err.status = response ? response.statusCode : 400;
-        return call(onError, err, callback);
-      }
-      var error;
-      var content_type = response.headers['content-type'];
-      var data = (body || '');
-
-      // CouchDB doesn't always return the right content-type for JSON data, so
-      // we check for ^{ and }$ (ignoring leading/trailing whitespace)
-      if (!options.binary && (options.json || !options.processData) &&
-          typeof data !== 'object' &&
-          (/json/.test(content_type) ||
-           (/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
-        data = JSON.parse(data);
-      }
-
-      if (response.statusCode >= 200 && response.statusCode < 300) {
-        call(onSuccess, data, response, callback);
-      }
-      else {
-        if (options.binary) {
-          data = JSON.parse(data.toString());
-        }
-        if (data.reason === 'missing') {
-          error = errors.MISSING_DOC;
-        } else if (data.reason === 'no_db_file') {
-          error = errors.error(errors.DB_MISSING, data.reason);
-        } else if (data.error === 'conflict') {
-          error = errors.REV_CONFLICT;
-        } else {
-          error = errors.error(errors.UNKNOWN_ERROR, data.reason, data.error);
-        }
-        error.status = response.statusCode;
-        call(callback, error);
-      }
-    });
-  }
-}
-
-module.exports = ajax;
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"../deps/uuid":12,"./blob.js":7,"./errors":8,"./extend.js":10,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":22,"request":20}],7:[function(_dereq_,module,exports){
-(function (global){
-"use strict";
-
-//Abstracts constructing a Blob object, so it also works in older
-//browsers that don't support the native Blob constructor. (i.e.
-//old QtWebKit versions, at least).
-function createBlob(parts, properties) {
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var BlobBuilder = global.BlobBuilder || global.MSBlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder;
-    var builder = new BlobBuilder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
-  }
-}
-
-module.exports = createBlob;
-
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],8:[function(_dereq_,module,exports){
-"use strict";
-
-function PouchError(opts) {
-  this.status = opts.status;
-  this.name = opts.error;
-  this.message = opts.reason;
-  this.error = true;
-}
-
-PouchError.prototype__proto__ = Error.prototype;
-
-PouchError.prototype.toString = function () {
-  return JSON.stringify({
-    status: this.status,
-    name: this.name,
-    message: this.message
-  });
-};
-
-exports.UNAUTHORIZED = new PouchError({
-  status: 401,
-  error: 'unauthorized',
-  reason: "Name or password is incorrect."
-});
-exports.MISSING_BULK_DOCS = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: "Missing JSON list of 'docs'"
-});
-exports.MISSING_DOC = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'missing'
-});
-exports.REV_CONFLICT = new PouchError({
-  status: 409,
-  error: 'conflict',
-  reason: 'Document update conflict'
-});
-exports.INVALID_ID = new PouchError({
-  status: 400,
-  error: 'invalid_id',
-  reason: '_id field must contain a string'
-});
-exports.MISSING_ID = new PouchError({
-  status: 412,
-  error: 'missing_id',
-  reason: '_id is required for puts'
-});
-exports.RESERVED_ID = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Only reserved document ids may start with underscore.'
-});
-exports.NOT_OPEN = new PouchError({
-  status: 412,
-  error: 'precondition_failed',
-  reason: 'Database not open so cannot close'
-});
-exports.UNKNOWN_ERROR = new PouchError({
-  status: 500,
-  error: 'unknown_error',
-  reason: 'Database encountered an unknown error'
-});
-exports.BAD_ARG = new PouchError({
-  status: 500,
-  error: 'badarg',
-  reason: 'Some query argument is invalid'
-});
-exports.INVALID_REQUEST = new PouchError({
-  status: 400,
-  error: 'invalid_request',
-  reason: 'Request was invalid'
-});
-exports.QUERY_PARSE_ERROR = new PouchError({
-  status: 400,
-  error: 'query_parse_error',
-  reason: 'Some query parameter is invalid'
-});
-exports.DOC_VALIDATION = new PouchError({
-  status: 500,
-  error: 'doc_validation',
-  reason: 'Bad special document member'
-});
-exports.BAD_REQUEST = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Something wrong with the request'
-});
-exports.NOT_AN_OBJECT = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Document must be a JSON object'
-});
-exports.DB_MISSING = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'Database not found'
-});
-exports.IDB_ERROR = new PouchError({
-  status: 500,
-  error: 'indexed_db_went_bad',
-  reason: 'unknown'
-});
-exports.WSQ_ERROR = new PouchError({
-  status: 500,
-  error: 'web_sql_went_bad',
-  reason: 'unknown'
-});
-exports.LDB_ERROR = new PouchError({
-  status: 500,
-  error: 'levelDB_went_went_bad',
-  reason: 'unknown'
-});
-exports.FORBIDDEN = new PouchError({
-  status: 403,
-  error: 'forbidden',
-  reason: 'Forbidden by design doc validate_doc_update function'
-});
-exports.error = function (error, reason, name) {
-  function CustomPouchError(msg) {
-    this.message = reason;
-    if (name) {
-      this.name = name;
-    }
-  }
-  CustomPouchError.prototype = error;
-  return new CustomPouchError(reason);
-};
-
-},{}],9:[function(_dereq_,module,exports){
-// some small shims for es5 just for the features we commonly use
-// some of this is copied from https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
-'use strict';
-
-if (!Object.keys) {
-  Object.keys = function keys(object) {
-
-    if ((typeof object !== 'object' && typeof object !== 'function') || object === null) {
-      throw new TypeError('Object.keys called on a non-object');
-    }
-
-    var mykeys = [];
-    for (var name in object) {
-      if (Object.prototype.hasOwnProperty.call(object, name)) {
-        mykeys.push(name);
-      }
-    }
-    return mykeys;
-  };
-}
-
-if (!Array.isArray) {
-  Array.isArray = function isArray(obj) {
-    return Object.prototype.toString.call(obj) === '[object Array]';
-  };
-}
-
-if (!('forEach' in Array.prototype)) {
-  Array.prototype.forEach = function (action, that /*opt*/) {
-    for (var i = 0, n = this.length; i < n; i++) {
-      if (i in this) {
-        action.call(that, this[i], i, this);
-      }
-    }
-  };
-}
-
-if (!('map' in Array.prototype)) {
-  Array.prototype.map = function (mapper, that /*opt*/) {
-    var other = new Array(this.length);
-    for (var i = 0, n = this.length; i < n; i++) {
-      if (i in this) {
-        other[i] = mapper.call(that, this[i], i, this);
-      }
-    }
-    return other;
-  };
-}
-
-},{}],10:[function(_dereq_,module,exports){
-"use strict";
-
-// Extends method
-// (taken from http://code.jquery.com/jquery-1.9.0.js)
-// Populate the class2type map
-var class2type = {};
-
-var types = ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object", "Error"];
-for (var i = 0; i < types.length; i++) {
-  var typename = types[i];
-  class2type["[object " + typename + "]"] = typename.toLowerCase();
-}
-
-var core_toString = class2type.toString;
-var core_hasOwn = class2type.hasOwnProperty;
-
-function type(obj) {
-  if (obj === null) {
-    return String(obj);
-  }
-  return typeof obj === "object" || typeof obj === "function" ?
-    class2type[core_toString.call(obj)] || "object" :
-    typeof obj;
-}
-
-function isWindow(obj) {
-  return obj !== null && obj === obj.window;
-}
-
-function isPlainObject(obj) {
-  // Must be an Object.
-  // Because of IE, we also have to check the presence of the constructor property.
-  // Make sure that DOM nodes and window objects don't pass through, as well
-  if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
-    return false;
-  }
-
-  try {
-    // Not own constructor property must be Object
-    if (obj.constructor &&
-      !core_hasOwn.call(obj, "constructor") &&
-      !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
-      return false;
-    }
-  } catch ( e ) {
-    // IE8,9 Will throw exceptions on certain host objects #9897
-    return false;
-  }
-
-  // Own properties are enumerated firstly, so to speed up,
-  // if last one is own, then all properties are own.
-  var key;
-  for (key in obj) {}
-
-  return key === undefined || core_hasOwn.call(obj, key);
-}
-
-
-function isFunction(obj) {
-  return type(obj) === "function";
-}
-
-var isArray = Array.isArray || function (obj) {
-  return type(obj) === "array";
-};
-
-function extend() {
-  var options, name, src, copy, copyIsArray, clone,
-    target = arguments[0] || {},
-    i = 1,
-    length = arguments.length,
-    deep = false;
-
-  // Handle a deep copy situation
-  if (typeof target === "boolean") {
-    deep = target;
-    target = arguments[1] || {};
-    // skip the boolean and the target
-    i = 2;
-  }
-
-  // Handle case when target is a string or something (possible in deep copy)
-  if (typeof target !== "object" && !isFunction(target)) {
-    target = {};
-  }
-
-  // extend jQuery itself if only one argument is passed
-  if (length === i) {
-    /* jshint validthis: true */
-    target = this;
-    --i;
-  }
-
-  for (; i < length; i++) {
-    // Only deal with non-null/undefined values
-    if ((options = arguments[i]) != null) {
-      // Extend the base object
-      for (name in options) {
-        //if (options.hasOwnProperty(name)) {
-        if (!(name in Object.prototype)) {
-
-          src = target[name];
-          copy = options[name];
-
-          // Prevent never-ending loop
-          if (target === copy) {
-            continue;
-          }
-
-          // Recurse if we're merging plain objects or arrays
-          if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
-            if (copyIsArray) {
-              copyIsArray = false;
-              clone = src && isArray(src) ? src : [];
-
-            } else {
-              clone = src && isPlainObject(src) ? src : {};
-            }
-
-            // Never move original objects, clone them
-            target[name] = extend(deep, clone, copy);
-
-          // Don't bring in undefined values
-          } else if (copy !== undefined) {
-            if (!(isArray(options) && isFunction(copy))) {
-              target[name] = copy;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // Return the modified object
-  return target;
-}
-
-
-module.exports = extend;
-
-
-},{}],11:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-/**
-*
-*  MD5 (Message-Digest Algorithm)
-*
-*  For original source see http://www.webtoolkit.info/
-*  Download: 15.02.2009 from http://www.webtoolkit.info/javascript-md5.html
-*
-*  Licensed under CC-BY 2.0 License
-*  (http://creativecommons.org/licenses/by/2.0/uk/)
-*
-**/
-var crypto = _dereq_('crypto');
-
-exports.MD5 = function (string) {
-  if (!process.browser) {
-    return crypto.createHash('md5').update(string).digest('hex');
-  }
-  function rotateLeft(lValue, iShiftBits) {
-    return (lValue<<iShiftBits) | (lValue>>>(32 - iShiftBits));
-  }
-
-  function addUnsigned(lX, lY) {
-    var lX4, lY4, lX8, lY8, lResult;
-    lX8 = (lX & 0x80000000);
-    lY8 = (lY & 0x80000000);
-    lX4 = (lX & 0x40000000);
-    lY4 = (lY & 0x40000000);
-    lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
-    if (lX4 & lY4) {
-      return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
-    }
-    if (lX4 | lY4) {
-      if (lResult & 0x40000000) {
-        return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
-      } else {
-        return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
-      }
-    } else {
-      return (lResult ^ lX8 ^ lY8);
-    }
-  }
-
-  function f(x, y, z) { return (x & y) | ((~x) & z); }
-  function g(x, y, z) { return (x & z) | (y & (~z)); }
-  function h(x, y, z) { return (x ^ y ^ z); }
-  function i(x, y, z) { return (y ^ (x | (~z))); }
-
-  function ff(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function gg(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function hh(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function ii(a, b, c, d, x, s, ac) {
-    a = addUnsigned(a, addUnsigned(addUnsigned(i(b, c, d), x), ac));
-    return addUnsigned(rotateLeft(a, s), b);
-  }
-
-  function convertToWordArray(string) {
-    var lWordCount;
-    var lMessageLength = string.length;
-    var lNumberOfWords_temp1 = lMessageLength + 8;
-    var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
-    var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
-    var lWordArray = new Array(lNumberOfWords - 1);
-    var lBytePosition = 0;
-    var lByteCount = 0;
-    while (lByteCount < lMessageLength) {
-      lWordCount = (lByteCount - (lByteCount % 4)) / 4;
-      lBytePosition = (lByteCount % 4) * 8;
-      lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
-      lByteCount++;
-    }
-    lWordCount = (lByteCount - (lByteCount % 4)) / 4;
-    lBytePosition = (lByteCount % 4) * 8;
-    lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
-    lWordArray[lNumberOfWords - 2] = lMessageLength<<3;
-    lWordArray[lNumberOfWords - 1] = lMessageLength>>>29;
-    return lWordArray;
-  }
-
-  function wordToHex(lValue) {
-    var   wordToHexValue = "",   wordToHexValue_temp = "", lByte, lCount;
-    for (lCount = 0;lCount <= 3;lCount++) {
-      lByte = (lValue>>>(lCount * 8)) & 255;
-      wordToHexValue_temp = "0" + lByte.toString(16);
-      wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
-    }
-    return   wordToHexValue;
-  }
-
-  //**	function Utf8Encode(string) removed. Aready defined in pidcrypt_utils.js
-
-  var x = [];
-  var k, AA, BB, CC, DD, a, b, c, d;
-  var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
-  var S21 = 5, S22 = 9,  S23 = 14, S24 = 20;
-  var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
-  var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
-
-  //	string = Utf8Encode(string); #function call removed
-
-  x = convertToWordArray(string);
-
-  a = 0x67452301;
-  b = 0xEFCDAB89;
-  c = 0x98BADCFE;
-  d = 0x10325476;
-
-  for (k = 0;k < x.length;k += 16) {
-    AA = a;
-    BB = b;
-    CC = c;
-    DD = d;
-    a = ff(a, b, c, d, x[k + 0],  S11, 0xD76AA478);
-    d = ff(d, a, b, c, x[k + 1],  S12, 0xE8C7B756);
-    c = ff(c, d, a, b, x[k + 2],  S13, 0x242070DB);
-    b = ff(b, c, d, a, x[k + 3],  S14, 0xC1BDCEEE);
-    a = ff(a, b, c, d, x[k + 4],  S11, 0xF57C0FAF);
-    d = ff(d, a, b, c, x[k + 5],  S12, 0x4787C62A);
-    c = ff(c, d, a, b, x[k + 6],  S13, 0xA8304613);
-    b = ff(b, c, d, a, x[k + 7],  S14, 0xFD469501);
-    a = ff(a, b, c, d, x[k + 8],  S11, 0x698098D8);
-    d = ff(d, a, b, c, x[k + 9],  S12, 0x8B44F7AF);
-    c = ff(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
-    b = ff(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
-    a = ff(a, b, c, d, x[k + 12], S11, 0x6B901122);
-    d = ff(d, a, b, c, x[k + 13], S12, 0xFD987193);
-    c = ff(c, d, a, b, x[k + 14], S13, 0xA679438E);
-    b = ff(b, c, d, a, x[k + 15], S14, 0x49B40821);
-    a = gg(a, b, c, d, x[k + 1],  S21, 0xF61E2562);
-    d = gg(d, a, b, c, x[k + 6],  S22, 0xC040B340);
-    c = gg(c, d, a, b, x[k + 11], S23, 0x265E5A51);
-    b = gg(b, c, d, a, x[k + 0],  S24, 0xE9B6C7AA);
-    a = gg(a, b, c, d, x[k + 5],  S21, 0xD62F105D);
-    d = gg(d, a, b, c, x[k + 10], S22, 0x2441453);
-    c = gg(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
-    b = gg(b, c, d, a, x[k + 4],  S24, 0xE7D3FBC8);
-    a = gg(a, b, c, d, x[k + 9],  S21, 0x21E1CDE6);
-    d = gg(d, a, b, c, x[k + 14], S22, 0xC33707D6);
-    c = gg(c, d, a, b, x[k + 3],  S23, 0xF4D50D87);
-    b = gg(b, c, d, a, x[k + 8],  S24, 0x455A14ED);
-    a = gg(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
-    d = gg(d, a, b, c, x[k + 2],  S22, 0xFCEFA3F8);
-    c = gg(c, d, a, b, x[k + 7],  S23, 0x676F02D9);
-    b = gg(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
-    a = hh(a, b, c, d, x[k + 5],  S31, 0xFFFA3942);
-    d = hh(d, a, b, c, x[k + 8],  S32, 0x8771F681);
-    c = hh(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
-    b = hh(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
-    a = hh(a, b, c, d, x[k + 1],  S31, 0xA4BEEA44);
-    d = hh(d, a, b, c, x[k + 4],  S32, 0x4BDECFA9);
-    c = hh(c, d, a, b, x[k + 7],  S33, 0xF6BB4B60);
-    b = hh(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
-    a = hh(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
-    d = hh(d, a, b, c, x[k + 0],  S32, 0xEAA127FA);
-    c = hh(c, d, a, b, x[k + 3],  S33, 0xD4EF3085);
-    b = hh(b, c, d, a, x[k + 6],  S34, 0x4881D05);
-    a = hh(a, b, c, d, x[k + 9],  S31, 0xD9D4D039);
-    d = hh(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
-    c = hh(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
-    b = hh(b, c, d, a, x[k + 2],  S34, 0xC4AC5665);
-    a = ii(a, b, c, d, x[k + 0],  S41, 0xF4292244);
-    d = ii(d, a, b, c, x[k + 7],  S42, 0x432AFF97);
-    c = ii(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
-    b = ii(b, c, d, a, x[k + 5],  S44, 0xFC93A039);
-    a = ii(a, b, c, d, x[k + 12], S41, 0x655B59C3);
-    d = ii(d, a, b, c, x[k + 3],  S42, 0x8F0CCC92);
-    c = ii(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
-    b = ii(b, c, d, a, x[k + 1],  S44, 0x85845DD1);
-    a = ii(a, b, c, d, x[k + 8],  S41, 0x6FA87E4F);
-    d = ii(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
-    c = ii(c, d, a, b, x[k + 6],  S43, 0xA3014314);
-    b = ii(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
-    a = ii(a, b, c, d, x[k + 4],  S41, 0xF7537E82);
-    d = ii(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
-    c = ii(c, d, a, b, x[k + 2],  S43, 0x2AD7D2BB);
-    b = ii(b, c, d, a, x[k + 9],  S44, 0xEB86D391);
-    a = addUnsigned(a, AA);
-    b = addUnsigned(b, BB);
-    c = addUnsigned(c, CC);
-    d = addUnsigned(d, DD);
-  }
-  var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
-  return temp.toLowerCase();
-};
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":22,"crypto":20}],12:[function(_dereq_,module,exports){
-"use strict";
-
-// BEGIN Math.uuid.js
-
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- *   length - the desired number of characters
- *   radix  - the number of allowable values for each character.
- *
- * EXAMPLES:
- *   // No arguments  - returns RFC4122, version 4 ID
- *   >>> Math.uuid()
- *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- *   // One argument - returns ID of the specified length
- *   >>> Math.uuid(15)     // 15 character ID (default base=62)
- *   "VcydxgltxrVZSTV"
- *
- *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
- *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
- *   "01001010"
- *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
- *   "47473046"
- *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
- *   "098F4D35"
- */
-
-
-function uuid(len, radix) {
-  var chars = uuid.CHARS;
-  var uuidInner = [];
-  var i;
-
-  radix = radix || chars.length;
-
-  if (len) {
-    // Compact form
-    for (i = 0; i < len; i++) {
-      uuidInner[i] = chars[0 | Math.random() * radix];
-    }
-  } else {
-    // rfc4122, version 4 form
-    var r;
-
-    // rfc4122 requires these characters
-    uuidInner[8] = uuidInner[13] = uuidInner[18] = uuidInner[23] = '-';
-    uuidInner[14] = '4';
-
-    // Fill in random data.  At i==19 set the high bits of clock sequence as
-    // per rfc4122, sec. 4.1.5
-    for (i = 0; i < 36; i++) {
-      if (!uuidInner[i]) {
-        r = 0 | Math.random() * 16;
-        uuidInner[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
-      }
-    }
-  }
-
-  return uuidInner.join('');
-}
-
-uuid.CHARS = (
-  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
-  'abcdefghijklmnopqrstuvwxyz'
-).split('');
-
-module.exports = uuid;
-
-
-},{}],13:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-_dereq_('./deps/es5_shims');
-
-var PouchDBVersion200 = _dereq_('./setup');
-
-module.exports = PouchDBVersion200;
-
-PouchDBVersion200.ajax = _dereq_('./deps/ajax');
-PouchDBVersion200.extend = _dereq_('./deps/extend');
-PouchDBVersion200.utils = _dereq_('./utils');
-PouchDBVersion200.Errors = _dereq_('./deps/errors');
-var replicate = _dereq_('./replicate');
-PouchDBVersion200.replicate = replicate.replicate;
-PouchDBVersion200.sync = replicate.sync;
-PouchDBVersion200.version = _dereq_('./version');
-var httpAdapter = _dereq_('./adapters/http');
-PouchDBVersion200.adapter('http', httpAdapter);
-PouchDBVersion200.adapter('https', httpAdapter);
-
-PouchDBVersion200.adapter('idb', _dereq_('./adapters/idb'));
-PouchDBVersion200.adapter('websql', _dereq_('./adapters/websql'));
-PouchDBVersion200.plugin(_dereq_('pouchdb-mapreduce'));
-
-if (!process.browser) {
-  var ldbAdapter = _dereq_('./adapters/leveldb');
-  PouchDBVersion200.adapter('ldb', ldbAdapter);
-  PouchDBVersion200.adapter('leveldb', ldbAdapter);
-}
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"./adapters/http":2,"./adapters/idb":3,"./adapters/leveldb":20,"./adapters/websql":4,"./deps/ajax":6,"./deps/errors":8,"./deps/es5_shims":9,"./deps/extend":10,"./replicate":15,"./setup":16,"./utils":18,"./version":19,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":22,"pouchdb-mapreduce":35}],14:[function(_dereq_,module,exports){
-'use strict';
-
-var extend = _dereq_('./deps/extend');
-
-
-// for a better overview of what this is doing, read:
-// https://github.com/apache/couchdb/blob/master/src/couchdb/couch_key_tree.erl
-//
-// But for a quick intro, CouchDB uses a revision tree to store a documents
-// history, A -> B -> C, when a document has conflicts, that is a branch in the
-// tree, A -> (B1 | B2 -> C), We store these as a nested array in the format
-//
-// KeyTree = [Path ... ]
-// Path = {pos: position_from_root, ids: Tree}
-// Tree = [Key, Opts, [Tree, ...]], in particular single node: [Key, []]
-
-// Turn a path as a flat array into a tree with a single branch
-function pathToTree(path) {
-  var doc = path.shift();
-  var root = [doc.id, doc.opts, []];
-  var leaf = root;
-  var nleaf;
-
-  while (path.length) {
-    doc = path.shift();
-    nleaf = [doc.id, doc.opts, []];
-    leaf[2].push(nleaf);
-    leaf = nleaf;
-  }
-  return root;
-}
-
-// Merge two trees together
-// The roots of tree1 and tree2 must be the same revision
-function mergeTree(in_tree1, in_tree2) {
-  var queue = [{tree1: in_tree1, tree2: in_tree2}];
-  var conflicts = false;
-  while (queue.length > 0) {
-    var item = queue.pop();
-    var tree1 = item.tree1;
-    var tree2 = item.tree2;
-
-    if (tree1[1].status || tree2[1].status) {
-      tree1[1].status = (tree1[1].status ===  'available' ||
-                         tree2[1].status === 'available') ? 'available' : 'missing';
-    }
-
-    for (var i = 0; i < tree2[2].length; i++) {
-      if (!tree1[2][0]) {
-        conflicts = 'new_leaf';
-        tree1[2][0] = tree2[2][i];
-        continue;
-      }
-
-      var merged = false;
-      for (var j = 0; j < tree1[2].length; j++) {
-        if (tree1[2][j][0] === tree2[2][i][0]) {
-          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
-          merged = true;
-        }
-      }
-      if (!merged) {
-        conflicts = 'new_branch';
-        tree1[2].push(tree2[2][i]);
-        tree1[2].sort();
-      }
-    }
-  }
-  return {conflicts: conflicts, tree: in_tree1};
-}
-
-function doMerge(tree, path, dontExpand) {
-  var restree = [];
-  var conflicts = false;
-  var merged = false;
-  var res;
-
-  if (!tree.length) {
-    return {tree: [path], conflicts: 'new_leaf'};
-  }
-
-  tree.forEach(function (branch) {
-    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
-      // Paths start at the same position and have the same root, so they need
-      // merged
-      res = mergeTree(branch.ids, path.ids);
-      restree.push({pos: branch.pos, ids: res.tree});
-      conflicts = conflicts || res.conflicts;
-      merged = true;
-    } else if (dontExpand !== true) {
-      // The paths start at a different position, take the earliest path and
-      // traverse up until it as at the same point from root as the path we want to
-      // merge.  If the keys match we return the longer path with the other merged
-      // After stemming we dont want to expand the trees
-
-      var t1 = branch.pos < path.pos ? branch : path;
-      var t2 = branch.pos < path.pos ? path : branch;
-      var diff = t2.pos - t1.pos;
-
-      var candidateParents = [];
-
-      var trees = [];
-      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
-      while (trees.length > 0) {
-        var item = trees.pop();
-        if (item.diff === 0) {
-          if (item.ids[0] === t2.ids[0]) {
-            candidateParents.push(item);
-          }
-          continue;
-        }
-        if (!item.ids) {
-          continue;
-        }
-        /*jshint loopfunc:true */
-        item.ids[2].forEach(function (el, idx) {
-          trees.push({ids: el, diff: item.diff - 1, parent: item.ids, parentIdx: idx});
-        });
-      }
-
-      var el = candidateParents[0];
-
-      if (!el) {
-        restree.push(branch);
-      } else {
-        res = mergeTree(el.ids, t2.ids);
-        el.parent[2][el.parentIdx] = res.tree;
-        restree.push({pos: t1.pos, ids: t1.ids});
-        conflicts = conflicts || res.conflicts;
-        merged = true;
-      }
-    } else {
-      restree.push(branch);
-    }
-  });
-
-  // We didnt find
-  if (!merged) {
-    restree.push(path);
-  }
-
-  restree.sort(function (a, b) {
-    return a.pos - b.pos;
-  });
-
-  return {
-    tree: restree,
-    conflicts: conflicts || 'internal_node'
-  };
-}
-
-// To ensure we dont grow the revision tree infinitely, we stem old revisions
-function stem(tree, depth) {
-  // First we break out the tree into a complete list of root to leaf paths,
-  // we cut off the start of the path and generate a new set of flat trees
-  var stemmedPaths = PouchMerge.rootToLeaf(tree).map(function (path) {
-    var stemmed = path.ids.slice(-depth);
-    return {
-      pos: path.pos + (path.ids.length - stemmed.length),
-      ids: pathToTree(stemmed)
-    };
-  });
-  // Then we remerge all those flat trees together, ensuring that we dont
-  // connect trees that would go beyond the depth limit
-  return stemmedPaths.reduce(function (prev, current, i, arr) {
-    return doMerge(prev, current, true).tree;
-  }, [stemmedPaths.shift()]);
-}
-
-var PouchMerge = {};
-
-PouchMerge.merge = function (tree, path, depth) {
-  // Ugh, nicer way to not modify arguments in place?
-  tree = extend(true, [], tree);
-  path = extend(true, {}, path);
-  var newTree = doMerge(tree, path);
-  return {
-    tree: stem(newTree.tree, depth),
-    conflicts: newTree.conflicts
-  };
-};
-
-// We fetch all leafs of the revision tree, and sort them based on tree length
-// and whether they were deleted, undeleted documents with the longest revision
-// tree (most edits) win
-// The final sort algorithm is slightly documented in a sidebar here:
-// http://guide.couchdb.org/draft/conflicts.html
-PouchMerge.winningRev = function (metadata) {
-  var leafs = [];
-  PouchMerge.traverseRevTree(metadata.rev_tree,
-                              function (isLeaf, pos, id, something, opts) {
-    if (isLeaf) {
-      leafs.push({pos: pos, id: id, deleted: !!opts.deleted});
-    }
-  });
-  leafs.sort(function (a, b) {
-    if (a.deleted !== b.deleted) {
-      return a.deleted > b.deleted ? 1 : -1;
-    }
-    if (a.pos !== b.pos) {
-      return b.pos - a.pos;
-    }
-    return a.id < b.id ? 1 : -1;
-  });
-
-  return leafs[0].pos + '-' + leafs[0].id;
-};
-
-// Pretty much all below can be combined into a higher order function to
-// traverse revisions
-// The return value from the callback will be passed as context to all
-// children of that node
-PouchMerge.traverseRevTree = function (revs, callback) {
-  var toVisit = [];
-
-  revs.forEach(function (tree) {
-    toVisit.push({pos: tree.pos, ids: tree.ids});
-  });
-  while (toVisit.length > 0) {
-    var node = toVisit.pop();
-    var pos = node.pos;
-    var tree = node.ids;
-    var newCtx = callback(tree[2].length === 0, pos, tree[0], node.ctx, tree[1]);
-    /*jshint loopfunc: true */
-    tree[2].forEach(function (branch) {
-      toVisit.push({pos: pos + 1, ids: branch, ctx: newCtx});
-    });
-  }
-};
-
-PouchMerge.collectLeaves = function (revs) {
-  var leaves = [];
-  PouchMerge.traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
-    if (isLeaf) {
-      leaves.unshift({rev: pos + "-" + id, pos: pos, opts: opts});
-    }
-  });
-  leaves.sort(function (a, b) {
-    return b.pos - a.pos;
-  });
-  leaves.map(function (leaf) { delete leaf.pos; });
-  return leaves;
-};
-
-// returns revs of all conflicts that is leaves such that
-// 1. are not deleted and
-// 2. are different than winning revision
-PouchMerge.collectConflicts = function (metadata) {
-  var win = PouchMerge.winningRev(metadata);
-  var leaves = PouchMerge.collectLeaves(metadata.rev_tree);
-  var conflicts = [];
-  leaves.forEach(function (leaf) {
-    if (leaf.rev !== win && !leaf.opts.deleted) {
-      conflicts.push(leaf.rev);
-    }
-  });
-  return conflicts;
-};
-
-PouchMerge.rootToLeaf = function (tree) {
-  var paths = [];
-  PouchMerge.traverseRevTree(tree, function (isLeaf, pos, id, history, opts) {
-    history = history ? history.slice(0) : [];
-    history.push({id: id, opts: opts});
-    if (isLeaf) {
-      var rootPos = pos + 1 - history.length;
-      paths.unshift({pos: rootPos, ids: history});
-    }
-    return history;
-  });
-  return paths;
-};
-
-
-module.exports = PouchMerge;
-
-},{"./deps/extend":10}],15:[function(_dereq_,module,exports){
-'use strict';
-
-var PouchUtils = _dereq_('./utils');
-var Pouch = _dereq_('./index');
-
-// We create a basic promise so the caller can cancel the replication possibly
-// before we have actually started listening to changes etc
-function Promise() {
-  var that = this;
-  this.cancelled = false;
-  this.cancel = function () {
-    that.cancelled = true;
-  };
-}
-
-
-// A batch of changes to be processed as a unit
-function Batch() {
-  this.seq = 0;
-  this.state = 'start';
-  this.changes = [];
-  this.docs = [];
-}
-
-
-// TODO: check CouchDB's replication id generation
-// Generate a unique id particular to this replication
-function genReplicationId(src, target, opts, callback) {
-  var filterFun = opts.filter ? opts.filter.toString() : '';
-  src.id(function (err, src_id) {
-    target.id(function (err, target_id) {
-      var queryData = src_id + target_id + filterFun +
-        JSON.stringify(opts.query_params);
-      callback('_local/' + PouchUtils.Crypto.MD5(queryData));
-    });
-  });
-}
-
-
-// A checkpoint lets us restart replications from when they were last cancelled
-function fetchCheckpoint(src, target, id, callback) {
-  target.get(id, function (err, targetDoc) {
-    if (err && err.status === 404) {
-      callback(null, 0);
-    } else if (err) {
-      callback(err);
-    } else {
-      src.get(id, function (err, sourceDoc) {
-        if (err && err.status === 404 ||
-            (!err && (targetDoc.last_seq !== sourceDoc.last_seq))) {
-          callback(null, 0);
-        } else if (err) {
-          callback(err);
-        } else {
-          callback(null, sourceDoc.last_seq);
-        }
-      });
-    }
-  });
-}
-
-
-function writeCheckpoint(src, target, id, checkpoint, callback) {
-  function updateCheckpoint(db, callback) {
-    db.get(id, function (err, doc) {
-      if (err && err.status === 404) {
-        doc = {_id: id};
-      } else if (err) {
-        return callback(err);
-      }
-      doc.last_seq = checkpoint;
-      db.put(doc, callback);
-    });
-  }
-  updateCheckpoint(target, function (err, doc) {
-    updateCheckpoint(src, function (err, doc) {
-      callback();
-    });
-  });
-}
-
-
-function replicate(repId, src, target, opts, promise) {
-  var batches = [];     // queue of batches of changes to be processed
-  var pendingBatch = new Batch();
-  var changesCompleted = false;
-  var completeCalled = false;
-  var last_seq = 0;
-  var continuous = opts.continuous || false;
-  var batch_size = opts.batch_size || 1;
-  var doc_ids = opts.doc_ids;
-  var result = {
-    ok: true,
-    start_time: new Date(),
-    docs_read: 0,
-    docs_written: 0,
-    errors: []
-  };
-
-
-  function writeDocs() {
-    if (batches[0].docs.length === 0) {
-      // This should never happen:
-      // batch processing continues past onRevsDiff only if there are diffs
-      // and replication is aborted if a get fails.
-      // TODO: throw or log the error
-      return finishBatch();
-    }
-
-    var docs = batches[0].docs;
-    target.bulkDocs({docs: docs}, {new_edits: false}, function (err, res) {
-      if (err) {
-        return abortReplication('target.bulkDocs completed with error', err);
-      }
-
-      result.docs_written += docs.length;
-      finishBatch();
-    });
-  }
-
-
-  function onGet(err, docs) {
-    if (promise.cancelled) {
-      return replicationCancelled();
-    }
-
-    if (err) {
-      return abortReplication('src.get completed with error', err);
-    }
-
-    Object.keys(docs).forEach(function (revpos) {
-      var doc = docs[revpos].ok;
-
-      if (doc) {
-        result.docs_read++;
-        batches[0].pendingRevs++;
-        batches[0].docs.push(doc);
-      }
-    });
-
-    fetchRev();
-  }
-
-
-  function fetchRev() {
-    var diffs = batches[0].diffs;
-
-    if (Object.keys(diffs).length === 0) {
-      writeDocs();
-      return;
-    }
-
-    var id = Object.keys(diffs)[0];
-    var revs = diffs[id].missing;
-    delete diffs[id];
-
-    src.get(id, {revs: true, open_revs: revs, attachments: true}, onGet);
-  }
-
-
-  function abortReplication(reason, err) {
-    if (completeCalled) {
-      return;
-    }
-    result.ok = false;
-    result.status = 'aborted';
-    result.errors.push(err);
-    result.end_time = new Date();
-    result.last_seq = last_seq;
-    promise.cancel();
-    batches = [];
-    pendingBatch = new Batch();
-    var error = {
-      status: 500,
-      error: 'Replication aborted',
-      reason: reason,
-      details: err
-    };
-    completeCalled = true;
-    PouchUtils.call(opts.complete, error, result);
-  }
-
-
-  function finishBatch() {
-    writeCheckpoint(src, target, repId, batches[0].seq, function (err, res) {
-      if (err) {
-        return abortReplication('writeCheckpoint completed with error', err);
-      }
-      last_seq = batches[0].seq;
-      result.last_seq = last_seq;
-      PouchUtils.call(opts.onChange, null, result);
-      batches.shift();
-      startNextBatch();
-    });
-  }
-
-  function onRevsDiff(err, diffs) {
-    if (promise.cancelled) {
-      return replicationCancelled();
-    }
-
-    if (err) {
-      return abortReplication('target.revsDiff completed with error', err);
-    }
-
-    if (Object.keys(diffs).length === 0) {
-      finishBatch();
-      return;
-    }
-
-    batches[0].diffs = diffs;
-    batches[0].pendingRevs = 0;
-    fetchRev();
-  }
-
-
-  function fetchRevsDiff() {
-    var diff = {};
-    batches[0].changes.forEach(function (change) {
-      diff[change.id] = change.changes.map(function (x) { return x.rev; });
-    });
-
-    target.revsDiff(diff, onRevsDiff);
-  }
-
-
-  function startNextBatch() {
-    if (promise.cancelled) {
-      return replicationCancelled();
-    }
-
-    if (batches.length === 0) {
-      processPendingBatch();
-      return;
-    }
-
-    if (batches[0].state === 'start') {
-      batches[0].state = 'processing';
-      fetchRevsDiff();
-    }
-  }
-
-
-  function processPendingBatch() {
-    if (pendingBatch.changes.length === 0) {
-      if (changesCompleted && batches.length === 0) {
-        replicationComplete();
-      }
-      return;
-    }
-
-    if (changesCompleted || pendingBatch.changes.length >= batch_size) {
-      batches.push(pendingBatch);
-      pendingBatch = new Batch();
-      startNextBatch();
-    }
-  }
-
-
-  function replicationCancelled() {
-    result.status = 'cancelled';
-    replicationComplete();
-  }
-
-  
-  function replicationComplete() {
-    if (completeCalled) {
-      return;
-    }
-    result.status = result.status || 'complete';
-    result.end_time = new Date();
-    result.last_seq = last_seq;
-    completeCalled = true;
-    return PouchUtils.call(opts.complete, null, result);
-  }
-
-
-  function onChange(change) {
-    if (promise.cancelled) {
-      return replicationCancelled();
-    }
-
-    if (completeCalled) {
-      // This should never happen
-      // The complete callback has already been called
-      // How to raise an exception in PouchDBVersion200?
-      return;
-    }
-
-    pendingBatch.seq = change.seq;
-    pendingBatch.changes.push(change);
-
-    processPendingBatch();
-  }
-
-
-  function complete(err, result) {
-    changesCompleted = true;
-    if (promise.cancelled) {
-      return replicationCancelled();
-    }
-
-    if (err) {
-      return abortReplication('src.changes completed with error', err);
-    }
-
-    processPendingBatch();
-  }
-
-
-  function getChanges() {
-    fetchCheckpoint(src, target, repId, function (err, checkpoint) {
-      if (err) {
-        return abortReplication('fetchCheckpoint completed with error', err);
-      }
-
-      last_seq = checkpoint;
-
-      // Was the replication cancelled by the caller before it had a chance
-      // to start. Shouldnt we be calling complete?
-      if (promise.cancelled) {
-        return replicationCancelled();
-      }
-
-      // Call changes on the source database, with callbacks to onChange for
-      // each change and complete when done.
-      var repOpts = {
-        continuous: continuous,
-        since: last_seq,
-        style: 'all_docs',
-        onChange: onChange,
-        complete: complete,
-        doc_ids: doc_ids
-      };
-
-      if (opts.filter) {
-        repOpts.filter = opts.filter;
-      }
-
-      if (opts.query_params) {
-        repOpts.query_params = opts.query_params;
-      }
-
-      var changes = src.changes(repOpts);
-
-      if (opts.continuous) {
-        var cancel = promise.cancel;
-        promise.cancel = function () {
-          cancel();
-          changes.cancel();
-        };
-      }
-    });
-  }
-
-  // If opts.since is given, set the checkpoint to opts.since
-  if (typeof opts.since === 'undefined') {
-    getChanges();
-  } else {
-    writeCheckpoint(src, target, repId, opts.since, function (err, res) {
-      if (err) {
-        return abortReplication('writeCheckpoint completed with error', err);
-      }
-      last_seq = opts.since;
-      getChanges();
-    });
-  }
-}
-
-function toPouch(db, callback) {
-  if (typeof db === 'string') {
-    return new Pouch(db, callback);
-  }
-  callback(null, db);
-}
-
-function replicateWrapper(src, target, opts, callback) {
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
-  }
-  if (opts === undefined) {
-    opts = {};
-  }
-  if (!opts.complete) {
-    opts.complete = callback;
-  }
-  var replicateRet = new Promise();
-  toPouch(src, function (err, src) {
-    if (err) {
-      return callback(err);
-    }
-    toPouch(target, function (err, target) {
-      if (err) {
-        return callback(err);
-      }
-      if (opts.server) {
-        if (typeof src.replicateOnServer !== 'function') {
-          return callback({
-            error: 'Server replication not supported for ' + src.type() +
-              'adapter'
-          });
-        }
-        if (src.type() !== target.type()) {
-          return callback({
-            error: 'Server replication for different adapter types (' +
-              src.type() + ' and ' + target.type() + ') is not supported'
-          });
-        }
-        src.replicateOnServer(target, opts, replicateRet);
-      } else {
-        genReplicationId(src, target, opts, function (repId) {
-          replicate(repId, src, target, opts, replicateRet);
-        });
-      }
-    });
-  });
-  return replicateRet;
-}
-
-function sync(db1, db2, opts, callback) {
-  var push_promise;
-  var pull_promise;
-
-  function complete(callback) {
-    return function (err, res) {
-      if (err) {
-        // cancel both replications if either experiences problems
-        cancel();
-      }
-      callback(err, res);
-    };
-  }
-
-  function onChange(src, callback) {
-    callback = callback || function () {};
-    return function (change) {
-      return {
-        source: src,
-        change: callback(change)
-      };
-    };
-  }
-
-  function makeOpts(src, opts) {
-    opts = PouchUtils.extend(true, {}, opts);
-    opts.complete = complete(opts.complete);
-    opts.onChange = onChange(src, opts.onChange);
-    return opts;
-  }
-
-  function push() {
-    push_promise = replicateWrapper(db1, db2, makeOpts(db1, opts), callback);
-    return push_promise;
-  }
-
-  function pull() {
-    pull_promise = replicateWrapper(db2, db1, makeOpts(db2, opts), callback);
-    return pull_promise;
-  }
-
-  function cancel() {
-    if (push_promise) {
-      push_promise.cancel();
-    }
-    if (pull_promise) {
-      pull_promise.cancel();
-    }
-  }
-
-  return {
-    push: push(),
-    pull: pull(),
-    cancel: cancel
-  };
-}
-
-exports.replicate = replicateWrapper;
-exports.sync = sync;
-
-},{"./index":13,"./utils":18}],16:[function(_dereq_,module,exports){
-"use strict";
-
-var PouchDBVersion200 = _dereq_("./constructor");
-var utils = _dereq_('./utils');
-var EventEmitter = _dereq_('events').EventEmitter;
-PouchDBVersion200.adapters = {};
-
-PouchDBVersion200.prefix = '_pouch_';
-
-var eventEmitter = new EventEmitter();
-
-var eventEmitterMethods = [
-  'on',
-  'addListener',
-  'emit',
-  'listeners',
-  'once',
-  'removeAllListeners',
-  'removeListener',
-  'setMaxListeners'
-];
-
-eventEmitterMethods.forEach(function (method) {
-  PouchDBVersion200[method] = eventEmitter[method].bind(eventEmitter);
-});
-PouchDBVersion200.setMaxListeners(0);
-PouchDBVersion200.parseAdapter = function (name) {
-  var match = name.match(/([a-z\-]*):\/\/(.*)/);
-  var adapter;
-  if (match) {
-    // the http adapter expects the fully qualified name
-    name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
-    adapter = match[1];
-    if (!PouchDBVersion200.adapters[adapter].valid()) {
-      throw 'Invalid adapter';
-    }
-    return {name: name, adapter: match[1]};
-  }
-
-  var preferredAdapters = ['idb', 'leveldb', 'websql'];
-  for (var i = 0; i < preferredAdapters.length; ++i) {
-    if (preferredAdapters[i] in PouchDBVersion200.adapters) {
-      adapter = PouchDBVersion200.adapters[preferredAdapters[i]];
-      var use_prefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-
-      return {
-        name: use_prefix ? PouchDBVersion200.prefix + name : name,
-        adapter: preferredAdapters[i]
-      };
-    }
-  }
-
-  throw 'No valid adapter found';
-};
-
-PouchDBVersion200.destroy = utils.toPromise(function (name, opts, callback) {
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-
-  var backend = PouchDBVersion200.parseAdapter(opts.name || name);
-  var dbName = backend.name;
-
-  // call destroy method of the particular adaptor
-  PouchDBVersion200.adapters[backend.adapter].destroy(dbName, opts, function (err, resp) {
-    if (err) {
-      callback(err);
-    } else {
-      PouchDBVersion200.emit('destroyed', dbName);
-      //so we don't have to sift through all dbnames
-      PouchDBVersion200.emit(dbName, 'destroyed');
-      callback(null, resp);
-    }
-  });
-});
-PouchDBVersion200.allDbs = utils.toPromise(function (callback) {
-  var err = new Error('allDbs method removed');
-  err.stats = '400';
-  callback(err);
-});
-PouchDBVersion200.adapter = function (id, obj) {
-  if (obj.valid()) {
-    PouchDBVersion200.adapters[id] = obj;
-  }
-};
-
-PouchDBVersion200.plugin = function (obj) {
-  Object.keys(obj).forEach(function (id) {
-    PouchDBVersion200.prototype[id] = obj[id];
-  });
-};
-
-module.exports = PouchDBVersion200;
-
-},{"./constructor":5,"./utils":18,"events":21}],17:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = TaskQueue;
-
-function TaskQueue() {
-  this.isReady = false;
-  this.failed = false;
-  this.queue = [];
-}
-
-TaskQueue.prototype.execute = function () {
-  var d, func;
-  if (this.failed) {
-    while ((d = this.queue.shift())) {
-      func = d.parameters[d.parameters.length - 1];
-      if (typeof func === 'function') {
-        func(this.failed);
-      } else if (d.name === 'changes' && typeof func.complete === 'function') {
-        func.complete(this.failed);
-      }
-    }
-  } else if (this.isReady) {
-    while ((d = this.queue.shift())) {
-      d.task = this.db[d.name].apply(this.db, d.parameters);
-    }
-  }
-};
-TaskQueue.prototype.fail = function (err) {
-  this.failed = err;
-  this.execute();
-};
-
-TaskQueue.prototype.ready = function (db) {
-  if (this.failed) {
-    return false;
-  } else if (arguments.length === 0) {
-    return this.isReady;
-  }
-  this.isReady = db ? true: false;
-  this.db = db;
-  this.execute();
-};
-
-TaskQueue.prototype.addTask = function (name, parameters) {
-  var task = { name: name, parameters: parameters };
-  this.queue.push(task);
-  if (this.failed) {
-    this.execute();
-  }
-  return task;
-};
-},{}],18:[function(_dereq_,module,exports){
-(function (process,global){
-/*jshint strict: false */
-/*global chrome */
-
-var merge = _dereq_('./merge');
-exports.extend = _dereq_('./deps/extend');
-exports.ajax = _dereq_('./deps/ajax');
-exports.createBlob = _dereq_('./deps/blob');
-var uuid = _dereq_('./deps/uuid');
-exports.Crypto = _dereq_('./deps/md5.js');
-var buffer = _dereq_('./deps/buffer');
-var errors = _dereq_('./deps/errors');
-var Promise = typeof global.Promise === 'function' ? global.Promise : _dereq_('bluebird');
-
-// List of top level reserved words for doc
-var reservedWords = [
-  '_id',
-  '_rev',
-  '_attachments',
-  '_deleted',
-  '_revisions',
-  '_revs_info',
-  '_conflicts',
-  '_deleted_conflicts',
-  '_local_seq',
-  '_rev_tree'
-];
-exports.inherits = _dereq_('inherits');
-exports.uuids = function (count, options) {
-
-  if (typeof(options) !== 'object') {
-    options = {};
-  }
-
-  var length = options.length;
-  var radix = options.radix;
-  var uuids = [];
-
-  while (uuids.push(uuid(length, radix)) < count) { }
-
-  return uuids;
-};
-
-// Give back one UUID
-exports.uuid = function (options) {
-  return exports.uuids(1, options)[0];
-};
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or '_local'
-//   - any other string value is a valid id
-// Returns the specific error object for each case
-exports.invalidIdError = function (id) {
-  if (!id) {
-    return errors.MISSING_ID;
-  } else if (typeof id !== 'string') {
-    return errors.INVALID_ID;
-  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
-    return errors.RESERVED_ID;
-  }
-};
-
-function isChromeApp() {
-  return (typeof chrome !== "undefined" &&
-          typeof chrome.storage !== "undefined" &&
-          typeof chrome.storage.local !== "undefined");
-}
-
-// Pretty dumb name for a function, just wraps callback calls so we dont
-// to if (callback) callback() everywhere
-exports.call = function (fun) {
-  if (typeof fun === typeof Function) {
-    var args = Array.prototype.slice.call(arguments, 1);
-    fun.apply(this, args);
-  }
-};
-
-exports.isLocalId = function (id) {
-  return (/^_local/).test(id);
-};
-
-// check if a specific revision of a doc has been deleted
-//  - metadata: the metadata object from the doc store
-//  - rev: (optional) the revision to check. defaults to winning revision
-exports.isDeleted = function (metadata, rev) {
-  if (!rev) {
-    rev = merge.winningRev(metadata);
-  }
-  if (rev.indexOf('-') >= 0) {
-    rev = rev.split('-')[1];
-  }
-  var deleted = false;
-  merge.traverseRevTree(metadata.rev_tree, function (isLeaf, pos, id, acc, opts) {
-    if (id === rev) {
-      deleted = !!opts.deleted;
-    }
-  });
-
-  return deleted;
-};
-
-exports.filterChange = function (opts) {
-  return function (change) {
-    var req = {};
-    var hasFilter = opts.filter && typeof opts.filter === 'function';
-
-    req.query = opts.query_params;
-    if (opts.filter && hasFilter && !opts.filter.call(this, change.doc, req)) {
-      return false;
-    }
-    if (opts.doc_ids && opts.doc_ids.indexOf(change.id) === -1) {
-      return false;
-    }
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else {
-      for (var att in change.doc._attachments) {
-        if (change.doc._attachments.hasOwnProperty(att)) {
-          change.doc._attachments[att].stub = true;
-        }
-      }
-    }
-    return true;
-  };
-};
-
-exports.processChanges = function (opts, changes, last_seq) {
-  // TODO: we should try to filter and limit as soon as possible
-  changes = changes.filter(exports.filterChange(opts));
-  if (opts.limit) {
-    if (opts.limit < changes.length) {
-      changes.length = opts.limit;
-    }
-  }
-  changes.forEach(function (change) {
-    exports.call(opts.onChange, change);
-  });
-  if (!opts.continuous) {
-    exports.call(opts.complete, null, {results: changes, last_seq: last_seq});
-  }
-};
-
-// Preprocess documents, parse their revisions, assign an id and a
-// revision for new writes that are missing them, etc
-exports.parseDoc = function (doc, newEdits) {
-  var error = null;
-  var nRevNum;
-  var newRevId;
-  var revInfo;
-  var opts = {status: 'available'};
-  if (doc._deleted) {
-    opts.deleted = true;
-  }
-
-  if (newEdits) {
-    if (!doc._id) {
-      doc._id = exports.uuid();
-    }
-    newRevId = exports.uuid({length: 32, radix: 16}).toLowerCase();
-    if (doc._rev) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        throw "invalid value for property '_rev'";
-      }
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], {status: 'missing'}, [[newRevId, opts, []]]]
-      }];
-      nRevNum = parseInt(revInfo[1], 10) + 1;
-    } else {
-      doc._rev_tree = [{
-        pos: 1,
-        ids : [newRevId, opts, []]
-      }];
-      nRevNum = 1;
-    }
-  } else {
-    if (doc._revisions) {
-      doc._rev_tree = [{
-        pos: doc._revisions.start - doc._revisions.ids.length + 1,
-        ids: doc._revisions.ids.reduce(function (acc, x) {
-          if (acc === null) {
-            return [x, opts, []];
-          } else {
-            return [x, {status: 'missing'}, [acc]];
-          }
-        }, null)
-      }];
-      nRevNum = doc._revisions.start;
-      newRevId = doc._revisions.ids[0];
-    }
-    if (!doc._rev_tree) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        return errors.BAD_ARG;
-      }
-      nRevNum = parseInt(revInfo[1], 10);
-      newRevId = revInfo[2];
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], opts, []]
-      }];
-    }
-  }
-
-  error = exports.invalidIdError(doc._id);
-
-  for (var key in doc) {
-    if (doc.hasOwnProperty(key) && key[0] === '_' && reservedWords.indexOf(key) === -1) {
-      error = exports.extend({}, errors.DOC_VALIDATION);
-      error.reason += ': ' + key;
-    }
-  }
-
-  doc._id = decodeURIComponent(doc._id);
-  doc._rev = [nRevNum, newRevId].join('-');
-
-  if (error) {
-    return error;
-  }
-
-  return Object.keys(doc).reduce(function (acc, key) {
-    if (/^_/.test(key) && key !== '_attachments') {
-      acc.metadata[key.slice(1)] = doc[key];
-    } else {
-      acc.data[key] = doc[key];
-    }
-    return acc;
-  }, {metadata : {}, data : {}});
-};
-
-exports.isCordova = function () {
-  return (typeof cordova !== "undefined" ||
-          typeof PhoneGap !== "undefined" ||
-          typeof phonegap !== "undefined");
-};
-
-exports.Changes = function () {
-
-  var api = {};
-  var listeners = {};
-
-  if (isChromeApp()) {
-    chrome.storage.onChanged.addListener(function (e) {
-      // make sure it's event addressed to us
-      if (e.db_name != null) {
-        api.notify(e.db_name.newValue);//object only has oldValue, newValue members
-      }
-    });
-  } else if (typeof window !== 'undefined') {
-    global.addEventListener("storage", function (e) {
-      api.notify(e.key);
-    });
-  }
-
-  api.addListener = function (db_name, id, db, opts) {
-    if (!listeners[db_name]) {
-      listeners[db_name] = {};
-    }
-    listeners[db_name][id] = {
-      db: db,
-      opts: opts
-    };
-  };
-
-  api.removeListener = function (db_name, id) {
-    if (listeners[db_name]) {
-      delete listeners[db_name][id];
-    }
-  };
-
-  api.clearListeners = function (db_name) {
-    delete listeners[db_name];
-  };
-
-  api.notifyLocalWindows = function (db_name) {
-    //do a useless change on a storage thing
-    //in order to get other windows's listeners to activate
-    if (isChromeApp()) {
-      chrome.storage.local.set({db_name: db_name});
-    } else if (global.localStorage) {
-      localStorage[db_name] = (localStorage[db_name] === "a") ? "b" : "a";
-    }
-  };
-
-  api.notify = function (db_name) {
-    if (!listeners[db_name]) { return; }
-
-    Object.keys(listeners[db_name]).forEach(function (i) {
-      var opts = listeners[db_name][i].opts;
-      listeners[db_name][i].db.changes({
-        include_docs: opts.include_docs,
-        conflicts: opts.conflicts,
-        continuous: false,
-        descending: false,
-        filter: opts.filter,
-        view: opts.view,
-        since: opts.since,
-        query_params: opts.query_params,
-        onChange: function (c) {
-          if (c.seq > opts.since && !opts.cancelled) {
-            opts.since = c.seq;
-            exports.call(opts.onChange, c);
-          }
-        }
-      });
-    });
-  };
-
-  return api;
-};
-
-if (!process.browser || !('atob' in global)) {
-  exports.atob = function (str) {
-    var base64 = new buffer(str, 'base64');
-    // Node.js will just skip the characters it can't encode instead of
-    // throwing and exception
-    if (base64.toString('base64') !== str) {
-      throw ("Cannot base64 encode full string");
-    }
-    return base64.toString('binary');
-  };
-} else {
-  exports.atob = function (str) {
-    return atob(str);
-  };
-}
-
-if (!process.browser || !('btoa' in global)) {
-  exports.btoa = function (str) {
-    return new buffer(str, 'binary').toString('base64');
-  };
-} else {
-  exports.btoa = function (str) {
-    return btoa(str);
-  };
-}
-
-// From http://stackoverflow.com/questions/14967647/encode-decode-image-with-base64-breaks-image (2013-04-21)
-exports.fixBinary = function (bin) {
-  if (!process.browser) {
-    // don't need to do this in Node
-    return bin;
-  }
-
-  var length = bin.length;
-  var buf = new ArrayBuffer(length);
-  var arr = new Uint8Array(buf);
-  for (var i = 0; i < length; i++) {
-    arr[i] = bin.charCodeAt(i);
-  }
-  return buf;
-};
-
-exports.toPromise = function (func) {
-  //create the function we will be returning
-  return function () {
-    var self = this;
-    var args = Array.prototype.slice.call(arguments);
-    var tempCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
-    // if the last argument is a function, assume its a callback
-    var usedCB;
-    if (tempCB) {
-      // if it was a callback, create a new callback which calls the callback function
-      // but we do so async so we don't trap any errors
-      usedCB = function (err, resp) {
-        process.nextTick(function () {
-          tempCB(err, resp);
-        });
-      };
-    }
-    var promise = new Promise(function (fulfill, reject) {
-      function callback(err, mesg) {
-        if (err) {
-          reject(err);
-        } else {
-          fulfill(mesg);
-        }
-      }
-      // create a callback for this invocation
-      args.push(callback);
-      func.apply(self, args);
-      // apply the function in the orig context
-    });
-    // if there is a callback, call it back
-    if (usedCB) {
-      promise.then(function (result) {
-        usedCB(null, result);
-      }, usedCB);
-    }
-    return promise;
-  };
-};
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./deps/ajax":6,"./deps/blob":7,"./deps/buffer":20,"./deps/errors":8,"./deps/extend":10,"./deps/md5.js":11,"./deps/uuid":12,"./merge":14,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":22,"bluebird":24,"inherits":23}],19:[function(_dereq_,module,exports){
-module.exports = _dereq_('../package.json').version;
-},{"../package.json":37}],20:[function(_dereq_,module,exports){
-
-},{}],21:[function(_dereq_,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
-  this._events = this._events || {};
-  this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
-  if (!isNumber(n) || n < 0 || isNaN(n))
-    throw TypeError('n must be a positive number');
-  this._maxListeners = n;
-  return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
-  var er, handler, len, args, i, listeners;
-
-  if (!this._events)
-    this._events = {};
-
-  // If there is no 'error' event listener then throw.
-  if (type === 'error') {
-    if (!this._events.error ||
-        (isObject(this._events.error) && !this._events.error.length)) {
-      er = arguments[1];
-      if (er instanceof Error) {
-        throw er; // Unhandled 'error' event
-      } else {
-        throw TypeError('Uncaught, unspecified "error" event.');
-      }
-      return false;
-    }
-  }
-
-  handler = this._events[type];
-
-  if (isUndefined(handler))
-    return false;
-
-  if (isFunction(handler)) {
-    switch (arguments.length) {
-      // fast cases
-      case 1:
-        handler.call(this);
-        break;
-      case 2:
-        handler.call(this, arguments[1]);
-        break;
-      case 3:
-        handler.call(this, arguments[1], arguments[2]);
-        break;
-      // slower
-      default:
-        len = arguments.length;
-        args = new Array(len - 1);
-        for (i = 1; i < len; i++)
-          args[i - 1] = arguments[i];
-        handler.apply(this, args);
-    }
-  } else if (isObject(handler)) {
-    len = arguments.length;
-    args = new Array(len - 1);
-    for (i = 1; i < len; i++)
-      args[i - 1] = arguments[i];
-
-    listeners = handler.slice();
-    len = listeners.length;
-    for (i = 0; i < len; i++)
-      listeners[i].apply(this, args);
-  }
-
-  return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
-  var m;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events)
-    this._events = {};
-
-  // To avoid recursion in the case that type === "newListener"! Before
-  // adding it to the listeners, first emit "newListener".
-  if (this._events.newListener)
-    this.emit('newListener', type,
-              isFunction(listener.listener) ?
-              listener.listener : listener);
-
-  if (!this._events[type])
-    // Optimize the case of one listener. Don't need the extra array object.
-    this._events[type] = listener;
-  else if (isObject(this._events[type]))
-    // If we've already got an array, just append.
-    this._events[type].push(listener);
-  else
-    // Adding the second element, need to change to array.
-    this._events[type] = [this._events[type], listener];
-
-  // Check for listener leak
-  if (isObject(this._events[type]) && !this._events[type].warned) {
-    var m;
-    if (!isUndefined(this._maxListeners)) {
-      m = this._maxListeners;
-    } else {
-      m = EventEmitter.defaultMaxListeners;
-    }
-
-    if (m && m > 0 && this._events[type].length > m) {
-      this._events[type].warned = true;
-      console.error('(node) warning: possible EventEmitter memory ' +
-                    'leak detected. %d listeners added. ' +
-                    'Use emitter.setMaxListeners() to increase limit.',
-                    this._events[type].length);
-      console.trace();
-    }
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  var fired = false;
-
-  function g() {
-    this.removeListener(type, g);
-
-    if (!fired) {
-      fired = true;
-      listener.apply(this, arguments);
-    }
-  }
-
-  g.listener = listener;
-  this.on(type, g);
-
-  return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
-  var list, position, length, i;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events || !this._events[type])
-    return this;
-
-  list = this._events[type];
-  length = list.length;
-  position = -1;
-
-  if (list === listener ||
-      (isFunction(list.listener) && list.listener === listener)) {
-    delete this._events[type];
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-
-  } else if (isObject(list)) {
-    for (i = length; i-- > 0;) {
-      if (list[i] === listener ||
-          (list[i].listener && list[i].listener === listener)) {
-        position = i;
-        break;
-      }
-    }
-
-    if (position < 0)
-      return this;
-
-    if (list.length === 1) {
-      list.length = 0;
-      delete this._events[type];
-    } else {
-      list.splice(position, 1);
-    }
-
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
-  var key, listeners;
-
-  if (!this._events)
-    return this;
-
-  // not listening for removeListener, no need to emit
-  if (!this._events.removeListener) {
-    if (arguments.length === 0)
-      this._events = {};
-    else if (this._events[type])
-      delete this._events[type];
-    return this;
-  }
-
-  // emit removeListener for all listeners on all events
-  if (arguments.length === 0) {
-    for (key in this._events) {
-      if (key === 'removeListener') continue;
-      this.removeAllListeners(key);
-    }
-    this.removeAllListeners('removeListener');
-    this._events = {};
-    return this;
-  }
-
-  listeners = this._events[type];
-
-  if (isFunction(listeners)) {
-    this.removeListener(type, listeners);
-  } else {
-    // LIFO order
-    while (listeners.length)
-      this.removeListener(type, listeners[listeners.length - 1]);
-  }
-  delete this._events[type];
-
-  return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
-  var ret;
-  if (!this._events || !this._events[type])
-    ret = [];
-  else if (isFunction(this._events[type]))
-    ret = [this._events[type]];
-  else
-    ret = this._events[type].slice();
-  return ret;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
-  var ret;
-  if (!emitter._events || !emitter._events[type])
-    ret = 0;
-  else if (isFunction(emitter._events[type]))
-    ret = 1;
-  else
-    ret = emitter._events[type].length;
-  return ret;
-};
-
-function isFunction(arg) {
-  return typeof arg === 'function';
-}
-
-function isNumber(arg) {
-  return typeof arg === 'number';
-}
-
-function isObject(arg) {
-  return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
-  return arg === void 0;
-}
-
-},{}],22:[function(_dereq_,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
-    var canSetImmediate = typeof window !== 'undefined'
-    && window.setImmediate;
-    var canPost = typeof window !== 'undefined'
-    && window.postMessage && window.addEventListener
-    ;
-
-    if (canSetImmediate) {
-        return function (f) { return window.setImmediate(f) };
-    }
-
-    if (canPost) {
-        var queue = [];
-        window.addEventListener('message', function (ev) {
-            var source = ev.source;
-            if ((source === window || source === null) && ev.data === 'process-tick') {
-                ev.stopPropagation();
-                if (queue.length > 0) {
-                    var fn = queue.shift();
-                    fn();
-                }
-            }
-        }, true);
-
-        return function nextTick(fn) {
-            queue.push(fn);
-            window.postMessage('process-tick', '*');
-        };
-    }
-
-    return function nextTick(fn) {
-        setTimeout(fn, 0);
-    };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-}
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-
-},{}],23:[function(_dereq_,module,exports){
-if (typeof Object.create === 'function') {
-  // implementation from standard node.js 'util' module
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    ctor.prototype = Object.create(superCtor.prototype, {
-      constructor: {
-        value: ctor,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-  };
-} else {
-  // old school shim for old browsers
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    var TempCtor = function () {}
-    TempCtor.prototype = superCtor.prototype
-    ctor.prototype = new TempCtor()
-    ctor.prototype.constructor = ctor
-  }
-}
-
-},{}],24:[function(_dereq_,module,exports){
-'use strict';
-
-var immediate = _dereq_('immediate');
-var isDefineProp = false;
-// prevents deoptimization
-(function(){
-    try {
-        Object.defineProperty({}, 'test', {value:true});
-        isDefineProp = true;
-    }catch(e){}
-}());
-function defineNonEnum(obj, name, value){
-    if(isDefineProp){
-         Object.defineProperty(obj, name, {
-            value: value,
-            configurable: true,
-            writable: true
-        });
-    }else{
-        obj[name] = value;
-    }
-}
-function Promise(resolver) {
-
-     if (!(this instanceof Promise)) {
-        return new Promise(resolver);
-    }
-
-    defineNonEnum(this, 'successQueue', []);
-    defineNonEnum(this, 'failureQueue', []);
-    defineNonEnum(this, 'resolved', false);
-
-  
-    if(typeof resolver === 'function'){
-        this.resolvePassed(resolver);
-    }
-}
-defineNonEnum(Promise.prototype, 'resolvePassed', function(resolver){
-    try{
-        resolver(this.fulfillUnwrap.bind(this),this.reject.bind(this));
-    }catch(e){
-        this.reject(e);
-    }
-});
-defineNonEnum(Promise.prototype, 'reject', function(reason){
-    this.resolve(false,reason);
-});
-defineNonEnum(Promise.prototype, 'fulfill', function(value){
-    this.resolve(true,value);
-});
-defineNonEnum(Promise.prototype, 'fulfillUnwrap', function(value){
-    unwrap(this.fulfill.bind(this), this.reject.bind(this), value);
-});
-Promise.prototype.then = function(onFulfilled, onRejected) {
-    if(this.resolved){
-        return this.resolved(onFulfilled, onRejected);
-    } else {
-        return this.pending(onFulfilled, onRejected);
-    }
-};
-(function(){
-    try {
-        Promise.prototype.catch = function(onRejected) {
-            return this.then(null, onRejected);
-        };
-    } catch(e){}
-}());
-defineNonEnum(Promise.prototype, 'pending', function(onFulfilled, onRejected){
-    var self = this;
-    return new Promise(function(success,failure){
-        if(typeof onFulfilled === 'function'){
-            self.successQueue.push({
-                resolve: success,
-                reject: failure,
-                callback:onFulfilled
-            });
-        }else{
-            self.successQueue.push({
-                next: success,
-                callback:false
-            });
-        }
-
-        if(typeof onRejected === 'function'){
-            self.failureQueue.push({
-                resolve: success,
-                reject: failure,
-                callback:onRejected
-            });
-        }else{
-            self.failureQueue.push({
-                next: failure,
-                callback:false
-            });
-        }
-    });
-});
-defineNonEnum(Promise.prototype, 'resolve', function (success, value){
-
-    if(this.resolved){
-        return;
-    }
-
-    this.resolved = createResolved(this, value, success?0:1);
-
-    var queue = success ? this.successQueue : this.failureQueue;
-    var len = queue.length;
-    var i = -1;
-    while(++i < len) {
-
-        if (queue[i].callback) {
-            immediate(execute,queue[i].callback, value, queue[i].resolve, queue[i].reject);
-        }else {
-            queue[i].next(value);
-        }
-    }
-});
-
-function unwrap(fulfill, reject, value){
-    if(value && typeof value.then==='function'){
-        value.then(fulfill,reject);
-    }else{
-        fulfill(value);
-    }
-}
-
-function createResolved(scope, value, whichArg) {
-    function resolved() {
-        var callback = arguments[whichArg];
-        if (typeof callback !== 'function') {
-            return scope;
-        }else{
-            return new Promise(function(resolve,reject){
-                immediate(execute,callback,value,resolve,reject);
-            });
-        }
-    }
-    return resolved;
-}
-
-function execute(callback, value, resolve, reject) {
-    try {
-        unwrap(resolve,reject,callback(value));
-    } catch (error) {
-        reject(error);
-    }
-}
-
-
-
-module.exports = Promise;
-
-},{"immediate":27}],25:[function(_dereq_,module,exports){
-"use strict";
-exports.test = function () {
-    return false;
-};
-},{}],26:[function(_dereq_,module,exports){
-(function (global){
-module.exports = typeof global === "object" && global ? global : this;
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],27:[function(_dereq_,module,exports){
-"use strict";
-var types = [
-    _dereq_("./nextTick"),
-    _dereq_("./mutation"),
-    _dereq_("./realSetImmediate"),
-    _dereq_("./postMessage"),
-    _dereq_("./messageChannel"),
-    _dereq_("./stateChange"),
-    _dereq_("./timeout")
-];
-var handlerQueue = [];
-function drainQueue() {
-    var i = 0,
-        task,
-        innerQueue = handlerQueue;
-	handlerQueue = [];
-	/*jslint boss: true */
-	while (task = innerQueue[i++]) {
-		task();
-	}
-}
-var nextTick;
-var i = -1;
-var len = types.length;
-while(++i<len){
-    if(types[i].test()){
-        nextTick = types[i].install(drainQueue);
-        break;
-    }
-}
-var retFunc = function (task) {
-    var len, args;
-    var nTask = task;
-    if (arguments.length > 1 && typeof task === "function") {
-        args = Array.prototype.slice.call(arguments, 1);
-        nTask = function(){
-            task.apply(undefined,args);
-        }
-    }
-    if ((len = handlerQueue.push(nTask)) === 1) {
-        nextTick(drainQueue);
-    }
-    return len;
-};
-retFunc.clear = function (n) {
-    if (n <= handlerQueue.length) {
-        handlerQueue[n - 1] = function () {};
-    }
-    return this;
-};
-module.exports = retFunc;
-
-},{"./messageChannel":28,"./mutation":29,"./nextTick":25,"./postMessage":30,"./realSetImmediate":31,"./stateChange":32,"./timeout":33}],28:[function(_dereq_,module,exports){
-"use strict";
-var globe = _dereq_("./global");
-exports.test = function () {
-    return !!globe.MessageChannel;
-};
-
-exports.install = function (func) {
-    var channel = new globe.MessageChannel();
-    channel.port1.onmessage = func;
-    return function () {
-        channel.port2.postMessage(0);
-    };
-};
-},{"./global":26}],29:[function(_dereq_,module,exports){
-"use strict";
-//based off rsvp
-//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/async.js
-var globe = _dereq_("./global");
-
-var MutationObserver = globe.MutationObserver || globe.WebKitMutationObserver;
-
-exports.test = function () {
-    return MutationObserver;
-};
-
-exports.install = function (handle) {
-    var observer = new MutationObserver(handle);
-    var element = globe.document.createElement("div");
-    observer.observe(element, { attributes: true });
-
-    // Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
-    globe.addEventListener("unload", function () {
-        observer.disconnect();
-        observer = null;
-    }, false);
-    return function () {
-        element.setAttribute("drainQueue", "drainQueue");
-    };
-};
-},{"./global":26}],30:[function(_dereq_,module,exports){
-"use strict";
-var globe = _dereq_("./global");
-exports.test = function () {
-    // The test against `importScripts` prevents this implementation from being installed inside a web worker,
-    // where `global.postMessage` means something completely different and can"t be used for this purpose.
-
-    if (!globe.postMessage || globe.importScripts) {
-        return false;
-    }
-
-    var postMessageIsAsynchronous = true;
-    var oldOnMessage = globe.onmessage;
-    globe.onmessage = function () {
-        postMessageIsAsynchronous = false;
-    };
-    globe.postMessage("", "*");
-    globe.onmessage = oldOnMessage;
-
-    return postMessageIsAsynchronous;
-};
-
-exports.install = function (func) {
-    var codeWord = "com.calvinmetcalf.setImmediate" + Math.random();
-    function globalMessage(event) {
-        if (event.source === globe && event.data === codeWord) {
-            func();
-        }
-    }
-    if (globe.addEventListener) {
-        globe.addEventListener("message", globalMessage, false);
-    } else {
-        globe.attachEvent("onmessage", globalMessage);
-    }
-    return function () {
-        globe.postMessage(codeWord, "*");
-    };
-};
-},{"./global":26}],31:[function(_dereq_,module,exports){
-"use strict";
-var globe = _dereq_("./global");
-exports.test = function () {
-    return  globe.setImmediate;
-};
-
-exports.install = function (handle) {
-    return globe.setTimeout.bind(globe, handle, 0);
-};
-
-},{"./global":26}],32:[function(_dereq_,module,exports){
-"use strict";
-var globe = _dereq_("./global");
-exports.test = function () {
-    return "document" in globe && "onreadystatechange" in globe.document.createElement("script");
-};
-
-exports.install = function (handle) {
-    return function () {
-
-        // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-        // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-        var scriptEl = globe.document.createElement("script");
-        scriptEl.onreadystatechange = function () {
-            handle();
-
-            scriptEl.onreadystatechange = null;
-            scriptEl.parentNode.removeChild(scriptEl);
-            scriptEl = null;
-        };
-        globe.document.documentElement.appendChild(scriptEl);
-
-        return handle;
-    };
-};
-},{"./global":26}],33:[function(_dereq_,module,exports){
-"use strict";
-exports.test = function () {
-    return true;
-};
-
-exports.install = function (t) {
-    return function () {
-        setTimeout(t, 0);
-    };
-};
-},{}],34:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = function (func, emit, sum, log, isArray, toJSON) {
-  /*jshint evil: true */
-  return eval("'use strict'; (" + func + ");");
-};
-
-},{}],35:[function(_dereq_,module,exports){
-(function (process,global){
-'use strict';
-
-var pouchCollate = _dereq_('pouchdb-collate');
-var Promise = typeof global.Promise === 'function' ? global.Promise : _dereq_('lie');
-var collate = pouchCollate.collate;
-var evalFunc = _dereq_('./evalfunc');
-var log = (typeof console !== 'undefined') ?
-  Function.prototype.bind.call(console.log, console) : function () {};
-var processKey = function (key) {
-  // Stringify keys since we want them as map keys (see #35)
-  return JSON.stringify(pouchCollate.normalizeKey(key));
-};
-// This is the first implementation of a basic plugin, we register the
-// plugin object with pouch and it is mixin'd to each database created
-// (regardless of adapter), adapters can override plugins by providing
-// their own implementation. functions on the plugin object that start
-// with _ are reserved function that are called by pouchdb for special
-// notifications.
-
-// If we wanted to store incremental views we can do it here by listening
-// to the changes feed (keeping track of our last update_seq between page loads)
-// and storing the result of the map function (possibly using the upcoming
-// extracted adapter functions)
-
-
-function createKeysLookup(keys) {
-  // creates a lookup map for the given keys, so that doing
-  // query() with keys doesn't become an O(n * m) operation
-  // lookup values are typically integer indexes, but may
-  // map to a list of integers, since keys can be duplicated
-  var lookup = {};
-
-  for (var i = 0, len = keys.length; i < len; i++) {
-    var key = processKey(keys[i]);
-    var val = lookup[key];
-    if (typeof val === 'undefined') {
-      lookup[key] = i;
-    } else if (typeof val === 'number') {
-      lookup[key] = [val, i];
-    } else { // array
-      val.push(i);
-    }
-  }
-
-  return lookup;
-}
-
-function sortByIdAndValue(a, b) {
-  // sort by id, then value
-  var idCompare = collate(a.id, b.id);
-  return idCompare !== 0 ? idCompare : collate(a.value, b.value);
-}
-function addAtIndex(idx, result, prelimResults) {
-  var val = prelimResults[idx];
-  if (typeof val === 'undefined') {
-    prelimResults[idx] = result;
-  } else if (!Array.isArray(val)) {
-    // same key for multiple docs, need to preserve document order, so create array
-    prelimResults[idx] = [val, result];
-  } else { // existing array
-    val.push(result);
-  }
-}
-
-function sum(values) {
-  return values.reduce(function (a, b) {
-    return a + b;
-  }, 0);
-}
-
-var builtInReduce = {
-  "_sum": function (keys, values) {
-    return sum(values);
-  },
-
-  "_count": function (keys, values, rereduce) {
-    return values.length;
-  },
-
-  "_stats": function (keys, values) {
-    return {
-      'sum': sum(values),
-      'min': Math.min.apply(null, values),
-      'max': Math.max.apply(null, values),
-      'count': values.length,
-      'sumsqr': (function () {
-        var _sumsqr = 0;
-        var error;
-        for (var idx in values) {
-          if (typeof values[idx] === 'number') {
-            _sumsqr += values[idx] * values[idx];
-          } else {
-            error =  new Error('builtin _stats function requires map values to be numbers');
-            error.name = 'invalid_value';
-            error.status = 500;
-            return error;
-          }
-        }
-        return _sumsqr;
-      })()
-    };
-  }
-};
-
-function addHttpParam(paramName, opts, params, asJson) {
-  // add an http param from opts to params, optionally json-encoded
-  var val = opts[paramName];
-  if (typeof val !== 'undefined') {
-    if (asJson) {
-      val = encodeURIComponent(JSON.stringify(val));
-    }
-    params.push(paramName + '=' + val);
-  }
-}
-
-function mapUsingKeys(inputResults, keys, keysLookup) {
-  // create a new results array from the given array,
-  // ensuring that the following conditions are respected:
-  // 1. docs are ordered by key, then doc id
-  // 2. docs can appear >1 time in the list, if their key is specified >1 time
-  // 3. keys can be unknown, in which case there's just a hole in the returned array
-
-  var prelimResults = new Array(keys.length);
-
-  inputResults.forEach(function (result) {
-    var idx = keysLookup[processKey(result.key)];
-    if (typeof idx === 'number') {
-      addAtIndex(idx, result, prelimResults);
-    } else { // array of indices
-      idx.forEach(function (subIdx) {
-        addAtIndex(subIdx, result, prelimResults);
-      });
-    }
-  });
-
-  // flatten the array, remove nulls, sort by doc ids
-  var outputResults = [];
-  prelimResults.forEach(function (result) {
-    if (Array.isArray(result)) {
-      outputResults = outputResults.concat(result.sort(sortByIdAndValue));
-    } else { // single result
-      outputResults.push(result);
-    }
-  });
-
-  return outputResults;
-}
-
-function viewQuery(db, fun, options) {
-  var origMap;
-  if (!options.skip) {
-    options.skip = 0;
-  }
-
-  if (!fun.reduce) {
-    options.reduce = false;
-  }
-
-  var results = [];
-  var current;
-  var num_started = 0;
-  var completed = false;
-  var keysLookup;
-
-  function emit(key, val) {
-    var viewRow = {
-      id: current.doc._id,
-      key: key,
-      value: val
-    };
-
-    if (typeof options.startkey !== 'undefined' && collate(key, options.startkey) < 0) {
-      return;
-    }
-    if (typeof options.endkey !== 'undefined' && collate(key, options.endkey) > 0) {
-      return;
-    }
-    if (typeof options.key !== 'undefined' && collate(key, options.key) !== 0) {
-      return;
-    }
-    if (typeof options.keys !== 'undefined') {
-      keysLookup = keysLookup || createKeysLookup(options.keys);
-      if (typeof keysLookup[processKey(key)] === 'undefined') {
-        return;
-      }
-    }
-
-    num_started++;
-    if (options.include_docs) {
-      //in this special case, join on _id (issue #106)
-      if (val && typeof val === 'object' && val._id) {
-        db.get(val._id,
-          function (_, joined_doc) {
-            if (joined_doc) {
-              viewRow.doc = joined_doc;
-            }
-            results.push(viewRow);
-            checkComplete();
-          });
-        return;
-      } else {
-        viewRow.doc = current.doc;
-      }
-    }
-    results.push(viewRow);
-  }
-  if (typeof fun.map === "function" && fun.map.length === 2) {
-    //save a reference to it
-    origMap = fun.map;
-    fun.map = function (doc) {
-      //call it with the emit as the second argument
-      return origMap(doc, emit);
-    };
-  } else {
-    // ugly way to make sure references to 'emit' in map/reduce bind to the
-    // above emit
-    fun.map = evalFunc(fun.map.toString(), emit, sum, log, Array.isArray, JSON.parse);
-  }
-  if (fun.reduce) {
-    if (builtInReduce[fun.reduce]) {
-      fun.reduce = builtInReduce[fun.reduce];
-    } else {
-      fun.reduce = evalFunc(fun.reduce.toString(), emit, sum, log, Array.isArray, JSON.parse);
-    }
-  }
-
-  //only proceed once all documents are mapped and joined
-  function checkComplete() {
-    var error;
-    if (completed && results.length === num_started) {
-
-      if (typeof options.keys !== 'undefined' && results.length) {
-        // user supplied a keys param, sort by keys
-        results = mapUsingKeys(results, options.keys, keysLookup);
-      } else { // normal sorting
-        results.sort(function (a, b) {
-          // sort by key, then id
-          var keyCollate = collate(a.key, b.key);
-          return keyCollate !== 0 ? keyCollate : collate(a.id, b.id);
-        });
-      }
-      if (options.descending) {
-        results.reverse();
-      }
-      if (options.reduce === false) {
-        return options.complete(null, {
-          total_rows: results.length,
-          offset: options.skip,
-          rows: ('limit' in options) ? results.slice(options.skip, options.limit + options.skip) :
-            (options.skip > 0) ? results.slice(options.skip) : results
-        });
-      }
-
-      var groups = [];
-      results.forEach(function (e) {
-        var last = groups[groups.length - 1];
-        if (last && collate(last.key[0][0], e.key) === 0) {
-          last.key.push([e.key, e.id]);
-          last.value.push(e.value);
-          return;
-        }
-        groups.push({key: [
-          [e.key, e.id]
-        ], value: [e.value]});
-      });
-      groups.forEach(function (e) {
-        e.value = fun.reduce.call(null, e.key, e.value);
-        if (e.value.sumsqr && e.value.sumsqr instanceof Error) {
-          error = e.value;
-          return;
-        }
-        e.key = e.key[0][0];
-      });
-      if (error) {
-        options.complete(error);
-        return;
-      }
-      options.complete(null, {
-        total_rows: groups.length,
-        offset: options.skip,
-        rows: ('limit' in options) ? groups.slice(options.skip, options.limit + options.skip) :
-          (options.skip > 0) ? groups.slice(options.skip) : groups
-      });
-    }
-  }
-
-  db.changes({
-    conflicts: true,
-    include_docs: true,
-    onChange: function (doc) {
-      if (!('deleted' in doc) && doc.id[0] !== "_") {
-        current = {doc: doc.doc};
-        fun.map.call(null, doc.doc);
-      }
-    },
-    complete: function () {
-      completed = true;
-      checkComplete();
-    }
-  });
-}
-
-function httpQuery(db, fun, opts) {
-  var callback = opts.complete;
-
-  // List of parameters to add to the PUT request
-  var params = [];
-  var body;
-  var method = 'GET';
-
-  // If opts.reduce exists and is defined, then add it to the list
-  // of parameters.
-  // If reduce=false then the results are that of only the map function
-  // not the final result of map and reduce.
-  addHttpParam('reduce', opts, params);
-  addHttpParam('include_docs', opts, params);
-  addHttpParam('limit', opts, params);
-  addHttpParam('descending', opts, params);
-  addHttpParam('group', opts, params);
-  addHttpParam('group_level', opts, params);
-  addHttpParam('skip', opts, params);
-  addHttpParam('startkey', opts, params, true);
-  addHttpParam('endkey', opts, params, true);
-  addHttpParam('key', opts, params, true);
-
-  // If keys are supplied, issue a POST request to circumvent GET query string limits
-  // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-  if (typeof opts.keys !== 'undefined') {
-    method = 'POST';
-    if (typeof fun === 'string') {
-      body = JSON.stringify({keys: opts.keys});
-    } else { // fun is {map : mapfun}, so append to this
-      fun.keys = opts.keys;
-    }
-  }
-
-  // Format the list of parameters into a valid URI query string
-  params = params.join('&');
-  params = params === '' ? '' : '?' + params;
-
-  // We are referencing a query defined in the design doc
-  if (typeof fun === 'string') {
-    var parts = fun.split('/');
-    db.request({
-      method: method,
-      url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
-      body: body
-    }, callback);
-    return;
-  }
-
-  // We are using a temporary view, terrible for performance but good for testing
-  var queryObject = JSON.parse(JSON.stringify(fun, function (key, val) {
-    if (typeof val === 'function') {
-      return val + ''; // implicitly `toString` it
-    }
-    return val;
-  }));
-
-  db.request({
-    method: 'POST',
-    url: '_temp_view' + params,
-    body: queryObject
-  }, callback);
-}
-
-exports.query = function (fun, opts, callback) {
-  var db = this;
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = opts || {};
-  if (callback) {
-    opts.complete = callback;
-  }
-  var tempCB = opts.complete;
-  var realCB;
-  if (opts.complete) {
-    realCB = function (err, resp) {
-      process.nextTick(function () {
-        tempCB(err, resp);
-      });
-    };
-  } 
-  var promise = new Promise(function (resolve, reject) {
-    opts.complete = function (err, data) {
-      if (err) {
-        reject(err);
-      } else {
-        resolve(data);
-      }
-    };
-
-    if (db.type() === 'http') {
-      if (typeof fun === 'function') {
-        return httpQuery(db, {map: fun}, opts);
-      }
-      return httpQuery(db, fun, opts);
-    }
-
-    if (typeof fun === 'object') {
-      return viewQuery(db, fun, opts);
-    }
-
-    if (typeof fun === 'function') {
-      return viewQuery(db, {map: fun}, opts);
-    }
-
-    var parts = fun.split('/');
-    db.get('_design/' + parts[0], function (err, doc) {
-      if (err) {
-        opts.complete(err);
-        return;
-      }
-
-      if (!doc.views[parts[1]]) {
-        opts.complete({ name: 'not_found', message: 'missing_named_view' });
-        return;
-      }
-      viewQuery(db, {
-        map: doc.views[parts[1]].map,
-        reduce: doc.views[parts[1]].reduce
-      }, opts);
-    });
-  });
-  if (realCB) {
-    promise.then(function (resp) {
-      realCB(null, resp);
-    }, realCB);
-  }
-  return promise;
-};
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./evalfunc":34,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":22,"lie":24,"pouchdb-collate":36}],36:[function(_dereq_,module,exports){
-'use strict';
-
-exports.collate = function (a, b) {
-  a = exports.normalizeKey(a);
-  b = exports.normalizeKey(b);
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  if (a === null) {
-    return 0;
-  }
-  if (typeof a === 'number') {
-    return a - b;
-  }
-  if (typeof a === 'boolean') {
-    return a === b ? 0 : (a < b ? -1 : 1);
-  }
-  if (typeof a === 'string') {
-    return stringCollate(a, b);
-  }
-  if (Array.isArray(a)) {
-    return arrayCollate(a, b);
-  }
-  if (typeof a === 'object') {
-    return objectCollate(a, b);
-  }
-}
-
-// couch considers null/NaN/Infinity/-Infinity === undefined,
-// for the purposes of mapreduce indexes. also, dates get stringified.
-exports.normalizeKey = function (key) {
-  if (typeof key === 'undefined') {
-    return null;
-  } else if (typeof key === 'number') {
-    if (key === Infinity || key === -Infinity || isNaN(key)) {
-      return null;
-    }
-  } else if (key instanceof Date) {
-    return key.toJSON();
-  }
-  return key;
-}
-
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = exports.collate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-  }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
-}
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = exports.collate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = exports.collate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
-    }
-
-  }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
-}
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-// null/undefined/NaN/Infinity/-Infinity are all considered null
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  if (id.indexOf(typeof x) !== -1) {
-    if (x === null) {
-      return 1;
-    }
-    return id.indexOf(typeof x) + 2;
-  }
-  if (Array.isArray(x)) {
-    return 4.5;
-  }
-}
-
-},{}],37:[function(_dereq_,module,exports){
-module.exports={
-  "name": "pouchdb",
-  "version": "2.0.0",
-  "description": "PouchDBVersion200 is a pocket-sized database.",
-  "release": "nightly",
-  "main": "./lib/index.js",
-  "homepage": "https://github.com/daleharvey/pouchdb",
-  "repository": "https://github.com/daleharvey/pouchdb",
-  "keywords": [
-    "db",
-    "couchdb",
-    "pouchdb"
-  ],
-  "tags": [
-    "db",
-    "couchdb",
-    "pouchdb"
-  ],
-  "dependencies": {
-    "request": "~2.28.0",
-    "pouchdb-mapreduce": "1.0.0",
-    "bluebird": "~1.0.0",
-    "level-sublevel": "~5.2.0",
-    "levelup": "~0.18.2",
-    "leveldown": "~0.10.2",
-    "inherits": "~2.0.1"
-  },
-  "devDependencies": {
-    "commander": "~2.1.0",
-    "watchify": "~0.4.1",
-    "uglify-js": "~2.4.6",
-    "jshint": "~2.3.0",
-    "http-proxy": "~0.10.3",
-    "corsproxy": "~0.2.13",
-    "http-server": "~0.5.5",
-    "browserify": "~3.24.13",
-    "lie": "~2.5.2",
-    "wd": "~0.2.8",
-    "tin": "~0.4.0",
-    "qunit-mocha-ui": "0.0.5",
-    "mocha": "~1.17.1",
-    "chai": "~1.9.0",
-    "istanbul": "~0.2.4",
-    "ncp": "~0.5.0"
-  },
-  "scripts": {
-    "jshint": "jshint -c .jshintrc bin/ lib/ tests/*.js",
-    "build-js": "browserify lib/index.js -s PouchDBVersion200 -o dist/pouchdb-nightly.js",
-    "uglify": "uglifyjs dist/pouchdb-nightly.js -mc > dist/pouchdb-nightly.min.js",
-    "build": "mkdir -p dist && npm run build-js && npm run uglify",
-    "test-node": "./bin/run-mocha.sh",
-    "test-browser": "mkdir -p dist && npm run build-js && ./bin/test-browser.js",
-    "dev": "./bin/dev-server.js",
-    "test": "npm run jshint && ./bin/run-test.sh",
-    "publish": "./bin/publish.sh",
-    "publish-site": "./bin/publish-site.sh"
-  },
-  "browser": {
-    "./adapters/leveldb": false,
-    "./deps/buffer": false,
-    "request": false,
-    "levelup": false,
-    "leveldown": false,
-    "crypto": false,
-    "bluebird": "lie",
-    "level-sublevel": false
-  }
-}
-
-},{}]},{},[13])
-(13)
-});
\ No newline at end of file
diff --git a/tests/integration/deps/pouchdb-2.2.0-postfixed.js b/tests/integration/deps/pouchdb-2.2.0-postfixed.js
deleted file mode 100644
index b963c6c..0000000
--- a/tests/integration/deps/pouchdb-2.2.0-postfixed.js
+++ /dev/null
@@ -1,8733 +0,0 @@
-!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.PouchDBVersion220=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-module.exports = "2.2.0";
-
-},{}],2:[function(_dereq_,module,exports){
-"use strict";
-
-var utils = _dereq_('./utils');
-var merge = _dereq_('./merge');
-var errors = _dereq_('./deps/errors');
-var EventEmitter = _dereq_('events').EventEmitter;
-var upsert = _dereq_('./deps/upsert');
-var Changes = _dereq_('./changes');
-var Promise = utils.Promise;
-
-/*
- * A generic pouch adapter
- */
-
-// returns first element of arr satisfying callback predicate
-function arrayFirst(arr, callback) {
-  for (var i = 0; i < arr.length; i++) {
-    if (callback(arr[i], i) === true) {
-      return arr[i];
-    }
-  }
-  return false;
-}
-
-// Wrapper for functions that call the bulkdocs api with a single doc,
-// if the first result is an error, return an error
-function yankError(callback) {
-  return function (err, results) {
-    if (err || results[0].error) {
-      callback(err || results[0]);
-    } else {
-      callback(null, results[0]);
-    }
-  };
-}
-
-// for every node in a revision tree computes its distance from the closest
-// leaf
-function computeHeight(revs) {
-  var height = {};
-  var edges = [];
-  merge.traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
-    var rev = pos + "-" + id;
-    if (isLeaf) {
-      height[rev] = 0;
-    }
-    if (prnt !== undefined) {
-      edges.push({from: prnt, to: rev});
-    }
-    return rev;
-  });
-
-  edges.reverse();
-  edges.forEach(function (edge) {
-    if (height[edge.from] === undefined) {
-      height[edge.from] = 1 + height[edge.to];
-    } else {
-      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
-    }
-  });
-  return height;
-}
-
-function allDocsKeysQuery(api, opts, callback) {
-  var keys =  ('limit' in opts) ?
-      opts.keys.slice(opts.skip, opts.limit + opts.skip) :
-      (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
-  if (opts.descending) {
-    keys.reverse();
-  }
-  if (!keys.length) {
-    return api._allDocs({limit: 0}, callback);
-  }
-  var finalResults = {
-    offset: opts.skip
-  };
-  return Promise.all(keys.map(function (key, i) {
-    var subOpts = utils.extend(true, {key: key, deleted: 'ok'}, opts);
-    ['limit', 'skip', 'keys'].forEach(function (optKey) {
-      delete subOpts[optKey];
-    });
-    return new Promise(function (resolve, reject) {
-      api._allDocs(subOpts, function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        finalResults.total_rows = res.total_rows;
-        resolve(res.rows[0] || {key: key, error: 'not_found'});
-      });
-    });
-  })).then(function (results) {
-    finalResults.rows = results;
-    return finalResults;
-  });
-}
-
-utils.inherits(AbstractPouchDBVersion220, EventEmitter);
-module.exports = AbstractPouchDBVersion220;
-
-function AbstractPouchDBVersion220() {
-  var self = this;
-  EventEmitter.call(this);
-  self.autoCompact = function (callback) {
-    if (!self.auto_compaction) {
-      return callback;
-    }
-    return function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        var count = res.length;
-        var decCount = function () {
-          count--;
-          if (!count) {
-            callback(null, res);
-          }
-        };
-        res.forEach(function (doc) {
-          if (doc.ok) {
-            // TODO: we need better error handling
-            self.compactDocument(doc.id, 1, decCount);
-          } else {
-            decCount();
-          }
-        });
-      }
-    };
-  };
-
-  var listeners = 0, changes;
-  var eventNames = ['change', 'delete', 'create', 'update'];
-  this.on('newListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      if (listeners) {
-        listeners++;
-        return;
-      } else {
-        listeners++;
-      }
-    } else {
-      return;
-    }
-    var lastChange = 0;
-    changes = this.changes({
-      conflicts: true,
-      include_docs: true,
-      continuous: true,
-      since: 'latest',
-      onChange: function (change) {
-        if (change.seq <= lastChange) {
-          return;
-        }
-        lastChange = change.seq;
-        self.emit('change', change);
-        if (change.doc._deleted) {
-          self.emit('delete', change);
-        } else if (change.doc._rev.split('-')[0] === '1') {
-          self.emit('create', change);
-        } else {
-          self.emit('update', change);
-        }
-      }
-    });
-  });
-  this.on('removeListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      listeners--;
-      if (listeners) {
-        return;
-      }
-    } else {
-      return;
-    }
-    changes.cancel();
-  });
-}
-
-AbstractPouchDBVersion220.prototype.post =
-  utils.adapterFun('post', function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-});
-
-AbstractPouchDBVersion220.prototype.put =
-  utils.adapterFun('put', utils.getArguments(function (args) {
-  var temp, temptype, opts, callback;
-  var doc = args.shift();
-  var id = '_id' in doc;
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    callback = args.pop();
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  doc = utils.clone(doc);
-  while (true) {
-    temp = args.shift();
-    temptype = typeof temp;
-    if (temptype === "string" && !id) {
-      doc._id = temp;
-      id = true;
-    } else if (temptype === "string" && id && !('_rev' in doc)) {
-      doc._rev = temp;
-    } else if (temptype === "object") {
-      opts = temp;
-    } else if (temptype === "function") {
-      callback = temp;
-    }
-    if (!args.length) {
-      break;
-    }
-  }
-  opts = opts || {};
-  var error = utils.invalidIdError(doc._id);
-  if (error) {
-    return callback(error);
-  }
-  this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-}));
-
-AbstractPouchDBVersion220.prototype.putAttachment =
-  utils.adapterFun('putAttachment', function (docId, attachmentId, rev,
-                                              blob, type, callback) {
-  var api = this;
-  if (typeof type === 'function') {
-    callback = type;
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-  if (typeof type === 'undefined') {
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-
-  function createAttachment(doc) {
-    doc._attachments = doc._attachments || {};
-    doc._attachments[attachmentId] = {
-      content_type: type,
-      data: blob
-    };
-    return api.put(doc);
-  }
-
-  return api.get(docId).then(function (doc) {
-    if (doc._rev !== rev) {
-      throw errors.REV_CONFLICT;
-    }
-
-    return createAttachment(doc);
-  }, function (err) {
-     // create new doc
-    if (err.error === errors.MISSING_DOC.error) {
-      return createAttachment({_id: docId});
-    } else {
-      throw err;
-    }
-  });
-});
-
-AbstractPouchDBVersion220.prototype.removeAttachment =
-  utils.adapterFun('removeAttachment', function (docId, attachmentId, rev,
-                                                 callback) {
-  var self = this;
-  self.get(docId, function (err, obj) {
-    if (err) {
-      callback(err);
-      return;
-    }
-    if (obj._rev !== rev) {
-      callback(errors.REV_CONFLICT);
-      return;
-    }
-    if (!obj._attachments) {
-      return callback();
-    }
-    delete obj._attachments[attachmentId];
-    if (Object.keys(obj._attachments).length === 0) {
-      delete obj._attachments;
-    }
-    self.put(obj, callback);
-  });
-});
-
-AbstractPouchDBVersion220.prototype.remove =
-  utils.adapterFun('remove', function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  } else if (typeof opts === 'string') {
-    doc = {
-      _id: doc,
-      _rev: opts
-    };
-  } else if (opts === undefined) {
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  opts.was_delete = true;
-  var newDoc = {_id: doc._id, _rev: doc._rev};
-  newDoc._deleted = true;
-  this.bulkDocs({docs: [newDoc]}, opts, yankError(callback));
-});
-
-AbstractPouchDBVersion220.prototype.revsDiff =
-  utils.adapterFun('revsDiff', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  var ids = Object.keys(req);
-  var count = 0;
-  var missing = {};
-
-  function addToMissing(id, revId) {
-    if (!missing[id]) {
-      missing[id] = {missing: []};
-    }
-    missing[id].missing.push(revId);
-  }
-
-  function processDoc(id, rev_tree) {
-    // Is this fast enough? Maybe we should switch to a set simulated by a map
-    var missingForId = req[id].slice(0);
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
-      opts) {
-        var rev = pos + '-' + revHash;
-        var idx = missingForId.indexOf(rev);
-        if (idx === -1) {
-          return;
-        }
-
-        missingForId.splice(idx, 1);
-        if (opts.status !== 'available') {
-          addToMissing(id, rev);
-        }
-      });
-
-    // Traversing the tree is synchronous, so now `missingForId` contains
-    // revisions that were not found in the tree
-    missingForId.forEach(function (rev) {
-      addToMissing(id, rev);
-    });
-  }
-
-  ids.map(function (id) {
-    this._getRevisionTree(id, function (err, rev_tree) {
-      if (err && err.name === 'not_found' && err.message === 'missing') {
-        missing[id] = {missing: req[id]};
-      } else if (err) {
-        return callback(err);
-      } else {
-        processDoc(id, rev_tree);
-      }
-
-      if (++count === ids.length) {
-        return callback(null, missing);
-      }
-    });
-  }, this);
-});
-
-// compact one document and fire callback
-// by compacting we mean removing all revisions which
-// are further from the leaf in revision tree than max_height
-AbstractPouchDBVersion220.prototype.compactDocument =
-  function (docId, max_height, callback) {
-  var self = this;
-  this._getRevisionTree(docId, function (err, rev_tree) {
-    if (err) {
-      return callback(err);
-    }
-    var height = computeHeight(rev_tree);
-    var candidates = [];
-    var revs = [];
-    Object.keys(height).forEach(function (rev) {
-      if (height[rev] > max_height) {
-        candidates.push(rev);
-      }
-    });
-
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, opts) {
-      var rev = pos + '-' + revHash;
-      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
-        opts.status = 'missing';
-        revs.push(rev);
-      }
-    });
-    self._doCompaction(docId, rev_tree, revs, callback);
-  });
-};
-
-// compact the whole database using single document
-// compaction
-AbstractPouchDBVersion220.prototype.compact =
-  utils.adapterFun('compact', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  var self = this;
-  this.changes({complete: function (err, res) {
-    if (err) {
-      callback(); // TODO: silently fail
-      return;
-    }
-    var count = res.results.length;
-    if (!count) {
-      callback();
-      return;
-    }
-    res.results.forEach(function (row) {
-      self.compactDocument(row.id, 0, function () {
-        count--;
-        if (!count) {
-          callback();
-        }
-      });
-    });
-  }});
-});
-
-/* Begin api wrappers. Specific functionality to storage belongs in the 
-   _[method] */
-AbstractPouchDBVersion220.prototype.get =
-  utils.adapterFun('get', function (id, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof id !== 'string') {
-    return callback(errors.INVALID_ID);
-  }
-  var leaves = [], self = this;
-  function finishOpenRevs() {
-    var result = [];
-    var count = leaves.length;
-    if (!count) {
-      return callback(null, result);
-    }
-    // order with open_revs is unspecified
-    leaves.forEach(function (leaf) {
-      self.get(id,
-               {rev: leaf, revs: opts.revs, attachments: opts.attachments},
-               function (err, doc) {
-        if (!err) {
-          result.push({ok: doc});
-        } else {
-          result.push({missing: leaf});
-        }
-        count--;
-        if (!count) {
-          callback(null, result);
-        }
-      });
-    });
-  }
-
-  if (opts.open_revs) {
-    if (opts.open_revs === "all") {
-      this._getRevisionTree(id, function (err, rev_tree) {
-        if (err) {
-          // if there's no such document we should treat this
-          // situation the same way as if revision tree was empty
-          rev_tree = [];
-        }
-        leaves = merge.collectLeaves(rev_tree).map(function (leaf) {
-          return leaf.rev;
-        });
-        finishOpenRevs();
-      });
-    } else {
-      if (Array.isArray(opts.open_revs)) {
-        leaves = opts.open_revs;
-        for (var i = 0; i < leaves.length; i++) {
-          var l = leaves[i];
-          // looks like it's the only thing couchdb checks
-          if (!(typeof(l) === "string" && /^\d+-/.test(l))) {
-            return callback(errors.error(errors.BAD_REQUEST,
-              "Invalid rev format"));
-          }
-        }
-        finishOpenRevs();
-      } else {
-        return callback(errors.error(errors.UNKNOWN_ERROR,
-          'function_clause'));
-      }
-    }
-    return; // open_revs does not like other options
-  }
-
-  return this._get(id, opts, function (err, result) {
-    opts = utils.clone(opts);
-    if (err) {
-      return callback(err);
-    }
-
-    var doc = result.doc;
-    if (!doc) {
-      // a smoke test for something being very wrong
-      return callback(new Error('no doc!'));
-    }
-    var metadata = result.metadata;
-    var ctx = result.ctx;
-
-    if (opts.conflicts) {
-      var conflicts = merge.collectConflicts(metadata);
-      if (conflicts.length) {
-        doc._conflicts = conflicts;
-      }
-    }
-
-    if (opts.revs || opts.revs_info) {
-      var paths = merge.rootToLeaf(metadata.rev_tree);
-      var path = arrayFirst(paths, function (arr) {
-        return arr.ids.map(function (x) { return x.id; })
-          .indexOf(doc._rev.split('-')[1]) !== -1;
-      });
-
-      path.ids.splice(path.ids.map(function (x) {return x.id; })
-                      .indexOf(doc._rev.split('-')[1]) + 1);
-      path.ids.reverse();
-
-      if (opts.revs) {
-        doc._revisions = {
-          start: (path.pos + path.ids.length) - 1,
-          ids: path.ids.map(function (rev) {
-            return rev.id;
-          })
-        };
-      }
-      if (opts.revs_info) {
-        var pos =  path.pos + path.ids.length;
-        doc._revs_info = path.ids.map(function (rev) {
-          pos--;
-          return {
-            rev: pos + '-' + rev.id,
-            status: rev.opts.status
-          };
-        });
-      }
-    }
-
-    if (opts.local_seq) {
-      doc._local_seq = result.metadata.seq;
-    }
-
-    if (opts.attachments && doc._attachments) {
-      var attachments = doc._attachments;
-      var count = Object.keys(attachments).length;
-      if (count === 0) {
-        return callback(null, doc);
-      }
-      Object.keys(attachments).forEach(function (key) {
-        this._getAttachment(attachments[key],
-                            {encode: true, ctx: ctx}, function (err, data) {
-          doc._attachments[key].data = data;
-          if (!--count) {
-            callback(null, doc);
-          }
-        });
-      }, self);
-    } else {
-      if (doc._attachments) {
-        for (var key in doc._attachments) {
-          if (doc._attachments.hasOwnProperty(key)) {
-            doc._attachments[key].stub = true;
-          }
-        }
-      }
-      callback(null, doc);
-    }
-  });
-});
-
-AbstractPouchDBVersion220.prototype.getAttachment =
-  utils.adapterFun('getAttachment', function (docId, attachmentId, opts,
-                                              callback) {
-  var self = this;
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  this._get(docId, opts, function (err, res) {
-    if (err) {
-      return callback(err);
-    }
-    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
-      opts.ctx = res.ctx;
-      self._getAttachment(res.doc._attachments[attachmentId], opts, callback);
-    } else {
-      return callback(errors.MISSING_DOC);
-    }
-  });
-});
-
-AbstractPouchDBVersion220.prototype.allDocs =
-  utils.adapterFun('allDocs', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
-  if ('keys' in opts) {
-    if (!Array.isArray(opts.keys)) {
-      return callback(new TypeError('options.keys must be an array'));
-    }
-    var incompatibleOpt =
-      ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
-      return incompatibleOpt in opts;
-    })[0];
-    if (incompatibleOpt) {
-      callback(errors.error(errors.QUERY_PARSE_ERROR,
-        'Query parameter `' + incompatibleOpt +
-        '` is not compatible with multi-get'
-      ));
-      return;
-    }
-    if (this.type() !== 'http') {
-      return allDocsKeysQuery(this, opts, callback);
-    }
-  }
-
-  return this._allDocs(opts, callback);
-});
-
-AbstractPouchDBVersion220.prototype.changes = function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  return new Changes(this, opts, callback);
-};
-
-AbstractPouchDBVersion220.prototype.close =
-  utils.adapterFun('close', function (callback) {
-  return this._close(callback);
-});
-
-AbstractPouchDBVersion220.prototype.info = utils.adapterFun('info', function (callback) {
-  var self = this;
-  this._info(function (err, info) {
-    if (err) {
-      return callback(err);
-    }
-    var len = self.prefix.length;
-    if (info.db_name.length > len &&
-        info.db_name.slice(0, len) === self.prefix) {
-      info.db_name = info.db_name.slice(len);
-    }
-    callback(null, info);
-  });
-});
-
-AbstractPouchDBVersion220.prototype.id = utils.adapterFun('id', function (callback) {
-  return this._id(callback);
-});
-
-AbstractPouchDBVersion220.prototype.type = function () {
-  return (typeof this._type === 'function') ? this._type() : this.adapter;
-};
-
-AbstractPouchDBVersion220.prototype.bulkDocs =
-  utils.adapterFun('bulkDocs', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-
-  opts = utils.clone(opts);
-
-  if (Array.isArray(req)) {
-    req = {
-      docs: req
-    };
-  }
-
-  if (!req || !req.docs || !Array.isArray(req.docs)) {
-    return callback(errors.MISSING_BULK_DOCS);
-  }
-
-  for (var i = 0; i < req.docs.length; ++i) {
-    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-  }
-
-  req = utils.clone(req);
-  if (!('new_edits' in opts)) {
-    if ('new_edits' in req) {
-      opts.new_edits = req.new_edits;
-    } else {
-      opts.new_edits = true;
-    }
-  }
-
-  return this._bulkDocs(req, opts, this.autoCompact(callback));
-});
-
-AbstractPouchDBVersion220.prototype.registerDependentDatabase =
-  utils.adapterFun('registerDependentDatabase', function (dependentDb,
-                                                          callback) {
-  var depDB = new this.constructor(dependentDb, {adapter: this._adapter});
-  function diffFun(doc) {
-    doc.dependentDbs = doc.dependentDbs || {};
-    if (doc.dependentDbs[dependentDb]) {
-      return false; // no update required
-    }
-    doc.dependentDbs[dependentDb] = true;
-    return doc;
-  }
-  upsert(this, '_local/_pouch_dependentDbs', diffFun, function (err) {
-    if (err) {
-      return callback(err);
-    }
-    return callback(null, {db: depDB});
-  });
-});
-
-},{"./changes":6,"./deps/errors":10,"./deps/upsert":11,"./merge":16,"./utils":21,"events":24}],3:[function(_dereq_,module,exports){
-"use strict";
-
-var utils = _dereq_('../utils');
-var errors = _dereq_('../deps/errors');
-// parseUri 1.2.2
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-function parseUri(str) {
-  var o = parseUri.options;
-  var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
-  var uri = {};
-  var i = 14;
-
-  while (i--) {
-    uri[o.key[i]] = m[i] || "";
-  }
-
-  uri[o.q.name] = {};
-  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
-    if ($1) {
-      uri[o.q.name][$1] = $2;
-    }
-  });
-
-  return uri;
-}
-
-function encodeDocId(id) {
-  if (/^_(design|local)/.test(id)) {
-    return id;
-  }
-  return encodeURIComponent(id);
-}
-
-parseUri.options = {
-  strictMode: false,
-  key: ["source", "protocol", "authority", "userInfo", "user", "password",
-        "host", "port", "relative", "path", "directory", "file", "query",
-        "anchor"],
-  q:   {
-    name:   "queryKey",
-    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
-  },
-  parser: {
-    /* jshint maxlen: false */
-    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
-    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
-  }
-};
-
-// Get all the information you possibly can about the URI given by name and
-// return it as a suitable object.
-function getHost(name, opts) {
-  // If the given name contains "http:"
-  if (/http(s?):/.test(name)) {
-    // Prase the URI into all its little bits
-    var uri = parseUri(name);
-
-    // Store the fact that it is a remote URI
-    uri.remote = true;
-
-    // Store the user and password as a separate auth object
-    if (uri.user || uri.password) {
-      uri.auth = {username: uri.user, password: uri.password};
-    }
-
-    // Split the path part of the URI into parts using '/' as the delimiter
-    // after removing any leading '/' and any trailing '/'
-    var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
-
-    // Store the first part as the database name and remove it from the parts
-    // array
-    uri.db = parts.pop();
-
-    // Restore the path by joining all the remaining parts (all the parts
-    // except for the database name) with '/'s
-    uri.path = parts.join('/');
-    opts = opts || {};
-    opts = utils.clone(opts);
-    uri.headers = opts.headers || {};
-
-    if (opts.auth || uri.auth) {
-      var nAuth = opts.auth || uri.auth;
-      var token = utils.btoa(nAuth.username + ':' + nAuth.password);
-      uri.headers.Authorization = 'Basic ' + token;
-    }
-
-    if (opts.headers) {
-      uri.headers = opts.headers;
-    }
-
-    return uri;
-  }
-
-  // If the given name does not contain 'http:' then return a very basic object
-  // with no host, the current path, the given name as the database name and no
-  // username/password
-  return {host: '', path: '/', db: name, auth: false};
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genDBUrl(opts, path) {
-  return genUrl(opts, opts.db + '/' + path);
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genUrl(opts, path) {
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' +
-           opts.path + pathDel + path;
-  }
-
-  return '/' + path;
-}
-// Implements the PouchDBVersion220 API for dealing with CouchDB instances over HTTP
-function HttpPouch(opts, callback) {
-  // The functions that will be publicly available for HttpPouch
-  var api = this;
-  api.getHost = opts.getHost ? opts.getHost : getHost;
-
-  // Parse the URI given by opts.name into an easy-to-use object
-  var host = api.getHost(opts.name, opts);
-
-  // Generate the database URL based on the host
-  var dbUrl = genDBUrl(host, '');
-
-  api.getUrl = function () {return dbUrl; };
-
-  var ajaxOpts = opts.ajax || {};
-  opts = utils.clone(opts);
-  function ajax(options, callback) {
-    return utils.ajax(utils.extend({}, ajaxOpts, options), callback);
-  }
-  var uuids = {
-    list: [],
-    get: function (opts, callback) {
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {count: 10};
-      }
-      var cb = function (err, body) {
-        if (err || !('uuids' in body)) {
-          callback(err || errors.UNKNOWN_ERROR);
-        } else {
-          uuids.list = uuids.list.concat(body.uuids);
-          callback(null, "OK");
-        }
-      };
-      var params = '?count=' + opts.count;
-      ajax({
-        headers: host.headers,
-        method: 'GET',
-        url: genUrl(host, '_uuids') + params
-      }, cb);
-    }
-  };
-
-  // Create a new CouchDB database based on the given opts
-  var createDB = function () {
-    ajax({headers: host.headers, method: 'PUT', url: dbUrl},
-         function (err, ret) {
-      // If we get an "Unauthorized" error
-      if (err && err.status === 401) {
-        // Test if the database already exists
-        ajax({headers: host.headers, method: 'HEAD', url: dbUrl},
-             function (err, ret) {
-          // If there is still an error
-          if (err) {
-            // Give the error to the callback to deal with
-            callback(err);
-          } else {
-            // Continue as if there had been no errors
-            callback(null, api);
-          }
-        });
-        // If there were no errros or if the only error is "Precondition Failed"
-        // (note: "Precondition Failed" occurs when we try to create a database
-        // that already exists)
-      } else if (!err || err.status === 412) {
-        // Continue as if there had been no errors
-        callback(null, api);
-      } else {
-        callback(err);
-      }
-    });
-  };
-  if (!opts.skipSetup) {
-    ajax({headers: host.headers, method: 'GET', url: dbUrl},
-         function (err, ret) {
-      //check if the db exists
-      if (err) {
-        if (err.status === 404) {
-          //if it doesn't, create it
-          createDB();
-        } else {
-          callback(err);
-        }
-      } else {
-        //go do stuff with the db
-        callback(null, api);
-      }
-    });
-  }
-
-  api.type = function () {
-    return 'http';
-  };
-
-  api.id = utils.adapterFun('id', function (callback) {
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genUrl(host, '')
-    }, function (err, result) {
-      var uuid = (result && result.uuid) ?
-        result.uuid + host.db : genDBUrl(host, '');
-      callback(null, uuid);
-    });
-  });
-
-  api.request = utils.adapterFun('request', function (options, callback) {
-    options.headers = host.headers;
-    options.url = genDBUrl(host, options.url);
-    ajax(options, callback);
-  });
-
-  // Sends a POST request to the host calling the couchdb _compact function
-  //    version: The version of CouchDB it is running
-  api.compact = utils.adapterFun('compact', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    ajax({
-      headers: host.headers,
-      url: genDBUrl(host, '_compact'),
-      method: 'POST'
-    }, function () {
-      function ping() {
-        api.info(function (err, res) {
-          if (!res.compact_running) {
-            callback();
-          } else {
-            setTimeout(ping, opts.interval || 200);
-          }
-        });
-      }
-      // Ping the http if it's finished compaction
-      if (typeof callback === "function") {
-        ping();
-      }
-    });
-  });
-
-  // Calls GET on the host, which gets back a JSON string containing
-  //    couchdb: A welcome string
-  //    version: The version of CouchDB it is running
-  api._info = function (callback) {
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, '')
-    }, function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        res.host = genDBUrl(host, '');
-        callback(null, res);
-      }
-    });
-  };
-
-  // Get the document with the given id from the database given by host.
-  // The id could be solely the _id in the database, or it may be a
-  // _design/ID or _local/ID path
-  api.get = utils.adapterFun('get', function (id, opts, callback) {
-    // If no options were given, set the callback to the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-
-    // List of parameters to add to the GET request
-    var params = [];
-
-    // If it exists, add the opts.revs value to the list of parameters.
-    // If revs=true then the resulting JSON will include a field
-    // _revisions containing an array of the revision IDs.
-    if (opts.revs) {
-      params.push('revs=true');
-    }
-
-    // If it exists, add the opts.revs_info value to the list of parameters.
-    // If revs_info=true then the resulting JSON will include the field
-    // _revs_info containing an array of objects in which each object
-    // representing an available revision.
-    if (opts.revs_info) {
-      params.push('revs_info=true');
-    }
-
-    if (opts.local_seq) {
-      params.push('local_seq=true');
-    }
-    // If it exists, add the opts.open_revs value to the list of parameters.
-    // If open_revs=all then the resulting JSON will include all the leaf
-    // revisions. If open_revs=["rev1", "rev2",...] then the resulting JSON
-    // will contain an array of objects containing data of all revisions
-    if (opts.open_revs) {
-      if (opts.open_revs !== "all") {
-        opts.open_revs = JSON.stringify(opts.open_revs);
-      }
-      params.push('open_revs=' + opts.open_revs);
-    }
-
-    // If it exists, add the opts.attachments value to the list of parameters.
-    // If attachments=true the resulting JSON will include the base64-encoded
-    // contents in the "data" property of each attachment.
-    if (opts.attachments) {
-      params.push('attachments=true');
-    }
-
-    // If it exists, add the opts.rev value to the list of parameters.
-    // If rev is given a revision number then get the specified revision.
-    if (opts.rev) {
-      params.push('rev=' + opts.rev);
-    }
-
-    // If it exists, add the opts.conflicts value to the list of parameters.
-    // If conflicts=true then the resulting JSON will include the field
-    // _conflicts containing all the conflicting revisions.
-    if (opts.conflicts) {
-      params.push('conflicts=' + opts.conflicts);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
-
-    if (opts.auto_encode) {
-      id = encodeDocId(id);
-    }
-
-    // Set the options for the ajax call
-    var options = {
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, id + params)
-    };
-
-    // If the given id contains at least one '/' and the part before the '/'
-    // is NOT "_design" and is NOT "_local"
-    // OR
-    // If the given id contains at least two '/' and the part before the first
-    // '/' is "_design".
-    // TODO This second condition seems strange since if parts[0] === '_design'
-    // then we already know that parts[0] !== '_local'.
-    var parts = id.split('/');
-    if ((parts.length > 1 && parts[0] !== '_design' && parts[0] !== '_local') ||
-        (parts.length > 2 && parts[0] === '_design' && parts[0] !== '_local')) {
-      // Binary is expected back from the server
-      options.binary = true;
-    }
-
-    // Get the document
-    ajax(options, function (err, doc, xhr) {
-      // If the document does not exist, send an error to the callback
-      if (err) {
-        return callback(err);
-      }
-
-      // Send the document to the callback
-      callback(null, doc, xhr);
-    });
-  });
-
-  // Delete the document given by doc from the database given by host.
-  api.remove = utils.adapterFun('remove', function (doc, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }  else if (typeof opts === 'string') {
-      doc = {
-        _id: doc,
-        _rev: opts
-      };
-    } else if (opts === undefined) {
-      opts = {};
-    }
-    // Delete the document
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + doc._rev
-    }, callback);
-  });
-
-  // Get the attachment
-  api.getAttachment =
-    utils.adapterFun('getAttachment', function (docId, attachmentId, opts,
-                                                callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-    if (opts.auto_encode) {
-      docId = encodeDocId(docId);
-    }
-    opts.auto_encode = false;
-    api.get(docId + '/' + attachmentId, opts, callback);
-  });
-
-  // Remove the attachment given by the id and rev
-  api.removeAttachment =
-    utils.adapterFun('removeAttachment', function (docId, attachmentId, rev,
-                                                   callback) {
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(docId) + '/' + attachmentId) + '?rev=' +
-           rev
-    }, callback);
-  });
-
-  // Add the attachment given by blob and its contentType property
-  // to the document with the given id, the revision given by rev, and
-  // add it to the database given by host.
-  api.putAttachment =
-    utils.adapterFun('putAttachment', function (docId, attachmentId, rev, blob,
-                                                type, callback) {
-    if (typeof type === 'function') {
-      callback = type;
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    if (typeof type === 'undefined') {
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    var id = encodeDocId(docId) + '/' + attachmentId;
-    var url = genDBUrl(host, id);
-    if (rev) {
-      url += '?rev=' + rev;
-    }
-
-    var opts = {
-      headers: host.headers,
-      method: 'PUT',
-      url: url,
-      processData: false,
-      body: blob,
-      timeout: 60000
-    };
-    opts.headers['Content-Type'] = type;
-    // Add the attachment
-    ajax(opts, callback);
-  });
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This fails if the doc has no _id field.
-  api.put = utils.adapterFun('put', utils.getArguments(function (args) {
-    var temp, temptype, opts, callback;
-    var doc = args.shift();
-    var id = '_id' in doc;
-    if (typeof doc !== 'object' || Array.isArray(doc)) {
-      callback = args.pop();
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    doc = utils.clone(doc);
-    while (true) {
-      temp = args.shift();
-      temptype = typeof temp;
-      if (temptype === "string" && !id) {
-        doc._id = temp;
-        id = true;
-      } else if (temptype === "string" && id && !('_rev' in doc)) {
-        doc._rev = temp;
-      } else if (temptype === "object") {
-        opts = utils.clone(temp);
-      } else if (temptype === "function") {
-        callback = temp;
-      }
-      if (!args.length) {
-        break;
-      }
-    }
-    opts = opts || {};
-    var error = utils.invalidIdError(doc._id);
-    if (error) {
-      return callback(error);
-    }
-
-    // List of parameter to add to the PUT request
-    var params = [];
-
-    // If it exists, add the opts.new_edits value to the list of parameters.
-    // If new_edits = false then the database will NOT assign this document a
-    // new revision number
-    if (opts && typeof opts.new_edits !== 'undefined') {
-      params.push('new_edits=' + opts.new_edits);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    // Add the document
-    ajax({
-      headers: host.headers,
-      method: 'PUT',
-      url: genDBUrl(host, encodeDocId(doc._id)) + params,
-      body: doc
-    }, callback);
-  }));
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This does not assume that doc is a new document 
-  // (i.e. does not have a _id or a _rev field.)
-  api.post = utils.adapterFun('post', function (doc, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (typeof doc !== 'object') {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    if (! ("_id" in doc)) {
-      if (uuids.list.length > 0) {
-        doc._id = uuids.list.pop();
-        api.put(doc, opts, callback);
-      } else {
-        uuids.get(function (err, resp) {
-          if (err) {
-            return callback(errors.UNKNOWN_ERROR);
-          }
-          doc._id = uuids.list.pop();
-          api.put(doc, opts, callback);
-        });
-      }
-    } else {
-      api.put(doc, opts, callback);
-    }
-  });
-
-  // Update/create multiple documents given by req in the database
-  // given by host.
-  api._bulkDocs = function (req, opts, callback) {
-    // If opts.new_edits exists add it to the document data to be
-    // send to the database.
-    // If new_edits=false then it prevents the database from creating
-    // new revision numbers for the documents. Instead it just uses
-    // the old ones. This is used in database replication.
-    if (typeof opts.new_edits !== 'undefined') {
-      req.new_edits = opts.new_edits;
-    }
-
-    // Update/create the documents
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_bulk_docs'),
-      body: req
-    }, callback);
-  };
-
-  // Get a listing of the documents in the database given
-  // by host and ordered by increasing id.
-  api.allDocs = utils.adapterFun('allDocs', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    // List of parameters to add to the GET request
-    var params = [];
-    var body;
-    var method = 'GET';
-
-    // TODO I don't see conflicts as a valid parameter for a
-    // _all_docs request 
-    // (see http://wiki.apache.org/couchdb/HTTP_Document_API#all_docs)
-    if (opts.conflicts) {
-      params.push('conflicts=true');
-    }
-
-    // If opts.descending is truthy add it to params
-    if (opts.descending) {
-      params.push('descending=true');
-    }
-
-    // If opts.include_docs exists, add the include_docs value to the
-    // list of parameters.
-    // If include_docs=true then include the associated document with each
-    // result.
-    if (opts.include_docs) {
-      params.push('include_docs=true');
-    }
-
-    if (opts.key) {
-      params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
-    }
-
-    // If opts.startkey exists, add the startkey value to the list of
-    // parameters.
-    // If startkey is given then the returned list of documents will
-    // start with the document whose id is startkey.
-    if (opts.startkey) {
-      params.push('startkey=' +
-        encodeURIComponent(JSON.stringify(opts.startkey)));
-    }
-
-    // If opts.endkey exists, add the endkey value to the list of parameters.
-    // If endkey is given then the returned list of docuemnts will
-    // end with the document whose id is endkey.
-    if (opts.endkey) {
-      params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
-    }
-
-    if (typeof opts.inclusive_end !== 'undefined') {
-      params.push('inclusive_end=' + !!opts.inclusive_end);
-    }
-
-    // If opts.limit exists, add the limit value to the parameter list.
-    if (typeof opts.limit !== 'undefined') {
-      params.push('limit=' + opts.limit);
-    }
-
-    if (typeof opts.skip !== 'undefined') {
-      params.push('skip=' + opts.skip);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    if (typeof opts.keys !== 'undefined') {
-
-      var MAX_URL_LENGTH = 2000;
-      // according to http://stackoverflow.com/a/417184/680742,
-      // the de factor URL length limit is 2000 characters
-
-      var keysAsString =
-        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-        // If the keys are short enough, do a GET. we do this to work around
-        // Safari not understanding 304s on POSTs (see issue #1239)
-        params += (params.indexOf('?') !== -1 ? '&' : '?') + keysAsString;
-      } else {
-        // If keys are too long, issue a POST request to circumvent GET
-        // query string limits
-        // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-        method = 'POST';
-        body = JSON.stringify({keys: opts.keys});
-      }
-    }
-
-    // Get the document listing
-    ajax({
-      headers: host.headers,
-      method: method,
-      url: genDBUrl(host, '_all_docs' + params),
-      body: body
-    }, callback);
-  });
-
-  // Get a list of changes made to documents in the database given by host.
-  // TODO According to the README, there should be two other methods here,
-  // api.changes.addListener and api.changes.removeListener.
-  api._changes = function (opts) {
-    // We internally page the results of a changes request, this means
-    // if there is a large set of changes to be returned we can start
-    // processing them quicker instead of waiting on the entire
-    // set of changes to return and attempting to process them at once
-    var CHANGES_LIMIT = 25;
-
-    opts = utils.clone(opts);
-    opts.timeout = opts.timeout || 0;
-
-    // set timeout to 20s to prevent aborting via Ajax timeout
-    var params = { timeout: 20 * 1000 };
-    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
-    if (limit === 0) {
-      limit = 1;
-    }
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-    //
-    var leftToFetch = limit;
-
-    if (opts.style) {
-      params.style = opts.style;
-    }
-
-    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
-      params.include_docs = true;
-    }
-
-    if (opts.continuous) {
-      params.feed = 'longpoll';
-    }
-
-    if (opts.conflicts) {
-      params.conflicts = true;
-    }
-
-    if (opts.descending) {
-      params.descending = true;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-      if (opts.filter === '_view' &&
-          opts.view &&
-          typeof opts.view === 'string') {
-        params.view = opts.view;
-      }
-    }
-
-    // If opts.query_params exists, pass it through to the changes request.
-    // These parameters may be used by the filter on the source database.
-    if (opts.query_params && typeof opts.query_params === 'object') {
-      for (var param_name in opts.query_params) {
-        if (opts.query_params.hasOwnProperty(param_name)) {
-          params[param_name] = opts.query_params[param_name];
-        }
-      }
-    }
-
-    var xhr;
-    var lastFetchedSeq;
-
-    // Get all the changes starting wtih the one immediately after the
-    // sequence number given by since.
-    var fetch = function (since, callback) {
-      if (opts.aborted) {
-        return;
-      }
-      params.since = since;
-      if (opts.descending) {
-        if (limit) {
-          params.limit = leftToFetch;
-        }
-      } else {
-        params.limit = (!limit || leftToFetch > CHANGES_LIMIT) ?
-          CHANGES_LIMIT : leftToFetch;
-      }
-
-      var paramStr = '?' + Object.keys(params).map(function (k) {
-        return k + '=' + params[k];
-      }).join('&');
-
-      // Set the options for the ajax call
-      var xhrOpts = {
-        headers: host.headers,
-        method: 'GET',
-        url: genDBUrl(host, '_changes' + paramStr),
-        // _changes can take a long time to generate, especially when filtered
-        timeout: opts.timeout
-      };
-      lastFetchedSeq = since;
-
-      if (opts.aborted) {
-        return;
-      }
-
-      // Get the changes
-      xhr = ajax(xhrOpts, callback);
-    };
-
-    // If opts.since exists, get all the changes from the sequence
-    // number given by opts.since. Otherwise, get all the changes
-    // from the sequence number 0.
-    var fetchTimeout = 10;
-    var fetchRetryCount = 0;
-
-    var results = {results: []};
-
-    var fetched = function (err, res) {
-      if (opts.aborted) {
-        return;
-      }
-      var raw_results_length = 0;
-      // If the result of the ajax call (res) contains changes (res.results)
-      if (res && res.results) {
-        raw_results_length = res.results.length;
-        results.last_seq = res.last_seq;
-        // For each change
-        var req = {};
-        req.query = opts.query_params;
-        res.results = res.results.filter(function (c) {
-          leftToFetch--;
-          var ret = utils.filterChange(opts)(c);
-          if (ret) {
-            if (returnDocs) {
-              results.results.push(c);
-            }
-            utils.call(opts.onChange, c);
-          }
-          return ret;
-        });
-      } else if (err) {
-        // In case of an error, stop listening for changes and call
-        // opts.complete
-        opts.aborted = true;
-        utils.call(opts.complete, err);
-        return;
-      }
-
-      // The changes feed may have timed out with no results
-      // if so reuse last update sequence
-      if (res && res.last_seq) {
-        lastFetchedSeq = res.last_seq;
-      }
-
-      var finished = (limit && leftToFetch <= 0) ||
-        (res && raw_results_length < CHANGES_LIMIT) ||
-        (opts.descending);
-
-      if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
-        // Increase retry delay exponentially as long as errors persist
-        if (err) {
-          fetchRetryCount += 1;
-        } else {
-          fetchRetryCount = 0;
-        }
-        var timeoutMultiplier = 1 << fetchRetryCount;
-        var retryWait = fetchTimeout * timeoutMultiplier;
-        var maximumWait = opts.maximumWait || 30000;
-
-        if (retryWait > maximumWait) {
-          utils.call(opts.complete, err || errors.UNKNOWN_ERROR);
-          return;
-        }
-
-        // Queue a call to fetch again with the newest sequence number
-        setTimeout(function () { fetch(lastFetchedSeq, fetched); }, retryWait);
-      } else {
-        // We're done, call the callback
-        utils.call(opts.complete, null, results);
-      }
-    };
-
-    fetch(opts.since || 0, fetched);
-
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        opts.aborted = true;
-        if (xhr) {
-          xhr.abort();
-        }
-      }
-    };
-  };
-
-  // Given a set of document/revision IDs (given by req), tets the subset of
-  // those that do NOT correspond to revisions stored in the database.
-  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
-  api.revsDiff = utils.adapterFun('revsDif', function (req, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Get the missing document/revision IDs
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_revs_diff'),
-      body: req
-    }, function (err, res) {
-      callback(err, res);
-    });
-  });
-
-  api.close = utils.adapterFun('close', function (callback) {
-    callback();
-  });
-
-  function replicateOnServer(target, opts, promise, targetHostUrl) {
-    opts = utils.clone(opts);
-    var targetHost = api.getHost(targetHostUrl);
-    var params = {
-      source: host.db,
-      target: targetHost.protocol === host.protocol &&
-        targetHost.authority ===
-          host.authority ? targetHost.db : targetHost.source
-    };
-
-    if (opts.continuous) {
-      params.continuous = true;
-    }
-
-    if (opts.create_target) {
-      params.create_target = true;
-    }
-
-    if (opts.doc_ids) {
-      params.doc_ids = opts.doc_ids;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-    }
-
-    if (opts.query_params) {
-      params.query_params = opts.query_params;
-    }
-
-    var result = {};
-    var repOpts = {
-      headers: host.headers,
-      method: 'POST',
-      url: genUrl(host, '_replicate'),
-      body: params
-    };
-
-    var xhr;
-    promise.cancel = function () {
-      this.cancelled = true;
-      if (xhr && !result.ok) {
-        xhr.abort();
-      }
-      if (result._local_id) {
-        repOpts.body = {
-          replication_id: result._local_id
-        };
-      }
-      repOpts.body.cancel = true;
-      ajax(repOpts, function (err, resp, xhr) {
-        // If the replication cancel request fails, send an error to the
-        // callback
-        if (err) {
-          return callback(err);
-        }
-        // Send the replication cancel result to the complete callback
-        utils.call(opts.complete, null, result, xhr);
-      });
-    };
-
-    if (promise.cancelled) {
-      return;
-    }
-
-    xhr = ajax(repOpts, function (err, resp, xhr) {
-      // If the replication fails, send an error to the callback
-      if (err) {
-        return callback(err);
-      }
-
-      result.ok = true;
-
-      // Provided by CouchDB from 1.2.0 onward to cancel replication
-      if (resp._local_id) {
-        result._local_id = resp._local_id;
-      }
-
-      // Send the replication result to the complete callback
-      utils.call(opts.complete, null, resp, xhr);
-    });
-  }
-
-  api.replicateOnServer = function (target, opts, promise) {
-    if (!api.taskqueue.isReady) {
-      api.taskqueue.addTask('replicateOnServer', [target, opts, promise]);
-      return promise;
-    }
-    target.info(function (err, info) {
-      replicateOnServer(target, opts, promise, info.host);
-    });
-  };
-  api.destroy = utils.adapterFun('destroy', function (callback) {
-    ajax({
-      url: genDBUrl(host, ''),
-      method: 'DELETE',
-      headers: host.headers
-    }, function (err, resp) {
-      if (err) {
-        api.emit('error', err);
-        callback(err);
-      } else {
-        api.emit('destroyed');
-        callback(null, resp);
-      }
-    });
-  });
-}
-
-// Delete the HttpPouch specified by the given name.
-HttpPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  var host = getHost(name, opts);
-  opts = opts || {};
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  opts.headers = host.headers;
-  opts.method = 'DELETE';
-  opts.url = genDBUrl(host, '');
-  var ajaxOpts = opts.ajax || {};
-  opts = utils.extend({}, opts, ajaxOpts);
-  utils.ajax(opts, callback);
-});
-
-// HttpPouch is a valid adapter.
-HttpPouch.valid = function () {
-  return true;
-};
-
-module.exports = HttpPouch;
-
-},{"../deps/errors":10,"../utils":21}],4:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-
-function idbError(callback) {
-  return function (event) {
-    callback(errors.error(errors.IDB_ERROR, event.target, event.type));
-  };
-}
-
-function isModernIdb() {
-  // check for outdated implementations of IDB
-  // that rely on the setVersion method instead of onupgradeneeded (issue #1207)
-
-  // cache based on appVersion, in case the browser is updated
-  var cacheKey = "_pouch__checkModernIdb_" +
-    (global.navigator && global.navigator.appVersion);
-  var cached = utils.hasLocalStorage() && global.localStorage[cacheKey];
-  if (cached) {
-    return JSON.parse(cached);
-  }
-
-  var dbName = '_pouch__checkModernIdb';
-  var result = global.indexedDB.open(dbName, 1).onupgradeneeded === null;
-
-  if (global.indexedDB.deleteDatabase) {
-    global.indexedDB.deleteDatabase(dbName); // db no longer needed
-  }
-  if (utils.hasLocalStorage()) {
-    global.localStorage[cacheKey] = JSON.stringify(result); // cache
-  }
-  return result;
-}
-
-function IdbPouch(opts, callback) {
-
-  // IndexedDB requires a versioned database structure, so we use the
-  // version here to manage migrations.
-  var ADAPTER_VERSION = 2;
-
-  // The object stores created for each database
-  // DOC_STORE stores the document meta data, its revision history and state
-  var DOC_STORE = 'document-store';
-  // BY_SEQ_STORE stores a particular version of a document, keyed by its
-  // sequence id
-  var BY_SEQ_STORE = 'by-sequence';
-  // Where we store attachments
-  var ATTACH_STORE = 'attach-store';
-  // Where we store meta data
-  var META_STORE = 'meta-store';
-  // Where we detect blob support
-  var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
-
-  var name = opts.name;
-  var req = global.indexedDB.open(name, ADAPTER_VERSION);
-  var docCount = -1;
-
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.openReqList[name] = req;
-
-  var blobSupport = null;
-  var instanceId = null;
-  var api = this;
-  var idb = null;
-
-  req.onupgradeneeded = function (e) {
-    var db = e.target.result;
-    if (e.oldVersion < 1) {
-      // initial schema
-      createSchema(db);
-    }
-    if (e.oldVersion < 2) {
-      // version 2 adds the deletedOrLocal index
-      addDeletedOrLocalIndex(e);
-    }
-  };
-
-  function createSchema(db) {
-    db.createObjectStore(DOC_STORE, {keyPath : 'id'})
-      .createIndex('seq', 'seq', {unique: true});
-    db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
-    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
-    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
-  }
-
-  function addDeletedOrLocalIndex(e) {
-    var docStore = e.currentTarget.transaction.objectStore(DOC_STORE);
-
-    docStore.openCursor().onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var deleted = utils.isDeleted(metadata);
-        var local = utils.isLocalId(metadata.id);
-        metadata.deletedOrLocal = (deleted || local) ? "1" : "0";
-        docStore.put(metadata);
-        cursor["continue"]();
-      } else {
-        docStore.createIndex('deletedOrLocal',
-                             'deletedOrLocal', {unique : false});
-      }
-    };
-  }
-
-  req.onsuccess = function (e) {
-
-    idb = e.target.result;
-
-    idb.onversionchange = function () {
-      idb.close();
-    };
-
-    var txn = idb.transaction([META_STORE, DETECT_BLOB_SUPPORT_STORE],
-                              'readwrite');
-
-    var req = txn.objectStore(META_STORE).get(META_STORE);
-
-    req.onsuccess = function (e) {
-
-      var idStored = false;
-      var checkSetupComplete = function () {
-        if (blobSupport === null || !idStored) {
-          return;
-        } else {
-          callback(null, api);
-        }
-      };
-
-      var meta = e.target.result || {id: META_STORE};
-      if (name  + '_id' in meta) {
-        instanceId = meta[name + '_id'];
-        idStored = true;
-        checkSetupComplete();
-      } else {
-        instanceId = utils.uuid();
-        meta[name + '_id'] = instanceId;
-        txn.objectStore(META_STORE).put(meta).onsuccess = function () {
-          idStored = true;
-          checkSetupComplete();
-        };
-      }
-
-      // detect blob support
-      try {
-        txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(utils.createBlob(),
-                                                       "key");
-        blobSupport = true;
-      } catch (err) {
-        blobSupport = false;
-      } finally {
-        checkSetupComplete();
-      }
-    };
-  };
-
-  req.onerror = idbError(callback);
-
-  api.type = function () {
-    return 'idb';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._bulkDocs = function idb_bulkDocs(req, opts, callback) {
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var results = [];
-    var docsWritten = 0;
-
-    function writeMetaData(e) {
-      var meta = e.target.result;
-      meta.updateSeq = (meta.updateSeq || 0) + docsWritten;
-      txn.objectStore(META_STORE).put(meta);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = writeMetaData;
-        return;
-      }
-      var currentDoc = docInfos.shift();
-      var req = txn.objectStore(DOC_STORE).get(currentDoc.metadata.id);
-      req.onsuccess = function process_docRead(event) {
-        var oldDoc = event.target.result;
-        if (!oldDoc) {
-          insertDoc(currentDoc);
-        } else {
-          updateDoc(oldDoc, currentDoc);
-        }
-      };
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        IdbPouch.Changes.notify(name);
-        IdbPouch.Changes.notifyLocalWindows(name);
-      });
-      docCount = -1; // invalidate
-      callback(null, aresults);
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        var data;
-        try {
-          data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        att.digest = 'md5-' + utils.MD5(data);
-        if (blobSupport) {
-          var type = att.content_type;
-          data = utils.fixBinary(data);
-          att.data = utils.createBlob([data], {type: type});
-        }
-        return finish();
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        var binary = utils.arrayBufferToBinaryString(this.result);
-        att.digest = 'md5-' + utils.MD5(binary);
-        if (!blobSupport) {
-          att.data = btoa(binary);
-        }
-        finish();
-      };
-      reader.readAsArrayBuffer(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        var recv = 0;
-        function attachmentProcessed() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key],
-                                 attachmentProcessed);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, winningRev, deleted, callback) {
-      var err = null;
-      var recv = 0;
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      docsWritten++;
-
-      if (deleted) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      function finish() {
-
-        docInfo.data._doc_id_rev = docInfo.data._id + "::" + docInfo.data._rev;
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-
-        index.getKey(docInfo.data._doc_id_rev).onsuccess = function (e) {
-
-          var dataReq = e.target.result ?
-            txn.objectStore(BY_SEQ_STORE).put(docInfo.data, e.target.result) :
-            txn.objectStore(BY_SEQ_STORE).put(docInfo.data);
-
-          dataReq.onsuccess = function (e) {
-            var metadata = docInfo.metadata;
-            metadata.seq = e.target.result;
-            // Current _rev is calculated from _rev_tree on read
-            delete metadata.rev;
-            var local = utils.isLocalId(metadata.id);
-            metadata.deletedOrLocal = (deleted || local) ? "1" : "0";
-            metadata.winningRev = merge.winningRev(metadata);
-            var metaDataReq = txn.objectStore(DOC_STORE).put(metadata);
-            metaDataReq.onsuccess = function () {
-              delete metadata.deletedOrLocal;
-              delete metadata.winningRev;
-              results.push(docInfo);
-              utils.call(callback);
-            };
-          };
-        };
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var winningRev = merge.winningRev(docInfo.metadata);
-      var deleted = utils.isDeleted(docInfo.metadata, winningRev);
-
-      var merged =
-        merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var wasPreviouslyDeleted = utils.isDeleted(oldDoc);
-      var inConflict = (wasPreviouslyDeleted && deleted && newEdits) ||
-        (!wasPreviouslyDeleted && newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-
-      writeDoc(docInfo, winningRev, deleted, processDocs);
-    }
-
-    function insertDoc(docInfo) {
-      var winningRev = merge.winningRev(docInfo.metadata);
-      var deleted = utils.isDeleted(docInfo.metadata, winningRev);
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && deleted) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-
-      writeDoc(docInfo, winningRev, deleted, processDocs);
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var objectStore = txn.objectStore(ATTACH_STORE);
-      objectStore.get(digest).onsuccess = function (e) {
-        var originalRefs = e.target.result && e.target.result.refs || {};
-        var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-        var newAtt = {
-          digest: digest,
-          body: data,
-          refs: originalRefs
-        };
-        newAtt.refs[ref] = true;
-        objectStore.put(newAtt).onsuccess = function (e) {
-          utils.call(callback);
-        };
-      };
-    }
-
-    var txn;
-    preprocessAttachments(function () {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE],
-                            'readwrite');
-      txn.onerror = idbError(callback);
-      txn.ontimeout = idbError(callback);
-      txn.oncomplete = complete;
-
-      processDocs();
-    });
-  };
-
-  function sortByBulkSeq(a, b) {
-    return a._bulk_seq - b._bulk_seq;
-  }
-
-  // First we look up the metadata in the ids database, then we fetch the
-  // current revision(s) from the by sequence store
-  api._get = function idb_get(id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    var txn;
-    opts = utils.clone(opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn =
-        idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: txn});
-    }
-
-    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
-      metadata = e.target.result;
-      // we can determine the result here if:
-      // 1. there is no such document
-      // 2. the document is deleted and we don't ask about specific rev
-      // When we ask with opts.rev we expect the answer to be either
-      // doc (possibly with _deleted=true) or missing error
-      if (!metadata) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-      var objectStore = txn.objectStore(BY_SEQ_STORE);
-
-      // metadata.winningRev was added later, so older DBs might not have it
-      var rev = opts.rev || metadata.winningRev || merge.winningRev(metadata);
-      var key = metadata.id + '::' + rev;
-
-      objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
-        doc = e.target.result;
-        if (doc && doc._doc_id_rev) {
-          delete(doc._doc_id_rev);
-        }
-        if (!doc) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        finish();
-      };
-    };
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var result;
-    var txn;
-    opts = utils.clone(opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn =
-        idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-
-    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
-      var data = e.target.result.body;
-      if (opts.encode) {
-        if (blobSupport) {
-          var reader = new FileReader();
-          reader.onloadend = function (e) {
-            var binary = utils.arrayBufferToBinaryString(this.result);
-            result = btoa(binary);
-            callback(null, result);
-          };
-          reader.readAsArrayBuffer(data);
-        } else {
-          result = data;
-          callback(null, result);
-        }
-      } else {
-        if (blobSupport) {
-          result = data;
-        } else {
-          data = utils.fixBinary(atob(data));
-          result = utils.createBlob([data], {type: type});
-        }
-        callback(null, result);
-      }
-    };
-  };
-
-  function allDocsQuery(totalRows, opts, callback) {
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-    var skip = opts.skip || 0;
-    var limit = typeof opts.limit === 'number' ? opts.limit : -1;
-    var inclusiveEnd = opts.inclusive_end !== false;
-    var descending = 'descending' in opts && opts.descending ? 'prev' : null;
-
-    var manualDescEnd = false;
-    if (descending && start && end) {
-      // unfortunately IDB has a quirk where IDBKeyRange.bound is invalid if the
-      // start is less than the end, even in descending mode.  Best bet
-      // is just to handle it manually in that case.
-      manualDescEnd = end;
-      end = false;
-    }
-
-    var keyRange;
-    try {
-      keyRange = start && end ? global.IDBKeyRange.bound(start, end, false,
-          !inclusiveEnd)
-        : start ? (descending ? global.IDBKeyRange.upperBound(start)
-                  : global.IDBKeyRange.lowerBound(start))
-        : end ? (descending ? global.IDBKeyRange.lowerBound(end, !inclusiveEnd)
-                : global.IDBKeyRange.upperBound(end, !inclusiveEnd))
-        : key ? global.IDBKeyRange.only(key) : null;
-    } catch (e) {
-      if (e.name === "DataError" && e.code === 0) {
-        // data error, start is less than end
-        return callback(null, {
-          total_rows : totalRows,
-          offset : opts.skip,
-          rows : []
-        });
-      } else {
-        return callback(errors.error(errors.IDB_ERROR, e.name, e.message));
-      }
-    }
-
-    var transaction = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readonly');
-    transaction.oncomplete = function () {
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    };
-
-    var oStore = transaction.objectStore(DOC_STORE);
-    var oCursor = descending ? oStore.openCursor(keyRange, descending)
-      : oStore.openCursor(keyRange);
-    var results = [];
-    oCursor.onsuccess = function (e) {
-      if (!e.target.result) {
-        return;
-      }
-      var cursor = e.target.result;
-      var metadata = cursor.value;
-      // metadata.winningRev added later, some dbs might be missing it
-      var winningRev = metadata.winningRev || merge.winningRev(metadata);
-
-      function allDocsInner(metadata, data) {
-        if (utils.isLocalId(metadata.id)) {
-          return cursor["continue"]();
-        }
-        var doc = {
-          id: metadata.id,
-          key: metadata.id,
-          value: {
-            rev: winningRev
-          }
-        };
-        if (opts.include_docs) {
-          doc.doc = data;
-          doc.doc._rev = winningRev;
-          if (doc.doc._doc_id_rev) {
-            delete(doc.doc._doc_id_rev);
-          }
-          if (opts.conflicts) {
-            doc.doc._conflicts = merge.collectConflicts(metadata);
-          }
-          for (var att in doc.doc._attachments) {
-            if (doc.doc._attachments.hasOwnProperty(att)) {
-              doc.doc._attachments[att].stub = true;
-            }
-          }
-        }
-        var deleted = utils.isDeleted(metadata, winningRev);
-        if (opts.deleted === 'ok') {
-          // deleted docs are okay with keys_requests
-          if (deleted) {
-            doc.value.deleted = true;
-            doc.doc = null;
-          }
-          results.push(doc);
-        } else if (!deleted && skip-- <= 0) {
-          if (manualDescEnd && doc.key < manualDescEnd) {
-            return;
-          }
-          results.push(doc);
-          if (--limit === 0) {
-            return;
-          }
-        }
-        cursor["continue"]();
-      }
-
-      if (!opts.include_docs) {
-        allDocsInner(metadata);
-      } else {
-        var index = transaction.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = metadata.id + "::" + winningRev;
-        index.get(key).onsuccess = function (event) {
-          allDocsInner(cursor.value, event.target.result);
-        };
-      }
-    };
-  }
-
-  function countDocs(callback) {
-    if (docCount !== -1) {
-      return callback(null, docCount);
-    }
-
-    var count;
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
-    index.count(global.IDBKeyRange.only("0")).onsuccess = function (e) {
-      count = e.target.result;
-    };
-    txn.onerror = idbError(callback);
-    txn.oncomplete = function () {
-      docCount = count;
-      callback(null, docCount);
-    };
-  }
-
-  api._allDocs = function idb_allDocs(opts, callback) {
-
-    // first count the total_rows
-    countDocs(function (err, totalRows) {
-      if (err) {
-        return callback(err);
-      }
-      if (opts.limit === 0) {
-        return callback(null, {
-          total_rows : totalRows,
-          offset : opts.skip,
-          rows : []
-        });
-      }
-      allDocsQuery(totalRows, opts, callback);
-    });
-  };
-
-  api._info = function idb_info(callback) {
-
-    countDocs(function (err, count) {
-      if (err) {
-        return callback(err);
-      }
-      if (idb === null) {
-        var error = new Error('db isn\'t open');
-        error.id = 'idbNull';
-        return callback(error);
-      }
-      var updateSeq = 0;
-      var txn = idb.transaction([META_STORE], 'readonly');
-
-      txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
-        updateSeq = e.target.result && e.target.result.updateSeq || 0;
-      };
-
-      txn.oncomplete = function () {
-        callback(null, {
-          db_name: name,
-          doc_count: count,
-          update_seq: updateSeq
-        });
-      };
-    });
-  };
-
-  api._changes = function (opts) {
-    opts = utils.clone(opts);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      IdbPouch.Changes.addListener(name, id, api, opts);
-      IdbPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          IdbPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending ? 'prev' : null;
-    var lastSeq = 0;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var limit = 'limit' in opts ? opts.limit : -1;
-    if (limit === 0) {
-      limit = 1; // per CouchDB _changes spec
-    }
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-
-    var results = [];
-    var numResults = 0;
-    var filter = utils.filterChange(opts);
-
-    var txn;
-
-    function fetchChanges() {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE]);
-      txn.oncomplete = onTxnComplete;
-
-      var req;
-
-      if (descending) {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true),
-                        descending);
-      } else {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true));
-      }
-
-      req.onsuccess = onsuccess;
-      req.onerror = onerror;
-    }
-
-    fetchChanges();
-
-    function onsuccess(event) {
-      var cursor = event.target.result;
-
-      if (!cursor) {
-        return;
-      }
-
-      var doc = cursor.value;
-
-      if (utils.isLocalId(doc._id) ||
-          (opts.doc_ids && opts.doc_ids.indexOf(doc._id) === -1)) {
-        return cursor["continue"]();
-      }
-
-      var index = txn.objectStore(DOC_STORE);
-      index.get(doc._id).onsuccess = function (event) {
-        var metadata = event.target.result;
-
-        if (lastSeq < metadata.seq) {
-          lastSeq = metadata.seq;
-        }
-        // metadata.winningRev was only added later
-        var winningRev = metadata.winningRev || merge.winningRev(metadata);
-        if (doc._rev !== winningRev) {
-          return cursor["continue"]();
-        }
-
-        delete doc['_doc_id_rev'];
-
-        var change = opts.processChange(doc, metadata, opts);
-        change.seq = cursor.key;
-        if (filter(change)) {
-          numResults++;
-          if (returnDocs) {
-            results.push(change);
-          }
-          opts.onChange(change);
-        }
-        if (numResults !== limit) {
-          cursor["continue"]();
-        }
-      };
-    }
-
-    function onTxnComplete() {
-      if (!opts.continuous) {
-        opts.complete(null, {
-          results: results,
-          last_seq: lastSeq
-        });
-      }
-    }
-  };
-
-  api._close = function (callback) {
-    if (idb === null) {
-      return callback(errors.NOT_OPEN);
-    }
-
-    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
-    // "Returns immediately and closes the connection in a separate thread..."
-    idb.close();
-    idb = null;
-    callback();
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var req = txn.objectStore(DOC_STORE).get(docId);
-    req.onsuccess = function (event) {
-      var doc = event.target.result;
-      if (!doc) {
-        callback(errors.MISSING_DOC);
-      } else {
-        callback(null, doc.rev_tree);
-      }
-    };
-  };
-
-  // This function removes revisions of document docId
-  // which are listed in revs and sets this document
-  // revision to to rev_tree
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    var txn = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readwrite');
-
-    var index = txn.objectStore(DOC_STORE);
-    index.get(docId).onsuccess = function (event) {
-      var metadata = event.target.result;
-      metadata.rev_tree = rev_tree;
-
-      var count = revs.length;
-      revs.forEach(function (rev) {
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = docId + "::" + rev;
-        index.getKey(key).onsuccess = function (e) {
-          var seq = e.target.result;
-          if (!seq) {
-            return;
-          }
-          txn.objectStore(BY_SEQ_STORE)['delete'](seq);
-
-          count--;
-          if (!count) {
-            txn.objectStore(DOC_STORE).put(metadata);
-          }
-        };
-      });
-    };
-    txn.oncomplete = function () {
-      utils.call(callback);
-    };
-  };
-
-}
-
-IdbPouch.valid = function () {
-  return global.indexedDB && isModernIdb();
-};
-
-IdbPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.Changes.clearListeners(name);
-
-  //Close open request for "name" database to fix ie delay.
-  if (IdbPouch.openReqList[name] && IdbPouch.openReqList[name].result) {
-    IdbPouch.openReqList[name].result.close();
-  }
-  var req = global.indexedDB.deleteDatabase(name);
-
-  req.onsuccess = function () {
-    //Remove open request from the list.
-    if (IdbPouch.openReqList[name]) {
-      IdbPouch.openReqList[name] = null;
-    }
-    if (utils.hasLocalStorage()) {
-      delete global.localStorage[name];
-    }
-
-    callback(null, { 'ok': true });
-  };
-
-  req.onerror = idbError(callback);
-});
-
-IdbPouch.Changes = new utils.Changes();
-
-module.exports = IdbPouch;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":10,"../merge":16,"../utils":21}],5:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-function quote(str) {
-  return "'" + str + "'";
-}
-
-var cachedDatabases = {};
-
-var openDB = utils.getArguments(function (args) {
-  if (typeof global !== 'undefined') {
-    if (global.navigator && global.navigator.sqlitePlugin &&
-        global.navigator.sqlitePlugin.openDatabase) {
-      return navigator.sqlitePlugin.openDatabase
-        .apply(navigator.sqlitePlugin, args);
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return global.sqlitePlugin.openDatabase
-        .apply(global.sqlitePlugin, args);
-    } else {
-      var db = cachedDatabases[args[0]];
-      if (!db) {
-        db = cachedDatabases[args[0]] =
-          global.openDatabase.apply(global, args);
-      }
-      return db;
-    }
-  }
-});
-
-var POUCH_VERSION = 1;
-var POUCH_SIZE =  3000000;
-var ADAPTER_VERSION = 2; // used to manage migrations
-
-// The object stores created for each database
-// DOC_STORE stores the document meta data, its revision history and state
-var DOC_STORE = quote('document-store');
-// BY_SEQ_STORE stores a particular version of a document, keyed by its
-// sequence id
-var BY_SEQ_STORE = quote('by-sequence');
-// Where we store attachments
-var ATTACH_STORE = quote('attach-store');
-var META_STORE = quote('metadata-store');
-
-// these indexes cover the ground for most allDocs queries
-var BY_SEQ_STORE_DELETED_INDEX_SQL =
-  'CREATE INDEX IF NOT EXISTS \'by-seq-deleted-idx\' ON ' +
-  BY_SEQ_STORE + ' (seq, deleted)';
-var DOC_STORE_LOCAL_INDEX_SQL =
-  'CREATE INDEX IF NOT EXISTS \'doc-store-local-idx\' ON ' +
-  DOC_STORE + ' (local, id)';
-var DOC_STORE_WINNINGSEQ_INDEX_SQL =
-  'CREATE INDEX IF NOT EXISTS \'doc-winningseq-idx\' ON ' +
-  DOC_STORE + ' (winningseq)';
-
-var DOC_STORE_AND_BY_SEQ_JOINER = BY_SEQ_STORE +
-  '.seq = ' + DOC_STORE + '.winningseq';
-
-var SELECT_DOCS = BY_SEQ_STORE + '.seq AS seq, ' +
-  BY_SEQ_STORE + '.deleted AS deleted, ' +
-  BY_SEQ_STORE + '.json AS data, ' +
-  DOC_STORE + '.json AS metadata';
-
-function select(selector, table, joiner, where, orderBy) {
-  return 'SELECT ' + selector + ' FROM ' +
-    (typeof table === 'string' ? table : table.join(' JOIN ')) +
-    (joiner ? (' ON ' + joiner) : '') +
-    (where ? (' WHERE ' +
-      (typeof where === 'string' ? where : where.join(' AND '))) : '') +
-    (orderBy ? (' ORDER BY ' + orderBy) : '');
-}
-
-function unknownError(callback) {
-  return function (event) {
-    // event may actually be a SQLError object, so report is as such
-    var errorNameMatch = event && event.constructor.toString()
-      .match(/function ([^\(]+)/);
-    var errorName = (errorNameMatch && errorNameMatch[1]) || event.type;
-    var errorReason = event.target || event.message;
-    callback(errors.error(errors.WSQ_ERROR, errorReason, errorName));
-  };
-}
-function decodeUtf8(str) {
-  return decodeURIComponent(window.escape(str));
-}
-function parseHexString(str, encoding) {
-  var result = '';
-  var charWidth = encoding === 'UTF-8' ? 2 : 4;
-  for (var i = 0, len = str.length; i < len; i += charWidth) {
-    var substring = str.substring(i, i + charWidth);
-    if (charWidth === 4) { // UTF-16, twiddle the bits
-      substring = substring.substring(2, 4) + substring.substring(0, 2);
-    }
-    result += String.fromCharCode(parseInt(substring, 16));
-  }
-  result = encoding === 'UTF-8' ? decodeUtf8(result) : result;
-  return result;
-}
-
-function WebSqlPouch(opts, callback) {
-  var api = this;
-  var instanceId = null;
-  var name = opts.name;
-  var idRequests = [];
-  var docCount = -1; // cache sqlite count(*) for performance
-  var encoding;
-
-  var db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  if (!db) {
-    return callback(errors.UNKNOWN_ERROR);
-  } else if (typeof db.readTransaction !== 'function') {
-    // doesn't exist in sqlite plugin
-    db.readTransaction = db.transaction;
-  }
-
-  function dbCreated() {
-    // note the db name in case the browser upgrades to idb
-    if (utils.hasLocalStorage()) {
-      global.localStorage['_pouch__websqldb_' + name] = true;
-    }
-    callback(null, api);
-  }
-
-  // In this migration, we added the 'deleted' and 'local' columns to the
-  // by-seq and doc store tables.
-  // To preserve existing user data, we re-process all the existing JSON
-  // and add these values.
-  // Called migration2 because it corresponds to adapter version (db_version) #2
-  function runMigration2(tx) {
-    // index used for the join in the allDocs query
-    tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
-
-    tx.executeSql('ALTER TABLE ' + BY_SEQ_STORE +
-      ' ADD COLUMN deleted TINYINT(1) DEFAULT 0', [], function () {
-      tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-      tx.executeSql('ALTER TABLE ' + DOC_STORE +
-        ' ADD COLUMN local TINYINT(1) DEFAULT 0', [], function () {
-        tx.executeSql(DOC_STORE_LOCAL_INDEX_SQL);
-
-        var sql = 'SELECT ' + DOC_STORE + '.winningseq AS seq, ' + DOC_STORE +
-          '.json AS metadata FROM ' + BY_SEQ_STORE + ' JOIN ' + DOC_STORE +
-          ' ON ' + BY_SEQ_STORE + '.seq = ' + DOC_STORE + '.winningseq';
-
-        tx.executeSql(sql, [], function (tx, result) {
-
-          var deleted = [];
-          var local = [];
-
-          for (var i = 0; i < result.rows.length; i++) {
-            var item = result.rows.item(i);
-            var seq = item.seq;
-            var metadata = JSON.parse(item.metadata);
-            if (utils.isDeleted(metadata)) {
-              deleted.push(seq);
-            }
-            if (utils.isLocalId(metadata.id)) {
-              local.push(metadata.id);
-            }
-          }
-
-          tx.executeSql('UPDATE ' + DOC_STORE + 'SET local = 1 WHERE id IN (' +
-            local.map(function () {
-            return '?';
-          }).join(',') + ')', local);
-          tx.executeSql('UPDATE ' + BY_SEQ_STORE +
-            ' SET deleted = 1 WHERE seq IN (' + deleted.map(function () {
-            return '?';
-          }).join(',') + ')', deleted);
-        });
-      });
-    });
-  }
-
-  function onGetInstanceId(tx) {
-    while (idRequests.length > 0) {
-      var idCallback = idRequests.pop();
-      idCallback(null, instanceId);
-    }
-    checkDbEncoding(tx);
-  }
-
-  function checkDbEncoding(tx) {
-    // check db encoding - utf-8 (chrome, opera) or utf-16 (safari)?
-    tx.executeSql('SELECT dbid, hex(dbid) AS hexId FROM ' + META_STORE, [],
-      function (err, result) {
-        var id = result.rows.item(0).dbid;
-        var hexId = result.rows.item(0).hexId;
-        encoding = (hexId.length === id.length * 2) ? 'UTF-8' : 'UTF-16';
-      }
-    );
-  }
-
-  function onGetVersion(tx, dbVersion) {
-    if (dbVersion === 0) {
-      // initial schema
-
-      var meta = 'CREATE TABLE IF NOT EXISTS ' + META_STORE +
-        ' (update_seq, dbid, db_version INTEGER)';
-      var attach = 'CREATE TABLE IF NOT EXISTS ' + ATTACH_STORE +
-        ' (digest, json, body BLOB)';
-      var doc = 'CREATE TABLE IF NOT EXISTS ' + DOC_STORE +
-        ' (id unique, json, winningseq, local TINYINT(1))';
-      var seq = 'CREATE TABLE IF NOT EXISTS ' + BY_SEQ_STORE +
-        ' (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
-        'doc_id_rev UNIQUE, json, deleted TINYINT(1))';
-
-      // creates
-      tx.executeSql(attach);
-      tx.executeSql(doc, [], function () {
-        tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
-        tx.executeSql(DOC_STORE_LOCAL_INDEX_SQL);
-      });
-      tx.executeSql(seq, [], function () {
-        tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-      });
-      tx.executeSql(meta, [], function () {
-        // mark the update_seq, db version, and new dbid
-        var initSeq = 'INSERT INTO ' + META_STORE +
-          ' (update_seq, db_version, dbid) VALUES (?, ?, ?)';
-        instanceId = utils.uuid();
-        tx.executeSql(initSeq, [0, ADAPTER_VERSION, instanceId]);
-        onGetInstanceId(tx);
-      });
-    } else { // version > 0
-
-      if (dbVersion === 1) {
-        runMigration2(tx);
-        // mark the db version within this transaction
-        tx.executeSql('UPDATE ' + META_STORE + ' SET db_version = ' +
-                      ADAPTER_VERSION);
-      } // in the future, add more migrations here
-
-      // notify db.id() callers
-      tx.executeSql('SELECT dbid FROM ' + META_STORE, [],
-                    function (tx, result) {
-        instanceId = result.rows.item(0).dbid;
-        onGetInstanceId(tx);
-      });
-    }
-  }
-
-  function setup() {
-
-    db.transaction(function (tx) {
-      // first get the version
-      tx.executeSql('SELECT sql FROM sqlite_master WHERE tbl_name = ' +
-                    META_STORE, [], function (tx, result) {
-        if (!result.rows.length) {
-          // database hasn't even been created yet (version 0)
-          onGetVersion(tx, 0);
-        } else if (!/db_version/.test(result.rows.item(0).sql)) {
-          // table was created, but without the new db_version column,
-          // so add it.
-          tx.executeSql('ALTER TABLE ' + META_STORE +
-            ' ADD COLUMN db_version INTEGER', [], function () {
-            // before version 2, this column didn't even exist
-            onGetVersion(tx, 1);
-          });
-        } else { // column exists, we can safely get it
-          tx.executeSql('SELECT db_version FROM ' + META_STORE, [],
-            function (tx, result) {
-            var dbVersion = result.rows.item(0).db_version;
-            onGetVersion(tx, dbVersion);
-          });
-        }
-      });
-    }, unknownError(callback), dbCreated);
-  }
-
-  if (utils.isCordova() && typeof global !== 'undefined') {
-    //to wait until custom api is made in pouch.adapters before doing setup
-    global.addEventListener(name + '_pouch', function cordova_init() {
-      global.removeEventListener(name + '_pouch', cordova_init, false);
-      setup();
-    }, false);
-  } else {
-    setup();
-  }
-
-  api.type = function () {
-    return 'websql';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._info = function (callback) {
-    db.readTransaction(function (tx) {
-      countDocs(tx, function (docCount) {
-        var sql = 'SELECT update_seq FROM ' + META_STORE;
-        tx.executeSql(sql, [], function (tx, result) {
-          var updateSeq = result.rows.item(0).update_seq;
-          callback(null, {
-            db_name: name,
-            doc_count: docCount,
-            update_seq: updateSeq
-          });
-        });
-      });
-    }, unknownError(callback));
-  };
-
-  api._bulkDocs = function (req, opts, callback) {
-
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    var docsWritten = 0;
-
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var tx;
-    var results = [];
-    var fetchedDocs = {};
-
-    function sortByBulkSeq(a, b) {
-      return a._bulk_seq - b._bulk_seq;
-    }
-
-    function complete(event) {
-      var aresults = [];
-      results.sort(sortByBulkSeq);
-      results.forEach(function (result) {
-        delete result._bulk_seq;
-        if (result.error) {
-          aresults.push(result);
-          return;
-        }
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        aresults.push({
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        });
-
-        if (utils.isLocalId(metadata.id)) {
-          return;
-        }
-
-        docsWritten++;
-
-        WebSqlPouch.Changes.notify(name);
-        WebSqlPouch.Changes.notifyLocalWindows(name);
-      });
-
-      var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-      tx.executeSql(updateseq, [], function (tx, result) {
-        var update_seq = result.rows.item(0).update_seq + docsWritten;
-        var sql = 'UPDATE ' + META_STORE + ' SET update_seq=?';
-        tx.executeSql(sql, [update_seq], function () {
-          callback(null, aresults);
-        });
-      });
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        try {
-          att.data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        var data = utils.fixBinary(att.data);
-        att.data = utils.createBlob([data], {type: att.content_type});
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        var binary = utils.arrayBufferToBinaryString(this.result);
-        att.data = binary;
-        att.digest = 'md5-' + utils.MD5(binary);
-        finish();
-      };
-      reader.readAsArrayBuffer(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-        var recv = 0;
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        function processedAttachment() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key],
-                                 processedAttachment);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, deleted, callback, isUpdate) {
-
-      function finish() {
-        var data = docInfo.data;
-        var doc_id_rev = data._id + "::" + data._rev;
-        var deletedInt = deleted ? 1 : 0;
-        var fetchSql = select('seq', BY_SEQ_STORE, null, 'doc_id_rev=?');
-
-        tx.executeSql(fetchSql, [doc_id_rev], function (err, res) {
-          var sql, sqlArgs;
-          if (res.rows.length) {
-            sql = 'UPDATE ' + BY_SEQ_STORE +
-              ' SET json=?, deleted=? WHERE doc_id_rev=?;';
-            sqlArgs = [JSON.stringify(data), deletedInt, doc_id_rev];
-            tx.executeSql(sql, sqlArgs, function (tx) {
-              dataWritten(tx, res.rows.item(0).seq);
-            });
-          } else {
-            sql = 'INSERT INTO ' + BY_SEQ_STORE +
-              ' (doc_id_rev, json, deleted) VALUES (?, ?, ?);';
-            sqlArgs = [doc_id_rev, JSON.stringify(data), deletedInt];
-            tx.executeSql(sql, sqlArgs, function (tx, result) {
-              dataWritten(tx, result.insertId);
-            });
-          }
-        });
-      }
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      var err = null;
-      var recv = 0;
-
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      if (deleted) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-
-      function dataWritten(tx, seq) {
-        docInfo.metadata.seq = seq;
-        delete docInfo.metadata.rev;
-
-        var mainRev = merge.winningRev(docInfo.metadata);
-
-        var sql = isUpdate ?
-          'UPDATE ' + DOC_STORE +
-          ' SET json=?, winningseq=(SELECT seq FROM ' + BY_SEQ_STORE +
-          ' WHERE doc_id_rev=?) WHERE id=?'
-          : 'INSERT INTO ' + DOC_STORE +
-          ' (id, winningseq, json, local) VALUES (?, ?, ?, ?);';
-        var metadataStr = JSON.stringify(docInfo.metadata);
-        var key = docInfo.metadata.id + "::" + mainRev;
-        var local = utils.isLocalId(docInfo.metadata.id) ? 1 : 0;
-        var params = isUpdate ?
-          [metadataStr, key, docInfo.metadata.id] :
-          [docInfo.metadata.id, seq, metadataStr, local];
-        tx.executeSql(sql, params, function () {
-          results.push(docInfo);
-          callback();
-        });
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo) {
-      var merged =
-        merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var deleted = utils.isDeleted(docInfo.metadata);
-      var oldDocDeleted = utils.isDeleted(oldDoc);
-      var inConflict = (oldDocDeleted && deleted && newEdits) ||
-        (!oldDocDeleted && newEdits && merged.conflicts !== 'new_leaf');
-      if (inConflict) {
-        results.push(makeErr(errors.REV_CONFLICT, docInfo._bulk_seq));
-        return processDocs();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-      writeDoc(docInfo, deleted, processDocs, true);
-    }
-
-    function insertDoc(docInfo) {
-      // Cant insert new deleted documents
-      var deleted = utils.isDeleted(docInfo.metadata);
-      if ('was_delete' in opts && deleted) {
-        results.push(errors.MISSING_DOC);
-        return processDocs();
-      }
-      writeDoc(docInfo, deleted, processDocs, false);
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        return complete();
-      }
-      var currentDoc = docInfos.shift();
-      var id = currentDoc.metadata.id;
-      if (id in fetchedDocs) {
-        updateDoc(fetchedDocs[id], currentDoc);
-      } else {
-        // if we have newEdits=false then we can update the same
-        // document twice in a single bulk docs call
-        fetchedDocs[id] = currentDoc.metadata;
-        insertDoc(currentDoc);
-      }
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-      var newAtt = {digest: digest};
-      var sql = 'SELECT digest, json FROM ' + ATTACH_STORE + ' WHERE digest=?';
-      tx.executeSql(sql, [digest], function (tx, result) {
-        if (!result.rows.length) {
-          newAtt.refs = {};
-          newAtt.refs[ref] = true;
-          sql = 'INSERT INTO ' + ATTACH_STORE +
-                '(digest, json, body) VALUES (?, ?, ?)';
-          tx.executeSql(sql, [digest, JSON.stringify(newAtt), data],
-            function () {
-            callback();
-          });
-        } else {
-          newAtt.refs = JSON.parse(result.rows.item(0).json).refs;
-          sql = 'UPDATE ' + ATTACH_STORE + ' SET json=?, body=? WHERE digest=?';
-          tx.executeSql(sql, [JSON.stringify(newAtt), data, digest],
-            function () {
-            callback();
-          });
-        }
-      });
-    }
-
-    function metadataFetched(tx, results) {
-      for (var j = 0; j < results.rows.length; j++) {
-        var row = results.rows.item(j);
-        var id = parseHexString(row.hexId, encoding);
-        fetchedDocs[id] = JSON.parse(row.json);
-      }
-      processDocs();
-    }
-
-    preprocessAttachments(function () {
-      db.transaction(function (txn) {
-        tx = txn;
-        var sql = 'SELECT hex(id) AS hexId, json FROM ' + DOC_STORE +
-          ' WHERE id IN ' + '(' +
-          docInfos.map(function () {return '?'; }).join(',') + ')';
-        var queryArgs = docInfos.map(function (d) { return d.metadata.id; });
-        tx.executeSql(sql, queryArgs, metadataFetched);
-      }, unknownError(callback), function () {
-        docCount = -1;
-      });
-    });
-  };
-
-  api._get = function (id, opts, callback) {
-    opts = utils.clone(opts);
-    var doc;
-    var metadata;
-    var err;
-    if (!opts.ctx) {
-      db.readTransaction(function (txn) {
-        opts.ctx = txn;
-        api._get(id, opts, callback);
-      });
-      return;
-    }
-    var tx = opts.ctx;
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: tx});
-    }
-
-    var sql;
-    var sqlArgs;
-    if (opts.rev) {
-      sql = select(
-        SELECT_DOCS,
-        [DOC_STORE, BY_SEQ_STORE],
-        null,
-        [BY_SEQ_STORE + '.doc_id_rev=?', DOC_STORE + '.id=?']);
-      sqlArgs = [id + '::' + opts.rev, id];
-    } else {
-      sql = select(
-        SELECT_DOCS,
-        [DOC_STORE, BY_SEQ_STORE],
-        DOC_STORE_AND_BY_SEQ_JOINER,
-        DOC_STORE + '.id=?');
-      sqlArgs = [id];
-    }
-    tx.executeSql(sql, sqlArgs, function (a, results) {
-      if (!results.rows.length) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      var item = results.rows.item(0);
-      metadata = JSON.parse(item.metadata);
-      if (item.deleted && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, 'deleted');
-        return finish();
-      }
-      doc = JSON.parse(item.data);
-      finish();
-    });
-  };
-
-  function countDocs(tx, callback) {
-
-    if (docCount !== -1) {
-      return callback(docCount);
-    }
-
-    // count the total rows
-    var sql = select(
-      'COUNT(' + DOC_STORE + '.id) AS \'num\'',
-      [DOC_STORE, BY_SEQ_STORE],
-      DOC_STORE_AND_BY_SEQ_JOINER,
-      [BY_SEQ_STORE + '.deleted=0', DOC_STORE + '.local=0']);
-
-    tx.executeSql(sql, [], function (tx, result) {
-      docCount = result.rows.item(0).num;
-      callback(docCount);
-    });
-  }
-
-  api._allDocs = function (opts, callback) {
-    var results = [];
-    var totalRows;
-
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-    var descending = 'descending' in opts ? opts.descending : false;
-    var limit = 'limit' in opts ? opts.limit : -1;
-    var offset = 'skip' in opts ? opts.skip : 0;
-    var inclusiveEnd = opts.inclusive_end !== false;
-
-    var sqlArgs = [];
-    var criteria = [DOC_STORE + '.local = 0'];
-
-    if (key !== false) {
-      criteria.push(DOC_STORE + '.id = ?');
-      sqlArgs.push(key);
-    } else if (start !== false || end !== false) {
-      if (start !== false) {
-        criteria.push(DOC_STORE + '.id ' + (descending ? '<=' : '>=') + ' ?');
-        sqlArgs.push(start);
-      }
-      if (end !== false) {
-        var comparator = descending ? '>' : '<';
-        if (inclusiveEnd) {
-          comparator += '=';
-        }
-        criteria.push(DOC_STORE + '.id ' + comparator + ' ?');
-        sqlArgs.push(end);
-      }
-      if (key !== false) {
-        criteria.push(DOC_STORE + '.id = ?');
-        sqlArgs.push(key);
-      }
-    }
-
-    if (opts.deleted !== 'ok') {
-      // report deleted if keys are specified
-      criteria.push(BY_SEQ_STORE + '.deleted = 0');
-    }
-
-    db.readTransaction(function (tx) {
-
-      // first count up the total rows
-      countDocs(tx, function (count) {
-        totalRows = count;
-
-        if (limit === 0) {
-          return;
-        }
-
-        // then actually fetch the documents
-        var sql = select(
-          SELECT_DOCS,
-          [DOC_STORE, BY_SEQ_STORE],
-          DOC_STORE_AND_BY_SEQ_JOINER,
-          criteria,
-          DOC_STORE + '.id ' + (descending ? 'DESC' : 'ASC')
-          );
-        sql += ' LIMIT ' + limit + ' OFFSET ' + offset;
-
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var item = result.rows.item(i);
-            var metadata = JSON.parse(item.metadata);
-            var data = JSON.parse(item.data);
-            var winningRev = data._rev;
-            var doc = {
-              id: metadata.id,
-              key: metadata.id,
-              value: {rev: winningRev}
-            };
-            if (opts.include_docs) {
-              doc.doc = data;
-              doc.doc._rev = winningRev;
-              if (opts.conflicts) {
-                doc.doc._conflicts = merge.collectConflicts(metadata);
-              }
-              for (var att in doc.doc._attachments) {
-                if (doc.doc._attachments.hasOwnProperty(att)) {
-                  doc.doc._attachments[att].stub = true;
-                }
-              }
-            }
-            if (item.deleted) {
-              if (opts.deleted === 'ok') {
-                doc.value.deleted = true;
-                doc.doc = null;
-              } else {
-                continue;
-              }
-            }
-            results.push(doc);
-          }
-        });
-      });
-    }, unknownError(callback), function () {
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    });
-  };
-
-  api._changes = function (opts) {
-    opts = utils.clone(opts);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      WebSqlPouch.Changes.addListener(name, id, api, opts);
-      WebSqlPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          WebSqlPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var limit = 'limit' in opts ? opts.limit : -1;
-    if (limit === 0) {
-      limit = 1; // per CouchDB _changes spec
-    }
-
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-    var results = [];
-    var numResults = 0;
-    function fetchChanges() {
-
-      var criteria = [
-        DOC_STORE + '.winningseq > ' + opts.since,
-        DOC_STORE + '.local = 0'
-      ];
-      var sqlArgs = [];
-      if (opts.doc_ids) {
-        criteria.push(DOC_STORE + '.id IN (' + opts.doc_ids.map(function () {
-          return '?';
-        }).join(',') + ')');
-        sqlArgs = opts.doc_ids;
-      }
-
-      var sql = select(SELECT_DOCS, [DOC_STORE, BY_SEQ_STORE],
-        DOC_STORE_AND_BY_SEQ_JOINER, criteria,
-        DOC_STORE + '.winningseq ' + (descending ? 'DESC' : 'ASC'));
-
-      var filter = utils.filterChange(opts);
-      if (!opts.view && !opts.filter) {
-        // we can just limit in the query
-        sql += ' LIMIT ' + limit;
-      }
-
-      db.readTransaction(function (tx) {
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          var lastSeq = 0;
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var res = result.rows.item(i);
-            var metadata = JSON.parse(res.metadata);
-            if (lastSeq < res.seq) {
-              lastSeq = res.seq;
-            }
-            var doc = JSON.parse(res.data);
-            var change = opts.processChange(doc, metadata, opts);
-            change.seq = res.seq;
-            if (filter(change)) {
-              numResults++;
-              if (returnDocs) {
-                results.push(change);
-              }
-              opts.onChange(change);
-            }
-            if (numResults === limit) {
-              break;
-            }
-          }
-          if (!opts.continuous) {
-            opts.complete(null, {
-              results: results,
-              last_seq: lastSeq
-            });
-          }
-        });
-      });
-    }
-
-    fetchChanges();
-  };
-
-  api._close = function (callback) {
-    //WebSQL databases do not need to be closed
-    callback();
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var res;
-    var tx = opts.ctx;
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-    var sql = 'SELECT hex(body) as body FROM ' + ATTACH_STORE +
-              ' WHERE digest=?';
-    tx.executeSql(sql, [digest], function (tx, result) {
-      // sqlite normally stores data as utf8, so even the hex() function
-      // "encodes" the binary data in utf8/16 before returning it. yet hex()
-      // is the only way to get the full data, so we do this.
-      var data = parseHexString(result.rows.item(0).body, encoding);
-      if (opts.encode) {
-        res = btoa(data);
-      } else {
-        data = utils.fixBinary(data);
-        res = utils.createBlob([data], {type: type});
-      }
-      callback(null, res);
-    });
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    db.readTransaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          callback(errors.MISSING_DOC);
-        } else {
-          var data = JSON.parse(result.rows.item(0).metadata);
-          callback(null, data.rev_tree);
-        }
-      });
-    });
-  };
-
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    if (!revs.length) {
-      return callback();
-    }
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          return utils.call(callback);
-        }
-        var metadata = JSON.parse(result.rows.item(0).metadata);
-        metadata.rev_tree = rev_tree;
-
-        // websql never calls callback if we do WHERE doc_id_rev IN (...)
-        var numDone = 0;
-        revs.forEach(function (rev) {
-          var docIdRev = docId + '::' + rev;
-          var sql = 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE doc_id_rev = ?';
-          tx.executeSql(sql, [docIdRev], function (tx) {
-            if (++numDone === revs.length) {
-              var sql = 'UPDATE ' + DOC_STORE + ' SET json = ? WHERE id = ?';
-              tx.executeSql(sql, [JSON.stringify(metadata), docId],
-                function () {
-                callback();
-              });
-            }
-          });
-        });
-      });
-    });
-  };
-}
-
-WebSqlPouch.valid = function () {
-  if (typeof global !== 'undefined') {
-    if (global.navigator &&
-        global.navigator.sqlitePlugin &&
-        global.navigator.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.openDatabase) {
-      return true;
-    }
-  }
-  return false;
-};
-
-WebSqlPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  var db = openDB(name, POUCH_VERSION, name, POUCH_SIZE);
-  db.transaction(function (tx) {
-    var stores = [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE];
-    stores.forEach(function (store) {
-      tx.executeSql('DROP TABLE IF EXISTS ' + store, []);
-    });
-  }, unknownError(callback), function () {
-    if (utils.hasLocalStorage()) {
-      delete global.localStorage['_pouch__websqldb_' + name];
-      delete global.localStorage[name];
-    }
-    callback(null, {'ok': true});
-  });
-});
-
-WebSqlPouch.Changes = new utils.Changes();
-
-module.exports = WebSqlPouch;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":10,"../merge":16,"../utils":21}],6:[function(_dereq_,module,exports){
-'use strict';
-var utils = _dereq_('./utils');
-var merge = _dereq_('./merge');
-var errors = _dereq_('./deps/errors');
-var EE = _dereq_('events').EventEmitter;
-var evalFilter = _dereq_('./evalFilter');
-var evalView = _dereq_('./evalView');
-module.exports = Changes;
-utils.inherits(Changes, EE);
-
-function Changes(db, opts, callback) {
-  EE.call(this);
-  var self = this;
-  this.db = db;
-  opts = opts ? utils.clone(opts) : {};
-  var oldComplete = callback || opts.complete || function () {};
-  var complete = opts.complete = utils.once(function (err, resp) {
-    if (err) {
-      self.emit('error', err);
-    } else {
-      self.emit('complete', resp);
-    }
-    self.removeAllListeners();
-    db.removeListener('destroyed', onDestroy);
-  });
-  if (oldComplete) {
-    self.on('complete', function (resp) {
-      oldComplete(null, resp);
-    });
-    self.on('error', function (err) {
-      oldComplete(err);
-    });
-  }
-  var oldOnChange = opts.onChange;
-  if (oldOnChange) {
-    self.on('change', oldOnChange);
-  }
-  function onDestroy() {
-    self.cancel();
-  }
-  db.once('destroyed', onDestroy);
-
-  opts.onChange = function (change) {
-    if (opts.isCancelled) {
-      return;
-    }
-    self.emit('change', change);
-    if (self.startSeq && self.startSeq <= change.seq) {
-      self.emit('uptodate');
-      self.startSeq = false;
-    }
-    if (change.deleted) {
-      self.emit('delete', change);
-    } else if (change.changes.length === 1 &&
-      change.changes[0].rev.slice(0, 2) === '1-') {
-      self.emit('create', change);
-    } else {
-      self.emit('update', change);
-    }
-  };
-
-  var promise = new utils.Promise(function (fulfill, reject) {
-    opts.complete = function (err, res) {
-      if (err) {
-        reject(err);
-      } else {
-        fulfill(res);
-      }
-    };
-  });
-  self.once('cancel', function () {
-    if (oldOnChange) {
-      self.removeListener('change', oldOnChange);
-    }
-    opts.complete(null, {status: 'cancelled'});
-  });
-  this.then = promise.then.bind(promise);
-  this['catch'] = promise['catch'].bind(promise);
-  this.then(function (result) {
-    complete(null, result);
-  }, complete);
-
-
-
-  if (!db.taskqueue.isReady) {
-    db.taskqueue.addTask(function () {
-      if (self.isCancelled) {
-        self.emit('cancel');
-      } else {
-        self.doChanges(opts);
-      }
-    });
-  } else {
-    self.doChanges(opts);
-  }
-}
-Changes.prototype.cancel = function () {
-  this.isCancelled = true;
-  if (this.db.taskqueue.isReady) {
-    this.emit('cancel');
-  }
-};
-function processChange(doc, metadata, opts) {
-  var changeList = [{rev: doc._rev}];
-  if (opts.style === 'all_docs') {
-    changeList = merge.collectLeaves(metadata.rev_tree)
-    .map(function (x) { return {rev: x.rev}; });
-  }
-  var change = {
-    id: metadata.id,
-    changes: changeList,
-    doc: doc
-  };
-
-  if (utils.isDeleted(metadata, doc._rev)) {
-    change.deleted = true;
-  }
-  if (opts.conflicts) {
-    change.doc._conflicts = merge.collectConflicts(metadata);
-    if (!change.doc._conflicts.length) {
-      delete change.doc._conflicts;
-    }
-  }
-  return change;
-}
-
-Changes.prototype.doChanges = function (opts) {
-  var self = this;
-  var callback = opts.complete;
-
-  opts = utils.clone(opts);
-  if ('live' in opts && !('continuous' in opts)) {
-    opts.continuous = opts.live;
-  }
-  opts.processChange = processChange;
-
-  if (!opts.since) {
-    opts.since = 0;
-  }
-  if (opts.since === 'latest') {
-    this.db.info().then(function (info) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      opts.since = info.update_seq  - 1;
-      self.doChanges(opts);
-    }, callback);
-    return;
-  }
-
-  if (opts.continuous && opts.since !== 'latest') {
-    this.db.info().then(function (info) {
-      self.startSeq = info.update_seq - 1;
-    }, function (err) {
-      if (err.id === 'idbNull') {
-        //db closed before this returned
-        //thats ok
-        return;
-      }
-      throw err;
-    });
-  }
-
-  if (this.db.type() !== 'http' &&
-    opts.filter && typeof opts.filter === 'string') {
-    return this.filterChanges(opts);
-  }
-
-  if (!('descending' in opts)) {
-    opts.descending = false;
-  }
-
-  // 0 and 1 should return 1 document
-  opts.limit = opts.limit === 0 ? 1 : opts.limit;
-  opts.complete = callback;
-  var newPromise = this.db._changes(opts);
-  if (newPromise && typeof newPromise.cancel === 'function') {
-    var cancel = self.cancel;
-    self.cancel = utils.getArguments(function (args) {
-      newPromise.cancel();
-      cancel.apply(this, args);
-    });
-  }
-};
-
-Changes.prototype.filterChanges = function (opts) {
-  var self = this;
-  var callback = opts.complete;
-  if (opts.filter === '_view') {
-    if (!opts.view || typeof opts.view !== 'string') {
-      var err = new  Error('`view` filter parameter is not provided.');
-      err.status = errors.BAD_REQUEST.status;
-      err.name = errors.BAD_REQUEST.name;
-      err.error = true;
-      callback(err);
-      return;
-    }
-    // fetch a view from a design doc, make it behave like a filter
-    var viewName = opts.view.split('/');
-    this.db.get('_design/' + viewName[0], function (err, ddoc) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      if (err) {
-        callback(err);
-        return;
-      }
-      if (ddoc && ddoc.views && ddoc.views[viewName[1]]) {
-        
-        var filter = evalView(ddoc.views[viewName[1]].map);
-        opts.filter = filter;
-        self.doChanges(opts);
-        return;
-      }
-      var msg = ddoc.views ? 'missing json key: ' + viewName[1] :
-        'missing json key: views';
-      if (!err) {
-        err = new  Error(msg);
-        err.status = errors.MISSING_DOC.status;
-        err.name = errors.MISSING_DOC.name;
-        err.error = true;
-      }
-      callback(err);
-      return;
-    });
-  } else {
-    // fetch a filter from a design doc
-    var filterName = opts.filter.split('/');
-    this.db.get('_design/' + filterName[0], function (err, ddoc) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      if (err) {
-        callback(err);
-        return;
-      }
-      if (ddoc && ddoc.filters && ddoc.filters[filterName[1]]) {
-        var filter = evalFilter(ddoc.filters[filterName[1]]);
-        opts.filter = filter;
-        self.doChanges(opts);
-        return;
-      } else {
-        var msg = (ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
-          : 'missing json key: filters';
-        if (!err) {
-          err = new  Error(msg);
-          err.status = errors.MISSING_DOC.status;
-          err.name = errors.MISSING_DOC.name;
-          err.error = true;
-        }
-        callback(err);
-        return;
-      }
-    });
-  }
-};
-},{"./deps/errors":10,"./evalFilter":13,"./evalView":14,"./merge":16,"./utils":21,"events":24}],7:[function(_dereq_,module,exports){
-(function (global){
-/*globals cordova */
-"use strict";
-
-var Adapter = _dereq_('./adapter');
-var utils = _dereq_('./utils');
-var TaskQueue = _dereq_('./taskqueue');
-var Promise = utils.Promise;
-
-function defaultCallback(err) {
-  if (err && global.debug) {
-    console.error(err);
-  }
-}
-
-utils.inherits(PouchDBVersion220, Adapter);
-function PouchDBVersion220(name, opts, callback) {
-
-  if (!(this instanceof PouchDBVersion220)) {
-    return new PouchDBVersion220(name, opts, callback);
-  }
-  var self = this;
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-  if (typeof callback === 'undefined') {
-    callback = defaultCallback;
-  }
-  opts = opts || {};
-  var oldCB = callback;
-  self.auto_compaction = opts.auto_compaction;
-  self.prefix = PouchDBVersion220.prefix;
-  Adapter.call(self);
-  self.taskqueue = new TaskQueue();
-  var promise = new Promise(function (fulfill, reject) {
-    callback = function (err, resp) {
-      if (err) {
-        return reject(err);
-      }
-      delete resp.then;
-      fulfill(resp);
-    };
-  
-    opts = utils.clone(opts);
-    var originalName = opts.name || name;
-    var backend, error;
-    (function () {
-      try {
-
-        if (typeof originalName !== 'string') {
-          error = new Error('Missing/invalid DB name');
-          error.code = 400;
-          throw error;
-        }
-
-        backend = PouchDBVersion220.parseAdapter(originalName, opts);
-        
-        opts.originalName = originalName;
-        opts.name = backend.name;
-        opts.adapter = opts.adapter || backend.adapter;
-        self._adapter = opts.adapter;
-        if (!PouchDBVersion220.adapters[opts.adapter]) {
-          error = new Error('Adapter is missing');
-          error.code = 404;
-          throw error;
-        }
-
-        if (!PouchDBVersion220.adapters[opts.adapter].valid()) {
-          error = new Error('Invalid Adapter');
-          error.code = 404;
-          throw error;
-        }
-      } catch (err) {
-        self.taskqueue.fail(err);
-        self.changes = utils.toPromise(function (opts) {
-          if (opts.complete) {
-            opts.complete(err);
-          }
-        });
-      }
-    }());
-    if (error) {
-      return reject(error); // constructor error, see above
-    }
-    self.adapter = opts.adapter;
-
-    // needs access to PouchDBVersion220;
-    self.replicate = {};
-
-    self.replicate.from = function (url, opts, callback) {
-      return PouchDBVersion220.replicate(url, self, opts, callback);
-    };
-
-    self.replicate.to = function (url, opts, callback) {
-      return PouchDBVersion220.replicate(self, url, opts, callback);
-    };
-
-    self.sync = function (dbName, opts, callback) {
-      return PouchDBVersion220.sync(self, dbName, opts, callback);
-    };
-
-    self.replicate.sync = self.sync;
-
-    self.destroy = utils.adapterFun('destroy', function (callback) {
-      var self = this;
-      self.info(function (err, info) {
-        if (err) {
-          return callback(err);
-        }
-        PouchDBVersion220.destroy(info.db_name, callback);
-      });
-    });
-
-    PouchDBVersion220.adapters[opts.adapter].call(self, opts, function (err, db) {
-      if (err) {
-        if (callback) {
-          self.taskqueue.fail(err);
-          callback(err);
-        }
-        return;
-      }
-      function destructionListener(event) {
-        if (event === 'destroyed') {
-          self.emit('destroyed');
-          PouchDBVersion220.removeListener(opts.name, destructionListener);
-        }
-      }
-      PouchDBVersion220.on(opts.name, destructionListener);
-      self.emit('created', self);
-      PouchDBVersion220.emit('created', opts.originalName);
-      self.taskqueue.ready(self);
-      callback(null, self);
-      
-    });
-    if (opts.skipSetup) {
-      self.taskqueue.ready(self);
-    }
-
-    if (utils.isCordova()) {
-      //to inform websql adapter that we can use api
-      cordova.fireWindowEvent(opts.name + "_pouch", {});
-    }
-  });
-  promise.then(function (resp) {
-    oldCB(null, resp);
-  }, oldCB);
-  self.then = promise.then.bind(promise);
-  self["catch"] = promise["catch"].bind(promise);
-
-}
-
-module.exports = PouchDBVersion220;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./adapter":2,"./taskqueue":20,"./utils":21}],8:[function(_dereq_,module,exports){
-"use strict";
-
-var createBlob = _dereq_('./blob.js');
-var errors = _dereq_('./errors');
-var utils = _dereq_("../utils");
-
-function ajax(options, adapterCallback) {
-
-  var requestCompleted = false;
-  var callback = utils.getArguments(function (args) {
-    if (requestCompleted) {
-      return;
-    }
-    adapterCallback.apply(this, args);
-    requestCompleted = true;
-  });
-
-  if (typeof options === "function") {
-    callback = options;
-    options = {};
-  }
-
-  options = utils.clone(options);
-
-  var defaultOptions = {
-    method : "GET",
-    headers: {},
-    json: true,
-    processData: true,
-    timeout: 10000,
-    cache: false
-  };
-
-  options = utils.extend(true, defaultOptions, options);
-
-  // cache-buster, specifically designed to work around IE's aggressive caching
-  // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/
-  if (options.method === 'GET' && !options.cache) {
-    var hasArgs = options.url.indexOf('?') !== -1;
-    options.url += (hasArgs ? '&' : '?') + '_nonce=' + utils.uuid(16);
-  }
-
-  function onSuccess(obj, resp, cb) {
-    if (!options.binary && !options.json && options.processData &&
-      typeof obj !== 'string') {
-      obj = JSON.stringify(obj);
-    } else if (!options.binary && options.json && typeof obj === 'string') {
-      try {
-        obj = JSON.parse(obj);
-      } catch (e) {
-        // Probably a malformed JSON from server
-        return cb(e);
-      }
-    }
-    if (Array.isArray(obj)) {
-      obj = obj.map(function (v) {
-        var obj;
-        if (v.ok) {
-          return v;
-        } else if (v.error && v.error === 'conflict') {
-          obj = errors.REV_CONFLICT;
-          obj.id = v.id;
-          return obj;
-        } else if (v.error && v.error === 'forbidden') {
-          obj = errors.FORBIDDEN;
-          obj.id = v.id;
-          obj.reason = v.reason;
-          return obj;
-        } else if (v.missing) {
-          obj = errors.MISSING_DOC;
-          obj.missing = v.missing;
-          return obj;
-        } else {
-          return v;
-        }
-      });
-    }
-    cb(null, obj, resp);
-  }
-
-  function onError(err, cb) {
-    var errParsed, errObj, errType, key;
-    try {
-      errParsed = JSON.parse(err.responseText);
-      //would prefer not to have a try/catch clause
-      for (key in errors) {
-        if (errors.hasOwnProperty(key) &&
-            errors[key].name === errParsed.error) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType, errParsed.reason);
-    } catch (e) {
-      for (var key in errors) {
-        if (errors.hasOwnProperty(key) && errors[key].status === err.status) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType);
-    }
-    cb(errObj);
-  }
-
-  var timer;
-  var xhr;
-  if (options.xhr) {
-    xhr = new options.xhr();
-  } else {
-    xhr = new XMLHttpRequest();
-  }
-  xhr.open(options.method, options.url);
-  xhr.withCredentials = true;
-
-  if (options.json) {
-    options.headers.Accept = 'application/json';
-    options.headers['Content-Type'] = options.headers['Content-Type'] ||
-      'application/json';
-    if (options.body &&
-        options.processData &&
-        typeof options.body !== "string") {
-      options.body = JSON.stringify(options.body);
-    }
-  }
-
-  if (options.binary) {
-    xhr.responseType = 'arraybuffer';
-  }
-
-  var createCookie = function (name, value, days) {
-    var expires = "";
-    if (days) {
-      var date = new Date();
-      date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
-      expires = "; expires=" + date.toGMTString();
-    }
-    document.cookie = name + "=" + value + expires + "; path=/";
-  };
-
-  for (var key in options.headers) {
-    if (key === 'Cookie') {
-      var cookie = options.headers[key].split('=');
-      createCookie(cookie[0], cookie[1], 10);
-    } else {
-      xhr.setRequestHeader(key, options.headers[key]);
-    }
-  }
-
-  if (!("body" in options)) {
-    options.body = null;
-  }
-
-  var abortReq = function () {
-    if (requestCompleted) {
-      return;
-    }
-    xhr.abort();
-    onError(xhr, callback);
-  };
-
-  xhr.onreadystatechange = function () {
-    if (xhr.readyState !== 4 || requestCompleted) {
-      return;
-    }
-    clearTimeout(timer);
-    if (xhr.status >= 200 && xhr.status < 300) {
-      var data;
-      if (options.binary) {
-        data = createBlob([xhr.response || ''], {
-          type: xhr.getResponseHeader('Content-Type')
-        });
-      } else {
-        data = xhr.responseText;
-      }
-      onSuccess(data, xhr, callback);
-    } else {
-      onError(xhr, callback);
-    }
-  };
-
-  if (options.timeout > 0) {
-    timer = setTimeout(abortReq, options.timeout);
-    xhr.onprogress = function () {
-      clearTimeout(timer);
-      timer = setTimeout(abortReq, options.timeout);
-    };
-    if (xhr.upload) { // does not exist in ie9
-      xhr.upload.onprogress = xhr.onprogress;
-    }
-  }
-  xhr.send(options.body);
-  return {abort: abortReq};
-
-}
-
-module.exports = ajax;
-
-},{"../utils":21,"./blob.js":9,"./errors":10}],9:[function(_dereq_,module,exports){
-(function (global){
-"use strict";
-
-//Abstracts constructing a Blob object, so it also works in older
-//browsers that don't support the native Blob constructor. (i.e.
-//old QtWebKit versions, at least).
-function createBlob(parts, properties) {
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var BlobBuilder = global.BlobBuilder ||
-                      global.MSBlobBuilder ||
-                      global.MozBlobBuilder ||
-                      global.WebKitBlobBuilder;
-    var builder = new BlobBuilder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
-  }
-}
-
-module.exports = createBlob;
-
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],10:[function(_dereq_,module,exports){
-"use strict";
-
-function PouchError(opts) {
-  this.status = opts.status;
-  this.name = opts.error;
-  this.message = opts.reason;
-  this.error = true;
-}
-
-PouchError.prototype__proto__ = Error.prototype;
-
-PouchError.prototype.toString = function () {
-  return JSON.stringify({
-    status: this.status,
-    name: this.name,
-    message: this.message
-  });
-};
-
-exports.UNAUTHORIZED = new PouchError({
-  status: 401,
-  error: 'unauthorized',
-  reason: "Name or password is incorrect."
-});
-exports.MISSING_BULK_DOCS = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: "Missing JSON list of 'docs'"
-});
-exports.MISSING_DOC = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'missing'
-});
-exports.REV_CONFLICT = new PouchError({
-  status: 409,
-  error: 'conflict',
-  reason: 'Document update conflict'
-});
-exports.INVALID_ID = new PouchError({
-  status: 400,
-  error: 'invalid_id',
-  reason: '_id field must contain a string'
-});
-exports.MISSING_ID = new PouchError({
-  status: 412,
-  error: 'missing_id',
-  reason: '_id is required for puts'
-});
-exports.RESERVED_ID = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Only reserved document ids may start with underscore.'
-});
-exports.NOT_OPEN = new PouchError({
-  status: 412,
-  error: 'precondition_failed',
-  reason: 'Database not open so cannot close'
-});
-exports.UNKNOWN_ERROR = new PouchError({
-  status: 500,
-  error: 'unknown_error',
-  reason: 'Database encountered an unknown error'
-});
-exports.BAD_ARG = new PouchError({
-  status: 500,
-  error: 'badarg',
-  reason: 'Some query argument is invalid'
-});
-exports.INVALID_REQUEST = new PouchError({
-  status: 400,
-  error: 'invalid_request',
-  reason: 'Request was invalid'
-});
-exports.QUERY_PARSE_ERROR = new PouchError({
-  status: 400,
-  error: 'query_parse_error',
-  reason: 'Some query parameter is invalid'
-});
-exports.DOC_VALIDATION = new PouchError({
-  status: 500,
-  error: 'doc_validation',
-  reason: 'Bad special document member'
-});
-exports.BAD_REQUEST = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Something wrong with the request'
-});
-exports.NOT_AN_OBJECT = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Document must be a JSON object'
-});
-exports.DB_MISSING = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'Database not found'
-});
-exports.IDB_ERROR = new PouchError({
-  status: 500,
-  error: 'indexed_db_went_bad',
-  reason: 'unknown'
-});
-exports.WSQ_ERROR = new PouchError({
-  status: 500,
-  error: 'web_sql_went_bad',
-  reason: 'unknown'
-});
-exports.LDB_ERROR = new PouchError({
-  status: 500,
-  error: 'levelDB_went_went_bad',
-  reason: 'unknown'
-});
-exports.FORBIDDEN = new PouchError({
-  status: 403,
-  error: 'forbidden',
-  reason: 'Forbidden by design doc validate_doc_update function'
-});
-exports.error = function (error, reason, name) {
-  function CustomPouchError(msg) {
-    this.message = reason;
-    if (name) {
-      this.name = name;
-    }
-  }
-  CustomPouchError.prototype = error;
-  return new CustomPouchError(reason);
-};
-
-},{}],11:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('../utils').Promise;
-
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    if (docId && typeof docId === 'object') {
-      docId = docId._id;
-    }
-    if (typeof docId !== 'string') {
-      return reject(new Error('doc id is required'));
-    }
-
-    db.get(docId, function (err, doc) {
-      if (err) {
-        if (err.name !== 'not_found') {
-          return reject(err);
-        }
-        return fulfill(tryAndPut(db, diffFun({_id : docId}), diffFun));
-      }
-      var newDoc = diffFun(doc);
-      if (!newDoc) {
-        return fulfill(doc);
-      }
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
-  });
-}
-
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc)["catch"](function (err) {
-    if (err.name !== 'conflict') {
-      throw err;
-    }
-    return upsert(db, doc, diffFun);
-  });
-}
-
-module.exports = function (db, docId, diffFun, cb) {
-  if (typeof cb === 'function') {
-    upsert(db, docId, diffFun).then(function (resp) {
-      cb(null, resp);
-    }, cb);
-  } else {
-    return upsert(db, docId, diffFun);
-  }
-};
-
-},{"../utils":21}],12:[function(_dereq_,module,exports){
-"use strict";
-
-// BEGIN Math.uuid.js
-
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- *   length - the desired number of characters
- *   radix  - the number of allowable values for each character.
- *
- * EXAMPLES:
- *   // No arguments  - returns RFC4122, version 4 ID
- *   >>> Math.uuid()
- *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- *   // One argument - returns ID of the specified length
- *   >>> Math.uuid(15)     // 15 character ID (default base=62)
- *   "VcydxgltxrVZSTV"
- *
- *   // Two arguments - returns ID of the specified length, and radix. 
- *   // (Radix must be <= 62)
- *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
- *   "01001010"
- *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
- *   "47473046"
- *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
- *   "098F4D35"
- */
-var chars = (
-  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
-  'abcdefghijklmnopqrstuvwxyz'
-).split('');
-function getValue(radix) {
-  return 0 | Math.random() * radix;
-}
-function uuid(len, radix) {
-  radix = radix || chars.length;
-  var out = '';
-  var i = -1;
-
-  if (len) {
-    // Compact form
-    while (++i < len) {
-      out += chars[getValue(radix)];
-    }
-    return out;
-  }
-    // rfc4122, version 4 form
-    // Fill in random data.  At i==19 set the high bits of clock sequence as
-    // per rfc4122, sec. 4.1.5
-  while (++i < 36) {
-    switch (i) {
-      case 8:
-      case 13:
-      case 18:
-      case 23:
-        out += '-';
-        break;
-      case 19:
-        out += chars[(getValue(16) & 0x3) | 0x8];
-        break;
-      default:
-        out += chars[getValue(16)];
-    }
-  }
-
-  return out;
-}
-
-
-
-module.exports = uuid;
-
-
-},{}],13:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = evalFilter;
-function evalFilter(input) {
-  /*jshint evil: true */
-  return eval([
-    '(function () { return ',
-    input,
-    ' })()'
-  ].join(''));
-}
-},{}],14:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = evalView;
-function evalView(input) {
-  /*jshint evil: true */
-  return eval([
-    '(function () {',
-    '  return function (doc) {',
-    '    var emitted = false;',
-    '    var emit = function (a, b) {',
-    '      emitted = true;',
-    '    };',
-    '    var view = ' + input + ';',
-    '    view(doc);',
-    '    if (emitted) {',
-    '      return true;',
-    '    }',
-    '  }',
-    '})()'
-  ].join('\n'));
-}
-},{}],15:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-var PouchDBVersion220 = _dereq_('./setup');
-
-module.exports = PouchDBVersion220;
-
-PouchDBVersion220.ajax = _dereq_('./deps/ajax');
-PouchDBVersion220.extend = _dereq_('extend');
-PouchDBVersion220.utils = _dereq_('./utils');
-PouchDBVersion220.Errors = _dereq_('./deps/errors');
-PouchDBVersion220.replicate = _dereq_('./replicate').replicate;
-PouchDBVersion220.sync = _dereq_('./sync');
-PouchDBVersion220.version = _dereq_('./version');
-var httpAdapter = _dereq_('./adapters/http');
-PouchDBVersion220.adapter('http', httpAdapter);
-PouchDBVersion220.adapter('https', httpAdapter);
-
-PouchDBVersion220.adapter('idb', _dereq_('./adapters/idb'));
-PouchDBVersion220.adapter('websql', _dereq_('./adapters/websql'));
-PouchDBVersion220.plugin(_dereq_('pouchdb-mapreduce'));
-
-if (!process.browser) {
-  var ldbAdapter = _dereq_('./adapters/leveldb');
-  PouchDBVersion220.adapter('ldb', ldbAdapter);
-  PouchDBVersion220.adapter('leveldb', ldbAdapter);
-}
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"./adapters/http":3,"./adapters/idb":4,"./adapters/leveldb":23,"./adapters/websql":5,"./deps/ajax":8,"./deps/errors":10,"./replicate":17,"./setup":18,"./sync":19,"./utils":21,"./version":1,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":25,"extend":26,"pouchdb-mapreduce":48}],16:[function(_dereq_,module,exports){
-'use strict';
-var utils = _dereq_('./utils');
-
-
-// for a better overview of what this is doing, read:
-// https://github.com/apache/couchdb/blob/master/src/couchdb/couch_key_tree.erl
-//
-// But for a quick intro, CouchDB uses a revision tree to store a documents
-// history, A -> B -> C, when a document has conflicts, that is a branch in the
-// tree, A -> (B1 | B2 -> C), We store these as a nested array in the format
-//
-// KeyTree = [Path ... ]
-// Path = {pos: position_from_root, ids: Tree}
-// Tree = [Key, Opts, [Tree, ...]], in particular single node: [Key, []]
-
-// Turn a path as a flat array into a tree with a single branch
-function pathToTree(path) {
-  var doc = path.shift();
-  var root = [doc.id, doc.opts, []];
-  var leaf = root;
-  var nleaf;
-
-  while (path.length) {
-    doc = path.shift();
-    nleaf = [doc.id, doc.opts, []];
-    leaf[2].push(nleaf);
-    leaf = nleaf;
-  }
-  return root;
-}
-
-// Merge two trees together
-// The roots of tree1 and tree2 must be the same revision
-function mergeTree(in_tree1, in_tree2) {
-  var queue = [{tree1: in_tree1, tree2: in_tree2}];
-  var conflicts = false;
-  while (queue.length > 0) {
-    var item = queue.pop();
-    var tree1 = item.tree1;
-    var tree2 = item.tree2;
-
-    if (tree1[1].status || tree2[1].status) {
-      tree1[1].status =
-        (tree1[1].status ===  'available' ||
-         tree2[1].status === 'available') ? 'available' : 'missing';
-    }
-
-    for (var i = 0; i < tree2[2].length; i++) {
-      if (!tree1[2][0]) {
-        conflicts = 'new_leaf';
-        tree1[2][0] = tree2[2][i];
-        continue;
-      }
-
-      var merged = false;
-      for (var j = 0; j < tree1[2].length; j++) {
-        if (tree1[2][j][0] === tree2[2][i][0]) {
-          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
-          merged = true;
-        }
-      }
-      if (!merged) {
-        conflicts = 'new_branch';
-        tree1[2].push(tree2[2][i]);
-        tree1[2].sort();
-      }
-    }
-  }
-  return {conflicts: conflicts, tree: in_tree1};
-}
-
-function doMerge(tree, path, dontExpand) {
-  var restree = [];
-  var conflicts = false;
-  var merged = false;
-  var res;
-
-  if (!tree.length) {
-    return {tree: [path], conflicts: 'new_leaf'};
-  }
-
-  tree.forEach(function (branch) {
-    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
-      // Paths start at the same position and have the same root, so they need
-      // merged
-      res = mergeTree(branch.ids, path.ids);
-      restree.push({pos: branch.pos, ids: res.tree});
-      conflicts = conflicts || res.conflicts;
-      merged = true;
-    } else if (dontExpand !== true) {
-      // The paths start at a different position, take the earliest path and
-      // traverse up until it as at the same point from root as the path we
-      // want to merge.  If the keys match we return the longer path with the
-      // other merged After stemming we dont want to expand the trees
-
-      var t1 = branch.pos < path.pos ? branch : path;
-      var t2 = branch.pos < path.pos ? path : branch;
-      var diff = t2.pos - t1.pos;
-
-      var candidateParents = [];
-
-      var trees = [];
-      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
-      while (trees.length > 0) {
-        var item = trees.pop();
-        if (item.diff === 0) {
-          if (item.ids[0] === t2.ids[0]) {
-            candidateParents.push(item);
-          }
-          continue;
-        }
-        if (!item.ids) {
-          continue;
-        }
-        /*jshint loopfunc:true */
-        item.ids[2].forEach(function (el, idx) {
-          trees.push(
-            {ids: el, diff: item.diff - 1, parent: item.ids, parentIdx: idx});
-        });
-      }
-
-      var el = candidateParents[0];
-
-      if (!el) {
-        restree.push(branch);
-      } else {
-        res = mergeTree(el.ids, t2.ids);
-        el.parent[2][el.parentIdx] = res.tree;
-        restree.push({pos: t1.pos, ids: t1.ids});
-        conflicts = conflicts || res.conflicts;
-        merged = true;
-      }
-    } else {
-      restree.push(branch);
-    }
-  });
-
-  // We didnt find
-  if (!merged) {
-    restree.push(path);
-  }
-
-  restree.sort(function (a, b) {
-    return a.pos - b.pos;
-  });
-
-  return {
-    tree: restree,
-    conflicts: conflicts || 'internal_node'
-  };
-}
-
-// To ensure we dont grow the revision tree infinitely, we stem old revisions
-function stem(tree, depth) {
-  // First we break out the tree into a complete list of root to leaf paths,
-  // we cut off the start of the path and generate a new set of flat trees
-  var stemmedPaths = PouchMerge.rootToLeaf(tree).map(function (path) {
-    var stemmed = path.ids.slice(-depth);
-    return {
-      pos: path.pos + (path.ids.length - stemmed.length),
-      ids: pathToTree(stemmed)
-    };
-  });
-  // Then we remerge all those flat trees together, ensuring that we dont
-  // connect trees that would go beyond the depth limit
-  return stemmedPaths.reduce(function (prev, current, i, arr) {
-    return doMerge(prev, current, true).tree;
-  }, [stemmedPaths.shift()]);
-}
-
-var PouchMerge = {};
-
-PouchMerge.merge = function (tree, path, depth) {
-  // Ugh, nicer way to not modify arguments in place?
-  tree = utils.extend(true, [], tree);
-  path = utils.clone(path);
-  var newTree = doMerge(tree, path);
-  return {
-    tree: stem(newTree.tree, depth),
-    conflicts: newTree.conflicts
-  };
-};
-
-// We fetch all leafs of the revision tree, and sort them based on tree length
-// and whether they were deleted, undeleted documents with the longest revision
-// tree (most edits) win
-// The final sort algorithm is slightly documented in a sidebar here:
-// http://guide.couchdb.org/draft/conflicts.html
-PouchMerge.winningRev = function (metadata) {
-  var leafs = [];
-  PouchMerge.traverseRevTree(metadata.rev_tree,
-                              function (isLeaf, pos, id, something, opts) {
-    if (isLeaf) {
-      leafs.push({pos: pos, id: id, deleted: !!opts.deleted});
-    }
-  });
-  leafs.sort(function (a, b) {
-    if (a.deleted !== b.deleted) {
-      return a.deleted > b.deleted ? 1 : -1;
-    }
-    if (a.pos !== b.pos) {
-      return b.pos - a.pos;
-    }
-    return a.id < b.id ? 1 : -1;
-  });
-
-  return leafs[0].pos + '-' + leafs[0].id;
-};
-
-// Pretty much all below can be combined into a higher order function to
-// traverse revisions
-// The return value from the callback will be passed as context to all
-// children of that node
-PouchMerge.traverseRevTree = function (revs, callback) {
-  var toVisit = revs.slice();
-
-  var node;
-  while ((node = toVisit.pop())) {
-    var pos = node.pos;
-    var tree = node.ids;
-    var branches = tree[2];
-    var newCtx =
-      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
-    for (var i = 0, len = branches.length; i < len; i++) {
-      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
-    }
-  }
-};
-
-PouchMerge.collectLeaves = function (revs) {
-  var leaves = [];
-  PouchMerge.traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
-    if (isLeaf) {
-      leaves.unshift({rev: pos + "-" + id, pos: pos, opts: opts});
-    }
-  });
-  leaves.sort(function (a, b) {
-    return b.pos - a.pos;
-  });
-  leaves.map(function (leaf) { delete leaf.pos; });
-  return leaves;
-};
-
-// returns revs of all conflicts that is leaves such that
-// 1. are not deleted and
-// 2. are different than winning revision
-PouchMerge.collectConflicts = function (metadata) {
-  var win = PouchMerge.winningRev(metadata);
-  var leaves = PouchMerge.collectLeaves(metadata.rev_tree);
-  var conflicts = [];
-  leaves.forEach(function (leaf) {
-    if (leaf.rev !== win && !leaf.opts.deleted) {
-      conflicts.push(leaf.rev);
-    }
-  });
-  return conflicts;
-};
-
-PouchMerge.rootToLeaf = function (tree) {
-  var paths = [];
-  PouchMerge.traverseRevTree(tree, function (isLeaf, pos, id, history, opts) {
-    history = history ? history.slice(0) : [];
-    history.push({id: id, opts: opts});
-    if (isLeaf) {
-      var rootPos = pos + 1 - history.length;
-      paths.unshift({pos: rootPos, ids: history});
-    }
-    return history;
-  });
-  return paths;
-};
-
-
-module.exports = PouchMerge;
-
-},{"./utils":21}],17:[function(_dereq_,module,exports){
-'use strict';
-
-var utils = _dereq_('./utils');
-var Pouch = _dereq_('./index');
-var EE = _dereq_('events').EventEmitter;
-
-// We create a basic promise so the caller can cancel the replication possibly
-// before we have actually started listening to changes etc
-utils.inherits(Replication, EE);
-function Replication(opts) {
-  EE.call(this);
-  this.cancelled = false;
-  var self = this;
-  var promise = new utils.Promise(function (fulfill, reject) {
-    self.once('complete', fulfill);
-    self.once('error', reject);
-  });
-  self.then = function (resolve, reject) {
-    return promise.then(resolve, reject);
-  };
-  self["catch"] = function (reject) {
-    return promise["catch"](reject);
-  };
-}
-
-Replication.prototype.cancel = function () {
-  this.cancelled = true;
-  this.emit('cancel');
-};
-
-Replication.prototype.ready = function (src, target) {
-  var self = this;
-  function onDestroy() {
-    self.cancel();
-  }
-  src.once('destroyed', onDestroy);
-  target.once('destroyed', onDestroy);
-  function cleanup() {
-    self.removeAllListeners();
-    src.removeListener('destroyed', onDestroy);
-    target.removeListener('destroyed', onDestroy);
-  }
-  this.then(cleanup, cleanup);
-};
-
-
-// TODO: check CouchDB's replication id generation
-// Generate a unique id particular to this replication
-function genReplicationId(src, target, opts) {
-  var filterFun = opts.filter ? opts.filter.toString() : '';
-  return src.id().then(function (src_id) {
-    return target.id().then(function (target_id) {
-      var queryData = src_id + target_id + filterFun +
-        JSON.stringify(opts.query_params) + opts.doc_ids;
-      return '_local/' + utils.MD5(queryData);
-    });
-  });
-}
-
-
-function updateCheckpoint(db, id, checkpoint) {
-    return db.get(id)["catch"](function (err) {
-      if (err.status === 404) {
-        return {_id: id};
-      }
-      throw err;
-    }).then(function (doc) {
-      doc.last_seq = checkpoint;
-      return db.put(doc);
-    });
-  }
-
-function Checkpointer(src, target, id) {
-  this.src = src;
-  this.target = target;
-  this.id = id;
-}
-
-Checkpointer.prototype.writeCheckpoint = function (checkpoint) {
-  var self = this;
-  return this.updateTarget(checkpoint).then(function () {
-    return self.updateSource(checkpoint);
-  });
-};
-Checkpointer.prototype.updateTarget = function (checkpoint) {
-  return updateCheckpoint(this.target, this.id, checkpoint);
-};
-Checkpointer.prototype.updateSource = function (checkpoint) {
-  var self = this;
-  if (this.readOnlySource) {
-    return utils.Promise.resolve(true);
-  }
-  return updateCheckpoint(this.src, this.id, checkpoint)["catch"](function (err) {
-    if (err.status === 401) {
-      self.readOnlySource = true;
-      return true;
-    }
-    throw err;
-  });
-};
-Checkpointer.prototype.getCheckpoint = function () {
-  var self = this;
-  return self.target.get(self.id).then(function (targetDoc) {
-    return self.src.get(self.id).then(function (sourceDoc) {
-      if (targetDoc.last_seq === sourceDoc.last_seq) {
-        return sourceDoc.last_seq;
-      }
-      return 0;
-    }, function (err) {
-      if (err.status === 404 && targetDoc.last_seq) {
-        return self.src.put({
-          _id: self.id,
-          last_seq: 0
-        }).then(function () {
-          return 0;
-        }, function (err) {
-          if (err.status === 401) {
-            self.readOnlySource = true;
-            return targetDoc.last_seq;
-          }
-          return 0;
-        });
-      }
-      throw err;
-    });
-  })["catch"](function (err) {
-    if (err.status !== 404) {
-      throw err;
-    }
-    return 0;
-  });
-};
-function replicate(repId, src, target, opts, returnValue) {
-  var batches = [];               // list of batches to be processed
-  var currentBatch;               // the batch currently being processed
-  var pendingBatch = {
-    seq: 0,
-    changes: [],
-    docs: []
-  }; // next batch, not yet ready to be processed
-  var writingCheckpoint = false;  // true while checkpoint is being written
-  var changesCompleted = false;   // true when all changes received
-  var replicationCompleted = false; // true when replication has completed
-  var last_seq = 0;
-  var continuous = opts.continuous || opts.live || false;
-  var batch_size = opts.batch_size || 100;
-  var batches_limit = opts.batches_limit || 10;
-  var changesPending = false;     // true while src.changes is running
-  var changesCount = 0; // number of changes received since calling src.changes
-  var doc_ids = opts.doc_ids;
-  var checkpointer = new Checkpointer(src, target, repId);
-  var result = {
-    ok: true,
-    start_time: new Date(),
-    docs_read: 0,
-    docs_written: 0,
-    doc_write_failures: 0,
-    errors: []
-  };
-  var changesOpts = {};
-  returnValue.ready(src, target);
-
-
-  function writeDocs() {
-    if (currentBatch.docs.length === 0) {
-      return;
-    }
-    var docs = currentBatch.docs;
-    return target.bulkDocs({
-      docs: docs
-    }, {
-      new_edits: false
-    }).then(function (res) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      var errors = [];
-      res.forEach(function (res) {
-        if (!res.ok) {
-          result.doc_write_failures++;
-          errors.push(new Error(res.reason || res.message || 'Unknown reason'));
-        }
-      });
-      if (errors.length > 0) {
-        var error = new Error('bulkDocs error');
-        error.other_errors = errors;
-        abortReplication('target.bulkDocs failed to write docs', error);
-        throw new Error('bulkWrite partial failure');
-      }
-    }, function (err) {
-      result.doc_write_failures += docs.length;
-      throw err;
-    });
-  }
-
-
-  function getNextDoc() {
-    var diffs = currentBatch.diffs;
-    var id = Object.keys(diffs)[0];
-    var revs = diffs[id].missing;
-    return src.get(id, {revs: true, open_revs: revs, attachments: true})
-    .then(function (docs) {
-      docs.forEach(function (doc) {
-        if (returnValue.cancelled) {
-          return completeReplication();
-        }
-        if (doc.ok) {
-          result.docs_read++;
-          currentBatch.pendingRevs++;
-          currentBatch.docs.push(doc.ok);
-          delete diffs[doc.ok._id];
-        }
-      });
-    });
-  }
-
-
-  function getAllDocs() {
-    if (Object.keys(currentBatch.diffs).length > 0) {
-      return getNextDoc().then(getAllDocs);
-    } else {
-      return utils.Promise.resolve();
-    }
-  }
-
-
-  function getRevisionOneDocs() {
-    // filter out the generation 1 docs and get them
-    // leaving the non-generation one docs to be got otherwise
-    var ids = Object.keys(currentBatch.diffs).filter(function (id) {
-      var missing = currentBatch.diffs[id].missing;
-      return missing.length === 1 && missing[0].slice(0, 2) === '1-';
-    });
-    return src.allDocs({
-      keys: ids,
-      include_docs: true
-    }).then(function (res) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw (new Error('cancelled'));
-      }
-      res.rows.forEach(function (row, i) {
-        if (row.doc && !row.deleted &&
-          row.value.rev.slice(0, 2) === '1-' && (
-            !row.doc._attachments ||
-            Object.keys(row.doc._attachments).length === 0
-          )
-        ) {
-          result.docs_read++;
-          currentBatch.pendingRevs++;
-          currentBatch.docs.push(row.doc);
-          delete currentBatch.diffs[row.id];
-        }
-      });
-    });
-  }
-
-
-  function getDocs() {
-    if (src.type() === 'http') {
-      return getRevisionOneDocs().then(getAllDocs);
-    } else {
-      return getAllDocs();
-    }
-  }
-
-
-  function finishBatch() {
-    writingCheckpoint = true;
-    return checkpointer.writeCheckpoint(
-      currentBatch.seq
-    ).then(function (res) {
-      writingCheckpoint = false;
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      result.last_seq = last_seq = currentBatch.seq;
-      result.docs_written += currentBatch.docs.length;
-      returnValue.emit('change', utils.clone(result));
-      currentBatch = undefined;
-      getChanges();
-    })["catch"](function (err) {
-      writingCheckpoint = false;
-      abortReplication('writeCheckpoint completed with error', err);
-      throw err;
-    });
-  }
-
-
-  function getDiffs() {
-    var diff = {};
-    currentBatch.changes.forEach(function (change) {
-      diff[change.id] = change.changes.map(function (x) {
-        return x.rev;
-      });
-    });
-    return target.revsDiff(diff).then(function (diffs) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      // currentBatch.diffs elements are deleted as the documents are written
-      currentBatch.diffs = diffs;
-      currentBatch.pendingRevs = 0;
-    });
-  }
-
-
-  function startNextBatch() {
-    if (returnValue.cancelled || currentBatch) {
-      return;
-    }
-    if (batches.length === 0) {
-      processPendingBatch(true);
-      return;
-    }
-    currentBatch = batches.shift();
-    getDiffs()
-    .then(getDocs)
-    .then(writeDocs)
-    .then(finishBatch)
-    .then(startNextBatch)[
-    "catch"](function (err) {
-      abortReplication('batch processing terminated with error', err);
-    });
-  }
-
-
-  function processPendingBatch(immediate) {
-    if (pendingBatch.changes.length === 0) {
-      if (batches.length === 0 && !currentBatch) {
-        if ((continuous && changesOpts.live) || changesCompleted) {
-          returnValue.emit('uptodate', utils.clone(result));
-        }
-        if (changesCompleted) {
-          completeReplication();
-        }
-      }
-      return;
-    }
-    if (
-      immediate ||
-      changesCompleted ||
-      pendingBatch.changes.length >= batch_size
-    ) {
-      batches.push(pendingBatch);
-      pendingBatch = {
-        seq: 0,
-        changes: [],
-        docs: []
-      };
-      startNextBatch();
-    }
-  }
-
-
-  function abortReplication(reason, err) {
-    if (replicationCompleted) {
-      return;
-    }
-    result.ok = false;
-    result.status = 'aborted';
-    err.message = reason;
-    result.errors.push(err);
-    batches = [];
-    pendingBatch = {
-      seq: 0,
-      changes: [],
-      docs: []
-    };
-    completeReplication();
-  }
-
-
-  function completeReplication() {
-    if (replicationCompleted) {
-      return;
-    }
-    if (returnValue.cancelled) {
-      result.status = 'cancelled';
-      if (writingCheckpoint) {
-        return;
-      }
-    }
-    result.status = result.status || 'complete';
-    result.end_time = new Date();
-    result.last_seq = last_seq;
-    replicationCompleted = returnValue.cancelled = true;
-    if (result.errors.length > 0) {
-      var error = result.errors.pop();
-      if (result.errors.length > 0) {
-        error.other_errors = result.errors;
-      }
-      error.result = result;
-      returnValue.emit('error', error);
-    } else {
-      returnValue.emit('complete', result);
-    }
-  }
-
-
-  function onChange(change) {
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    changesCount++;
-    if (
-      pendingBatch.changes.length === 0 &&
-      batches.length === 0 &&
-      !currentBatch
-    ) {
-      returnValue.emit('outofdate', utils.clone(result));
-    }
-    pendingBatch.seq = change.seq;
-    pendingBatch.changes.push(change);
-    processPendingBatch(batches.length === 0);
-  }
-
-
-  function onChangesComplete(changes) {
-    changesPending = false;
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    if (changesCount > 0) {
-      changesOpts.since = changes.last_seq;
-      getChanges();
-    } else {
-      if (continuous) {
-        changesOpts.live = true;
-        getChanges();
-      } else {
-        changesCompleted = true;
-      }
-    }
-    processPendingBatch(true);
-  }
-
-
-  function onChangesError(err) {
-    changesPending = false;
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    abortReplication('changes rejected', err);
-  }
-
-
-  function getChanges() {
-    if (
-      !changesPending &&
-      !changesCompleted &&
-      batches.length < batches_limit
-    ) {
-      changesPending = true;
-      changesCount = 0;
-      src.changes(changesOpts)
-      .on('change', onChange)
-      .then(onChangesComplete)[
-      "catch"](onChangesError);
-    }
-  }
-
-
-  function startChanges() {
-    checkpointer.getCheckpoint().then(function (checkpoint) {
-      last_seq = checkpoint;
-      changesOpts = {
-        since: last_seq,
-        limit: batch_size,
-        style: 'all_docs',
-        doc_ids: doc_ids,
-        returnDocs: false
-      };
-      if (opts.filter) {
-        changesOpts.filter = opts.filter;
-      }
-      if (opts.query_params) {
-        changesOpts.query_params = opts.query_params;
-      }
-      getChanges();
-    })["catch"](function (err) {
-      abortReplication('getCheckpoint rejected with ', err);
-    });
-  }
-
-
-  returnValue.once('cancel', completeReplication);
-
-  if (typeof opts.onChange === 'function') {
-    returnValue.on('change', opts.onChange);
-  }
-
-  if (typeof opts.complete === 'function') {
-    returnValue.once('error', opts.complete);
-    returnValue.once('complete', function (result) {
-      opts.complete(null, result);
-    });
-  }
-
-  if (typeof opts.since === 'undefined') {
-    startChanges();
-  } else {
-    writingCheckpoint = true;
-    checkpointer.writeCheckpoint(opts.since).then(function (res) {
-      writingCheckpoint = false;
-      if (returnValue.cancelled) {
-        completeReplication();
-        return;
-      }
-      last_seq = opts.since;
-      startChanges();
-    })["catch"](function (err) {
-      writingCheckpoint = false;
-      abortReplication('writeCheckpoint completed with error', err);
-      throw err;
-    });
-  }
-}
-
-
-function toPouch(db) {
-  if (typeof db === 'string') {
-    return new Pouch(db);
-  } else if (db.then) {
-    return db;
-  } else {
-    return utils.Promise.resolve(db);
-  }
-}
-
-
-function replicateWrapper(src, target, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof opts === 'undefined') {
-    opts = {};
-  }
-  if (!opts.complete) {
-    opts.complete = callback || function () {};
-  }
-  opts = utils.clone(opts);
-  opts.continuous = opts.continuous || opts.live;
-  var replicateRet = new Replication(opts);
-  toPouch(src).then(function (src) {
-    return toPouch(target).then(function (target) {
-      if (opts.server) {
-        if (typeof src.replicateOnServer !== 'function') {
-          throw new TypeError(
-            'Server replication not supported for ' + src.type() + ' adapter'
-          );
-        }
-        if (src.type() !== target.type()) {
-          throw new TypeError('Server replication' +
-              ' for different adapter types (' +
-            src.type() + ' and ' + target.type() + ') is not supported'
-          );
-        }
-        src.replicateOnServer(target, opts, replicateRet);
-      } else {
-        return genReplicationId(src, target, opts).then(function (repId) {
-          replicate(repId, src, target, opts, replicateRet);
-        });
-      }
-    });
-  })["catch"](function (err) {
-    opts.complete(err);
-  });
-  return replicateRet;
-}
-
-exports.replicate = replicateWrapper;
-
-},{"./index":15,"./utils":21,"events":24}],18:[function(_dereq_,module,exports){
-(function (global){
-"use strict";
-
-var PouchDBVersion220 = _dereq_("./constructor");
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-var EventEmitter = _dereq_('events').EventEmitter;
-PouchDBVersion220.adapters = {};
-
-PouchDBVersion220.prefix = '_pouch_';
-
-var eventEmitter = new EventEmitter();
-
-var eventEmitterMethods = [
-  'on',
-  'addListener',
-  'emit',
-  'listeners',
-  'once',
-  'removeAllListeners',
-  'removeListener',
-  'setMaxListeners'
-];
-
-var preferredAdapters = ['levelalt', 'idb', 'leveldb', 'websql'];
-
-eventEmitterMethods.forEach(function (method) {
-  PouchDBVersion220[method] = eventEmitter[method].bind(eventEmitter);
-});
-PouchDBVersion220.setMaxListeners(0);
-PouchDBVersion220.parseAdapter = function (name, opts) {
-  var match = name.match(/([a-z\-]*):\/\/(.*)/);
-  var adapter, adapterName;
-  if (match) {
-    // the http adapter expects the fully qualified name
-    name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
-    adapter = match[1];
-    if (!PouchDBVersion220.adapters[adapter].valid()) {
-      throw 'Invalid adapter';
-    }
-    return {name: name, adapter: match[1]};
-  }
-
-  // check for browsers that have been upgraded from websql-only to websql+idb
-  var skipIdb = 'idb' in PouchDBVersion220.adapters && 'websql' in PouchDBVersion220.adapters &&
-    utils.hasLocalStorage() &&
-    global.localStorage['_pouch__websqldb_' + PouchDBVersion220.prefix + name];
-
-  if (typeof opts !== 'undefined' && opts.db) {
-    adapterName = 'leveldb';
-  } else {
-    for (var i = 0; i < preferredAdapters.length; ++i) {
-      adapterName = preferredAdapters[i];
-      if (adapterName in PouchDBVersion220.adapters) {
-        if (skipIdb && adapterName === 'idb') {
-          continue; // keep using websql to avoid user data loss
-        }
-        break;
-      }
-    }
-  }
-
-  if (adapterName) {
-    adapter = PouchDBVersion220.adapters[adapterName];
-    var use_prefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-
-    return {
-      name: use_prefix ? PouchDBVersion220.prefix + name : name,
-      adapter: adapterName
-    };
-  }
-
-  throw 'No valid adapter found';
-};
-
-PouchDBVersion220.destroy = utils.toPromise(function (name, opts, callback) {
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-
-  var backend = PouchDBVersion220.parseAdapter(opts.name || name, opts);
-  var dbName = backend.name;
-
-  var adapter = PouchDBVersion220.adapters[backend.adapter];
-
-  function destroyDb() {
-    // call destroy method of the particular adaptor
-    adapter.destroy(dbName, opts, function (err, resp) {
-      if (err) {
-        callback(err);
-      } else {
-        PouchDBVersion220.emit('destroyed', dbName);
-        //so we don't have to sift through all dbnames
-        PouchDBVersion220.emit(dbName, 'destroyed');
-        callback(null, resp || { 'ok': true });
-      }
-    });
-  }
-
-  var usePrefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-
-  var trueDbName = usePrefix ?
-    dbName.replace(new RegExp('^' + PouchDBVersion220.prefix), '') : dbName;
-  new PouchDBVersion220(trueDbName, {adapter : backend.adapter}, function (err, db) {
-    if (err) {
-      return callback(err);
-    }
-    db.get('_local/_pouch_dependentDbs', function (err, localDoc) {
-      if (err) {
-        if (err.name !== 'not_found') {
-          return callback(err);
-        } else { // no dependencies
-          return destroyDb();
-        }
-      }
-      var dependentDbs = localDoc.dependentDbs;
-      var deletedMap = Object.keys(dependentDbs).map(function (name) {
-        var trueName = usePrefix ?
-          name.replace(new RegExp('^' + PouchDBVersion220.prefix), '') : name;
-        return PouchDBVersion220.destroy(trueName, {adapter: backend.adapter});
-      });
-      Promise.all(deletedMap).then(destroyDb, function (error) {
-        callback(error);
-      });
-    });
-  });
-});
-
-PouchDBVersion220.allDbs = utils.toPromise(function (callback) {
-  var err = new Error('allDbs method removed');
-  err.stats = '400';
-  callback(err);
-});
-PouchDBVersion220.adapter = function (id, obj) {
-  if (obj.valid()) {
-    PouchDBVersion220.adapters[id] = obj;
-  }
-};
-
-PouchDBVersion220.plugin = function (obj) {
-  Object.keys(obj).forEach(function (id) {
-    PouchDBVersion220.prototype[id] = obj[id];
-  });
-};
-
-module.exports = PouchDBVersion220;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./constructor":7,"./utils":21,"events":24}],19:[function(_dereq_,module,exports){
-'use strict';
-var utils = _dereq_('./utils');
-var replicate = _dereq_('./replicate').replicate;
-var EE = _dereq_('events').EventEmitter;
-
-module.exports = Sync;
-utils.inherits(Sync, EE);
-function Sync(src, target, opts, callback) {
-  if (!(this instanceof Sync)) {
-    return new Sync(src, target, opts, callback);
-  }
-  var self = this;
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof opts === 'undefined') {
-    opts = {};
-  }
-  this.canceled = false;
-  opts = utils.clone(opts);
-  var onChange, complete;
-  if ('onChange' in opts) {
-    onChange = opts.onChange;
-    delete opts.onChange;
-  }
-  if (typeof callback === 'function' && !opts.complete) {
-    complete = callback;
-  } else if ('complete' in opts) {
-    complete = opts.complete;
-    delete opts.complete;
-  }
-  this.push = replicate(src, target, opts);
-
-  this.pull = replicate(target, src, opts);
-  var emittedCancel = false;
-  function onCancel(data) {
-    if (!emittedCancel) {
-      emittedCancel = true;
-      self.emit('cancel', data);
-    }
-  }
-
-  function pullChange(change) {
-    self.emit('change', {
-      direction: 'pull',
-      change: change
-    });
-  }
-  function pushChange(change) {
-    self.emit('change', {
-      direction: 'push',
-      change: change
-    });
-  }
-  var listeners = {};
-
-  function removal(event, func) {
-    if (event === 'change' &&
-      (func === pullChange ||
-      func === pushChange)) {
-      self.removeAllListeners('change');
-    } else if (event === 'cancel' &&
-      func === onCancel) {
-      self.removeAllListeners('cancel');
-    } else if (event in listeners && func === listeners[event]) {
-      self.removeAllListeners(event);
-    }
-  }
-
-  this.on('newListener', function (event) {
-    if (event === 'change') {
-      self.pull.on('change', pullChange);
-      self.push.on('change', pushChange);
-    } else if (event === 'cancel') {
-      self.pull.on('cancel', onCancel);
-      self.push.on('cancel', onCancel);
-    } else if (event !== 'error' &&
-      event !== 'complete' && !(event in listeners)) {
-      listeners[event] = function (e) {
-        self.emit(event, e);
-      };
-      self.pull.on(event, listeners[event]);
-      self.push.on(event, listeners[event]);
-    }
-  });
-
-  this.on('removeListener', function (event) {
-    if (event === 'change') {
-      self.pull.removeListener('change', pullChange);
-      self.push.removeListener('change', pushChange);
-    } else if (event === 'cancel') {
-      self.pull.removeListener('cancel', onCancel);
-      self.push.removeListener('cancel', onCancel);
-    } else if (event in listeners) {
-      if (typeof listeners[event] === 'function') {
-        self.pull.removeListener(event, listeners[event]);
-        self.push.removeListener(event, listeners[event]);
-        delete listeners[event];
-      }
-    }
-  });
-
-  this.pull.on('removeListener', removal);
-  this.push.on('removeListener', removal);
-
-  var promise = utils.Promise.all([
-    this.push,
-    this.pull
-  ]).then(function (resp) {
-    var out = {
-      push: resp[0],
-      pull: resp[1]
-    };
-    self.emit('complete', out);
-    if (complete) {
-      complete(null, out);
-    }
-    self.removeAllListeners();
-    return out;
-  }, function (err) {
-    self.cancel();
-    self.emit('error', err);
-    if (complete) {
-      complete(err);
-    }
-    self.removeAllListeners();
-    throw err;
-  });
-
-  this.then = function (success, err) {
-    return promise.then(success, err);
-  };
-
-  this["catch"] = function (err) {
-    return promise["catch"](err);
-  };
-}
-
-Sync.prototype.cancel = function () {
-  if (!this.canceled) {
-    this.canceled = true;
-    this.push.cancel();
-    this.pull.cancel();
-  }
-};
-},{"./replicate":17,"./utils":21,"events":24}],20:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = TaskQueue;
-
-function TaskQueue() {
-  this.isReady = false;
-  this.failed = false;
-  this.queue = [];
-}
-
-TaskQueue.prototype.execute = function () {
-  var d, func;
-  if (this.failed) {
-    while ((d = this.queue.shift())) {
-      if (typeof d === 'function') {
-        d(this.failed);
-        continue;
-      }
-      func = d.parameters[d.parameters.length - 1];
-      if (typeof func === 'function') {
-        func(this.failed);
-      } else if (d.name === 'changes' && typeof func.complete === 'function') {
-        func.complete(this.failed);
-      }
-    }
-  } else if (this.isReady) {
-    while ((d = this.queue.shift())) {
-
-      if (typeof d === 'function') {
-        d();
-      } else {
-        d.task = this.db[d.name].apply(this.db, d.parameters);
-      }
-    }
-  }
-};
-
-TaskQueue.prototype.fail = function (err) {
-  this.failed = err;
-  this.execute();
-};
-
-TaskQueue.prototype.ready = function (db) {
-  if (this.failed) {
-    return false;
-  } else if (arguments.length === 0) {
-    return this.isReady;
-  }
-  this.isReady = db ? true: false;
-  this.db = db;
-  this.execute();
-};
-
-TaskQueue.prototype.addTask = function (name, parameters) {
-  if (typeof name === 'function') {
-    this.queue.push(name);
-    if (this.failed) {
-      this.execute();
-    }
-  } else {
-    var task = { name: name, parameters: parameters };
-    this.queue.push(task);
-    if (this.failed) {
-      this.execute();
-    }
-    return task;
-  }
-};
-
-},{}],21:[function(_dereq_,module,exports){
-(function (process,global){
-/*jshint strict: false */
-/*global chrome */
-var crypto = _dereq_('crypto');
-var md5 = _dereq_('md5-jkmyers');
-var merge = _dereq_('./merge');
-exports.extend = _dereq_('extend');
-exports.ajax = _dereq_('./deps/ajax');
-exports.createBlob = _dereq_('./deps/blob');
-exports.uuid = _dereq_('./deps/uuid');
-exports.getArguments = _dereq_('argsarray');
-var buffer = _dereq_('./deps/buffer');
-var errors = _dereq_('./deps/errors');
-var EventEmitter = _dereq_('events').EventEmitter;
-
-if (typeof global.Promise === 'function') {
-  exports.Promise = global.Promise;
-} else {
-  exports.Promise = _dereq_('bluebird');
-}
-var Promise = exports.Promise;
-
-function toObject(array) {
-  var obj = {};
-  array.forEach(function (item) { obj[item] = true; });
-  return obj;
-}
-// List of top level reserved words for doc
-var reservedWords = toObject([
-  '_id',
-  '_rev',
-  '_attachments',
-  '_deleted',
-  '_revisions',
-  '_revs_info',
-  '_conflicts',
-  '_deleted_conflicts',
-  '_local_seq',
-  '_rev_tree'
-]);
-exports.clone = function (obj) {
-  return exports.extend(true, {}, obj);
-};
-exports.inherits = _dereq_('inherits');
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or 
-//     '_local'
-//   - any other string value is a valid id
-// Returns the specific error object for each case
-exports.invalidIdError = function (id) {
-  if (!id) {
-    return errors.MISSING_ID;
-  } else if (typeof id !== 'string') {
-    return errors.INVALID_ID;
-  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
-    return errors.RESERVED_ID;
-  }
-};
-
-function isChromeApp() {
-  return (typeof chrome !== "undefined" &&
-          typeof chrome.storage !== "undefined" &&
-          typeof chrome.storage.local !== "undefined");
-}
-
-// Pretty dumb name for a function, just wraps callback calls so we dont
-// to if (callback) callback() everywhere
-exports.call = exports.getArguments(function (args) {
-  if (!args.length) {
-    return;
-  }
-  var fun = args.shift();
-  if (typeof fun === 'function') {
-    fun.apply(this, args);
-  }
-});
-
-exports.isLocalId = function (id) {
-  return (/^_local/).test(id);
-};
-
-// check if a specific revision of a doc has been deleted
-//  - metadata: the metadata object from the doc store
-//  - rev: (optional) the revision to check. defaults to winning revision
-exports.isDeleted = function (metadata, rev) {
-  if (!rev) {
-    rev = merge.winningRev(metadata);
-  }
-  var dashIndex = rev.indexOf('-');
-  if (dashIndex !== -1) {
-    rev = rev.substring(dashIndex + 1);
-  }
-  var deleted = false;
-  merge.traverseRevTree(metadata.rev_tree,
-  function (isLeaf, pos, id, acc, opts) {
-    if (id === rev) {
-      deleted = !!opts.deleted;
-    }
-  });
-
-  return deleted;
-};
-
-exports.filterChange = function (opts) {
-  return function (change) {
-    var req = {};
-    var hasFilter = opts.filter && typeof opts.filter === 'function';
-
-    req.query = opts.query_params;
-    if (opts.filter && hasFilter && !opts.filter.call(this, change.doc, req)) {
-      return false;
-    }
-    if (opts.doc_ids && opts.doc_ids.indexOf(change.id) === -1) {
-      return false;
-    }
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else {
-      for (var att in change.doc._attachments) {
-        if (change.doc._attachments.hasOwnProperty(att)) {
-          change.doc._attachments[att].stub = true;
-        }
-      }
-    }
-    return true;
-  };
-};
-
-// Preprocess documents, parse their revisions, assign an id and a
-// revision for new writes that are missing them, etc
-exports.parseDoc = function (doc, newEdits) {
-  var nRevNum;
-  var newRevId;
-  var revInfo;
-  var opts = {status: 'available'};
-  if (doc._deleted) {
-    opts.deleted = true;
-  }
-
-  if (newEdits) {
-    if (!doc._id) {
-      doc._id = exports.uuid();
-    }
-    newRevId = exports.uuid(32, 16).toLowerCase();
-    if (doc._rev) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        throw "invalid value for property '_rev'";
-      }
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], {status: 'missing'}, [[newRevId, opts, []]]]
-      }];
-      nRevNum = parseInt(revInfo[1], 10) + 1;
-    } else {
-      doc._rev_tree = [{
-        pos: 1,
-        ids : [newRevId, opts, []]
-      }];
-      nRevNum = 1;
-    }
-  } else {
-    if (doc._revisions) {
-      doc._rev_tree = [{
-        pos: doc._revisions.start - doc._revisions.ids.length + 1,
-        ids: doc._revisions.ids.reduce(function (acc, x) {
-          if (acc === null) {
-            return [x, opts, []];
-          } else {
-            return [x, {status: 'missing'}, [acc]];
-          }
-        }, null)
-      }];
-      nRevNum = doc._revisions.start;
-      newRevId = doc._revisions.ids[0];
-    }
-    if (!doc._rev_tree) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        return errors.BAD_ARG;
-      }
-      nRevNum = parseInt(revInfo[1], 10);
-      newRevId = revInfo[2];
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], opts, []]
-      }];
-    }
-  }
-
-  var error = exports.invalidIdError(doc._id);
-  if (error) {
-    return error;
-  }
-
-  doc._id = decodeURIComponent(doc._id);
-  doc._rev = [nRevNum, newRevId].join('-');
-
-  var result = {metadata : {}, data : {}};
-  for (var key in doc) {
-    if (doc.hasOwnProperty(key)) {
-      var specialKey = key[0] === '_';
-      if (specialKey && !reservedWords[key]) {
-        error = errors.error(errors.DOC_VALIDATION);
-        error.reason += ': ' + key;
-        return error;
-      } else if (specialKey && key !== '_attachments') {
-        result.metadata[key.slice(1)] = doc[key];
-      } else {
-        result.data[key] = doc[key];
-      }
-    }
-  }
-  return result;
-};
-
-exports.isCordova = function () {
-  return (typeof cordova !== "undefined" ||
-          typeof PhoneGap !== "undefined" ||
-          typeof phonegap !== "undefined");
-};
-
-exports.hasLocalStorage = function () {
-  if (isChromeApp()) {
-    return false;
-  }
-  try {
-    return global.localStorage;
-  } catch (e) {
-    return false;
-  }
-};
-exports.Changes = function () {
-
-  var api = {};
-  var eventEmitter = new EventEmitter();
-  var isChrome = isChromeApp();
-  var listeners = {};
-  var hasLocal = false;
-  if (!isChrome) {
-    hasLocal = exports.hasLocalStorage();
-  }
-  if (isChrome) {
-    chrome.storage.onChanged.addListener(function (e) {
-      // make sure it's event addressed to us
-      if (e.db_name != null) {
-        //object only has oldValue, newValue members
-        eventEmitter.emit(e.dbName.newValue);
-      }
-    });
-  } else if (hasLocal) {
-    if (global.addEventListener) {
-      global.addEventListener("storage", function (e) {
-        eventEmitter.emit(e.key);
-      });
-    } else {
-      global.attachEvent("storage", function (e) {
-        eventEmitter.emit(e.key);
-      });
-    }
-  }
-
-  api.addListener = function (dbName, id, db, opts) {
-    if (listeners[id]) {
-      return;
-    }
-    function eventFunction() {
-      db.changes({
-        include_docs: opts.include_docs,
-        conflicts: opts.conflicts,
-        continuous: false,
-        descending: false,
-        filter: opts.filter,
-        view: opts.view,
-        since: opts.since,
-        query_params: opts.query_params,
-        onChange: function (c) {
-          if (c.seq > opts.since && !opts.cancelled) {
-            opts.since = c.seq;
-            exports.call(opts.onChange, c);
-          }
-        }
-      });
-    }
-    listeners[id] = eventFunction;
-    eventEmitter.on(dbName, eventFunction);
-  };
-
-  api.removeListener = function (dbName, id) {
-    if (!(id in listeners)) {
-      return;
-    }
-    eventEmitter.removeListener(dbName, listeners[id]);
-  };
-
-  api.clearListeners = function (dbName) {
-    eventEmitter.removeAllListeners(dbName);
-  };
-
-  api.notifyLocalWindows = function (dbName) {
-    //do a useless change on a storage thing
-    //in order to get other windows's listeners to activate
-    if (isChrome) {
-      chrome.storage.local.set({dbName: dbName});
-    } else if (hasLocal) {
-      localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
-    }
-  };
-
-  api.notify = function (dbName) {
-    eventEmitter.emit(dbName);
-  };
-
-  return api;
-};
-
-if (!process.browser || !('atob' in global)) {
-  exports.atob = function (str) {
-    var base64 = new buffer(str, 'base64');
-    // Node.js will just skip the characters it can't encode instead of
-    // throwing and exception
-    if (base64.toString('base64') !== str) {
-      throw ("Cannot base64 encode full string");
-    }
-    return base64.toString('binary');
-  };
-} else {
-  exports.atob = function (str) {
-    return atob(str);
-  };
-}
-
-if (!process.browser || !('btoa' in global)) {
-  exports.btoa = function (str) {
-    return new buffer(str, 'binary').toString('base64');
-  };
-} else {
-  exports.btoa = function (str) {
-    return btoa(str);
-  };
-}
-
-// From http://stackoverflow.com/questions/14967647/ (continues on next line)
-// encode-decode-image-with-base64-breaks-image (2013-04-21)
-exports.fixBinary = function (bin) {
-  if (!process.browser) {
-    // don't need to do this in Node
-    return bin;
-  }
-
-  var length = bin.length;
-  var buf = new ArrayBuffer(length);
-  var arr = new Uint8Array(buf);
-  for (var i = 0; i < length; i++) {
-    arr[i] = bin.charCodeAt(i);
-  }
-  return buf;
-};
-
-exports.once = function (fun) {
-  var called = false;
-  return exports.getArguments(function (args) {
-    if (called) {
-      console.trace();
-      throw new Error('once called  more than once');
-    } else {
-      called = true;
-      fun.apply(this, args);
-    }
-  });
-};
-
-exports.toPromise = function (func) {
-  //create the function we will be returning
-  return exports.getArguments(function (args) {
-    var self = this;
-    var tempCB =
-      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
-    // if the last argument is a function, assume its a callback
-    var usedCB;
-    if (tempCB) {
-      // if it was a callback, create a new callback which calls it,
-      // but do so async so we don't trap any errors
-      usedCB = function (err, resp) {
-        process.nextTick(function () {
-          tempCB(err, resp);
-        });
-      };
-    }
-    var promise = new Promise(function (fulfill, reject) {
-      var resp;
-      try {
-        var callback = exports.once(function (err, mesg) {
-          if (err) {
-            reject(err);
-          } else {
-            fulfill(mesg);
-          }
-        });
-        // create a callback for this invocation
-        // apply the function in the orig context
-        args.push(callback);
-        resp = func.apply(self, args);
-        if (resp && typeof resp.then === 'function') {
-          fulfill(resp);
-        }
-      } catch (e) {
-        reject(e);
-      }
-    });
-    // if there is a callback, call it back
-    if (usedCB) {
-      promise.then(function (result) {
-        usedCB(null, result);
-      }, usedCB);
-    }
-    promise.cancel = function () {
-      return this;
-    };
-    return promise;
-  });
-};
-
-exports.adapterFun = function (name, callback) {
-  return exports.toPromise(exports.getArguments(function (args) {
-    var self = this;
-    if (!this.taskqueue.isReady) {
-      return new exports.Promise(function (fulfill, reject) {
-        self.taskqueue.addTask(function (failed) {
-          if (failed) {
-            reject(failed);
-          } else {
-            fulfill(self[name].apply(self, args));
-          }
-        });
-      });
-    }
-    return callback.apply(this, args);
-  }));
-};
-//Can't find original post, but this is close
-//http://stackoverflow.com/questions/6965107/ (continues on next line)
-//converting-between-strings-and-arraybuffers
-exports.arrayBufferToBinaryString = function (buffer) {
-  var binary = "";
-  var bytes = new Uint8Array(buffer);
-  var length = bytes.byteLength;
-  for (var i = 0; i < length; i++) {
-    binary += String.fromCharCode(bytes[i]);
-  }
-  return binary;
-};
-
-exports.cancellableFun = function (fun, self, opts) {
-
-  opts = opts ? exports.clone(true, {}, opts) : {};
-
-  var emitter = new EventEmitter();
-  var oldComplete = opts.complete || function () { };
-  var complete = opts.complete = exports.once(function (err, resp) {
-    if (err) {
-      oldComplete(err);
-    } else {
-      emitter.emit('end', resp);
-      oldComplete(null, resp);
-    }
-    emitter.removeAllListeners();
-  });
-  var oldOnChange = opts.onChange || function () {};
-  var lastChange = 0;
-  self.on('destroyed', function () {
-    emitter.removeAllListeners();
-  });
-  opts.onChange = function (change) {
-    oldOnChange(change);
-    if (change.seq <= lastChange) {
-      return;
-    }
-    lastChange = change.seq;
-    emitter.emit('change', change);
-    if (change.deleted) {
-      emitter.emit('delete', change);
-    } else if (change.changes.length === 1 &&
-      change.changes[0].rev.slice(0, 1) === '1-') {
-      emitter.emit('create', change);
-    } else {
-      emitter.emit('update', change);
-    }
-  };
-  var promise = new Promise(function (fulfill, reject) {
-    opts.complete = function (err, res) {
-      if (err) {
-        reject(err);
-      } else {
-        fulfill(res);
-      }
-    };
-  });
-
-  promise.then(function (result) {
-    complete(null, result);
-  }, complete);
-
-  // this needs to be overwridden by caller, dont fire complete until
-  // the task is ready
-  promise.cancel = function () {
-    promise.isCancelled = true;
-    if (self.taskqueue.isReady) {
-      opts.complete(null, {status: 'cancelled'});
-    }
-  };
-
-  if (!self.taskqueue.isReady) {
-    self.taskqueue.addTask(function () {
-      if (promise.isCancelled) {
-        opts.complete(null, {status: 'cancelled'});
-      } else {
-        fun(self, opts, promise);
-      }
-    });
-  } else {
-    fun(self, opts, promise);
-  }
-  promise.on = emitter.on.bind(emitter);
-  promise.once = emitter.once.bind(emitter);
-  promise.addListener = emitter.addListener.bind(emitter);
-  promise.removeListener = emitter.removeListener.bind(emitter);
-  promise.removeAllListeners = emitter.removeAllListeners.bind(emitter);
-  promise.setMaxListeners = emitter.setMaxListeners.bind(emitter);
-  promise.listeners = emitter.listeners.bind(emitter);
-  promise.emit = emitter.emit.bind(emitter);
-  return promise;
-};
-exports.Crypto = {};
-exports.MD5 = exports.Crypto.MD5 = function (string) {
-  if (!process.browser) {
-    return crypto.createHash('md5').update(string).digest('hex');
-  } else {
-    return md5(string);
-  }
-};
-
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./deps/ajax":8,"./deps/blob":9,"./deps/buffer":23,"./deps/errors":10,"./deps/uuid":12,"./merge":16,"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":25,"argsarray":22,"bluebird":31,"crypto":23,"events":24,"extend":26,"inherits":27,"md5-jkmyers":45}],22:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = argsArray;
-
-function argsArray(fun) {
-  return function () {
-    var len = arguments.length;
-    if (len) {
-      var args = [];
-      var i = -1;
-      while (++i < len) {
-        args[i] = arguments[i];
-      }
-      return fun.call(this, args);
-    } else {
-      return fun.call(this, []);
-    }
-  };
-}
-},{}],23:[function(_dereq_,module,exports){
-
-},{}],24:[function(_dereq_,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
-  this._events = this._events || {};
-  this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
-  if (!isNumber(n) || n < 0 || isNaN(n))
-    throw TypeError('n must be a positive number');
-  this._maxListeners = n;
-  return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
-  var er, handler, len, args, i, listeners;
-
-  if (!this._events)
-    this._events = {};
-
-  // If there is no 'error' event listener then throw.
-  if (type === 'error') {
-    if (!this._events.error ||
-        (isObject(this._events.error) && !this._events.error.length)) {
-      er = arguments[1];
-      if (er instanceof Error) {
-        throw er; // Unhandled 'error' event
-      } else {
-        throw TypeError('Uncaught, unspecified "error" event.');
-      }
-      return false;
-    }
-  }
-
-  handler = this._events[type];
-
-  if (isUndefined(handler))
-    return false;
-
-  if (isFunction(handler)) {
-    switch (arguments.length) {
-      // fast cases
-      case 1:
-        handler.call(this);
-        break;
-      case 2:
-        handler.call(this, arguments[1]);
-        break;
-      case 3:
-        handler.call(this, arguments[1], arguments[2]);
-        break;
-      // slower
-      default:
-        len = arguments.length;
-        args = new Array(len - 1);
-        for (i = 1; i < len; i++)
-          args[i - 1] = arguments[i];
-        handler.apply(this, args);
-    }
-  } else if (isObject(handler)) {
-    len = arguments.length;
-    args = new Array(len - 1);
-    for (i = 1; i < len; i++)
-      args[i - 1] = arguments[i];
-
-    listeners = handler.slice();
-    len = listeners.length;
-    for (i = 0; i < len; i++)
-      listeners[i].apply(this, args);
-  }
-
-  return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
-  var m;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events)
-    this._events = {};
-
-  // To avoid recursion in the case that type === "newListener"! Before
-  // adding it to the listeners, first emit "newListener".
-  if (this._events.newListener)
-    this.emit('newListener', type,
-              isFunction(listener.listener) ?
-              listener.listener : listener);
-
-  if (!this._events[type])
-    // Optimize the case of one listener. Don't need the extra array object.
-    this._events[type] = listener;
-  else if (isObject(this._events[type]))
-    // If we've already got an array, just append.
-    this._events[type].push(listener);
-  else
-    // Adding the second element, need to change to array.
-    this._events[type] = [this._events[type], listener];
-
-  // Check for listener leak
-  if (isObject(this._events[type]) && !this._events[type].warned) {
-    var m;
-    if (!isUndefined(this._maxListeners)) {
-      m = this._maxListeners;
-    } else {
-      m = EventEmitter.defaultMaxListeners;
-    }
-
-    if (m && m > 0 && this._events[type].length > m) {
-      this._events[type].warned = true;
-      console.error('(node) warning: possible EventEmitter memory ' +
-                    'leak detected. %d listeners added. ' +
-                    'Use emitter.setMaxListeners() to increase limit.',
-                    this._events[type].length);
-      console.trace();
-    }
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  var fired = false;
-
-  function g() {
-    this.removeListener(type, g);
-
-    if (!fired) {
-      fired = true;
-      listener.apply(this, arguments);
-    }
-  }
-
-  g.listener = listener;
-  this.on(type, g);
-
-  return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
-  var list, position, length, i;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events || !this._events[type])
-    return this;
-
-  list = this._events[type];
-  length = list.length;
-  position = -1;
-
-  if (list === listener ||
-      (isFunction(list.listener) && list.listener === listener)) {
-    delete this._events[type];
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-
-  } else if (isObject(list)) {
-    for (i = length; i-- > 0;) {
-      if (list[i] === listener ||
-          (list[i].listener && list[i].listener === listener)) {
-        position = i;
-        break;
-      }
-    }
-
-    if (position < 0)
-      return this;
-
-    if (list.length === 1) {
-      list.length = 0;
-      delete this._events[type];
-    } else {
-      list.splice(position, 1);
-    }
-
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
-  var key, listeners;
-
-  if (!this._events)
-    return this;
-
-  // not listening for removeListener, no need to emit
-  if (!this._events.removeListener) {
-    if (arguments.length === 0)
-      this._events = {};
-    else if (this._events[type])
-      delete this._events[type];
-    return this;
-  }
-
-  // emit removeListener for all listeners on all events
-  if (arguments.length === 0) {
-    for (key in this._events) {
-      if (key === 'removeListener') continue;
-      this.removeAllListeners(key);
-    }
-    this.removeAllListeners('removeListener');
-    this._events = {};
-    return this;
-  }
-
-  listeners = this._events[type];
-
-  if (isFunction(listeners)) {
-    this.removeListener(type, listeners);
-  } else {
-    // LIFO order
-    while (listeners.length)
-      this.removeListener(type, listeners[listeners.length - 1]);
-  }
-  delete this._events[type];
-
-  return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
-  var ret;
-  if (!this._events || !this._events[type])
-    ret = [];
-  else if (isFunction(this._events[type]))
-    ret = [this._events[type]];
-  else
-    ret = this._events[type].slice();
-  return ret;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
-  var ret;
-  if (!emitter._events || !emitter._events[type])
-    ret = 0;
-  else if (isFunction(emitter._events[type]))
-    ret = 1;
-  else
-    ret = emitter._events[type].length;
-  return ret;
-};
-
-function isFunction(arg) {
-  return typeof arg === 'function';
-}
-
-function isNumber(arg) {
-  return typeof arg === 'number';
-}
-
-function isObject(arg) {
-  return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
-  return arg === void 0;
-}
-
-},{}],25:[function(_dereq_,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
-    var canSetImmediate = typeof window !== 'undefined'
-    && window.setImmediate;
-    var canPost = typeof window !== 'undefined'
-    && window.postMessage && window.addEventListener
-    ;
-
-    if (canSetImmediate) {
-        return function (f) { return window.setImmediate(f) };
-    }
-
-    if (canPost) {
-        var queue = [];
-        window.addEventListener('message', function (ev) {
-            var source = ev.source;
-            if ((source === window || source === null) && ev.data === 'process-tick') {
-                ev.stopPropagation();
-                if (queue.length > 0) {
-                    var fn = queue.shift();
-                    fn();
-                }
-            }
-        }, true);
-
-        return function nextTick(fn) {
-            queue.push(fn);
-            window.postMessage('process-tick', '*');
-        };
-    }
-
-    return function nextTick(fn) {
-        setTimeout(fn, 0);
-    };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-}
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-
-},{}],26:[function(_dereq_,module,exports){
-var hasOwn = Object.prototype.hasOwnProperty;
-var toString = Object.prototype.toString;
-
-function isPlainObject(obj) {
-	if (!obj || toString.call(obj) !== '[object Object]' || obj.nodeType || obj.setInterval)
-		return false;
-
-	var has_own_constructor = hasOwn.call(obj, 'constructor');
-	var has_is_property_of_method = hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
-	// Not own constructor property must be Object
-	if (obj.constructor && !has_own_constructor && !has_is_property_of_method)
-		return false;
-
-	// Own properties are enumerated firstly, so to speed up,
-	// if last one is own, then all properties are own.
-	var key;
-	for ( key in obj ) {}
-
-	return key === undefined || hasOwn.call( obj, key );
-};
-
-module.exports = function extend() {
-	var options, name, src, copy, copyIsArray, clone,
-	    target = arguments[0] || {},
-	    i = 1,
-	    length = arguments.length,
-	    deep = false;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-		target = arguments[1] || {};
-		// skip the boolean and the target
-		i = 2;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && typeof target !== "function") {
-		target = {};
-	}
-
-	for ( ; i < length; i++ ) {
-		// Only deal with non-null/undefined values
-		if ( (options = arguments[ i ]) != null ) {
-			// Extend the base object
-			for ( name in options ) {
-				src = target[ name ];
-				copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy ) {
-					continue;
-				}
-
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( isPlainObject(copy) || (copyIsArray = Array.isArray(copy)) ) ) {
-					if ( copyIsArray ) {
-						copyIsArray = false;
-						clone = src && Array.isArray(src) ? src : [];
-
-					} else {
-						clone = src && isPlainObject(src) ? src : {};
-					}
-
-					// Never move original objects, clone them
-					target[ name ] = extend( deep, clone, copy );
-
-				// Don't bring in undefined values
-				} else if ( copy !== undefined ) {
-					target[ name ] = copy;
-				}
-			}
-		}
-	}
-
-	// Return the modified object
-	return target;
-};
-
-},{}],27:[function(_dereq_,module,exports){
-if (typeof Object.create === 'function') {
-  // implementation from standard node.js 'util' module
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    ctor.prototype = Object.create(superCtor.prototype, {
-      constructor: {
-        value: ctor,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-  };
-} else {
-  // old school shim for old browsers
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    var TempCtor = function () {}
-    TempCtor.prototype = superCtor.prototype
-    ctor.prototype = new TempCtor()
-    ctor.prototype.constructor = ctor
-  }
-}
-
-},{}],28:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = INTERNAL;
-
-function INTERNAL() {}
-},{}],29:[function(_dereq_,module,exports){
-'use strict';
-var INTERNAL = _dereq_('./INTERNAL');
-var Promise = _dereq_('./promise');
-var reject = _dereq_('./reject');
-var resolve = _dereq_('./resolve');
-
-module.exports = function all(iterable) {
-  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
-    return reject(new TypeError('must be an array'));
-  }
-  var len = iterable.length;
-  if (!len) {
-    return resolve([]);
-  }
-  var values = [];
-  var resolved = 0;
-  var i = -1;
-  var promise = new Promise(INTERNAL);
-  function allResolver(value, i) {
-    resolve(value).then(function (outValue) {
-      values[i] = outValue;
-      if (++resolved === len) {
-        promise.resolve(values);
-      }
-    }, function (error) {
-      promise.reject(error);
-    });
-  }
-  
-  while (++i < len) {
-    allResolver(iterable[i], i);
-  }
-  return promise;
-};
-},{"./INTERNAL":28,"./promise":33,"./reject":34,"./resolve":35}],30:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = getThen;
-
-function getThen(obj) {
-  // Make sure we only access the accessor once as required by the spec
-  var then = obj && obj.then;
-  if (obj && typeof obj === 'object' && typeof then === 'function') {
-    return function appyThen() {
-      then.apply(obj, arguments);
-    };
-  }
-}
-},{}],31:[function(_dereq_,module,exports){
-module.exports = exports = _dereq_('./promise');
-
-exports.resolve = _dereq_('./resolve');
-exports.reject = _dereq_('./reject');
-exports.all = _dereq_('./all');
-},{"./all":29,"./promise":33,"./reject":34,"./resolve":35}],32:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = once;
-
-/* Wrap an arbitrary number of functions and allow only one of them to be
-   executed and only once */
-function once() {
-  var called = 0;
-  return function wrapper(wrappedFunction) {
-    return function () {
-      if (called++) {
-        return;
-      }
-      wrappedFunction.apply(this, arguments);
-    };
-  };
-}
-},{}],33:[function(_dereq_,module,exports){
-'use strict';
-
-var unwrap = _dereq_('./unwrap');
-var INTERNAL = _dereq_('./INTERNAL');
-var once = _dereq_('./once');
-var tryCatch = _dereq_('./tryCatch');
-var getThen = _dereq_('./getThen');
-
-// Lazy man's symbols for states
-var PENDING = ['PENDING'],
-  FULFILLED = ['FULFILLED'],
-  REJECTED = ['REJECTED'];
-module.exports = Promise;
-function Promise(resolver) {
-  if (!(this instanceof Promise)) {
-    return new Promise(resolver);
-  }
-  if (typeof resolver !== 'function') {
-    throw new TypeError('reslover must be a function');
-  }
-  this.state = PENDING;
-  this.queue = [];
-  if (resolver !== INTERNAL) {
-    safelyResolveThenable(this, resolver);
-  }
-}
-Promise.prototype.resolve = function (value) {
-  var result = tryCatch(getThen, value);
-  if (result.status === 'error') {
-    return this.reject(result.value);
-  }
-  var thenable = result.value;
-
-  if (thenable) {
-    safelyResolveThenable(this, thenable);
-  } else {
-    this.state = FULFILLED;
-    this.outcome = value;
-    var i = -1;
-    var len = this.queue.length;
-    while (++i < len) {
-      this.queue[i].callFulfilled(value);
-    }
-  }
-  return this;
-};
-Promise.prototype.reject = function (error) {
-  this.state = REJECTED;
-  this.outcome = error;
-  var i = -1;
-  var len = this.queue.length;
-  while (++i < len) {
-    this.queue[i].callRejected(error);
-  }
-  return this;
-};
-
-Promise.prototype['catch'] = function (onRejected) {
-  return this.then(null, onRejected);
-};
-Promise.prototype.then = function (onFulfilled, onRejected) {
-  var onFulfilledFunc = typeof onFulfilled === 'function';
-  var onRejectedFunc = typeof onRejected === 'function';
-  if (!onFulfilledFunc && this.state === FULFILLED || !onRejected && this.state === REJECTED) {
-    return this;
-  }
-  var promise = new Promise(INTERNAL);
-
-  var thenHandler =  {
-    promise: promise,
-  };
-  if (this.state !== REJECTED) {
-    if (onFulfilledFunc) {
-      thenHandler.callFulfilled = function (value) {
-        unwrap(promise, onFulfilled, value);
-      };
-    } else {
-      thenHandler.callFulfilled = function (value) {
-        promise.resolve(value);
-      };
-    }
-  }
-  if (this.state !== FULFILLED) {
-    if (onRejectedFunc) {
-      thenHandler.callRejected = function (value) {
-        unwrap(promise, onRejected, value);
-      };
-    } else {
-      thenHandler.callRejected = function (value) {
-        promise.reject(value);
-      };
-    }
-  }
-  if (this.state === FULFILLED) {
-    thenHandler.callFulfilled(this.outcome);
-  } else if (this.state === REJECTED) {
-    thenHandler.callRejected(this.outcome);
-  } else {
-    this.queue.push(thenHandler);
-  }
-
-  return promise;
-};
-function safelyResolveThenable(self, thenable) {
-  // Either fulfill, reject or reject with error
-  var onceWrapper = once();
-  var onError = onceWrapper(function (value) {
-    return self.reject(value);
-  });
-  var result = tryCatch(function () {
-    thenable(
-      onceWrapper(function (value) {
-        return self.resolve(value);
-      }),
-      onError
-    );
-  });
-  if (result.status === 'error') {
-    onError(result.value);
-  }
-}
-},{"./INTERNAL":28,"./getThen":30,"./once":32,"./tryCatch":36,"./unwrap":37}],34:[function(_dereq_,module,exports){
-'use strict';
-
-var Promise = _dereq_('./promise');
-var INTERNAL = _dereq_('./INTERNAL');
-
-module.exports = reject;
-
-function reject(reason) {
-	var promise = new Promise(INTERNAL);
-	return promise.reject(reason);
-}
-},{"./INTERNAL":28,"./promise":33}],35:[function(_dereq_,module,exports){
-'use strict';
-
-var Promise = _dereq_('./promise');
-var INTERNAL = _dereq_('./INTERNAL');
-
-module.exports = resolve;
-
-var FALSE = new Promise(INTERNAL).resolve(false);
-var NULL = new Promise(INTERNAL).resolve(null);
-var UNDEFINED = new Promise(INTERNAL).resolve(void 0);
-var ZERO = new Promise(INTERNAL).resolve(0);
-var EMPTYSTRING = new Promise(INTERNAL).resolve('');
-
-function resolve(value) {
-  if (value) {
-    return new Promise(INTERNAL).resolve(value);
-  }
-  var valueType = typeof value;
-  switch (valueType) {
-    case 'boolean':
-      return FALSE;
-    case 'undefined':
-      return UNDEFINED;
-    case 'object':
-      return NULL;
-    case 'number':
-      return ZERO;
-    case 'string':
-      return EMPTYSTRING;
-  }
-}
-},{"./INTERNAL":28,"./promise":33}],36:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = tryCatch;
-
-function tryCatch(func, value) {
-  var out = {};
-  try {
-    out.value = func(value);
-    out.status = 'success';
-  } catch (e) {
-    out.status = 'error';
-    out.value = e;
-  }
-  return out;
-}
-},{}],37:[function(_dereq_,module,exports){
-'use strict';
-
-var immediate = _dereq_('immediate');
-
-module.exports = unwrap;
-
-function unwrap(promise, func, value) {
-  immediate(function () {
-    var returnValue;
-    try {
-      returnValue = func(value);
-    } catch (e) {
-      return promise.reject(e);
-    }
-    if (returnValue === promise) {
-      promise.reject(new TypeError('Cannot resolve promise with itself'));
-    } else {
-      promise.resolve(returnValue);
-    }
-  });
-}
-},{"immediate":39}],38:[function(_dereq_,module,exports){
-'use strict';
-exports.test = function () {
-  return false;
-};
-},{}],39:[function(_dereq_,module,exports){
-'use strict';
-var types = [
-  _dereq_('./nextTick'),
-  _dereq_('./mutation'),
-  _dereq_('./postMessage'),
-  _dereq_('./messageChannel'),
-  _dereq_('./stateChange'),
-  _dereq_('./timeout')
-];
-var handlerQueue = [];
-function drainQueue() {
-  var i = 0,
-  task,
-  innerQueue = handlerQueue;
-  handlerQueue = [];
-  while ((task = innerQueue[i++])) {
-    task();
-  }
-}
-var nextTick;
-var i = -1;
-var len = types.length;
-while (++ i < len) {
-  if (types[i].test()) {
-    nextTick = types[i].install(drainQueue);
-    break;
-  }
-}
-module.exports = function (task) {
-  var len, i, args;
-  var nTask = task;
-  if (arguments.length > 1 && typeof task === 'function') {
-    args = new Array(arguments.length - 1);
-    i = 0;
-    while (++i < arguments.length) {
-      args[i - 1] = arguments[i];
-    }
-    nTask = function () {
-      task.apply(undefined, args);
-    };
-  }
-  if ((len = handlerQueue.push(nTask)) === 1) {
-    nextTick(drainQueue);
-  }
-  return len;
-};
-module.exports.clear = function (n) {
-  if (n <= handlerQueue.length) {
-    handlerQueue[n - 1] = function () {};
-  }
-  return this;
-};
-
-},{"./messageChannel":40,"./mutation":41,"./nextTick":38,"./postMessage":42,"./stateChange":43,"./timeout":44}],40:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-exports.test = function () {
-  return typeof global.MessageChannel !== 'undefined';
-};
-
-exports.install = function (func) {
-  var channel = new global.MessageChannel();
-  channel.port1.onmessage = func;
-  return function () {
-    channel.port2.postMessage(0);
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],41:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-//based off rsvp https://github.com/tildeio/rsvp.js
-//license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
-//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js
-
-var Mutation = global.MutationObserver || global.WebKitMutationObserver;
-
-exports.test = function () {
-  return Mutation;
-};
-
-exports.install = function (handle) {
-  var called = 0;
-  var observer = new Mutation(handle);
-  var element = global.document.createTextNode('');
-  observer.observe(element, {
-    characterData: true
-  });
-  return function () {
-    element.data = (called = ++called % 2);
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],42:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-// The test against `importScripts` prevents this implementation from being installed inside a web worker,
-// where `global.postMessage` means something completely different and can't be used for this purpose.
-
-exports.test = function () {
-  if (!global.postMessage || global.importScripts) {
-    return false;
-  }
-
-  var postMessageIsAsynchronous = true;
-  var oldOnMessage = global.onmessage;
-  global.onmessage = function () {
-    postMessageIsAsynchronous = false;
-  };
-  global.postMessage('', '*');
-  global.onmessage = oldOnMessage;
-
-  return postMessageIsAsynchronous;
-};
-
-exports.install = function (func) {
-  var codeWord = 'com.calvinmetcalf.setImmediate' + Math.random();
-  function globalMessage(event) {
-    if (event.source === global && event.data === codeWord) {
-      func();
-    }
-  }
-  if (global.addEventListener) {
-    global.addEventListener('message', globalMessage, false);
-  } else {
-    global.attachEvent('onmessage', globalMessage);
-  }
-  return function () {
-    global.postMessage(codeWord, '*');
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],43:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-exports.test = function () {
-  return 'document' in global && 'onreadystatechange' in global.document.createElement('script');
-};
-
-exports.install = function (handle) {
-  return function () {
-
-    // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-    // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-    var scriptEl = global.document.createElement('script');
-    scriptEl.onreadystatechange = function () {
-      handle();
-
-      scriptEl.onreadystatechange = null;
-      scriptEl.parentNode.removeChild(scriptEl);
-      scriptEl = null;
-    };
-    global.document.documentElement.appendChild(scriptEl);
-
-    return handle;
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],44:[function(_dereq_,module,exports){
-'use strict';
-exports.test = function () {
-  return true;
-};
-
-exports.install = function (t) {
-  return function () {
-    setTimeout(t, 0);
-  };
-};
-},{}],45:[function(_dereq_,module,exports){
-!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.md5=b()}(this,function(){function a(a,b){var g=a[0],h=a[1],i=a[2],j=a[3];g=c(g,h,i,j,b[0],7,-680876936),j=c(j,g,h,i,b[1],12,-389564586),i=c(i,j,g,h,b[2],17,606105819),h=c(h,i,j,g,b[3],22,-1044525330),g=c(g,h,i,j,b[4],7,-176418897),j=c(j,g,h,i,b[5],12,1200080426),i=c(i,j,g,h,b[6],17,-1473231341),h=c(h,i,j,g,b[7],22,-45705983),g=c(g,h,i,j,b[8],7,1770035416),j=c(j,g,h,i,b[9],12,-1958414417),i=c(i,j,g,h,b[10],17,-42063),h=c(h,i,j,g,b[11],22,-1990404162),g=c(g,h,i,j,b[12],7,1804603682),j=c(j,g,h,i,b[13],12,-40341101),i=c(i,j,g,h,b[14],17,-1502002290),h=c(h,i,j,g,b[15],22,1236535329),g=d(g,h,i,j,b[1],5,-165796510),j=d(j,g,h,i,b[6],9,-1069501632),i=d(i,j,g,h,b[11],14,643717713),h=d(h,i,j,g,b[0],20,-373897302),g=d(g,h,i,j,b[5],5,-701558691),j=d(j,g,h,i,b[10],9,38016083),i=d(i,j,g,h,b[15],14,-660478335),h=d(h,i,j,g,b[4],20,-405537848),g=d(g,h,i,j,b[9],5,568446438),j=d(j,g,h,i,b[14],9,-1019803690),i=d(i,j,g,h,b[3],14,-187363961),h=d(h,i,j,g,b[8],20,1163531501),g=d(g,h,i,j,b[13],5,-1444681467),j=d(j,g,h,i,b[2],9,-51403784),i=d(i,j,g,h,b[7],14,1735328473),h=d(h,i,j,g,b[12],20,-1926607734),g=e(g,h,i,j,b[5],4,-378558),j=e(j,g,h,i,b[8],11,-2022574463),i=e(i,j,g,h,b[11],16,1839030562),h=e(h,i,j,g,b[14],23,-35309556),g=e(g,h,i,j,b[1],4,-1530992060),j=e(j,g,h,i,b[4],11,1272893353),i=e(i,j,g,h,b[7],16,-155497632),h=e(h,i,j,g,b[10],23,-1094730640),g=e(g,h,i,j,b[13],4,681279174),j=e(j,g,h,i,b[0],11,-358537222),i=e(i,j,g,h,b[3],16,-722521979),h=e(h,i,j,g,b[6],23,76029189),g=e(g,h,i,j,b[9],4,-640364487),j=e(j,g,h,i,b[12],11,-421815835),i=e(i,j,g,h,b[15],16,530742520),h=e(h,i,j,g,b[2],23,-995338651),g=f(g,h,i,j,b[0],6,-198630844),j=f(j,g,h,i,b[7],10,1126891415),i=f(i,j,g,h,b[14],15,-1416354905),h=f(h,i,j,g,b[5],21,-57434055),g=f(g,h,i,j,b[12],6,1700485571),j=f(j,g,h,i,b[3],10,-1894986606),i=f(i,j,g,h,b[10],15,-1051523),h=f(h,i,j,g,b[1],21,-2054922799),g=f(g,h,i,j,b[8],6,1873313359),j=f(j,g,h,i,b[15],10,-30611744),i=f(i,j,g,h,b[6],15,-1560198380),h=f(h,i,j,g,b[13],21,1309151649),g=f(g,h,i,j,b[4],6,-145523070),j=f(j,g,h,i,b[11],10,-1120210379),i=f(i,j,g,h,b[2],15,718787259),h=f(h,i,j,g,b[9],21,-343485551),a[0]=l(g,a[0]),a[1]=l(h,a[1]),a[2]=l(i,a[2]),a[3]=l(j,a[3])}function b(a,b,c,d,e,f){return b=l(l(b,a),l(d,f)),l(b<<e|b>>>32-e,c)}function c(a,c,d,e,f,g,h){return b(c&d|~c&e,a,c,f,g,h)}function d(a,c,d,e,f,g,h){return b(c&e|d&~e,a,c,f,g,h)}function e(a,c,d,e,f,g,h){return b(c^d^e,a,c,f,g,h)}function f(a,c,d,e,f,g,h){return b(d^(c|~e),a,c,f,g,h)}function g(b){txt="";var c,d=b.length,e=[1732584193,-271733879,-1732584194,271733878];for(c=64;c<=b.length;c+=64)a(e,h(b.substring(c-64,c)));b=b.substring(c-64);var f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(c=0;c<b.length;c++)f[c>>2]|=b.charCodeAt(c)<<(c%4<<3);if(f[c>>2]|=128<<(c%4<<3),c>55)for(a(e,f),c=0;16>c;c++)f[c]=0;return f[14]=8*d,a(e,f),e}function h(a){var b,c=[];for(b=0;64>b;b+=4)c[b>>2]=a.charCodeAt(b)+(a.charCodeAt(b+1)<<8)+(a.charCodeAt(b+2)<<16)+(a.charCodeAt(b+3)<<24);return c}function i(a){for(var b="",c=0;4>c;c++)b+=m[a>>8*c+4&15]+m[a>>8*c&15];return b}function j(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return a.join("")}function k(a){return j(g(a))}function l(a,b){return a+b&4294967295}function l(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}var m="0123456789abcdef".split("");return"5d41402abc4b2a76b9719d911017c592"!=k("hello"),k});
-},{}],46:[function(_dereq_,module,exports){
-'use strict';
-
-var upsert = _dereq_('./upsert');
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-
-module.exports = function (opts) {
-  var sourceDB = opts.db;
-  var viewName = opts.viewName;
-  var mapFun = opts.map;
-  var reduceFun = opts.reduce;
-  var randomizer = opts.randomizer;
-
-  var viewSignature = mapFun.toString() + (reduceFun && reduceFun.toString()) +
-    (randomizer && randomizer.toString());
-
-  if (sourceDB._cachedViews) {
-    var cachedView = sourceDB._cachedViews[viewSignature];
-    if (cachedView) {
-      return Promise.resolve(cachedView);
-    }
-  }
-
-  return sourceDB.info().then(function (info) {
-    var depDbName = info.db_name + '-mrview-' + utils.MD5(viewSignature);
-
-    // save the view name in the source PouchDBVersion220 so it can be cleaned up if necessary
-    // (e.g. when the _design doc is deleted, remove all associated view data)
-    function diffFunction(doc) {
-      doc.views = doc.views || {};
-      var depDbs = doc.views[viewName] = doc.views[viewName] || {};
-      /* istanbul ignore if */
-      if (depDbs[depDbName]) {
-        return; // no update necessary
-      }
-      depDbs[depDbName] = true;
-      return doc;
-    }
-    return upsert(sourceDB, '_local/mrviews', diffFunction).then(function () {
-      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
-        var db = res.db;
-        db.auto_compaction = true;
-        var view = {
-          name: depDbName,
-          db: db, 
-          sourceDB: sourceDB,
-          adapter: sourceDB.adapter,
-          mapFun: mapFun,
-          reduceFun: reduceFun
-        };
-        return view.db.get('_local/lastSeq').then(null, function (err) {
-          /* istanbul ignore if */
-          if (err.name !== 'not_found') {
-            throw err;
-          }
-        }).then(function (lastSeqDoc) {
-          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
-          if (!randomizer) {
-            // randomizer implies the view is temporary, no need to cache it
-            sourceDB._cachedViews = sourceDB._cachedViews || {};
-            sourceDB._cachedViews[viewSignature] = view;
-            view.db.on('destroyed', function () {
-              delete sourceDB._cachedViews[viewSignature];
-            });
-          }
-          return view;
-        });
-      });
-    });
-  });
-};
-
-},{"./upsert":52,"./utils":53}],47:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = function (func, emit, sum, log, isArray, toJSON) {
-  /*jshint evil:true,unused:false */
-  return eval("'use strict'; (" + func + ");");
-};
-
-},{}],48:[function(_dereq_,module,exports){
-'use strict';
-
-var pouchCollate = _dereq_('pouchdb-collate');
-var TaskQueue = _dereq_('./taskqueue');
-var collate = pouchCollate.collate;
-var toIndexableString = pouchCollate.toIndexableString;
-var normalizeKey = pouchCollate.normalizeKey;
-var createView = _dereq_('./create-view');
-var evalFunc = _dereq_('./evalfunc');
-var log; 
-/* istanbul ignore else */
-if ((typeof console !== 'undefined') && (typeof console.log === 'function')) {
-  log = Function.prototype.bind.call(console.log, console);
-} else {
-  log = function () {};
-}
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-var mainQueue = new TaskQueue();
-var CHANGES_BATCH_SIZE = 50;
-
-function parseViewName(name) {
-  // can be either 'ddocname/viewname' or just 'viewname'
-  // (where the ddoc name is the same)
-  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
-}
-
-function tryCode(db, fun, args) {
-  // emit an event if there was an error thrown by a map/reduce function.
-  // putting try/catches in a single function also avoids deoptimizations.
-  try {
-    return {
-      output : fun.apply(null, args)
-    };
-  } catch (e) {
-    db.emit('error', e);
-    return {error : e};
-  }
-}
-
-function sortByKeyThenValue(x, y) {
-  var keyCompare = collate(x.key, y.key);
-  return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
-}
-
-function sliceResults(results, limit, skip) {
-  skip = skip || 0;
-  if (typeof limit === 'number') {
-    return results.slice(skip, limit + skip);
-  } else if (skip > 0) {
-    return results.slice(skip);
-  }
-  return results;
-}
-
-function createBuiltInError(name) {
-  var error = new Error('builtin ' + name +
-    ' function requires map values to be numbers' +
-    ' or number arrays');
-  error.name = 'invalid_value';
-  error.status = 500;
-  return error;
-}
-
-function sum(values) {
-  var result = 0;
-  for (var i = 0, len = values.length; i < len; i++) {
-    var num = values[i];
-    if (typeof num !== 'number') {
-      if (Array.isArray(num)) {
-        // lists of numbers are also allowed, sum them separately
-        result = typeof result === 'number' ? [result] : result;
-        for (var j = 0, jLen = num.length; j < jLen; j++) {
-          var jNum = num[j];
-          if (typeof jNum !== 'number') {
-            throw createBuiltInError('_sum');
-          } else if (typeof result[j] === 'undefined') {
-            result.push(jNum);
-          } else {
-            result[j] += jNum;
-          }
-        }
-      } else { // not array/number
-        throw createBuiltInError('_sum');
-      }
-    } else if (typeof result === 'number') {
-      result += num;
-    } else { // add number to array
-      result[0] += num;
-    }
-  }
-  return result;
-}
-
-var builtInReduce = {
-  _sum: function (keys, values) {
-    return sum(values);
-  },
-
-  _count: function (keys, values) {
-    return values.length;
-  },
-
-  _stats: function (keys, values) {
-    // no need to implement rereduce=true, because Pouch
-    // will never call it
-    function sumsqr(values) {
-      var _sumsqr = 0;
-      for (var i = 0, len = values.length; i < len; i++) {
-        var num = values[i];
-        _sumsqr += (num * num);
-      }
-      return _sumsqr;
-    }
-    return {
-      sum     : sum(values),
-      min     : Math.min.apply(null, values),
-      max     : Math.max.apply(null, values),
-      count   : values.length,
-      sumsqr : sumsqr(values)
-    };
-  }
-};
-
-function addHttpParam(paramName, opts, params, asJson) {
-  // add an http param from opts to params, optionally json-encoded
-  var val = opts[paramName];
-  if (typeof val !== 'undefined') {
-    if (asJson) {
-      val = encodeURIComponent(JSON.stringify(val));
-    }
-    params.push(paramName + '=' + val);
-  }
-}
-
-function checkQueryParseError(options, fun) {
-  var startkeyName = options.descending ? 'endkey' : 'startkey';
-  var endkeyName = options.descending ? 'startkey' : 'endkey';
-
-  if (typeof options[startkeyName] !== 'undefined' &&
-    typeof options[endkeyName] !== 'undefined' &&
-    collate(options[startkeyName], options[endkeyName]) > 0) {
-    throw new QueryParseError('No rows can match your key range, reverse your ' +
-        'start_key and end_key or set {descending : true}');
-  } else if (fun.reduce && options.reduce !== false) {
-    if (options.include_docs) {
-      throw new QueryParseError('{include_docs:true} is invalid for reduce');
-    } else if (options.keys && options.keys.length > 1 &&
-        !options.group && !options.group_level) {
-      throw new QueryParseError('Multi-key fetches for reduce views must use {group: true}');
-    }
-  }
-  if (options.group_level) {
-    if (typeof options.group_level !== 'number') {
-      throw new QueryParseError('Invalid value for integer: "' + options.group_level + '"');
-    }
-    if (options.group_level < 0) {
-      throw new QueryParseError('Invalid value for positive integer: ' +
-        '"' + options.group_level + '"');
-    }
-  }
-}
-
-function httpQuery(db, fun, opts) {
-  // List of parameters to add to the PUT request
-  var params = [];
-  var body;
-  var method = 'GET';
-
-  // If opts.reduce exists and is defined, then add it to the list
-  // of parameters.
-  // If reduce=false then the results are that of only the map function
-  // not the final result of map and reduce.
-  addHttpParam('reduce', opts, params);
-  addHttpParam('include_docs', opts, params);
-  addHttpParam('limit', opts, params);
-  addHttpParam('descending', opts, params);
-  addHttpParam('group', opts, params);
-  addHttpParam('group_level', opts, params);
-  addHttpParam('skip', opts, params);
-  addHttpParam('startkey', opts, params, true);
-  addHttpParam('endkey', opts, params, true);
-  addHttpParam('inclusive_end', opts, params);
-  addHttpParam('key', opts, params, true);
-
-  // Format the list of parameters into a valid URI query string
-  params = params.join('&');
-  params = params === '' ? '' : '?' + params;
-
-  // If keys are supplied, issue a POST request to circumvent GET query string limits
-  // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-  if (typeof opts.keys !== 'undefined') {
-    var MAX_URL_LENGTH = 2000;
-    // according to http://stackoverflow.com/a/417184/680742,
-    // the de facto URL length limit is 2000 characters
-
-    var keysAsString =
-      'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-    if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-      // If the keys are short enough, do a GET. we do this to work around
-      // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
-      params += (params[0] === '?' ? '&' : '?') + keysAsString;
-    } else {
-      method = 'POST';
-      if (typeof fun === 'string') {
-        body = JSON.stringify({keys: opts.keys});
-      } else { // fun is {map : mapfun}, so append to this
-        fun.keys = opts.keys;
-      }
-    }
-  }
-
-  // We are referencing a query defined in the design doc
-  if (typeof fun === 'string') {
-    var parts = parseViewName(fun);
-    return db.request({
-      method: method,
-      url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
-      body: body
-    });
-  }
-
-  // We are using a temporary view, terrible for performance but good for testing
-  body = body || {};
-  Object.keys(fun).forEach(function (key) {
-    if (Array.isArray(fun[key])) {
-      body[key] = fun[key];
-    } else {
-      body[key] = fun[key].toString();
-    }
-  });
-  return db.request({
-    method: 'POST',
-    url: '_temp_view' + params,
-    body: body
-  });
-}
-
-function defaultsTo(value) {
-  return function (reason) {
-    /* istanbul ignore else */
-    if (reason.name === 'not_found') {
-      return value;
-    } else {
-      throw reason;
-    }
-  };
-}
-function saveKeyValues(view, docIdsToEmits, seq) {
-  return view.db.get('_local/lastSeq')
-    .then(null, defaultsTo({_id: '_local/lastSeq', seq: 0}))
-    .then(function (lastSeqDoc) {
-      return Promise.all(Object.keys(docIdsToEmits).map(function (docId) {
-        return view.db.get('_local/doc_' + docId)
-          .then(null, defaultsTo({_id : '_local/doc_' + docId, keys : []}))
-          .then(function (metaDoc) {
-            return view.db.allDocs({keys : metaDoc.keys, include_docs : true}).then(function (res) {
-              var kvDocs = res.rows.map(function (row) {
-                return row.doc;
-              }).filter(function (row) {
-                return row;
-              });
-
-              var indexableKeysToKeyValues = docIdsToEmits[docId];
-              var oldKeysMap = {};
-              kvDocs.forEach(function (kvDoc) {
-                oldKeysMap[kvDoc._id] = true;
-                kvDoc._deleted = !indexableKeysToKeyValues[kvDoc._id];
-                if (!kvDoc._deleted) {
-                  kvDoc.value = indexableKeysToKeyValues[kvDoc._id];
-                }
-              });
-
-              var newKeys = Object.keys(indexableKeysToKeyValues);
-              newKeys.forEach(function (key) {
-                if (!oldKeysMap[key]) {
-                  // new doc
-                  kvDocs.push({
-                    _id : key,
-                    value : indexableKeysToKeyValues[key]
-                  });
-                }
-              });
-              metaDoc.keys = utils.uniq(newKeys.concat(metaDoc.keys));
-              kvDocs.push(metaDoc);
-
-              return kvDocs;
-            });
-          });
-      })).then(function (listOfDocsToPersist) {
-        var docsToPersist = [];
-        listOfDocsToPersist.forEach(function (docList) {
-          docsToPersist = docsToPersist.concat(docList);
-        });
-
-        lastSeqDoc.seq = seq;
-        docsToPersist.push(lastSeqDoc);
-
-        return view.db.bulkDocs({docs : docsToPersist});
-      });
-    });
-}
-
-var updateView = utils.sequentialize(mainQueue, function (view) {
-  // bind the emit function once
-  var mapResults;
-  var doc;
-
-  function emit(key, value) {
-    mapResults.push({
-      id  : doc._id,
-      key : normalizeKey(key),
-      value : normalizeKey(value)
-    });
-  }
-
-  var mapFun;
-  // for temp_views one can use emit(doc, emit), see #38
-  if (typeof view.mapFun === "function" && view.mapFun.length === 2) {
-    var origMap = view.mapFun;
-    mapFun = function (doc) {
-      return origMap(doc, emit);
-    };
-  } else {
-    mapFun = evalFunc(view.mapFun.toString(), emit, sum, log, Array.isArray, JSON.parse);
-  }
-
-  var currentSeq = view.seq || 0;
-
-  function processChange(docIdsToEmits, seq) {
-    return function () {
-      return saveKeyValues(view, docIdsToEmits, seq);
-    };
-  }
-  var queue = new TaskQueue();
-  // TODO(neojski): https://github.com/daleharvey/pouchdb/issues/1521
-
-  return new Promise(function (resolve, reject) {
-
-    function complete() {
-      queue.finish().then(function () {
-        view.seq = currentSeq;
-        resolve();
-      });
-    }
-
-    function processNextBatch() {
-      view.sourceDB.changes({
-        conflicts: true,
-        include_docs: true,
-        since : currentSeq,
-        limit : CHANGES_BATCH_SIZE
-      }).on('complete', function (response) {
-        var results = response.results;
-        if (!results.length) {
-          return complete();
-        }
-        var docIdsToEmits = {};
-        for (var i = 0, l = results.length; i < l; i++) {
-          var change = results[i];
-          if (change.doc._id[0] !== '_') {
-            mapResults = [];
-            doc = change.doc;
-
-            if (!doc._deleted) {
-              tryCode(view.sourceDB, mapFun, [doc]);
-            }
-            mapResults.sort(sortByKeyThenValue);
-
-            var indexableKeysToKeyValues = {};
-            for (var j = 0, jl = mapResults.length; j < jl; j++) {
-              var obj = mapResults[j];
-              var indexableKey = toIndexableString([obj.key, obj.id, j]);
-              indexableKeysToKeyValues[indexableKey] = obj;
-            }
-            docIdsToEmits[change.doc._id] = indexableKeysToKeyValues;
-          }
-          currentSeq = change.seq;
-        }
-        queue.add(processChange(docIdsToEmits, currentSeq));
-        if (results.length < CHANGES_BATCH_SIZE) {
-          return complete();
-        }
-        return processNextBatch();
-      }).on('error', onError);
-      /* istanbul ignore next */
-      function onError(err) {
-        reject(err);
-      }
-    }
-    processNextBatch();
-  });
-});
-
-function reduceView(view, results, options) {
-  if (options.group_level === 0) {
-    delete options.group_level;
-  }
-
-  var shouldGroup = options.group || options.group_level;
-
-  var reduceFun;
-  if (builtInReduce[view.reduceFun]) {
-    reduceFun = builtInReduce[view.reduceFun];
-  } else {
-    reduceFun = evalFunc(
-      view.reduceFun.toString(), null, sum, log, Array.isArray, JSON.parse);
-  }
-
-  var groups = [];
-  var lvl = options.group_level;
-  results.forEach(function (e) {
-    var last = groups[groups.length - 1];
-    var key = shouldGroup ? e.key : null;
-
-    // only set group_level for array keys
-    if (shouldGroup && Array.isArray(key) && typeof lvl === 'number') {
-      key = key.length > lvl ? key.slice(0, lvl) : key;
-    }
-
-    if (last && collate(last.key[0][0], key) === 0) {
-      last.key.push([key, e.id]);
-      last.value.push(e.value);
-      return;
-    }
-    groups.push({key: [
-      [key, e.id]
-    ], value: [e.value]});
-  });
-  for (var i = 0, len = groups.length; i < len; i++) {
-    var e = groups[i];
-    var reduceTry = tryCode(view.sourceDB, reduceFun, [e.key, e.value, false]);
-    // CouchDB typically just sets the value to null if reduce errors out
-    e.value = reduceTry.error ? null : reduceTry.output;
-    e.key = e.key[0][0];
-  }
-  // no total_rows/offset when reducing
-  return {rows: sliceResults(groups, options.limit, options.skip)};
-}
-
-var queryView = utils.sequentialize(mainQueue, function (view, opts) {
-  var totalRows;
-  var shouldReduce = view.reduceFun && opts.reduce !== false;
-  var skip = opts.skip || 0;
-  if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
-    // equivalent query
-    opts.limit = 0;
-    delete opts.keys;
-  }
-
-  function fetchFromView(viewOpts) {
-    viewOpts.include_docs = true;
-    return view.db.allDocs(viewOpts).then(function (res) {
-      totalRows = res.total_rows;
-      return res.rows.map(function (result) {
-        return result.doc.value;
-      });
-    });
-  }
-
-  function onMapResultsReady(results) {
-    var res;
-    if (shouldReduce) {
-      res = reduceView(view, results, opts);
-    } else {
-      res = {
-        total_rows: totalRows,
-        offset: skip,
-        rows: results
-      };
-    }
-    if (opts.include_docs) {
-      var getDocsPromises = results.map(function (row) {
-        var val = row.value;
-        var docId = (val && typeof val === 'object' && val._id) || row.id;
-        return view.sourceDB.get(docId).then(function (joinedDoc) {
-          row.doc = joinedDoc;
-        }, function () {
-          // document error = don't join
-        });
-      });
-      return Promise.all(getDocsPromises).then(function () {
-        return res;
-      });
-    } else {
-      return res;
-    }
-  }
-
-  var flatten = function (array) {
-    return array.reduce(function (prev, cur) {
-      return prev.concat(cur);
-    });
-  };
-
-  if (typeof opts.keys !== 'undefined') {
-    var keys = opts.keys;
-    var fetchPromises = keys.map(function (key) {
-      var viewOpts = {
-        startkey : toIndexableString([key]),
-        endkey   : toIndexableString([key, {}])
-      };
-      return fetchFromView(viewOpts);
-    });
-    return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
-  } else { // normal query, no 'keys'
-    var viewOpts = {
-      descending : opts.descending
-    };
-    if (typeof opts.startkey !== 'undefined') {
-      viewOpts.startkey = opts.descending ?
-        toIndexableString([opts.startkey, {}]) :
-        toIndexableString([opts.startkey]);
-    }
-    if (typeof opts.endkey !== 'undefined') {
-      var inclusiveEnd = opts.inclusive_end !== false;
-      if (opts.descending) {
-        inclusiveEnd = !inclusiveEnd;
-      }
-
-      viewOpts.endkey = toIndexableString(inclusiveEnd ? [opts.endkey, {}] : [opts.endkey]);
-    }
-    if (typeof opts.key !== 'undefined') {
-      var keyStart = toIndexableString([opts.key]);
-      var keyEnd = toIndexableString([opts.key, {}]);
-      if (viewOpts.descending) {
-        viewOpts.endkey = keyStart;
-        viewOpts.startkey = keyEnd;
-      } else {
-        viewOpts.startkey = keyStart;
-        viewOpts.endkey = keyEnd;
-      }
-    }
-    if (!shouldReduce) {
-      if (typeof opts.limit === 'number') {
-        viewOpts.limit = opts.limit;
-      }
-      viewOpts.skip = skip;
-    }
-    return fetchFromView(viewOpts).then(onMapResultsReady);
-  }
-});
-
-function httpViewCleanup(db) {
-  return db.request({
-    method: 'POST',
-    url: '_view_cleanup'
-  });
-}
-
-var localViewCleanup = utils.sequentialize(mainQueue, function (db) {
-  return db.get('_local/mrviews').then(function (metaDoc) {
-    var docsToViews = {};
-    Object.keys(metaDoc.views).forEach(function (fullViewName) {
-      var parts = fullViewName.split('/');
-      var designDocName = '_design/' + parts[0];
-      var viewName = parts[1];
-      docsToViews[designDocName] = docsToViews[designDocName] || {};
-      docsToViews[designDocName][viewName] = true;
-    });
-    var opts = {
-      keys : Object.keys(docsToViews),
-      include_docs : true
-    };
-    return db.allDocs(opts).then(function (res) {
-      var viewsToStatus = {};
-      res.rows.forEach(function (row) {
-        Object.keys(docsToViews[row.key]).forEach(function (viewName) {
-          var viewDBNames = Object.keys(metaDoc.views[row.key.substring(8) + '/' + viewName]);
-          // design doc deleted, or view function nonexistent
-          var statusIsGood = row.doc && row.doc.views && row.doc.views[viewName];
-          viewDBNames.forEach(function (viewDBName) {
-            viewsToStatus[viewDBName] = viewsToStatus[viewDBName] || statusIsGood;
-          });
-        });
-      });
-      var dbsToDelete = Object.keys(viewsToStatus).filter(function (viewDBName) {
-        return !viewsToStatus[viewDBName];
-      });
-      var destroyPromises = dbsToDelete.map(function (viewDBName) {
-        return db.constructor.destroy(viewDBName, {adapter : db.adapter});
-      });
-      return Promise.all(destroyPromises).then(function () {
-        return {ok: true};
-      });
-    });
-  }, defaultsTo({ok: true}));
-});
-
-exports.viewCleanup = utils.callbackify(function () {
-  var db = this;
-  if (db.type() === 'http') {
-    return httpViewCleanup(db);
-  }
-  return localViewCleanup(db);
-});
-
-function queryPromised(db, fun, opts) {
-  if (db.type() === 'http') {
-    return httpQuery(db, fun, opts);
-  }
-
-  if (typeof fun !== 'string') {
-    // temp_view
-    checkQueryParseError(opts, fun);
-
-    var randomizer = Math.round(Math.random()  * 1000000) + 1;
-    var createViewOpts = {
-      db : db,
-      viewName : 'temp_view/temp_view',
-      map : fun.map,
-      reduce : fun.reduce,
-      randomizer : randomizer
-    };
-    return createView(createViewOpts).then(function (view) {
-      function cleanup() {
-        return view.db.destroy();
-      }
-      return utils.fin(updateView(view).then(function () {
-        return queryView(view, opts);
-      }), cleanup);
-    });
-  } else {
-    // persistent view
-    var fullViewName = fun;
-    var parts = parseViewName(fullViewName);
-    var designDocName = parts[0];
-    var viewName = parts[1];
-    return db.get('_design/' + designDocName).then(function (doc) {
-      var fun = doc.views && doc.views[viewName];
-
-      if (!fun || typeof fun.map !== 'string') {
-        var error = new Error('ddoc ' + designDocName + ' has no view named ' +
-          viewName);
-        error.name = 'not_found';
-        error.status = 400;
-        throw error;
-      }
-      checkQueryParseError(opts, fun);
-
-      var createViewOpts = {
-        db : db,
-        viewName : fullViewName,
-        map : fun.map,
-        reduce : fun.reduce
-      };
-      return createView(createViewOpts).then(function (view) {
-        if (opts.stale === 'ok' || opts.stale === 'update_after') {
-          if (opts.stale === 'update_after') {
-            updateView(view);
-          }
-          return queryView(view, opts);
-        } else { // stale not ok
-          return updateView(view).then(function () {
-            return queryView(view, opts);
-          });
-        }
-      });
-    });
-  }
-}
-
-exports.query = function (fun, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend({}, opts);
-
-  if (typeof fun === 'function') {
-    fun = {map : fun};
-  }
-
-  var db = this;
-  var promise = Promise.resolve().then(function () {
-    return queryPromised(db, fun, opts);
-  });
-  utils.promisedCallback(promise, callback);
-  return promise;
-};
-
-exports.putView = function (name, fun, rev, opts, callback) {
-  if (typeof rev === 'object') {
-    callback = opts;
-    opts = rev;
-    rev = null;
-  } else if (typeof rev === 'function') {
-    callback = rev;
-    rev = opts = null;
-  } else if (typeof opts === 'function') {
-    callback = opts;
-    opts = null;
-  }
-  opts = utils.extend({}, opts || {});
-
-  if (typeof fun === 'function' || typeof fun === 'string') {
-    fun = {map : fun};
-  }
-
-  var error;
-
-  if (typeof name !== 'string') {
-    error = new Error('you must supply a design doc/view name');
-    error.name = 'putview_error';
-    error.status = 400;
-    return utils.promisedCallback(Promise.reject(error), callback);
-  } else if (!fun || ['function', 'string'].indexOf(typeof fun.map) === -1) {
-    error = new Error('you must supply a map function');
-    error.name = 'putview_error';
-    error.status = 400;
-    return utils.promisedCallback(Promise.reject(error), callback);
-  }
-
-  if (typeof fun.map === 'function') {
-    fun.map = fun.map.toString();
-  }
-  if (typeof fun.reduce === 'function') {
-    fun.reduce = fun.reduce.toString();
-  }
-
-  var parts = name.split('/');
-  var designDocName = '_design/' + parts[0];
-  var viewName = parts[1];
-
-  var doc = {
-    _id : designDocName,
-    views : {}
-  };
-  doc.views[viewName] = fun;
-  if (rev) {
-    doc._rev = rev;
-  }
-
-  return this.put(doc, callback);
-};
-
-function QueryParseError(message) {
-  this.status = 400;
-  this.name = 'query_parse_error';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, QueryParseError);
-  } catch (e) {}
-}
-
-utils.inherits(QueryParseError, Error);
-
-},{"./create-view":46,"./evalfunc":47,"./taskqueue":51,"./utils":53,"pouchdb-collate":49}],49:[function(_dereq_,module,exports){
-'use strict';
-
-var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
-var MAGNITUDE_DIGITS = 3; // ditto
-var SEP = ''; // set to '_' for easier debugging 
-
-var utils = _dereq_('./utils');
-
-exports.collate = function (a, b) {
-
-  if (a === b) {
-    return 0;
-  }
-
-  a = exports.normalizeKey(a);
-  b = exports.normalizeKey(b);
-
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  if (a === null) {
-    return 0;
-  }
-  switch (typeof a) {
-    case 'number':
-      return a - b;
-    case 'boolean':
-      return a === b ? 0 : (a < b ? -1 : 1);
-    case 'string':
-      return stringCollate(a, b);
-  }
-  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
-};
-
-// couch considers null/NaN/Infinity/-Infinity === undefined,
-// for the purposes of mapreduce indexes. also, dates get stringified.
-exports.normalizeKey = function (key) {
-  switch (typeof key) {
-    case 'undefined':
-      return null;
-    case 'number':
-      if (key === Infinity || key === -Infinity || isNaN(key)) {
-        return null;
-      }
-      return key;
-    case 'object':
-      var origKey = key;
-      if (Array.isArray(key)) {
-        var len = key.length;
-        key = new Array(len);
-        for (var i = 0; i < len; i++) {
-          key[i] = exports.normalizeKey(origKey[i]);
-        }
-      } else if (key instanceof Date) {
-        return key.toJSON();
-      } else if (key !== null) { // generic object
-        key = {};
-        for (var k in origKey) {
-          if (origKey.hasOwnProperty(k)) {
-            var val = origKey[k];
-            if (typeof val !== 'undefined') {
-              key[k] = exports.normalizeKey(val);
-            }
-          }
-        }
-      }
-  }
-  return key;
-};
-
-function indexify(key) {
-  if (key !== null) {
-    switch (typeof key) {
-      case 'boolean':
-        return key ? 1 : 0;
-      case 'number':
-        return numToIndexableString(key);
-      case 'string':
-        // We've to be sure that key does not contain \u0000
-        // Do order-preserving replacements:
-        // 0 -> 1, 1
-        // 1 -> 1, 2
-        // 2 -> 2, 2
-        return key
-          .replace(/\u0002/g, '\u0002\u0002')
-          .replace(/\u0001/g, '\u0001\u0002')
-          .replace(/\u0000/g, '\u0001\u0001');
-      case 'object':
-        var isArray = Array.isArray(key);
-        var arr = isArray ? key : Object.keys(key);
-        var i = -1;
-        var len = arr.length;
-        var result = '';
-        if (isArray) {
-          while (++i < len) {
-            result += exports.toIndexableString(arr[i]);
-          }
-        } else {
-          while (++i < len) {
-            var objKey = arr[i];
-            result += exports.toIndexableString(objKey) +
-                exports.toIndexableString(key[objKey]);
-          }
-        }
-        return result;
-    }
-  }
-  return '';
-}
-
-// convert the given key to a string that would be appropriate
-// for lexical sorting, e.g. within a database, where the
-// sorting is the same given by the collate() function.
-exports.toIndexableString = function (key) {
-  var zero = '\u0000';
-  key = exports.normalizeKey(key);
-  return collationIndex(key) + SEP + indexify(key) + zero;
-};
-
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = exports.collate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-  }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
-}
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = exports.collate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = exports.collate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
-    }
-
-  }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
-}
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-// null/undefined/NaN/Infinity/-Infinity are all considered null
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  var idx = id.indexOf(typeof x);
-  //false if -1 otherwise true, but fast!!!!1
-  if (~idx) {
-    if (x === null) {
-      return 1;
-    }
-    if (Array.isArray(x)) {
-      return 5;
-    }
-    return idx < 3 ? (idx + 2) : (idx + 3);
-  }
-  if (Array.isArray(x)) {
-    return 5;
-  }
-}
-
-// conversion:
-// x yyy zz...zz
-// x = 0 for negative, 1 for 0, 2 for positive
-// y = exponent (for negative numbers negated) moved so that it's >= 0
-// z = mantisse
-function numToIndexableString(num) {
-
-  if (num === 0) {
-    return '1';
-  }
-
-  // convert number to exponential format for easier and
-  // more succinct string sorting
-  var expFormat = num.toExponential().split(/e\+?/);
-  var magnitude = parseInt(expFormat[1], 10);
-
-  var neg = num < 0;
-
-  var result = neg ? '0' : '2';
-
-  // first sort by magnitude
-  // it's easier if all magnitudes are positive
-  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
-  var magString = utils.padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
-
-  result += SEP + magString;
-
-  // then sort by the factor
-  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
-  if (neg) { // for negative reverse ordering
-    factor = 10 - factor;
-  }
-
-  var factorStr = factor.toFixed(20);
-
-  // strip zeros from the end
-  factorStr = factorStr.replace(/\.?0+$/, '');
-
-  result += SEP + factorStr;
-
-  return result;
-}
-
-},{"./utils":50}],50:[function(_dereq_,module,exports){
-'use strict';
-
-function pad(str, padWith, upToLength) {
-  var padding = '';
-  var targetLength = upToLength - str.length;
-  while (padding.length < targetLength) {
-    padding += padWith;
-  }
-  return padding;
-}
-
-exports.padLeft = function (str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return padding + str;
-};
-
-exports.padRight = function (str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return str + padding;
-};
-
-exports.stringLexCompare = function (a, b) {
-
-  var aLen = a.length;
-  var bLen = b.length;
-
-  var i;
-  for (i = 0; i < aLen; i++) {
-    if (i === bLen) {
-      // b is shorter substring of a
-      return 1;
-    }
-    var aChar = a.charAt(i);
-    var bChar = b.charAt(i);
-    if (aChar !== bChar) {
-      return aChar < bChar ? -1 : 1;
-    }
-  }
-
-  if (aLen < bLen) {
-    // a is shorter substring of b
-    return -1;
-  }
-
-  return 0;
-};
-
-/*
- * returns the decimal form for the given integer, i.e. writes
- * out all the digits (in base-10) instead of using scientific notation
- */
-exports.intToDecimalForm = function (int) {
-
-  var isNeg = int < 0;
-  var result = '';
-
-  do {
-    var remainder = isNeg ? -Math.ceil(int % 10) : Math.floor(int % 10);
-
-    result = remainder + result;
-    int = isNeg ? Math.ceil(int / 10) : Math.floor(int / 10);
-  } while (int);
-
-
-  if (isNeg && result !== '0') {
-    result = '-' + result;
-  }
-
-  return result;
-};
-},{}],51:[function(_dereq_,module,exports){
-'use strict';
-/*
- * Simple task queue to sequentialize actions. Assumes callbacks will eventually fire (once).
- */
-
-var Promise = _dereq_('./utils').Promise;
-
-function TaskQueue() {
-  this.promise = new Promise(function (fulfill) {fulfill(); });
-}
-TaskQueue.prototype.add = function (promiseFactory) {
-  this.promise = this.promise.then(null, function () {
-    // just recover
-  }).then(function () {
-    return promiseFactory();
-  });
-  return this.promise;
-};
-TaskQueue.prototype.finish = function () {
-  return this.promise;
-};
-
-module.exports = TaskQueue;
-
-},{"./utils":53}],52:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('./utils').Promise;
-
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    if (docId && typeof docId === 'object') {
-      docId = docId._id;
-    }
-    if (typeof docId !== 'string') {
-      return reject(new Error('doc id is required'));
-    }
-
-    db.get(docId, function (err, doc) {
-      if (err) {
-        if (err.name !== 'not_found') {
-          return reject(err);
-        }
-        return fulfill(tryAndPut(db, diffFun({_id : docId}), diffFun));
-      }
-      var newDoc = diffFun(doc);
-      if (!newDoc) {
-        return fulfill(doc);
-      }
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
-  });
-}
-
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc).then(null, function (err) {
-    if (err.name !== 'conflict') {
-      throw err;
-    }
-    return upsert(db, doc, diffFun);
-  });
-}
-
-module.exports = upsert;
-
-},{"./utils":53}],53:[function(_dereq_,module,exports){
-(function (process,global){
-'use strict';
-/* istanbul ignore if */
-if (typeof global.Promise === 'function') {
-  exports.Promise = global.Promise;
-} else {
-  exports.Promise = _dereq_('lie');
-}
-// uniquify a list, similar to underscore's _.uniq
-exports.uniq = function (arr) {
-  var map = {};
-  arr.forEach(function (element) {
-    map[element] = true;
-  });
-  return Object.keys(map);
-};
-
-exports.inherits = _dereq_('inherits');
-exports.extend = _dereq_('extend');
-var argsarray = _dereq_('argsarray');
-
-exports.promisedCallback = function (promise, callback) {
-  if (callback) {
-    promise.then(function (res) {
-      callback(null, res);
-    }, function (reason) {
-      callback(reason);
-    });
-  }
-  return promise;
-};
-
-exports.callbackify = function (fun) {
-  return argsarray(function (args) {
-    var cb = args.pop();
-    var promise = fun.apply(this, args);
-    if (typeof cb === 'function') {
-      exports.promisedCallback(promise, cb);
-    }
-    return promise;
-  });
-};
-
-// Promise finally util similar to Q.finally
-exports.fin = function (promise, cb) {
-  return promise.then(function (res) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        return res;
-      });
-    }
-    return res;
-  }, function (reason) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        throw reason;
-      });
-    }
-    throw reason;
-  });
-};
-
-exports.sequentialize = function (queue, promiseFactory) {
-  return function () {
-    var args = arguments;
-    var that = this;
-    return queue.add(function () {
-      return promiseFactory.apply(that, args);
-    });
-  };
-};
-
-var crypto = _dereq_('crypto');
-var md5 = _dereq_('md5-jkmyers');
-
-exports.MD5 = function (string) {
-  /* istanbul ignore else */
-  if (!process.browser) {
-    return crypto.createHash('md5').update(string).digest('hex');
-  } else {
-    return md5(string);
-  }
-};
-}).call(this,_dereq_("/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"/Users/daleharvey/src/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":25,"argsarray":22,"crypto":23,"extend":26,"inherits":27,"lie":31,"md5-jkmyers":45}]},{},[15])
-(15)
-});
\ No newline at end of file
diff --git a/tests/integration/deps/pouchdb-3.0.6-postfixed.js b/tests/integration/deps/pouchdb-3.0.6-postfixed.js
deleted file mode 100644
index 0ed3dfd..0000000
--- a/tests/integration/deps/pouchdb-3.0.6-postfixed.js
+++ /dev/null
@@ -1,10873 +0,0 @@
-//    PouchDBVersion306 3.0.6
-//    
-//    (c) 2012-2014 Dale Harvey and the PouchDBVersion306 team
-//    PouchDBVersion306 may be freely distributed under the Apache license, version 2.0.
-//    For all details and documentation:
-//    http://pouchdb.com
-!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.PouchDBVersion306=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-"use strict";
-
-var utils = _dereq_('./utils');
-var merge = _dereq_('./merge');
-var errors = _dereq_('./deps/errors');
-var EventEmitter = _dereq_('events').EventEmitter;
-var upsert = _dereq_('./deps/upsert');
-var Changes = _dereq_('./changes');
-var Promise = utils.Promise;
-
-/*
- * A generic pouch adapter
- */
-
-// returns first element of arr satisfying callback predicate
-function arrayFirst(arr, callback) {
-  for (var i = 0; i < arr.length; i++) {
-    if (callback(arr[i], i) === true) {
-      return arr[i];
-    }
-  }
-  return false;
-}
-
-// Wrapper for functions that call the bulkdocs api with a single doc,
-// if the first result is an error, return an error
-function yankError(callback) {
-  return function (err, results) {
-    if (err || results[0].error) {
-      callback(err || results[0]);
-    } else {
-      callback(null, results[0]);
-    }
-  };
-}
-
-// for every node in a revision tree computes its distance from the closest
-// leaf
-function computeHeight(revs) {
-  var height = {};
-  var edges = [];
-  merge.traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
-    var rev = pos + "-" + id;
-    if (isLeaf) {
-      height[rev] = 0;
-    }
-    if (prnt !== undefined) {
-      edges.push({from: prnt, to: rev});
-    }
-    return rev;
-  });
-
-  edges.reverse();
-  edges.forEach(function (edge) {
-    if (height[edge.from] === undefined) {
-      height[edge.from] = 1 + height[edge.to];
-    } else {
-      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
-    }
-  });
-  return height;
-}
-
-function allDocsKeysQuery(api, opts, callback) {
-  var keys =  ('limit' in opts) ?
-      opts.keys.slice(opts.skip, opts.limit + opts.skip) :
-      (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
-  if (opts.descending) {
-    keys.reverse();
-  }
-  if (!keys.length) {
-    return api._allDocs({limit: 0}, callback);
-  }
-  var finalResults = {
-    offset: opts.skip
-  };
-  return Promise.all(keys.map(function (key, i) {
-    var subOpts = utils.extend(true, {key: key, deleted: 'ok'}, opts);
-    ['limit', 'skip', 'keys'].forEach(function (optKey) {
-      delete subOpts[optKey];
-    });
-    return new Promise(function (resolve, reject) {
-      api._allDocs(subOpts, function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        finalResults.total_rows = res.total_rows;
-        resolve(res.rows[0] || {key: key, error: 'not_found'});
-      });
-    });
-  })).then(function (results) {
-    finalResults.rows = results;
-    return finalResults;
-  });
-}
-
-utils.inherits(AbstractPouchDBVersion306, EventEmitter);
-module.exports = AbstractPouchDBVersion306;
-
-function AbstractPouchDBVersion306() {
-  var self = this;
-  EventEmitter.call(this);
-  self.autoCompact = function (callback) {
-    // http doesn't have auto-compaction
-    if (!self.auto_compaction || self.type() === 'http') {
-      return callback;
-    }
-    return function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        var count = res.length;
-        var decCount = function () {
-          count--;
-          if (!count) {
-            callback(null, res);
-          }
-        };
-        if (!res.length) {
-          return callback(null, res);
-        }
-        res.forEach(function (doc) {
-          if (doc.ok && doc.id) { // if no id, then it was a local doc
-            // TODO: we need better error handling
-            self.compactDocument(doc.id, 1, decCount);
-          } else {
-            decCount();
-          }
-        });
-      }
-    };
-  };
-
-  var listeners = 0, changes;
-  var eventNames = ['change', 'delete', 'create', 'update'];
-  this.on('newListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      if (listeners) {
-        listeners++;
-        return;
-      } else {
-        listeners++;
-      }
-    } else {
-      return;
-    }
-    var lastChange = 0;
-    changes = this.changes({
-      conflicts: true,
-      include_docs: true,
-      continuous: true,
-      since: 'now',
-      onChange: function (change) {
-        if (change.seq <= lastChange) {
-          return;
-        }
-        lastChange = change.seq;
-        self.emit('change', change);
-        if (change.doc._deleted) {
-          self.emit('delete', change);
-        } else if (change.doc._rev.split('-')[0] === '1') {
-          self.emit('create', change);
-        } else {
-          self.emit('update', change);
-        }
-      }
-    });
-  });
-  this.on('removeListener', function (eventName) {
-    if (~eventNames.indexOf(eventName)) {
-      listeners--;
-      if (listeners) {
-        return;
-      }
-    } else {
-      return;
-    }
-    changes.cancel();
-  });
-}
-
-AbstractPouchDBVersion306.prototype.post =
-  utils.adapterFun('post', function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-});
-
-AbstractPouchDBVersion306.prototype.put =
-  utils.adapterFun('put', utils.getArguments(function (args) {
-  var temp, temptype, opts, callback;
-  var doc = args.shift();
-  var id = '_id' in doc;
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    callback = args.pop();
-    return callback(errors.NOT_AN_OBJECT);
-  }
-  doc = utils.clone(doc);
-  while (true) {
-    temp = args.shift();
-    temptype = typeof temp;
-    if (temptype === "string" && !id) {
-      doc._id = temp;
-      id = true;
-    } else if (temptype === "string" && id && !('_rev' in doc)) {
-      doc._rev = temp;
-    } else if (temptype === "object") {
-      opts = temp;
-    } else if (temptype === "function") {
-      callback = temp;
-    }
-    if (!args.length) {
-      break;
-    }
-  }
-  opts = opts || {};
-  var error = utils.invalidIdError(doc._id);
-  if (error) {
-    return callback(error);
-  }
-  if (utils.isLocalId(doc._id) && typeof this._putLocal === 'function') {
-    if (doc._deleted) {
-      return this._removeLocal(doc, callback);
-    } else {
-      return this._putLocal(doc, callback);
-    }
-  }
-  this.bulkDocs({docs: [doc]}, opts,
-      this.autoCompact(yankError(callback)));
-}));
-
-AbstractPouchDBVersion306.prototype.putAttachment =
-  utils.adapterFun('putAttachment', function (docId, attachmentId, rev,
-                                              blob, type, callback) {
-  var api = this;
-  if (typeof type === 'function') {
-    callback = type;
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-  if (typeof type === 'undefined') {
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-
-  function createAttachment(doc) {
-    doc._attachments = doc._attachments || {};
-    doc._attachments[attachmentId] = {
-      content_type: type,
-      data: blob
-    };
-    return api.put(doc);
-  }
-
-  return api.get(docId).then(function (doc) {
-    if (doc._rev !== rev) {
-      throw errors.REV_CONFLICT;
-    }
-
-    return createAttachment(doc);
-  }, function (err) {
-     // create new doc
-    if (err.error === errors.MISSING_DOC.error) {
-      return createAttachment({_id: docId});
-    } else {
-      throw err;
-    }
-  });
-});
-
-AbstractPouchDBVersion306.prototype.removeAttachment =
-  utils.adapterFun('removeAttachment', function (docId, attachmentId, rev,
-                                                 callback) {
-  var self = this;
-  self.get(docId, function (err, obj) {
-    if (err) {
-      callback(err);
-      return;
-    }
-    if (obj._rev !== rev) {
-      callback(errors.REV_CONFLICT);
-      return;
-    }
-    if (!obj._attachments) {
-      return callback();
-    }
-    delete obj._attachments[attachmentId];
-    if (Object.keys(obj._attachments).length === 0) {
-      delete obj._attachments;
-    }
-    self.put(obj, callback);
-  });
-});
-
-AbstractPouchDBVersion306.prototype.remove =
-  utils.adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
-  var doc;
-  if (typeof optsOrRev === 'string') {
-    // id, rev, opts, callback style
-    doc = {
-      _id: docOrId,
-      _rev: optsOrRev
-    };
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-  } else {
-    // doc, opts, callback style
-    doc = docOrId;
-    if (typeof optsOrRev === 'function') {
-      callback = optsOrRev;
-      opts = {};
-    } else {
-      callback = opts;
-      opts = optsOrRev;
-    }
-  }
-  opts = utils.clone(opts || {});
-  opts.was_delete = true;
-  var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
-  newDoc._deleted = true;
-  if (utils.isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
-    return this._removeLocal(doc, callback);
-  }
-  this.bulkDocs({docs: [newDoc]}, opts, yankError(callback));
-});
-
-AbstractPouchDBVersion306.prototype.revsDiff =
-  utils.adapterFun('revsDiff', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  var ids = Object.keys(req);
-
-  if (!ids.length) {
-    return callback(null, {});
-  }
-
-  var count = 0;
-  var missing = new utils.Map();
-
-  function addToMissing(id, revId) {
-    if (!missing.has(id)) {
-      missing.set(id, {missing: []});
-    }
-    missing.get(id).missing.push(revId);
-  }
-
-  function processDoc(id, rev_tree) {
-    // Is this fast enough? Maybe we should switch to a set simulated by a map
-    var missingForId = req[id].slice(0);
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
-      opts) {
-        var rev = pos + '-' + revHash;
-        var idx = missingForId.indexOf(rev);
-        if (idx === -1) {
-          return;
-        }
-
-        missingForId.splice(idx, 1);
-        if (opts.status !== 'available') {
-          addToMissing(id, rev);
-        }
-      });
-
-    // Traversing the tree is synchronous, so now `missingForId` contains
-    // revisions that were not found in the tree
-    missingForId.forEach(function (rev) {
-      addToMissing(id, rev);
-    });
-  }
-
-  ids.map(function (id) {
-    this._getRevisionTree(id, function (err, rev_tree) {
-      if (err && err.status === 404 && err.message === 'missing') {
-        missing.set(id, {missing: req[id]});
-      } else if (err) {
-        return callback(err);
-      } else {
-        processDoc(id, rev_tree);
-      }
-
-      if (++count === ids.length) {
-        // convert LazyMap to object
-        var missingObj = {};
-        missing.forEach(function (value, key) {
-          missingObj[key] = value;
-        });
-        return callback(null, missingObj);
-      }
-    });
-  }, this);
-});
-
-// compact one document and fire callback
-// by compacting we mean removing all revisions which
-// are further from the leaf in revision tree than max_height
-AbstractPouchDBVersion306.prototype.compactDocument =
-  utils.adapterFun('compactDocument', function (docId, max_height, callback) {
-  var self = this;
-  this._getRevisionTree(docId, function (err, rev_tree) {
-    if (err) {
-      return callback(err);
-    }
-    var height = computeHeight(rev_tree);
-    var candidates = [];
-    var revs = [];
-    Object.keys(height).forEach(function (rev) {
-      if (height[rev] > max_height) {
-        candidates.push(rev);
-      }
-    });
-
-    merge.traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, opts) {
-      var rev = pos + '-' + revHash;
-      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
-        opts.status = 'missing';
-        revs.push(rev);
-      }
-    });
-    self._doCompaction(docId, rev_tree, revs, callback);
-  });
-});
-
-// compact the whole database using single document
-// compaction
-AbstractPouchDBVersion306.prototype.compact =
-  utils.adapterFun('compact', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  var self = this;
-
-  opts = utils.clone(opts || {});
-
-  self.get('_local/compaction')["catch"](function () {
-    return false;
-  }).then(function (doc) {
-    if (typeof self._compact === 'function') {
-      if (doc && doc.last_seq) {
-        opts.last_seq = doc.last_seq;
-      }
-      return self._compact(opts, callback);
-    }
-
-  });
-});
-AbstractPouchDBVersion306.prototype._compact = function (opts, callback) {
-  var done = false;
-  var started = 0;
-  var copts = {
-    returnDocs: false
-  };
-  var self = this;
-  var lastSeq;
-  function finish() {
-    self.get('_local/compaction')["catch"](function () {
-      return false;
-    }).then(function (doc) {
-      doc = doc || {_id: '_local/compaction'};
-      doc.last_seq = lastSeq;
-      return self.put(doc);
-    }).then(function () {
-      callback();
-    }, callback);
-  }
-  if (opts.last_seq) {
-    copts.since = opts.last_seq;
-  }
-  function afterCompact() {
-    started--;
-    if (!started && done) {
-      finish();
-    }
-  }
-  function onChange(row) {
-    started++;
-    self.compactDocument(row.id, 0).then(afterCompact, callback);
-  }
-  self.changes(copts).on('change', onChange).on('complete', function (resp) {
-    done = true;
-    lastSeq = resp.last_seq;
-    if (!started) {
-      finish();
-    }
-  }).on('error', callback);
-};
-/* Begin api wrappers. Specific functionality to storage belongs in the 
-   _[method] */
-AbstractPouchDBVersion306.prototype.get =
-  utils.adapterFun('get', function (id, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof id !== 'string') {
-    return callback(errors.INVALID_ID);
-  }
-  if (utils.isLocalId(id) && typeof this._getLocal === 'function') {
-    return this._getLocal(id, callback);
-  }
-  var leaves = [], self = this;
-  function finishOpenRevs() {
-    var result = [];
-    var count = leaves.length;
-    if (!count) {
-      return callback(null, result);
-    }
-    // order with open_revs is unspecified
-    leaves.forEach(function (leaf) {
-      self.get(id,
-               {rev: leaf, revs: opts.revs, attachments: opts.attachments},
-               function (err, doc) {
-        if (!err) {
-          result.push({ok: doc});
-        } else {
-          result.push({missing: leaf});
-        }
-        count--;
-        if (!count) {
-          callback(null, result);
-        }
-      });
-    });
-  }
-
-  if (opts.open_revs) {
-    if (opts.open_revs === "all") {
-      this._getRevisionTree(id, function (err, rev_tree) {
-        if (err) {
-          // if there's no such document we should treat this
-          // situation the same way as if revision tree was empty
-          rev_tree = [];
-        }
-        leaves = merge.collectLeaves(rev_tree).map(function (leaf) {
-          return leaf.rev;
-        });
-        finishOpenRevs();
-      });
-    } else {
-      if (Array.isArray(opts.open_revs)) {
-        leaves = opts.open_revs;
-        for (var i = 0; i < leaves.length; i++) {
-          var l = leaves[i];
-          // looks like it's the only thing couchdb checks
-          if (!(typeof(l) === "string" && /^\d+-/.test(l))) {
-            return callback(errors.error(errors.BAD_REQUEST,
-              "Invalid rev format"));
-          }
-        }
-        finishOpenRevs();
-      } else {
-        return callback(errors.error(errors.UNKNOWN_ERROR,
-          'function_clause'));
-      }
-    }
-    return; // open_revs does not like other options
-  }
-
-  return this._get(id, opts, function (err, result) {
-    opts = utils.clone(opts);
-    if (err) {
-      return callback(err);
-    }
-
-    var doc = result.doc;
-    if (!doc) {
-      // a smoke test for something being very wrong
-      return callback(new Error('no doc!'));
-    }
-    var metadata = result.metadata;
-    var ctx = result.ctx;
-
-    if (opts.conflicts) {
-      var conflicts = merge.collectConflicts(metadata);
-      if (conflicts.length) {
-        doc._conflicts = conflicts;
-      }
-    }
-
-    if (opts.revs || opts.revs_info) {
-      var paths = merge.rootToLeaf(metadata.rev_tree);
-      var path = arrayFirst(paths, function (arr) {
-        return arr.ids.map(function (x) { return x.id; })
-          .indexOf(doc._rev.split('-')[1]) !== -1;
-      });
-
-      var indexOfRev = path.ids.map(function (x) {return x.id; })
-        .indexOf(doc._rev.split('-')[1]) + 1;
-      var howMany = path.ids.length - indexOfRev;
-      path.ids.splice(indexOfRev, howMany);
-      path.ids.reverse();
-
-      if (opts.revs) {
-        doc._revisions = {
-          start: (path.pos + path.ids.length) - 1,
-          ids: path.ids.map(function (rev) {
-            return rev.id;
-          })
-        };
-      }
-      if (opts.revs_info) {
-        var pos =  path.pos + path.ids.length;
-        doc._revs_info = path.ids.map(function (rev) {
-          pos--;
-          return {
-            rev: pos + '-' + rev.id,
-            status: rev.opts.status
-          };
-        });
-      }
-    }
-
-    if (opts.local_seq) {
-      doc._local_seq = result.metadata.seq;
-    }
-
-    if (opts.attachments && doc._attachments) {
-      var attachments = doc._attachments;
-      var count = Object.keys(attachments).length;
-      if (count === 0) {
-        return callback(null, doc);
-      }
-      Object.keys(attachments).forEach(function (key) {
-        this._getAttachment(attachments[key],
-                            {encode: true, ctx: ctx}, function (err, data) {
-          var att = doc._attachments[key];
-          att.data = data;
-          delete att.stub;
-          if (!--count) {
-            callback(null, doc);
-          }
-        });
-      }, self);
-    } else {
-      if (doc._attachments) {
-        for (var key in doc._attachments) {
-          if (doc._attachments.hasOwnProperty(key)) {
-            doc._attachments[key].stub = true;
-          }
-        }
-      }
-      callback(null, doc);
-    }
-  });
-});
-
-AbstractPouchDBVersion306.prototype.getAttachment =
-  utils.adapterFun('getAttachment', function (docId, attachmentId, opts,
-                                              callback) {
-  var self = this;
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  this._get(docId, opts, function (err, res) {
-    if (err) {
-      return callback(err);
-    }
-    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
-      opts.ctx = res.ctx;
-      self._getAttachment(res.doc._attachments[attachmentId], opts, callback);
-    } else {
-      return callback(errors.MISSING_DOC);
-    }
-  });
-});
-
-AbstractPouchDBVersion306.prototype.allDocs =
-  utils.adapterFun('allDocs', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
-  if ('keys' in opts) {
-    if (!Array.isArray(opts.keys)) {
-      return callback(new TypeError('options.keys must be an array'));
-    }
-    var incompatibleOpt =
-      ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
-      return incompatibleOpt in opts;
-    })[0];
-    if (incompatibleOpt) {
-      callback(errors.error(errors.QUERY_PARSE_ERROR,
-        'Query parameter `' + incompatibleOpt +
-        '` is not compatible with multi-get'
-      ));
-      return;
-    }
-    if (this.type() !== 'http') {
-      return allDocsKeysQuery(this, opts, callback);
-    }
-  }
-
-  return this._allDocs(opts, callback);
-});
-
-AbstractPouchDBVersion306.prototype.changes = function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  return new Changes(this, opts, callback);
-};
-
-AbstractPouchDBVersion306.prototype.close =
-  utils.adapterFun('close', function (callback) {
-  this._closed = true;
-  return this._close(callback);
-});
-
-AbstractPouchDBVersion306.prototype.info = utils.adapterFun('info', function (callback) {
-  var self = this;
-  this._info(function (err, info) {
-    if (err) {
-      return callback(err);
-    }
-    // assume we know better than the adapter, unless it informs us
-    info.db_name = info.db_name || self._db_name;
-    info.auto_compaction = !!(self._auto_compaction && self.type() !== 'http');
-    callback(null, info);
-  });
-});
-
-AbstractPouchDBVersion306.prototype.id = utils.adapterFun('id', function (callback) {
-  return this._id(callback);
-});
-
-AbstractPouchDBVersion306.prototype.type = function () {
-  return (typeof this._type === 'function') ? this._type() : this.adapter;
-};
-
-AbstractPouchDBVersion306.prototype.bulkDocs =
-  utils.adapterFun('bulkDocs', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-
-  opts = utils.clone(opts);
-
-  if (Array.isArray(req)) {
-    req = {
-      docs: req
-    };
-  }
-
-  if (!req || !req.docs || !Array.isArray(req.docs)) {
-    return callback(errors.MISSING_BULK_DOCS);
-  }
-
-  for (var i = 0; i < req.docs.length; ++i) {
-    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-  }
-
-  req = utils.clone(req);
-  if (!('new_edits' in opts)) {
-    if ('new_edits' in req) {
-      opts.new_edits = req.new_edits;
-    } else {
-      opts.new_edits = true;
-    }
-  }
-
-  return this._bulkDocs(req, opts, this.autoCompact(callback));
-});
-
-AbstractPouchDBVersion306.prototype.registerDependentDatabase =
-  utils.adapterFun('registerDependentDatabase', function (dependentDb,
-                                                          callback) {
-  var depDB = new this.constructor(dependentDb, {adapter: this._adapter});
-  function diffFun(doc) {
-    doc.dependentDbs = doc.dependentDbs || {};
-    if (doc.dependentDbs[dependentDb]) {
-      return false; // no update required
-    }
-    doc.dependentDbs[dependentDb] = true;
-    return doc;
-  }
-  upsert(this, '_local/_pouch_dependentDbs', diffFun, function (err) {
-    if (err) {
-      return callback(err);
-    }
-    return callback(null, {db: depDB});
-  });
-});
-
-},{"./changes":6,"./deps/errors":11,"./deps/upsert":13,"./merge":18,"./utils":23,"events":27}],2:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-var CHANGES_BATCH_SIZE = 25;
-
-var utils = _dereq_('../utils');
-var errors = _dereq_('../deps/errors');
-// parseUri 1.2.2
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-function parseUri(str) {
-  var o = parseUri.options;
-  var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
-  var uri = {};
-  var i = 14;
-
-  while (i--) {
-    uri[o.key[i]] = m[i] || "";
-  }
-
-  uri[o.q.name] = {};
-  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
-    if ($1) {
-      uri[o.q.name][$1] = $2;
-    }
-  });
-
-  return uri;
-}
-
-function encodeDocId(id) {
-  if (/^_(design|local)/.test(id)) {
-    return id;
-  }
-  return encodeURIComponent(id);
-}
-
-function preprocessAttachments(doc) {
-  if (!doc._attachments || !Object.keys(doc._attachments)) {
-    return utils.Promise.resolve();
-  }
-
-  return utils.Promise.all(Object.keys(doc._attachments).map(function (key) {
-    var attachment = doc._attachments[key];
-    if (attachment.data && typeof attachment.data !== 'string') {
-      if (typeof process === undefined || process.browser) {
-        return new utils.Promise(function (resolve) {
-          var reader = new FileReader();
-          reader.onloadend = function (e) {
-            attachment.data = utils.btoa(
-              utils.arrayBufferToBinaryString(e.target.result));
-            resolve();
-          };
-          reader.readAsArrayBuffer(attachment.data);
-        });
-      } else {
-        attachment.data = attachment.data.toString('base64');
-      }
-    }
-  }));
-}
-
-parseUri.options = {
-  strictMode: false,
-  key: ["source", "protocol", "authority", "userInfo", "user", "password",
-        "host", "port", "relative", "path", "directory", "file", "query",
-        "anchor"],
-  q:   {
-    name:   "queryKey",
-    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
-  },
-  parser: {
-    /* jshint maxlen: false */
-    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
-    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
-  }
-};
-
-// Get all the information you possibly can about the URI given by name and
-// return it as a suitable object.
-function getHost(name, opts) {
-  // If the given name contains "http:"
-  if (/http(s?):/.test(name)) {
-    // Prase the URI into all its little bits
-    var uri = parseUri(name);
-
-    // Store the fact that it is a remote URI
-    uri.remote = true;
-
-    // Store the user and password as a separate auth object
-    if (uri.user || uri.password) {
-      uri.auth = {username: uri.user, password: uri.password};
-    }
-
-    // Split the path part of the URI into parts using '/' as the delimiter
-    // after removing any leading '/' and any trailing '/'
-    var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
-
-    // Store the first part as the database name and remove it from the parts
-    // array
-    uri.db = parts.pop();
-
-    // Restore the path by joining all the remaining parts (all the parts
-    // except for the database name) with '/'s
-    uri.path = parts.join('/');
-    opts = opts || {};
-    opts = utils.clone(opts);
-    uri.headers = opts.headers || {};
-
-    if (opts.auth || uri.auth) {
-      var nAuth = opts.auth || uri.auth;
-      var token = utils.btoa(nAuth.username + ':' + nAuth.password);
-      uri.headers.Authorization = 'Basic ' + token;
-    }
-
-    if (opts.headers) {
-      uri.headers = opts.headers;
-    }
-
-    return uri;
-  }
-
-  // If the given name does not contain 'http:' then return a very basic object
-  // with no host, the current path, the given name as the database name and no
-  // username/password
-  return {host: '', path: '/', db: name, auth: false};
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genDBUrl(opts, path) {
-  return genUrl(opts, opts.db + '/' + path);
-}
-
-// Generate a URL with the host data given by opts and the given path
-function genUrl(opts, path) {
-  if (opts.remote) {
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    var pathDel = !opts.path ? '' : '/';
-
-    // If the host already has a path, then we need to have a path delimiter
-    // Otherwise, the path delimiter is the empty string
-    return opts.protocol + '://' + opts.host + ':' + opts.port + '/' +
-           opts.path + pathDel + path;
-  }
-
-  return '/' + path;
-}
-// Implements the PouchDBVersion306 API for dealing with CouchDB instances over HTTP
-function HttpPouch(opts, callback) {
-  // The functions that will be publicly available for HttpPouch
-  var api = this;
-  api.getHost = opts.getHost ? opts.getHost : getHost;
-
-  // Parse the URI given by opts.name into an easy-to-use object
-  var host = api.getHost(opts.name, opts);
-
-  // Generate the database URL based on the host
-  var dbUrl = genDBUrl(host, '');
-
-  api.getUrl = function () {return dbUrl; };
-  api.getHeaders = function () {return utils.clone(host.headers); };
-
-  var ajaxOpts = opts.ajax || {};
-  opts = utils.clone(opts);
-  function ajax(options, callback) {
-    return utils.ajax(utils.extend({}, ajaxOpts, options), callback);
-  }
-
-  // Create a new CouchDB database based on the given opts
-  var createDB = function () {
-    ajax({headers: host.headers, method: 'PUT', url: dbUrl},
-         function (err, ret) {
-      // If we get an "Unauthorized" error
-      if (err && err.status === 401) {
-        // Test if the database already exists
-        ajax({headers: host.headers, method: 'HEAD', url: dbUrl},
-             function (err, ret) {
-          // If there is still an error
-          if (err) {
-            // Give the error to the callback to deal with
-            callback(err);
-          } else {
-            // Continue as if there had been no errors
-            callback(null, api);
-          }
-        });
-        // If there were no errros or if the only error is "Precondition Failed"
-        // (note: "Precondition Failed" occurs when we try to create a database
-        // that already exists)
-      } else if (!err || err.status === 412) {
-        // Continue as if there had been no errors
-        callback(null, api);
-      } else {
-        callback(err);
-      }
-    });
-  };
-  if (!opts.skipSetup) {
-    ajax({headers: host.headers, method: 'GET', url: dbUrl},
-         function (err, ret) {
-      //check if the db exists
-      if (err) {
-        if (err.status === 404) {
-          //if it doesn't, create it
-          createDB();
-        } else {
-          callback(err);
-        }
-      } else {
-        //go do stuff with the db
-        callback(null, api);
-      }
-    });
-  }
-
-  api.type = function () {
-    return 'http';
-  };
-
-  api.id = utils.adapterFun('id', function (callback) {
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genUrl(host, '')
-    }, function (err, result) {
-      var uuid = (result && result.uuid) ?
-        result.uuid + host.db : genDBUrl(host, '');
-      callback(null, uuid);
-    });
-  });
-
-  api.request = utils.adapterFun('request', function (options, callback) {
-    options.headers = host.headers;
-    options.url = genDBUrl(host, options.url);
-    ajax(options, callback);
-  });
-
-  // Sends a POST request to the host calling the couchdb _compact function
-  //    version: The version of CouchDB it is running
-  api.compact = utils.adapterFun('compact', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    ajax({
-      headers: host.headers,
-      url: genDBUrl(host, '_compact'),
-      method: 'POST'
-    }, function () {
-      function ping() {
-        api.info(function (err, res) {
-          if (!res.compact_running) {
-            callback();
-          } else {
-            setTimeout(ping, opts.interval || 200);
-          }
-        });
-      }
-      // Ping the http if it's finished compaction
-      if (typeof callback === "function") {
-        ping();
-      }
-    });
-  });
-
-  // Calls GET on the host, which gets back a JSON string containing
-  //    couchdb: A welcome string
-  //    version: The version of CouchDB it is running
-  api._info = function (callback) {
-    ajax({
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, '')
-    }, function (err, res) {
-      if (err) {
-        callback(err);
-      } else {
-        res.host = genDBUrl(host, '');
-        callback(null, res);
-      }
-    });
-  };
-
-  // Get the document with the given id from the database given by host.
-  // The id could be solely the _id in the database, or it may be a
-  // _design/ID or _local/ID path
-  api.get = utils.adapterFun('get', function (id, opts, callback) {
-    // If no options were given, set the callback to the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-
-    // List of parameters to add to the GET request
-    var params = [];
-
-    // If it exists, add the opts.revs value to the list of parameters.
-    // If revs=true then the resulting JSON will include a field
-    // _revisions containing an array of the revision IDs.
-    if (opts.revs) {
-      params.push('revs=true');
-    }
-
-    // If it exists, add the opts.revs_info value to the list of parameters.
-    // If revs_info=true then the resulting JSON will include the field
-    // _revs_info containing an array of objects in which each object
-    // representing an available revision.
-    if (opts.revs_info) {
-      params.push('revs_info=true');
-    }
-
-    if (opts.local_seq) {
-      params.push('local_seq=true');
-    }
-    // If it exists, add the opts.open_revs value to the list of parameters.
-    // If open_revs=all then the resulting JSON will include all the leaf
-    // revisions. If open_revs=["rev1", "rev2",...] then the resulting JSON
-    // will contain an array of objects containing data of all revisions
-    if (opts.open_revs) {
-      if (opts.open_revs !== "all") {
-        opts.open_revs = JSON.stringify(opts.open_revs);
-      }
-      params.push('open_revs=' + opts.open_revs);
-    }
-
-    // If it exists, add the opts.attachments value to the list of parameters.
-    // If attachments=true the resulting JSON will include the base64-encoded
-    // contents in the "data" property of each attachment.
-    if (opts.attachments) {
-      params.push('attachments=true');
-    }
-
-    // If it exists, add the opts.rev value to the list of parameters.
-    // If rev is given a revision number then get the specified revision.
-    if (opts.rev) {
-      params.push('rev=' + opts.rev);
-    }
-
-    // If it exists, add the opts.conflicts value to the list of parameters.
-    // If conflicts=true then the resulting JSON will include the field
-    // _conflicts containing all the conflicting revisions.
-    if (opts.conflicts) {
-      params.push('conflicts=' + opts.conflicts);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
-
-    if (opts.auto_encode) {
-      id = encodeDocId(id);
-    }
-
-    // Set the options for the ajax call
-    var options = {
-      headers: host.headers,
-      method: 'GET',
-      url: genDBUrl(host, id + params)
-    };
-
-    // If the given id contains at least one '/' and the part before the '/'
-    // is NOT "_design" and is NOT "_local"
-    // OR
-    // If the given id contains at least two '/' and the part before the first
-    // '/' is "_design".
-    // TODO This second condition seems strange since if parts[0] === '_design'
-    // then we already know that parts[0] !== '_local'.
-    var parts = id.split('/');
-    if ((parts.length > 1 && parts[0] !== '_design' && parts[0] !== '_local') ||
-        (parts.length > 2 && parts[0] === '_design' && parts[0] !== '_local')) {
-      // Binary is expected back from the server
-      options.binary = true;
-    }
-
-    // Get the document
-    ajax(options, function (err, doc, xhr) {
-      // If the document does not exist, send an error to the callback
-      if (err) {
-        return callback(err);
-      }
-
-      // Send the document to the callback
-      callback(null, doc, xhr);
-    });
-  });
-
-  // Delete the document given by doc from the database given by host.
-  api.remove = utils.adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
-    var doc;
-    if (typeof optsOrRev === 'string') {
-      // id, rev, opts, callback style
-      doc = {
-        _id: docOrId,
-        _rev: optsOrRev
-      };
-      if (typeof opts === 'function') {
-        callback = opts;
-        opts = {};
-      }
-    } else {
-      // doc, opts, callback style
-      doc = docOrId;
-      if (typeof optsOrRev === 'function') {
-        callback = optsOrRev;
-        opts = {};
-      } else {
-        callback = opts;
-        opts = optsOrRev;
-      }
-    }
-
-    var rev = (doc._rev || opts.rev);
-
-    // Delete the document
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev
-    }, callback);
-  });
-
-  // Get the attachment
-  api.getAttachment =
-    utils.adapterFun('getAttachment', function (docId, attachmentId, opts,
-                                                callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (opts.auto_encode === undefined) {
-      opts.auto_encode = true;
-    }
-    if (opts.auto_encode) {
-      docId = encodeDocId(docId);
-    }
-    opts.auto_encode = false;
-    api.get(docId + '/' + attachmentId, opts, callback);
-  });
-
-  // Remove the attachment given by the id and rev
-  api.removeAttachment =
-    utils.adapterFun('removeAttachment', function (docId, attachmentId, rev,
-                                                   callback) {
-    ajax({
-      headers: host.headers,
-      method: 'DELETE',
-      url: genDBUrl(host, encodeDocId(docId) + '/' + attachmentId) + '?rev=' +
-           rev
-    }, callback);
-  });
-
-  // Add the attachment given by blob and its contentType property
-  // to the document with the given id, the revision given by rev, and
-  // add it to the database given by host.
-  api.putAttachment =
-    utils.adapterFun('putAttachment', function (docId, attachmentId, rev, blob,
-                                                type, callback) {
-    if (typeof type === 'function') {
-      callback = type;
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    if (typeof type === 'undefined') {
-      type = blob;
-      blob = rev;
-      rev = null;
-    }
-    var id = encodeDocId(docId) + '/' + attachmentId;
-    var url = genDBUrl(host, id);
-    if (rev) {
-      url += '?rev=' + rev;
-    }
-
-    var opts = {
-      headers: utils.clone(host.headers),
-      method: 'PUT',
-      url: url,
-      processData: false,
-      body: blob,
-      timeout: 60000
-    };
-    opts.headers['Content-Type'] = type;
-    // Add the attachment
-    ajax(opts, callback);
-  });
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This fails if the doc has no _id field.
-  api.put = utils.adapterFun('put', utils.getArguments(function (args) {
-    var temp, temptype, opts;
-    var doc = args.shift();
-    var id = '_id' in doc;
-    var callback = args.pop();
-    if (typeof doc !== 'object' || Array.isArray(doc)) {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-
-    doc = utils.clone(doc);
-
-    preprocessAttachments(doc).then(function () {
-      while (true) {
-        temp = args.shift();
-        temptype = typeof temp;
-        if (temptype === "string" && !id) {
-          doc._id = temp;
-          id = true;
-        } else if (temptype === "string" && id && !('_rev' in doc)) {
-          doc._rev = temp;
-        } else if (temptype === "object") {
-          opts = utils.clone(temp);
-        }
-        if (!args.length) {
-          break;
-        }
-      }
-      opts = opts || {};
-      var error = utils.invalidIdError(doc._id);
-      if (error) {
-        throw error;
-      }
-
-      // List of parameter to add to the PUT request
-      var params = [];
-
-      // If it exists, add the opts.new_edits value to the list of parameters.
-      // If new_edits = false then the database will NOT assign this document a
-      // new revision number
-      if (opts && typeof opts.new_edits !== 'undefined') {
-        params.push('new_edits=' + opts.new_edits);
-      }
-
-      // Format the list of parameters into a valid URI query string
-      params = params.join('&');
-      if (params !== '') {
-        params = '?' + params;
-      }
-
-      // Add the document
-      ajax({
-        headers: host.headers,
-        method: 'PUT',
-        url: genDBUrl(host, encodeDocId(doc._id)) + params,
-        body: doc
-      }, function (err, res) {
-        if (err) {
-          return callback(err);
-        }
-        res.ok = true;
-        callback(null, res);
-      });
-    })["catch"](callback);
-
-  }));
-
-  // Add the document given by doc (in JSON string format) to the database
-  // given by host. This does not assume that doc is a new document 
-  // (i.e. does not have a _id or a _rev field.)
-  api.post = utils.adapterFun('post', function (doc, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    if (typeof doc !== 'object') {
-      return callback(errors.NOT_AN_OBJECT);
-    }
-    if (! ("_id" in doc)) {
-      doc._id = utils.uuid();
-    }
-    api.put(doc, opts, function (err, res) {
-      if (err) {
-        return callback(err);
-      }
-      res.ok = true;
-      callback(null, res);
-    });
-  });
-
-  // Update/create multiple documents given by req in the database
-  // given by host.
-  api._bulkDocs = function (req, opts, callback) {
-    // If opts.new_edits exists add it to the document data to be
-    // send to the database.
-    // If new_edits=false then it prevents the database from creating
-    // new revision numbers for the documents. Instead it just uses
-    // the old ones. This is used in database replication.
-    if (typeof opts.new_edits !== 'undefined') {
-      req.new_edits = opts.new_edits;
-    }
-
-    utils.Promise.all(req.docs.map(preprocessAttachments)).then(function () {
-      // Update/create the documents
-      ajax({
-        headers: host.headers,
-        method: 'POST',
-        url: genDBUrl(host, '_bulk_docs'),
-        body: req
-      }, function (err, results) {
-        if (err) {
-          return callback(err);
-        }
-        results.forEach(function (result) {
-          result.ok = true; // smooths out cloudant not adding this
-        });
-        callback(null, results);
-      });
-    })["catch"](callback);
-  };
-
-  // Get a listing of the documents in the database given
-  // by host and ordered by increasing id.
-  api.allDocs = utils.adapterFun('allDocs', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = utils.clone(opts);
-    // List of parameters to add to the GET request
-    var params = [];
-    var body;
-    var method = 'GET';
-
-    // TODO I don't see conflicts as a valid parameter for a
-    // _all_docs request 
-    // (see http://wiki.apache.org/couchdb/HTTP_Document_API#all_docs)
-    if (opts.conflicts) {
-      params.push('conflicts=true');
-    }
-
-    // If opts.descending is truthy add it to params
-    if (opts.descending) {
-      params.push('descending=true');
-    }
-
-    // If opts.include_docs exists, add the include_docs value to the
-    // list of parameters.
-    // If include_docs=true then include the associated document with each
-    // result.
-    if (opts.include_docs) {
-      params.push('include_docs=true');
-    }
-
-    if (opts.key) {
-      params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
-    }
-
-    // If opts.startkey exists, add the startkey value to the list of
-    // parameters.
-    // If startkey is given then the returned list of documents will
-    // start with the document whose id is startkey.
-    if (opts.startkey) {
-      params.push('startkey=' +
-        encodeURIComponent(JSON.stringify(opts.startkey)));
-    }
-
-    // If opts.endkey exists, add the endkey value to the list of parameters.
-    // If endkey is given then the returned list of docuemnts will
-    // end with the document whose id is endkey.
-    if (opts.endkey) {
-      params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
-    }
-
-    if (typeof opts.inclusive_end !== 'undefined') {
-      params.push('inclusive_end=' + !!opts.inclusive_end);
-    }
-
-    // If opts.limit exists, add the limit value to the parameter list.
-    if (typeof opts.limit !== 'undefined') {
-      params.push('limit=' + opts.limit);
-    }
-
-    if (typeof opts.skip !== 'undefined') {
-      params.push('skip=' + opts.skip);
-    }
-
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    if (params !== '') {
-      params = '?' + params;
-    }
-
-    if (typeof opts.keys !== 'undefined') {
-
-      var MAX_URL_LENGTH = 2000;
-      // according to http://stackoverflow.com/a/417184/680742,
-      // the de factor URL length limit is 2000 characters
-
-      var keysAsString =
-        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-        // If the keys are short enough, do a GET. we do this to work around
-        // Safari not understanding 304s on POSTs (see issue #1239)
-        params += (params.indexOf('?') !== -1 ? '&' : '?') + keysAsString;
-      } else {
-        // If keys are too long, issue a POST request to circumvent GET
-        // query string limits
-        // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-        method = 'POST';
-        body = JSON.stringify({keys: opts.keys});
-      }
-    }
-
-    // Get the document listing
-    ajax({
-      headers: host.headers,
-      method: method,
-      url: genDBUrl(host, '_all_docs' + params),
-      body: body
-    }, callback);
-  });
-
-  // Get a list of changes made to documents in the database given by host.
-  // TODO According to the README, there should be two other methods here,
-  // api.changes.addListener and api.changes.removeListener.
-  api._changes = function (opts) {
-    // We internally page the results of a changes request, this means
-    // if there is a large set of changes to be returned we can start
-    // processing them quicker instead of waiting on the entire
-    // set of changes to return and attempting to process them at once
-    var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
-
-    opts = utils.clone(opts);
-    opts.timeout = opts.timeout || 30 * 1000;
-
-    // We give a 5 second buffer for CouchDB changes to respond with
-    // an ok timeout
-    var params = { timeout: opts.timeout - (5 * 1000) };
-    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
-    if (limit === 0) {
-      limit = 1;
-    }
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-    //
-    var leftToFetch = limit;
-
-    if (opts.style) {
-      params.style = opts.style;
-    }
-
-    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
-      params.include_docs = true;
-    }
-
-    if (opts.continuous) {
-      params.feed = 'longpoll';
-    }
-
-    if (opts.conflicts) {
-      params.conflicts = true;
-    }
-
-    if (opts.descending) {
-      params.descending = true;
-    }
-
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-      if (opts.filter === '_view' &&
-          opts.view &&
-          typeof opts.view === 'string') {
-        params.view = opts.view;
-      }
-    }
-
-    // If opts.query_params exists, pass it through to the changes request.
-    // These parameters may be used by the filter on the source database.
-    if (opts.query_params && typeof opts.query_params === 'object') {
-      for (var param_name in opts.query_params) {
-        if (opts.query_params.hasOwnProperty(param_name)) {
-          params[param_name] = opts.query_params[param_name];
-        }
-      }
-    }
-
-    var xhr;
-    var lastFetchedSeq;
-
-    // Get all the changes starting wtih the one immediately after the
-    // sequence number given by since.
-    var fetch = function (since, callback) {
-      if (opts.aborted) {
-        return;
-      }
-      params.since = since;
-      if (opts.descending) {
-        if (limit) {
-          params.limit = leftToFetch;
-        }
-      } else {
-        params.limit = (!limit || leftToFetch > batchSize) ?
-          batchSize : leftToFetch;
-      }
-
-      var paramStr = '?' + Object.keys(params).map(function (k) {
-        return k + '=' + params[k];
-      }).join('&');
-
-      // Set the options for the ajax call
-      var xhrOpts = {
-        headers: host.headers,
-        method: 'GET',
-        url: genDBUrl(host, '_changes' + paramStr),
-        // _changes can take a long time to generate, especially when filtered
-        timeout: opts.timeout
-      };
-      lastFetchedSeq = since;
-
-      if (opts.aborted) {
-        return;
-      }
-
-      // Get the changes
-      xhr = ajax(xhrOpts, callback);
-    };
-
-    // If opts.since exists, get all the changes from the sequence
-    // number given by opts.since. Otherwise, get all the changes
-    // from the sequence number 0.
-    var fetchTimeout = 10;
-    var fetchRetryCount = 0;
-
-    var results = {results: []};
-
-    var fetched = function (err, res) {
-      if (opts.aborted) {
-        return;
-      }
-      var raw_results_length = 0;
-      // If the result of the ajax call (res) contains changes (res.results)
-      if (res && res.results) {
-        raw_results_length = res.results.length;
-        results.last_seq = res.last_seq;
-        // For each change
-        var req = {};
-        req.query = opts.query_params;
-        res.results = res.results.filter(function (c) {
-          leftToFetch--;
-          var ret = utils.filterChange(opts)(c);
-          if (ret) {
-            if (returnDocs) {
-              results.results.push(c);
-            }
-            utils.call(opts.onChange, c);
-          }
-          return ret;
-        });
-      } else if (err) {
-        // In case of an error, stop listening for changes and call
-        // opts.complete
-        opts.aborted = true;
-        utils.call(opts.complete, err);
-        return;
-      }
-
-      // The changes feed may have timed out with no results
-      // if so reuse last update sequence
-      if (res && res.last_seq) {
-        lastFetchedSeq = res.last_seq;
-      }
-
-      var finished = (limit && leftToFetch <= 0) ||
-        (res && raw_results_length < batchSize) ||
-        (opts.descending);
-
-      if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
-        // Increase retry delay exponentially as long as errors persist
-        if (err) {
-          fetchRetryCount += 1;
-        } else {
-          fetchRetryCount = 0;
-        }
-        var timeoutMultiplier = 1 << fetchRetryCount;
-        var retryWait = fetchTimeout * timeoutMultiplier;
-        var maximumWait = opts.maximumWait || 30000;
-
-        if (retryWait > maximumWait) {
-          utils.call(opts.complete, err || errors.UNKNOWN_ERROR);
-          return;
-        }
-
-        // Queue a call to fetch again with the newest sequence number
-        setTimeout(function () { fetch(lastFetchedSeq, fetched); }, retryWait);
-      } else {
-        // We're done, call the callback
-        utils.call(opts.complete, null, results);
-      }
-    };
-
-    fetch(opts.since || 0, fetched);
-
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        opts.aborted = true;
-        if (xhr) {
-          xhr.abort();
-        }
-      }
-    };
-  };
-
-  // Given a set of document/revision IDs (given by req), tets the subset of
-  // those that do NOT correspond to revisions stored in the database.
-  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
-  api.revsDiff = utils.adapterFun('revsDiff', function (req, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-
-    // Get the missing document/revision IDs
-    ajax({
-      headers: host.headers,
-      method: 'POST',
-      url: genDBUrl(host, '_revs_diff'),
-      body: JSON.stringify(req)
-    }, callback);
-  });
-
-  api._close = function (callback) {
-    callback();
-  };
-
-  api.destroy = utils.adapterFun('destroy', function (callback) {
-    ajax({
-      url: genDBUrl(host, ''),
-      method: 'DELETE',
-      headers: host.headers
-    }, function (err, resp) {
-      if (err) {
-        api.emit('error', err);
-        callback(err);
-      } else {
-        api.emit('destroyed');
-        callback(null, resp);
-      }
-    });
-  });
-}
-
-// Delete the HttpPouch specified by the given name.
-HttpPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  var host = getHost(name, opts);
-  opts = opts || {};
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  opts.headers = host.headers;
-  opts.method = 'DELETE';
-  opts.url = genDBUrl(host, '');
-  var ajaxOpts = opts.ajax || {};
-  opts = utils.extend({}, opts, ajaxOpts);
-  utils.ajax(opts, callback);
-});
-
-// HttpPouch is a valid adapter.
-HttpPouch.valid = function () {
-  return true;
-};
-
-module.exports = HttpPouch;
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"../deps/errors":11,"../utils":23,"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28}],3:[function(_dereq_,module,exports){
-(function (process,global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-var vuvuzela = _dereq_('vuvuzela');
-
-var cachedDBs = {};
-var taskQueue = {
-  running: false,
-  queue: []
-};
-
-function tryCode(fun, that, args) {
-  try {
-    fun.apply(that, args);
-  } catch (err) { // shouldn't happen
-    if (window.PouchDBVersion306) {
-      window.PouchDBVersion306.emit('error', err);
-    }
-  }
-}
-
-function applyNext() {
-  if (taskQueue.running || !taskQueue.queue.length) {
-    return;
-  }
-  taskQueue.running = true;
-  var item = taskQueue.queue.shift();
-  item.action(function (err, res) {
-    tryCode(item.callback, this, [err, res]);
-    taskQueue.running = false;
-    process.nextTick(applyNext);
-  });
-}
-
-function idbError(callback) {
-  return function (event) {
-    var message = (event.target && event.target.error &&
-      event.target.error.name) || event.target;
-    callback(errors.error(errors.IDB_ERROR, message, event.type));
-  };
-}
-
-function isModernIdb() {
-  // check for outdated implementations of IDB
-  // that rely on the setVersion method instead of onupgradeneeded (issue #1207)
-
-  // cache based on appVersion, in case the browser is updated
-  var cacheKey = "_pouch__checkModernIdb_" +
-    (global.navigator && global.navigator.appVersion);
-  var cached = utils.hasLocalStorage() && global.localStorage[cacheKey];
-  if (cached) {
-    return JSON.parse(cached);
-  }
-
-  var dbName = '_pouch__checkModernIdb';
-  var result = global.indexedDB.open(dbName, 1).onupgradeneeded === null;
-
-  if (global.indexedDB.deleteDatabase) {
-    global.indexedDB.deleteDatabase(dbName); // db no longer needed
-  }
-  if (utils.hasLocalStorage()) {
-    global.localStorage[cacheKey] = JSON.stringify(result); // cache
-  }
-  return result;
-}
-
-// Unfortunately, the metadata has to be stringified
-// when it is put into the database, because otherwise
-// IndexedDB can throw errors for deeply-nested objects.
-// Originally we just used JSON.parse/JSON.stringify; now
-// we use this custom vuvuzela library that avoids recursion.
-// If we could do it all over again, we'd probably use a
-// format for the revision trees other than JSON.
-function encodeMetadata(metadata, winningRev, deleted) {
-  var storedObject = {data: vuvuzela.stringify(metadata)};
-  storedObject.winningRev = winningRev;
-  storedObject.deletedOrLocal = deleted ? '1' : '0';
-  storedObject.id = metadata.id;
-  return storedObject;
-}
-
-function decodeMetadata(storedObject) {
-  if (!storedObject) {
-    return null;
-  }
-  if (!storedObject.data) {
-    // old format, when we didn't store it stringified
-    return storedObject;
-  }
-  var metadata = vuvuzela.parse(storedObject.data);
-  metadata.winningRev = storedObject.winningRev;
-  metadata.deletedOrLocal = storedObject.deletedOrLocal === '1';
-  return metadata;
-}
-
-function IdbPouch(opts, callback) {
-  var api = this;
-
-  taskQueue.queue.push({
-    action: function (thisCallback) {
-      init(api, opts, thisCallback);
-    },
-    callback: callback
-  });
-  applyNext();
-}
-
-function init(api, opts, callback) {
-
-  // IndexedDB requires a versioned database structure, so we use the
-  // version here to manage migrations.
-  var ADAPTER_VERSION = 3;
-
-  // The object stores created for each database
-  // DOC_STORE stores the document meta data, its revision history and state
-  // Keyed by document id
-  var DOC_STORE = 'document-store';
-  // BY_SEQ_STORE stores a particular version of a document, keyed by its
-  // sequence id
-  var BY_SEQ_STORE = 'by-sequence';
-  // Where we store attachments
-  var ATTACH_STORE = 'attach-store';
-  // Where we store database-wide meta data in a single record
-  // keyed by id: META_STORE
-  var META_STORE = 'meta-store';
-  // Where we store local documents
-  var LOCAL_STORE = 'local-store';
-  // Where we detect blob support
-  var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
-
-  var name = opts.name;
-
-  var blobSupport = null;
-  var instanceId = null;
-  var idStored = false;
-  var idb = null;
-  var docCount = -1;
-
-  function createSchema(db) {
-    db.createObjectStore(DOC_STORE, {keyPath : 'id'})
-      .createIndex('seq', 'seq', {unique: true});
-    db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
-    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
-    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
-  }
-
-  // migration to version 2
-  // unfortunately "deletedOrLocal" is a misnomer now that we no longer
-  // store local docs in the main doc-store, but whaddyagonnado
-  function addDeletedOrLocalIndex(e, callback) {
-    var transaction = e.currentTarget.transaction;
-    var docStore = transaction.objectStore(DOC_STORE);
-    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
-
-    docStore.openCursor().onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var deleted = utils.isDeleted(metadata);
-        metadata.deletedOrLocal = deleted ? "1" : "0";
-        docStore.put(metadata);
-        cursor["continue"]();
-      } else {
-        callback(transaction);
-      }
-    };
-  }
-
-  // migrations to get to version 3
-
-  function createLocalStoreSchema(db) {
-    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-  }
-
-  function migrateLocalStore(e, tx) {
-    tx = tx || e.currentTarget.transaction;
-    var localStore = tx.objectStore(LOCAL_STORE);
-    var docStore = tx.objectStore(DOC_STORE);
-    var seqStore = tx.objectStore(BY_SEQ_STORE);
-
-    var cursor = docStore.openCursor();
-    cursor.onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var docId = metadata.id;
-        var local = utils.isLocalId(docId);
-        var rev = merge.winningRev(metadata);
-        if (local) {
-          var docIdRev = docId + "::" + rev;
-          // remove all seq entries
-          // associated with this docId
-          var start = docId + "::";
-          var end = docId + "::~";
-          var index = seqStore.index('_doc_id_rev');
-          var range = global.IDBKeyRange.bound(start, end, false, false);
-          var seqCursor = index.openCursor(range);
-          seqCursor.onsuccess = function (e) {
-            seqCursor = e.target.result;
-            if (!seqCursor) {
-              // done
-              docStore["delete"](cursor.primaryKey);
-              cursor["continue"]();
-            } else {
-              var data = seqCursor.value;
-              if (data._doc_id_rev === docIdRev) {
-                localStore.put(data);
-              }
-              seqStore["delete"](seqCursor.primaryKey);
-              seqCursor["continue"]();
-            }
-          };
-        } else {
-          cursor["continue"]();
-        }
-      }
-    };
-  }
-
-  api.type = function () {
-    return 'idb';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._bulkDocs = function idb_bulkDocs(req, opts, callback) {
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      if (doc._id && utils.isLocalId(doc._id)) {
-        return doc;
-      }
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var results = new Array(docInfos.length);
-    var fetchedDocs = new utils.Map();
-    var updateSeq = 0;
-    var numDocsWritten = 0;
-
-    function writeMetaData(e) {
-      var meta = e.target.result;
-      meta.updateSeq = (meta.updateSeq || 0) + updateSeq;
-      txn.objectStore(META_STORE).put(meta);
-    }
-
-    function checkDoneWritingDocs() {
-      if (++numDocsWritten === docInfos.length) {
-        txn.objectStore(META_STORE).get(META_STORE).onsuccess = writeMetaData;
-      }
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        return;
-      }
-
-      var idsToDocs = new utils.Map();
-
-      docInfos.forEach(function (currentDoc, resultsIdx) {
-        if (currentDoc._id && utils.isLocalId(currentDoc._id)) {
-          api[currentDoc._deleted ? '_removeLocal' : '_putLocal'](
-              currentDoc, {ctx: txn}, function (err, resp) {
-            if (err) {
-              results[resultsIdx] = err;
-            } else {
-              results[resultsIdx] = {};
-            }
-            checkDoneWritingDocs();
-          });
-          return;
-        }
-
-        var id = currentDoc.metadata.id;
-        if (idsToDocs.has(id)) {
-          idsToDocs.get(id).push([currentDoc, resultsIdx]);
-        } else {
-          idsToDocs.set(id, [[currentDoc, resultsIdx]]);
-        }
-      });
-
-      // in the case of new_edits, the user can provide multiple docs
-      // with the same id. these need to be processed sequentially
-      idsToDocs.forEach(function (docs, id) {
-        var numDone = 0;
-
-        function docWritten() {
-          checkDoneWritingDocs();
-          if (++numDone < docs.length) {
-            nextDoc();
-          }
-        }
-        function nextDoc() {
-          var value = docs[numDone];
-          var currentDoc = value[0];
-          var resultsIdx = value[1];
-
-          if (fetchedDocs.has(id)) {
-            updateDoc(fetchedDocs.get(id), currentDoc, resultsIdx, docWritten);
-          } else {
-            insertDoc(currentDoc, resultsIdx, docWritten);
-          }
-        }
-        nextDoc();
-      });
-    }
-
-    function fetchExistingDocs(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var numFetched = 0;
-
-      function checkDone() {
-        if (++numFetched === docInfos.length) {
-          callback();
-        }
-      }
-
-      docInfos.forEach(function (docInfo) {
-        if (docInfo._id && utils.isLocalId(docInfo._id)) {
-          return checkDone(); // skip local docs
-        }
-        var id = docInfo.metadata.id;
-        var req = txn.objectStore(DOC_STORE).get(id);
-        req.onsuccess = function process_docRead(event) {
-          var metadata = decodeMetadata(event.target.result);
-          if (metadata) {
-            fetchedDocs.set(id, metadata);
-          }
-          checkDone();
-        };
-      });
-    }
-
-    function complete() {
-      var aresults = results.map(function (result) {
-        if (result._bulk_seq) {
-          delete result._bulk_seq;
-        } else if (!Object.keys(result).length) {
-          return {
-            ok: true
-          };
-        }
-        if (result.error) {
-          return result;
-        }
-
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        return {
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        };
-      });
-      IdbPouch.Changes.notify(name);
-      docCount = -1; // invalidate
-      callback(null, aresults);
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        var data;
-        try {
-          data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        if (blobSupport) {
-          var type = att.content_type;
-          data = utils.fixBinary(data);
-          att.data = utils.createBlob([data], {type: type});
-        }
-        utils.MD5(data).then(function (result) {
-          att.digest = 'md5-' + result;
-          finish();
-        });
-        return;
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        var binary = utils.arrayBufferToBinaryString(this.result || '');
-        if (!blobSupport) {
-          att.data = btoa(binary);
-        }
-        utils.MD5(binary).then(function (result) {
-          att.digest = 'md5-' + result;
-          finish();
-        });
-      };
-      reader.readAsArrayBuffer(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        var recv = 0;
-        function attachmentProcessed() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key],
-                                 attachmentProcessed);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, winningRev, deleted, callback, resultsIdx) {
-      var err = null;
-      var recv = 0;
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      if (deleted) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      function finish() {
-        updateSeq++;
-        docInfo.data._doc_id_rev = docInfo.data._id + "::" + docInfo.data._rev;
-        var seqStore = txn.objectStore(BY_SEQ_STORE);
-        var index = seqStore.index('_doc_id_rev');
-
-        function afterPut(e) {
-          var metadata = docInfo.metadata;
-          metadata.seq = e.target.result;
-          // Current _rev is calculated from _rev_tree on read
-          delete metadata.rev;
-          var metadataToStore = encodeMetadata(metadata, winningRev, deleted);
-          var metaDataReq = txn.objectStore(DOC_STORE).put(metadataToStore);
-          metaDataReq.onsuccess = function () {
-            delete metadata.deletedOrLocal;
-            delete metadata.winningRev;
-            results[resultsIdx] = docInfo;
-            fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
-            utils.call(callback);
-          };
-        }
-
-        var putReq = seqStore.put(docInfo.data);
-
-        putReq.onsuccess = afterPut;
-        putReq.onerror = function (e) {
-          // ConstraintError, need to update, not put (see #1638 for details)
-          e.preventDefault(); // avoid transaction abort
-          e.stopPropagation(); // avoid transaction onerror
-          var getKeyReq = index.getKey(docInfo.data._doc_id_rev);
-          getKeyReq.onsuccess = function (e) {
-            var putReq = seqStore.put(docInfo.data, e.target.result);
-            updateSeq--; // discount, since it's an update, not a new seq
-            putReq.onsuccess = afterPut;
-          };
-        };
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo, resultsIdx, callback) {
-      var merged =
-        merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var wasPreviouslyDeleted = utils.isDeleted(oldDoc);
-      var deleted = utils.isDeleted(docInfo.metadata);
-      var inConflict = (wasPreviouslyDeleted && deleted && newEdits) ||
-        (!wasPreviouslyDeleted && newEdits && merged.conflicts !== 'new_leaf');
-
-      if (inConflict) {
-        results[resultsIdx] = makeErr(errors.REV_CONFLICT, docInfo._bulk_seq);
-        return callback();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-
-      // recalculate
-      var winningRev = merge.winningRev(docInfo.metadata);
-      deleted = utils.isDeleted(docInfo.metadata, winningRev);
-
-      writeDoc(docInfo, winningRev, deleted, callback, resultsIdx);
-    }
-
-    function insertDoc(docInfo, resultsIdx, callback) {
-      var winningRev = merge.winningRev(docInfo.metadata);
-      var deleted = utils.isDeleted(docInfo.metadata, winningRev);
-      // Cant insert new deleted documents
-      if ('was_delete' in opts && deleted) {
-        results[resultsIdx] = errors.MISSING_DOC;
-        return callback();
-      }
-
-      writeDoc(docInfo, winningRev, deleted, callback, resultsIdx);
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var objectStore = txn.objectStore(ATTACH_STORE);
-      objectStore.get(digest).onsuccess = function (e) {
-        var originalRefs = e.target.result && e.target.result.refs || {};
-        var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-        var newAtt = {
-          digest: digest,
-          body: data,
-          refs: originalRefs
-        };
-        newAtt.refs[ref] = true;
-        objectStore.put(newAtt).onsuccess = function (e) {
-          utils.call(callback);
-        };
-      };
-    }
-
-    var txn;
-    preprocessAttachments(function () {
-      var stores = [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE,
-        LOCAL_STORE];
-      txn = idb.transaction(stores, 'readwrite');
-      txn.onerror = idbError(callback);
-      txn.ontimeout = idbError(callback);
-      txn.oncomplete = complete;
-
-      fetchExistingDocs(processDocs);
-    });
-  };
-
-  // First we look up the metadata in the ids database, then we fetch the
-  // current revision(s) from the by sequence store
-  api._get = function idb_get(id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    var txn;
-    opts = utils.clone(opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn =
-        idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: txn});
-    }
-
-    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
-      metadata = decodeMetadata(e.target.result);
-      // we can determine the result here if:
-      // 1. there is no such document
-      // 2. the document is deleted and we don't ask about specific rev
-      // When we ask with opts.rev we expect the answer to be either
-      // doc (possibly with _deleted=true) or missing error
-      if (!metadata) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      if (utils.isDeleted(metadata) && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, "deleted");
-        return finish();
-      }
-      var objectStore = txn.objectStore(BY_SEQ_STORE);
-
-      // metadata.winningRev was added later, so older DBs might not have it
-      var rev = opts.rev || metadata.winningRev || merge.winningRev(metadata);
-      var key = metadata.id + '::' + rev;
-
-      objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
-        doc = e.target.result;
-        if (doc && doc._doc_id_rev) {
-          delete(doc._doc_id_rev);
-        }
-        if (!doc) {
-          err = errors.MISSING_DOC;
-          return finish();
-        }
-        finish();
-      };
-    };
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var txn;
-    opts = utils.clone(opts);
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      txn =
-        idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-    }
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-
-    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
-      var data = e.target.result.body;
-      if (opts.encode) {
-        if (!data) {
-          callback(null, '');
-        } else if (typeof data !== 'string') { // we have blob support
-          var reader = new FileReader();
-          reader.onloadend = function (e) {
-            var binary = utils.arrayBufferToBinaryString(this.result || '');
-            callback(null, btoa(binary));
-          };
-          reader.readAsArrayBuffer(data);
-        } else { // no blob support
-          callback(null, data);
-        }
-      } else {
-        if (!data) {
-          callback(null, utils.createBlob([''], {type: type}));
-        } else if (typeof data !== 'string') { // we have blob support
-          callback(null, data);
-        } else { // no blob support
-          data = utils.fixBinary(atob(data));
-          callback(null, utils.createBlob([data], {type: type}));
-        }
-      }
-    };
-  };
-
-  function allDocsQuery(totalRows, opts, callback) {
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-    var skip = opts.skip || 0;
-    var limit = typeof opts.limit === 'number' ? opts.limit : -1;
-    var inclusiveEnd = opts.inclusive_end !== false;
-    var descending = 'descending' in opts && opts.descending ? 'prev' : null;
-
-    var manualDescEnd = false;
-    if (descending && start && end) {
-      // unfortunately IDB has a quirk where IDBKeyRange.bound is invalid if the
-      // start is less than the end, even in descending mode.  Best bet
-      // is just to handle it manually in that case.
-      manualDescEnd = end;
-      end = false;
-    }
-
-    var keyRange = null;
-    try {
-      if (start && end) {
-        keyRange = global.IDBKeyRange.bound(start, end, false, !inclusiveEnd);
-      } else if (start) {
-        if (descending) {
-          keyRange = global.IDBKeyRange.upperBound(start);
-        } else {
-          keyRange = global.IDBKeyRange.lowerBound(start);
-        }
-      } else if (end) {
-        if (descending) {
-          keyRange = global.IDBKeyRange.lowerBound(end, !inclusiveEnd);
-        } else {
-          keyRange = global.IDBKeyRange.upperBound(end, !inclusiveEnd);
-        }
-      } else if (key) {
-        keyRange = global.IDBKeyRange.only(key);
-      }
-    } catch (e) {
-      if (e.name === "DataError" && e.code === 0) {
-        // data error, start is less than end
-        return callback(null, {
-          total_rows : totalRows,
-          offset : opts.skip,
-          rows : []
-        });
-      } else {
-        return callback(errors.error(errors.IDB_ERROR, e.name, e.message));
-      }
-    }
-
-    var transaction = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readonly');
-    transaction.oncomplete = function () {
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    };
-
-    var oStore = transaction.objectStore(DOC_STORE);
-    var oCursor = descending ? oStore.openCursor(keyRange, descending)
-      : oStore.openCursor(keyRange);
-    var results = [];
-    oCursor.onsuccess = function (e) {
-      if (!e.target.result) {
-        return;
-      }
-      var cursor = e.target.result;
-      var metadata = decodeMetadata(cursor.value);
-      // metadata.winningRev added later, some dbs might be missing it
-      var winningRev = metadata.winningRev || merge.winningRev(metadata);
-
-      function allDocsInner(metadata, data) {
-        var doc = {
-          id: metadata.id,
-          key: metadata.id,
-          value: {
-            rev: winningRev
-          }
-        };
-        if (opts.include_docs) {
-          doc.doc = data;
-          doc.doc._rev = winningRev;
-          if (doc.doc._doc_id_rev) {
-            delete(doc.doc._doc_id_rev);
-          }
-          if (opts.conflicts) {
-            doc.doc._conflicts = merge.collectConflicts(metadata);
-          }
-          for (var att in doc.doc._attachments) {
-            if (doc.doc._attachments.hasOwnProperty(att)) {
-              doc.doc._attachments[att].stub = true;
-            }
-          }
-        }
-        var deleted = utils.isDeleted(metadata, winningRev);
-        if (opts.deleted === 'ok') {
-          // deleted docs are okay with keys_requests
-          if (deleted) {
-            doc.value.deleted = true;
-            doc.doc = null;
-          }
-          results.push(doc);
-        } else if (!deleted && skip-- <= 0) {
-          if (manualDescEnd) {
-            if (inclusiveEnd && doc.key < manualDescEnd) {
-              return;
-            } else if (!inclusiveEnd && doc.key <= manualDescEnd) {
-              return;
-            }
-          }
-          results.push(doc);
-          if (--limit === 0) {
-            return;
-          }
-        }
-        cursor["continue"]();
-      }
-
-      if (!opts.include_docs) {
-        allDocsInner(metadata);
-      } else {
-        var index = transaction.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = metadata.id + "::" + winningRev;
-        index.get(key).onsuccess = function (event) {
-          allDocsInner(decodeMetadata(cursor.value), event.target.result);
-        };
-      }
-    };
-  }
-
-  function countDocs(callback) {
-    if (docCount !== -1) {
-      return callback(null, docCount);
-    }
-
-    var count;
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
-    index.count(global.IDBKeyRange.only("0")).onsuccess = function (e) {
-      count = e.target.result;
-    };
-    txn.onerror = idbError(callback);
-    txn.oncomplete = function () {
-      docCount = count;
-      callback(null, docCount);
-    };
-  }
-
-  api._allDocs = function idb_allDocs(opts, callback) {
-
-    // first count the total_rows
-    countDocs(function (err, totalRows) {
-      if (err) {
-        return callback(err);
-      }
-      if (opts.limit === 0) {
-        return callback(null, {
-          total_rows : totalRows,
-          offset : opts.skip,
-          rows : []
-        });
-      }
-      allDocsQuery(totalRows, opts, callback);
-    });
-  };
-
-  api._info = function idb_info(callback) {
-
-    countDocs(function (err, count) {
-      if (err) {
-        return callback(err);
-      }
-      if (idb === null) {
-        var error = new Error('db isn\'t open');
-        error.id = 'idbNull';
-        return callback(error);
-      }
-      var updateSeq = 0;
-      var txn = idb.transaction([META_STORE], 'readonly');
-
-      txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
-        updateSeq = e.target.result && e.target.result.updateSeq || 0;
-      };
-
-      txn.oncomplete = function () {
-        callback(null, {
-          doc_count: count,
-          update_seq: updateSeq
-        });
-      };
-    });
-  };
-
-  api._changes = function (opts) {
-    opts = utils.clone(opts);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      IdbPouch.Changes.addListener(name, id, api, opts);
-      IdbPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          IdbPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending ? 'prev' : null;
-    var lastSeq = 0;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var limit = 'limit' in opts ? opts.limit : -1;
-    if (limit === 0) {
-      limit = 1; // per CouchDB _changes spec
-    }
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-
-    var results = [];
-    var numResults = 0;
-    var filter = utils.filterChange(opts);
-
-    var txn;
-
-    function fetchChanges() {
-      txn = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readonly');
-      txn.oncomplete = onTxnComplete;
-
-      var req;
-
-      if (descending) {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true),
-                        descending);
-      } else {
-        req = txn.objectStore(BY_SEQ_STORE)
-            .openCursor(global.IDBKeyRange.lowerBound(opts.since, true));
-      }
-
-      req.onsuccess = onsuccess;
-      req.onerror = onerror;
-    }
-
-    fetchChanges();
-
-    function onsuccess(event) {
-      var cursor = event.target.result;
-
-      if (!cursor) {
-        return;
-      }
-
-      var doc = cursor.value;
-
-      if (opts.doc_ids && opts.doc_ids.indexOf(doc._id) === -1) {
-        return cursor["continue"]();
-      }
-
-      var index = txn.objectStore(DOC_STORE);
-      index.get(doc._id).onsuccess = function (event) {
-        var metadata = decodeMetadata(event.target.result);
-
-        if (lastSeq < metadata.seq) {
-          lastSeq = metadata.seq;
-        }
-        // metadata.winningRev was only added later
-        var winningRev = metadata.winningRev || merge.winningRev(metadata);
-        if (doc._rev !== winningRev) {
-          return cursor["continue"]();
-        }
-
-        delete doc['_doc_id_rev'];
-
-        var change = opts.processChange(doc, metadata, opts);
-        change.seq = cursor.key;
-        if (filter(change)) {
-          numResults++;
-          if (returnDocs) {
-            results.push(change);
-          }
-          opts.onChange(change);
-        }
-        if (numResults !== limit) {
-          cursor["continue"]();
-        }
-      };
-    }
-
-    function onTxnComplete() {
-      if (!opts.continuous) {
-        opts.complete(null, {
-          results: results,
-          last_seq: lastSeq
-        });
-      }
-    }
-  };
-
-  api._close = function (callback) {
-    if (idb === null) {
-      return callback(errors.NOT_OPEN);
-    }
-
-    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
-    // "Returns immediately and closes the connection in a separate thread..."
-    idb.close();
-    delete cachedDBs[name];
-    idb = null;
-    callback();
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    var txn = idb.transaction([DOC_STORE], 'readonly');
-    var req = txn.objectStore(DOC_STORE).get(docId);
-    req.onsuccess = function (event) {
-      var doc = decodeMetadata(event.target.result);
-      if (!doc) {
-        callback(errors.MISSING_DOC);
-      } else {
-        callback(null, doc.rev_tree);
-      }
-    };
-  };
-
-  // This function removes revisions of document docId
-  // which are listed in revs and sets this document
-  // revision to to rev_tree
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    var txn = idb.transaction([DOC_STORE, BY_SEQ_STORE], 'readwrite');
-
-    var index = txn.objectStore(DOC_STORE);
-    index.get(docId).onsuccess = function (event) {
-      var metadata = decodeMetadata(event.target.result);
-      metadata.rev_tree = rev_tree;
-
-      var count = revs.length;
-      revs.forEach(function (rev) {
-        var index = txn.objectStore(BY_SEQ_STORE).index('_doc_id_rev');
-        var key = docId + "::" + rev;
-        index.getKey(key).onsuccess = function (e) {
-          var seq = e.target.result;
-          if (!seq) {
-            return;
-          }
-          txn.objectStore(BY_SEQ_STORE)["delete"](seq);
-
-          count--;
-          if (!count) {
-            // winningRev is not guaranteed to be there, since it's
-            // not formally migrated. deletedOrLocal is a
-            // now-unfortunate name that really just means "deleted"
-            var winningRev = metadata.winningRev ||
-              merge.winningRev(metadata);
-            var deleted = metadata.deletedOrLocal;
-            txn.objectStore(DOC_STORE).put(
-              encodeMetadata(metadata, winningRev, deleted));
-          }
-        };
-      });
-    };
-    txn.oncomplete = function () {
-      utils.call(callback);
-    };
-  };
-
-
-  api._getLocal = function (id, callback) {
-    var tx = idb.transaction([LOCAL_STORE], 'readonly');
-    var req = tx.objectStore(LOCAL_STORE).get(id);
-
-    req.onerror = idbError(callback);
-    req.onsuccess = function (e) {
-      var doc = e.target.result;
-      if (!doc) {
-        callback(errors.MISSING_DOC);
-      } else {
-        delete doc['_doc_id_rev'];
-        callback(null, doc);
-      }
-    };
-  };
-
-  api._putLocal = function (doc, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    delete doc._revisions; // ignore this, trust the rev
-    var oldRev = doc._rev;
-    var id = doc._id;
-    if (!oldRev) {
-      doc._rev = '0-1';
-    } else {
-      doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
-    }
-    doc._doc_id_rev = id + '::' + doc._rev;
-
-    var tx = opts.ctx;
-    var ret;
-    if (!tx) {
-      tx = idb.transaction([LOCAL_STORE], 'readwrite');
-      tx.onerror = idbError(callback);
-      tx.oncomplete = function () {
-        if (ret) {
-          callback(null, ret);
-        }
-      };
-    }
-
-    var oStore = tx.objectStore(LOCAL_STORE);
-    var req;
-    if (oldRev) {
-      var index = oStore.index('_doc_id_rev');
-      var docIdRev = id + '::' + oldRev;
-      req = index.get(docIdRev);
-      req.onsuccess = function (e) {
-        if (!e.target.result) {
-          callback(errors.REV_CONFLICT);
-        } else { // update
-          var req = oStore.put(doc);
-          req.onsuccess = function () {
-            ret = {ok: true, id: doc._id, rev: doc._rev};
-            if (opts.ctx) { // retuthis.immediately
-              callback(null, ret);
-            }
-          };
-        }
-      };
-    } else { // new doc
-      req = oStore.get(id);
-      req.onsuccess = function (e) {
-        if (e.target.result) { // already exists
-          callback(errors.REV_CONFLICT);
-        } else { // insert
-          var req = oStore.put(doc);
-          req.onsuccess = function () {
-            ret = {ok: true, id: doc._id, rev: doc._rev};
-            if (opts.ctx) { // return immediately
-              callback(null, ret);
-            }
-          };
-        }
-      };
-    }
-  };
-
-  api._removeLocal = function (doc, callback) {
-    var tx = idb.transaction([LOCAL_STORE], 'readwrite');
-    var ret;
-    tx.oncomplete = function () {
-      if (ret) {
-        callback(null, ret);
-      }
-    };
-    var docIdRev = doc._id + '::' + doc._rev;
-    var oStore = tx.objectStore(LOCAL_STORE);
-    var index = oStore.index('_doc_id_rev');
-    var req = index.get(docIdRev);
-
-    req.onerror = idbError(callback);
-    req.onsuccess = function (e) {
-      var doc = e.target.result;
-      if (!doc) {
-        callback(errors.MISSING_DOC);
-      } else {
-        var req = index.getKey(docIdRev);
-        req.onsuccess = function (e) {
-          var key = e.target.result;
-          oStore["delete"](key);
-          ret = {ok: true, id: doc._id, rev: '0-0'};
-        };
-      }
-    };
-  };
-
-  var cached = cachedDBs[name];
-
-  if (cached) {
-    idb = cached.idb;
-    blobSupport = cached.blobSupport;
-    instanceId = cached.instanceId;
-    idStored = cached.idStored;
-    process.nextTick(function () {
-      callback(null, api);
-    });
-    return;
-  }
-
-  var req = global.indexedDB.open(name, ADAPTER_VERSION);
-
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.openReqList[name] = req;
-
-  req.onupgradeneeded = function (e) {
-    var db = e.target.result;
-    if (e.oldVersion < 1) {
-      // initial schema
-      createSchema(db);
-    }
-    if (e.oldVersion < 3) {
-      createLocalStoreSchema(db);
-      if (e.oldVersion < 2) {
-        // version 2 adds the deletedOrLocal index
-        addDeletedOrLocalIndex(e, function (transaction) {
-          migrateLocalStore(e, transaction);
-        });
-      } else {
-        migrateLocalStore(e);
-      }
-    }
-  };
-
-  req.onsuccess = function (e) {
-
-    idb = e.target.result;
-
-    idb.onversionchange = function () {
-      idb.close();
-      delete cachedDBs[name];
-    };
-    idb.onabort = function () {
-      idb.close();
-      delete cachedDBs[name];
-    };
-
-    var txn = idb.transaction([META_STORE, DETECT_BLOB_SUPPORT_STORE],
-      'readwrite');
-
-    var req = txn.objectStore(META_STORE).get(META_STORE);
-
-    req.onsuccess = function (e) {
-
-      var checkSetupComplete = function () {
-        if (blobSupport === null || !idStored) {
-          return;
-        } else {
-          cachedDBs[name] = {
-            idb: idb,
-            blobSupport: blobSupport,
-            instanceId: instanceId,
-            idStored: idStored,
-            loaded: true
-          };
-          callback(null, api);
-        }
-      };
-
-      var meta = e.target.result || {id: META_STORE};
-      if (name  + '_id' in meta) {
-        instanceId = meta[name + '_id'];
-        idStored = true;
-        checkSetupComplete();
-      } else {
-        instanceId = utils.uuid();
-        meta[name + '_id'] = instanceId;
-        txn.objectStore(META_STORE).put(meta).onsuccess = function () {
-          idStored = true;
-          checkSetupComplete();
-        };
-      }
-
-      // Detect blob support. Chrome didn't support it until version 38.
-      // in version 37 they had a broken version where PNGs (and possibly
-      // other binary types) aren't stored correctly.
-      try {
-        var blob = utils.createBlob([''], {type: 'image/png'});
-        txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');
-        txn.oncomplete = function () {
-          // have to do it in a separate transaction, else the correct
-          // content type is always returned
-          txn = idb.transaction([META_STORE, DETECT_BLOB_SUPPORT_STORE],
-            'readwrite');
-          var getBlobReq = txn.objectStore(
-            DETECT_BLOB_SUPPORT_STORE).get('key');
-          getBlobReq.onsuccess = function (e) {
-            var storedBlob = e.target.result;
-            var url = URL.createObjectURL(storedBlob);
-            utils.ajax({
-              url: url,
-              cache: true,
-              binary: true
-            }, function (err, res) {
-              if (err && err.status === 405) {
-                // firefox won't let us do that. but firefox doesn't
-                // have the blob type bug that Chrome does, so that's ok
-                blobSupport = true;
-              } else {
-                blobSupport = !!(res && res.type === 'image/png');
-              }
-              checkSetupComplete();
-            });
-          };
-        };
-      } catch (err) {
-        blobSupport = false;
-        checkSetupComplete();
-      }
-    };
-  };
-
-  req.onerror = idbError(callback);
-
-}
-
-IdbPouch.valid = function () {
-  // Issue #2533, we finally gave up on doing bug
-  // detection instead of browser sniffing. Safari brought us
-  // to our knees.
-  var isSafari = typeof openDatabase !== 'undefined' &&
-    /Safari/.test(navigator.userAgent) &&
-    !/Chrome/.test(navigator.userAgent);
-  return !isSafari && global.indexedDB && isModernIdb();
-};
-
-function destroy(name, opts, callback) {
-  if (!('openReqList' in IdbPouch)) {
-    IdbPouch.openReqList = {};
-  }
-  IdbPouch.Changes.removeAllListeners(name);
-
-  //Close open request for "name" database to fix ie delay.
-  if (IdbPouch.openReqList[name] && IdbPouch.openReqList[name].result) {
-    IdbPouch.openReqList[name].result.close();
-  }
-  var req = global.indexedDB.deleteDatabase(name);
-
-  req.onsuccess = function () {
-    //Remove open request from the list.
-    if (IdbPouch.openReqList[name]) {
-      IdbPouch.openReqList[name] = null;
-    }
-    if (utils.hasLocalStorage() && (name in global.localStorage)) {
-      delete global.localStorage[name];
-    }
-    delete cachedDBs[name];
-    callback(null, { 'ok': true });
-  };
-
-  req.onerror = idbError(callback);
-}
-
-IdbPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  taskQueue.queue.push({
-    action: function (thisCallback) {
-      destroy(name, opts, thisCallback);
-    },
-    callback: callback
-  });
-  applyNext();
-});
-
-IdbPouch.Changes = new utils.Changes();
-
-module.exports = IdbPouch;
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":11,"../merge":18,"../utils":23,"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"vuvuzela":58}],4:[function(_dereq_,module,exports){
-module.exports = ['idb', 'websql'];
-},{}],5:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-var utils = _dereq_('../utils');
-var merge = _dereq_('../merge');
-var errors = _dereq_('../deps/errors');
-var vuvuzela = _dereq_('vuvuzela');
-function quote(str) {
-  return "'" + str + "'";
-}
-
-var cachedDatabases = {};
-
-var openDB = utils.getArguments(function (args) {
-  if (typeof global !== 'undefined') {
-    if (global.navigator && global.navigator.sqlitePlugin &&
-        global.navigator.sqlitePlugin.openDatabase) {
-      return navigator.sqlitePlugin.openDatabase
-        .apply(navigator.sqlitePlugin, args);
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return global.sqlitePlugin.openDatabase
-        .apply(global.sqlitePlugin, args);
-    } else {
-      var db = cachedDatabases[args[0]];
-      if (!db) {
-        db = cachedDatabases[args[0]] =
-          global.openDatabase.apply(global, args);
-      }
-      return db;
-    }
-  }
-});
-
-var POUCH_VERSION = 1;
-var ADAPTER_VERSION = 4; // used to manage migrations
-
-// The object stores created for each database
-// DOC_STORE stores the document meta data, its revision history and state
-var DOC_STORE = quote('document-store');
-// BY_SEQ_STORE stores a particular version of a document, keyed by its
-// sequence id
-var BY_SEQ_STORE = quote('by-sequence');
-// Where we store attachments
-var ATTACH_STORE = quote('attach-store');
-var LOCAL_STORE = quote('local-store');
-var META_STORE = quote('metadata-store');
-
-// these indexes cover the ground for most allDocs queries
-var BY_SEQ_STORE_DELETED_INDEX_SQL =
-  'CREATE INDEX IF NOT EXISTS \'by-seq-deleted-idx\' ON ' +
-  BY_SEQ_STORE + ' (seq, deleted)';
-var BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL =
-  'CREATE UNIQUE INDEX IF NOT EXISTS \'by-seq-doc-id-rev\' ON ' +
-    BY_SEQ_STORE + ' (doc_id, rev)';
-var DOC_STORE_WINNINGSEQ_INDEX_SQL =
-  'CREATE INDEX IF NOT EXISTS \'doc-winningseq-idx\' ON ' +
-  DOC_STORE + ' (winningseq)';
-
-var DOC_STORE_AND_BY_SEQ_JOINER = BY_SEQ_STORE +
-  '.seq = ' + DOC_STORE + '.winningseq';
-
-var SELECT_DOCS = BY_SEQ_STORE + '.seq AS seq, ' +
-  BY_SEQ_STORE + '.deleted AS deleted, ' +
-  BY_SEQ_STORE + '.json AS data, ' +
-  BY_SEQ_STORE + '.rev AS rev, ' +
-  DOC_STORE + '.json AS metadata';
-
-function select(selector, table, joiner, where, orderBy) {
-  return 'SELECT ' + selector + ' FROM ' +
-    (typeof table === 'string' ? table : table.join(' JOIN ')) +
-    (joiner ? (' ON ' + joiner) : '') +
-    (where ? (' WHERE ' +
-      (typeof where === 'string' ? where : where.join(' AND '))) : '') +
-    (orderBy ? (' ORDER BY ' + orderBy) : '');
-}
-
-function unknownError(callback) {
-  return function (event) {
-    // event may actually be a SQLError object, so report is as such
-    var errorNameMatch = event && event.constructor.toString()
-      .match(/function ([^\(]+)/);
-    var errorName = (errorNameMatch && errorNameMatch[1]) || event.type;
-    var errorReason = event.target || event.message;
-    callback(errors.error(errors.WSQ_ERROR, errorReason, errorName));
-  };
-}
-function decodeUtf8(str) {
-  return decodeURIComponent(window.escape(str));
-}
-function parseHexString(str, encoding) {
-  var result = '';
-  var charWidth = encoding === 'UTF-8' ? 2 : 4;
-  for (var i = 0, len = str.length; i < len; i += charWidth) {
-    var substring = str.substring(i, i + charWidth);
-    if (charWidth === 4) { // UTF-16, twiddle the bits
-      substring = substring.substring(2, 4) + substring.substring(0, 2);
-    }
-    result += String.fromCharCode(parseInt(substring, 16));
-  }
-  result = encoding === 'UTF-8' ? decodeUtf8(result) : result;
-  return result;
-}
-
-function stringifyDoc(doc) {
-  // don't bother storing the id/rev. it uses lots of space,
-  // in persistent map/reduce especially
-  delete doc._id;
-  delete doc._rev;
-  return JSON.stringify(doc);
-}
-
-function unstringifyDoc(doc, id, rev) {
-  doc = JSON.parse(doc);
-  doc._id = id;
-  doc._rev = rev;
-  return doc;
-}
-
-function getSize(opts) {
-  if ('size' in opts) {
-    // triggers immediate popup in iOS, fixes #2347
-    // e.g. 5000001 asks for 5 MB, 10000001 asks for 10 MB,
-    return opts.size * 1000000;
-  }
-  // In iOS, doesn't matter as long as it's <= 5000000.
-  // Except that if you request too much, our tests fail
-  // because of the native "do you accept?" popup.
-  // In Android <=4.3, this value is actually used as an
-  // honest-to-god ceiling for data, so we need to
-  // set it to a decently high number.
-  var isAndroid = /Android/.test(window.navigator.userAgent);
-  return isAndroid ? 5000000 : 1;
-}
-
-function WebSqlPouch(opts, callback) {
-  var api = this;
-  var instanceId = null;
-  var name = opts.name;
-  var size = getSize(opts);
-  var idRequests = [];
-  var docCount = -1; // cache sqlite count(*) for performance
-  var encoding;
-
-  var db = openDB(name, POUCH_VERSION, name, size);
-  if (!db) {
-    return callback(errors.UNKNOWN_ERROR);
-  } else if (typeof db.readTransaction !== 'function') {
-    // doesn't exist in sqlite plugin
-    db.readTransaction = db.transaction;
-  }
-
-  function dbCreated() {
-    // note the db name in case the browser upgrades to idb
-    if (utils.hasLocalStorage()) {
-      global.localStorage['_pouch__websqldb_' + name] = true;
-    }
-    callback(null, api);
-  }
-
-  // In this migration, we added the 'deleted' and 'local' columns to the
-  // by-seq and doc store tables.
-  // To preserve existing user data, we re-process all the existing JSON
-  // and add these values.
-  // Called migration2 because it corresponds to adapter version (db_version) #2
-  function runMigration2(tx, callback) {
-    // index used for the join in the allDocs query
-    tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
-
-    tx.executeSql('ALTER TABLE ' + BY_SEQ_STORE +
-      ' ADD COLUMN deleted TINYINT(1) DEFAULT 0', [], function () {
-      tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-      tx.executeSql('ALTER TABLE ' + DOC_STORE +
-        ' ADD COLUMN local TINYINT(1) DEFAULT 0', [], function () {
-        tx.executeSql('CREATE INDEX IF NOT EXISTS \'doc-store-local-idx\' ON ' +
-          DOC_STORE + ' (local, id)');
-
-        var sql = 'SELECT ' + DOC_STORE + '.winningseq AS seq, ' + DOC_STORE +
-          '.json AS metadata FROM ' + BY_SEQ_STORE + ' JOIN ' + DOC_STORE +
-          ' ON ' + BY_SEQ_STORE + '.seq = ' + DOC_STORE + '.winningseq';
-
-        tx.executeSql(sql, [], function (tx, result) {
-
-          var deleted = [];
-          var local = [];
-
-          for (var i = 0; i < result.rows.length; i++) {
-            var item = result.rows.item(i);
-            var seq = item.seq;
-            var metadata = JSON.parse(item.metadata);
-            if (utils.isDeleted(metadata)) {
-              deleted.push(seq);
-            }
-            if (utils.isLocalId(metadata.id)) {
-              local.push(metadata.id);
-            }
-          }
-          tx.executeSql('UPDATE ' + DOC_STORE + 'SET local = 1 WHERE id IN (' +
-            local.map(function () {
-            return '?';
-          }).join(',') + ')', local, function () {
-            tx.executeSql('UPDATE ' + BY_SEQ_STORE +
-              ' SET deleted = 1 WHERE seq IN (' + deleted.map(function () {
-              return '?';
-            }).join(',') + ')', deleted, callback);
-          });
-        });
-      });
-    });
-  }
-
-  // in this migration, we make all the local docs unversioned
-  function runMigration3(tx, callback) {
-    var local = 'CREATE TABLE IF NOT EXISTS ' + LOCAL_STORE +
-      ' (id UNIQUE, rev, json)';
-    tx.executeSql(local, [], function () {
-      var sql = 'SELECT ' + DOC_STORE + '.id AS id, ' +
-        BY_SEQ_STORE + '.json AS data ' +
-        'FROM ' + BY_SEQ_STORE + ' JOIN ' +
-        DOC_STORE + ' ON ' + BY_SEQ_STORE + '.seq = ' +
-        DOC_STORE + '.winningseq WHERE local = 1';
-      tx.executeSql(sql, [], function (tx, res) {
-        var rows = [];
-        for (var i = 0; i < res.rows.length; i++) {
-          rows.push(res.rows.item(i));
-        }
-        function doNext() {
-          if (!rows.length) {
-            return callback();
-          }
-          var row = rows.shift();
-          var rev = JSON.parse(row.data)._rev;
-          tx.executeSql('INSERT INTO ' + LOCAL_STORE +
-              ' (id, rev, json) VALUES (?,?,?)',
-              [row.id, rev, row.data], function (tx) {
-            tx.executeSql('DELETE FROM ' + DOC_STORE + ' WHERE id=?',
-                [row.id], function (tx) {
-              tx.executeSql('DELETE FROM ' + BY_SEQ_STORE + ' WHERE seq=?',
-                  [row.seq], function () {
-                doNext();
-              });
-            });
-          });
-        }
-        doNext();
-      });
-    });
-  }
-
-  // in this migration, we remove doc_id_rev and just use rev
-  function runMigration4(tx, callback) {
-
-    function updateRows(rows, encoding) {
-      function doNext() {
-        if (!rows.length) {
-          return callback();
-        }
-        var row = rows.shift();
-        var doc_id_rev = parseHexString(row.hex, encoding);
-        var idx = doc_id_rev.lastIndexOf('::');
-        var doc_id = doc_id_rev.substring(0, idx);
-        var rev = doc_id_rev.substring(idx + 2);
-        var sql = 'UPDATE ' + BY_SEQ_STORE +
-          ' SET doc_id=?, rev=? WHERE doc_id_rev=?';
-        tx.executeSql(sql, [doc_id, rev, doc_id_rev], function () {
-          doNext();
-        });
-      }
-      doNext();
-    }
-
-    var sql = 'ALTER TABLE ' + BY_SEQ_STORE + ' ADD COLUMN doc_id';
-    tx.executeSql(sql, [], function (tx) {
-      var sql = 'ALTER TABLE ' + BY_SEQ_STORE + ' ADD COLUMN rev';
-      tx.executeSql(sql, [], function (tx) {
-        tx.executeSql(BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL, [], function (tx) {
-          var sql = 'SELECT hex(doc_id_rev) as hex FROM ' + BY_SEQ_STORE;
-          tx.executeSql(sql, [], function (tx, res) {
-            var rows = [];
-            for (var i = 0; i < res.rows.length; i++) {
-              rows.push(res.rows.item(i));
-            }
-            // it sucks, but we fetch the encoding twice
-            tx.executeSql(
-                'SELECT dbid, hex(dbid) AS hexId FROM ' + META_STORE, [],
-              function (tx, result) {
-                var id = result.rows.item(0).dbid;
-                var hexId = result.rows.item(0).hexId;
-                var encoding = (hexId.length === id.length * 2) ?
-                  'UTF-8' : 'UTF-16';
-                updateRows(rows, encoding);
-              }
-            );
-          });
-        });
-      });
-    });
-  }
-
-  function onGetInstanceId(tx) {
-    while (idRequests.length > 0) {
-      var idCallback = idRequests.pop();
-      idCallback(null, instanceId);
-    }
-    checkDbEncoding(tx);
-  }
-
-  function checkDbEncoding(tx) {
-    // check db encoding - utf-8 (chrome, opera) or utf-16 (safari)?
-    tx.executeSql('SELECT dbid, hex(dbid) AS hexId FROM ' + META_STORE, [],
-      function (tx, result) {
-        var id = result.rows.item(0).dbid;
-        var hexId = result.rows.item(0).hexId;
-        encoding = (hexId.length === id.length * 2) ? 'UTF-8' : 'UTF-16';
-      }
-    );
-  }
-
-  function onGetVersion(tx, dbVersion) {
-    if (dbVersion === 0) {
-      // initial schema
-
-      var meta = 'CREATE TABLE IF NOT EXISTS ' + META_STORE +
-        ' (update_seq INTEGER, dbid, db_version INTEGER)';
-      var attach = 'CREATE TABLE IF NOT EXISTS ' + ATTACH_STORE +
-        ' (digest, json, body BLOB)';
-      var doc = 'CREATE TABLE IF NOT EXISTS ' + DOC_STORE +
-        ' (id unique, json, winningseq)';
-      var seq = 'CREATE TABLE IF NOT EXISTS ' + BY_SEQ_STORE +
-        ' (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
-        'json, deleted TINYINT(1), doc_id, rev)';
-      var local = 'CREATE TABLE IF NOT EXISTS ' + LOCAL_STORE +
-        ' (id UNIQUE, rev, json)';
-
-      // creates
-      tx.executeSql(attach);
-      tx.executeSql(local);
-      tx.executeSql(doc, [], function () {
-        tx.executeSql(DOC_STORE_WINNINGSEQ_INDEX_SQL);
-        tx.executeSql(seq, [], function () {
-          tx.executeSql(BY_SEQ_STORE_DELETED_INDEX_SQL);
-          tx.executeSql(BY_SEQ_STORE_DOC_ID_REV_INDEX_SQL);
-          tx.executeSql(meta, [], function () {
-            // mark the update_seq, db version, and new dbid
-            var initSeq = 'INSERT INTO ' + META_STORE +
-              ' (update_seq, db_version, dbid) VALUES (?, ?, ?)';
-            instanceId = utils.uuid();
-            var initSeqArgs = [0, ADAPTER_VERSION, instanceId];
-            tx.executeSql(initSeq, initSeqArgs, function (tx) {
-              onGetInstanceId(tx);
-            });
-          });
-        });
-      });
-    } else { // version > 0
-
-      var setupDone = function () {
-        var migrated = dbVersion < ADAPTER_VERSION;
-        if (migrated) {
-          // update the db version within this transaction
-          tx.executeSql('UPDATE ' + META_STORE + ' SET db_version = ' +
-            ADAPTER_VERSION);
-        }
-        // notify db.id() callers
-        var sql = 'SELECT dbid FROM ' + META_STORE;
-        tx.executeSql(sql, [], function (tx, result) {
-          instanceId = result.rows.item(0).dbid;
-          onGetInstanceId(tx);
-        });
-      };
-
-      // would love to use promises here, but then websql
-      // ends the transaction early
-      switch (dbVersion) {
-        case 1:
-          runMigration2(tx, function () {
-            runMigration3(tx, function () {
-              runMigration4(tx, setupDone);
-            });
-          });
-          break;
-        case 2:
-          runMigration3(tx, function () {
-            runMigration4(tx, setupDone);
-          });
-          break;
-        case 3:
-          runMigration4(tx, setupDone);
-          break;
-        default:
-          setupDone();
-          break;
-      }
-    }
-  }
-
-  function setup() {
-
-    db.transaction(function (tx) {
-      // first get the version
-      tx.executeSql('SELECT sql FROM sqlite_master WHERE tbl_name = ' +
-                    META_STORE, [], function (tx, result) {
-        if (!result.rows.length) {
-          // database hasn't even been created yet (version 0)
-          onGetVersion(tx, 0);
-        } else if (!/db_version/.test(result.rows.item(0).sql)) {
-          // table was created, but without the new db_version column,
-          // so add it.
-          tx.executeSql('ALTER TABLE ' + META_STORE +
-            ' ADD COLUMN db_version INTEGER', [], function () {
-            // before version 2, this column didn't even exist
-            onGetVersion(tx, 1);
-          });
-        } else { // column exists, we can safely get it
-          tx.executeSql('SELECT db_version FROM ' + META_STORE, [],
-            function (tx, result) {
-            var dbVersion = result.rows.item(0).db_version;
-            onGetVersion(tx, dbVersion);
-          });
-        }
-      });
-    }, unknownError(callback), dbCreated);
-  }
-
-  if (utils.isCordova() && typeof global !== 'undefined') {
-    //to wait until custom api is made in pouch.adapters before doing setup
-    global.addEventListener(name + '_pouch', function cordova_init() {
-      global.removeEventListener(name + '_pouch', cordova_init, false);
-      setup();
-    }, false);
-  } else {
-    setup();
-  }
-
-  api.type = function () {
-    return 'websql';
-  };
-
-  api._id = utils.toPromise(function (callback) {
-    callback(null, instanceId);
-  });
-
-  api._info = function (callback) {
-    db.readTransaction(function (tx) {
-      countDocs(tx, function (docCount) {
-        var sql = 'SELECT update_seq FROM ' + META_STORE;
-        tx.executeSql(sql, [], function (tx, result) {
-          var updateSeq = result.rows.item(0).update_seq;
-          callback(null, {
-            doc_count: docCount,
-            update_seq: updateSeq
-          });
-        });
-      });
-    }, unknownError(callback));
-  };
-
-  api._bulkDocs = function (req, opts, callback) {
-
-    var newEdits = opts.new_edits;
-    var userDocs = req.docs;
-
-    // Parse the docs, give them a sequence number for the result
-    var docInfos = userDocs.map(function (doc, i) {
-      if (doc._id && utils.isLocalId(doc._id)) {
-        return doc;
-      }
-      var newDoc = utils.parseDoc(doc, newEdits);
-      newDoc._bulk_seq = i;
-      return newDoc;
-    });
-
-    var docInfoErrors = docInfos.filter(function (docInfo) {
-      return docInfo.error;
-    });
-    if (docInfoErrors.length) {
-      return callback(docInfoErrors[0]);
-    }
-
-    var tx;
-    var results = new Array(docInfos.length);
-    var updateSeq = 0;
-    var fetchedDocs = new utils.Map();
-    var numDocsWritten = 0;
-
-    function complete() {
-      var aresults = results.map(function (result) {
-        if (result._bulk_seq) {
-          delete result._bulk_seq;
-        } else if (!Object.keys(result).length) {
-          return {
-            ok: true
-          };
-        }
-        if (result.error) {
-          return result;
-        }
-
-        var metadata = result.metadata;
-        var rev = merge.winningRev(metadata);
-
-        return {
-          ok: true,
-          id: metadata.id,
-          rev: rev
-        };
-      });
-      WebSqlPouch.Changes.notify(name);
-
-      var updateseq = 'SELECT update_seq FROM ' + META_STORE;
-      tx.executeSql(updateseq, [], function (tx, result) {
-        var update_seq = result.rows.item(0).update_seq + updateSeq;
-        var sql = 'UPDATE ' + META_STORE + ' SET update_seq=?';
-        tx.executeSql(sql, [update_seq], function () {
-          callback(null, aresults);
-        });
-      });
-    }
-
-    function preprocessAttachment(att, finish) {
-      if (att.stub) {
-        return finish();
-      }
-      if (typeof att.data === 'string') {
-        try {
-          att.data = atob(att.data);
-        } catch (e) {
-          var err = errors.error(errors.BAD_ARG,
-                                "Attachments need to be base64 encoded");
-          return callback(err);
-        }
-        var data = utils.fixBinary(att.data);
-        att.data = utils.createBlob([data], {type: att.content_type});
-      }
-      var reader = new FileReader();
-      reader.onloadend = function (e) {
-        var binary = utils.arrayBufferToBinaryString(this.result);
-        att.data = binary;
-        utils.MD5(binary).then(function (result) {
-          att.digest = 'md5-' + result;
-          finish();
-        });
-      };
-      reader.readAsArrayBuffer(att.data);
-    }
-
-    function preprocessAttachments(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var docv = 0;
-
-      docInfos.forEach(function (docInfo) {
-        var attachments = docInfo.data && docInfo.data._attachments ?
-          Object.keys(docInfo.data._attachments) : [];
-        var recv = 0;
-
-        if (!attachments.length) {
-          return done();
-        }
-
-        function processedAttachment() {
-          recv++;
-          if (recv === attachments.length) {
-            done();
-          }
-        }
-
-        for (var key in docInfo.data._attachments) {
-          if (docInfo.data._attachments.hasOwnProperty(key)) {
-            preprocessAttachment(docInfo.data._attachments[key],
-                                 processedAttachment);
-          }
-        }
-      });
-
-      function done() {
-        docv++;
-        if (docInfos.length === docv) {
-          callback();
-        }
-      }
-    }
-
-    function writeDoc(docInfo, winningRev, deleted, callback, isUpdate,
-                      resultsIdx) {
-
-      function finish() {
-        updateSeq++;
-        var data = docInfo.data;
-        var deletedInt = deleted ? 1 : 0;
-
-        var id = data._id;
-        var rev = data._rev;
-        var json = stringifyDoc(data);
-        var sql = 'INSERT INTO ' + BY_SEQ_STORE +
-          ' (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);';
-        var sqlArgs = [id, rev, json, deletedInt];
-
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          dataWritten(tx, result.insertId);
-        }, function () {
-          // constraint error, recover by updating instead (see #1638)
-          var fetchSql = select('seq', BY_SEQ_STORE, null,
-            'doc_id=? AND rev=?');
-          tx.executeSql(fetchSql, [id, rev], function (tx, res) {
-            var seq = res.rows.item(0).seq;
-            var sql = 'UPDATE ' + BY_SEQ_STORE +
-              ' SET json=?, deleted=? WHERE doc_id=? AND rev=?;';
-            var sqlArgs = [json, deletedInt, id, rev];
-            tx.executeSql(sql, sqlArgs, function (tx) {
-              updateSeq--; // discount, since it's an update, not a new seq
-              dataWritten(tx, seq);
-            });
-          });
-          return false; // ack that we've handled the error
-        });
-      }
-
-      function collectResults(attachmentErr) {
-        if (!err) {
-          if (attachmentErr) {
-            err = attachmentErr;
-            callback(err);
-          } else if (recv === attachments.length) {
-            finish();
-          }
-        }
-      }
-
-      var err = null;
-      var recv = 0;
-
-      docInfo.data._id = docInfo.metadata.id;
-      docInfo.data._rev = docInfo.metadata.rev;
-
-      if (deleted) {
-        docInfo.data._deleted = true;
-      }
-
-      var attachments = docInfo.data._attachments ?
-        Object.keys(docInfo.data._attachments) : [];
-
-      function attachmentSaved(err) {
-        recv++;
-        collectResults(err);
-      }
-
-      for (var key in docInfo.data._attachments) {
-        if (!docInfo.data._attachments[key].stub) {
-          var data = docInfo.data._attachments[key].data;
-          delete docInfo.data._attachments[key].data;
-          var digest = docInfo.data._attachments[key].digest;
-          saveAttachment(docInfo, digest, data, attachmentSaved);
-        } else {
-          recv++;
-          collectResults();
-        }
-      }
-
-      if (!attachments.length) {
-        finish();
-      }
-
-      function dataWritten(tx, seq) {
-        docInfo.metadata.seq = seq;
-        delete docInfo.metadata.rev;
-
-        var sql = isUpdate ?
-          'UPDATE ' + DOC_STORE +
-          ' SET json=?, winningseq=(SELECT seq FROM ' + BY_SEQ_STORE +
-          ' WHERE doc_id=' + DOC_STORE + '.id AND rev=?) WHERE id=?'
-          : 'INSERT INTO ' + DOC_STORE +
-          ' (id, winningseq, json) VALUES (?, ?, ?);';
-        var metadataStr = vuvuzela.stringify(docInfo.metadata);
-        var id = docInfo.metadata.id;
-        var params = isUpdate ?
-          [metadataStr, winningRev, id] :
-          [id, seq, metadataStr];
-        tx.executeSql(sql, params, function () {
-          results[resultsIdx] = docInfo;
-          fetchedDocs.set(id, docInfo.metadata);
-          callback();
-        });
-      }
-    }
-
-    function updateDoc(oldDoc, docInfo, resultsIdx, callback) {
-      var merged =
-        merge.merge(oldDoc.rev_tree, docInfo.metadata.rev_tree[0], 1000);
-      var deleted = utils.isDeleted(docInfo.metadata);
-      var oldDocDeleted = utils.isDeleted(oldDoc);
-      var inConflict = (oldDocDeleted && deleted && newEdits) ||
-        (!oldDocDeleted && newEdits && merged.conflicts !== 'new_leaf');
-      if (inConflict) {
-        results[resultsIdx] = makeErr(errors.REV_CONFLICT, docInfo._bulk_seq);
-        return callback();
-      }
-
-      docInfo.metadata.rev_tree = merged.tree;
-
-      // recalculate
-      var winningRev = merge.winningRev(docInfo.metadata);
-      deleted = utils.isDeleted(docInfo.metadata, winningRev);
-
-      writeDoc(docInfo, winningRev, deleted, callback, true, resultsIdx);
-    }
-
-    function insertDoc(docInfo, resultsIdx, callback) {
-      // Cant insert new deleted documents
-      var winningRev = merge.winningRev(docInfo.metadata);
-      var deleted = utils.isDeleted(docInfo.metadata, winningRev);
-      if ('was_delete' in opts && deleted) {
-        results[resultsIdx] = errors.MISSING_DOC;
-        return callback();
-      }
-      writeDoc(docInfo, winningRev, deleted, callback, false, resultsIdx);
-    }
-
-    function checkDoneWritingDocs() {
-      if (++numDocsWritten === docInfos.length) {
-        complete();
-      }
-    }
-
-    function processDocs() {
-      if (!docInfos.length) {
-        return complete();
-      }
-
-      var idsToDocs = new utils.Map();
-
-      docInfos.forEach(function (currentDoc, resultsIdx) {
-
-        if (currentDoc._id && utils.isLocalId(currentDoc._id)) {
-          api[currentDoc._deleted ? '_removeLocal' : '_putLocal'](
-              currentDoc, {ctx: tx}, function (err, resp) {
-            if (err) {
-              results[resultsIdx] = err;
-            } else {
-              results[resultsIdx] = {};
-            }
-            checkDoneWritingDocs();
-          });
-          return;
-        }
-
-        var id = currentDoc.metadata.id;
-        if (idsToDocs.has(id)) {
-          idsToDocs.get(id).push([currentDoc, resultsIdx]);
-        } else {
-          idsToDocs.set(id, [[currentDoc, resultsIdx]]);
-        }
-      });
-
-      // in the case of new_edits, the user can provide multiple docs
-      // with the same id. these need to be processed sequentially
-      idsToDocs.forEach(function (docs, id) {
-        var numDone = 0;
-
-        function docWritten() {
-          checkDoneWritingDocs();
-          if (++numDone < docs.length) {
-            nextDoc();
-          }
-        }
-        function nextDoc() {
-          var value = docs[numDone];
-          var currentDoc = value[0];
-          var resultsIdx = value[1];
-
-          if (fetchedDocs.has(id)) {
-            updateDoc(fetchedDocs.get(id), currentDoc, resultsIdx, docWritten);
-          } else {
-            insertDoc(currentDoc, resultsIdx, docWritten);
-          }
-        }
-        nextDoc();
-      });
-    }
-
-    function fetchExistingDocs(callback) {
-      if (!docInfos.length) {
-        return callback();
-      }
-
-      var numFetched = 0;
-
-      function checkDone() {
-        if (++numFetched === docInfos.length) {
-          callback();
-        }
-      }
-
-      docInfos.forEach(function (docInfo) {
-        if (docInfo._id && utils.isLocalId(docInfo._id)) {
-          return checkDone(); // skip local docs
-        }
-        var id = docInfo.metadata.id;
-        tx.executeSql('SELECT json FROM ' + DOC_STORE +
-          ' WHERE id = ?', [id], function (tx, result) {
-          if (result.rows.length) {
-            var metadata = vuvuzela.parse(result.rows.item(0).json);
-            fetchedDocs.set(id, metadata);
-          }
-          checkDone();
-        });
-      });
-    }
-
-    // Insert sequence number into the error so we can sort later
-    function makeErr(err, seq) {
-      err._bulk_seq = seq;
-      return err;
-    }
-
-    function saveAttachment(docInfo, digest, data, callback) {
-      var ref = [docInfo.metadata.id, docInfo.metadata.rev].join('@');
-      var newAtt = {digest: digest};
-      var sql = 'SELECT digest, json FROM ' + ATTACH_STORE + ' WHERE digest=?';
-      tx.executeSql(sql, [digest], function (tx, result) {
-        if (!result.rows.length) {
-          newAtt.refs = {};
-          newAtt.refs[ref] = true;
-          sql = 'INSERT INTO ' + ATTACH_STORE +
-                '(digest, json, body) VALUES (?, ?, ?)';
-          tx.executeSql(sql, [digest, JSON.stringify(newAtt), data],
-            function () {
-            callback();
-          });
-        } else {
-          newAtt.refs = JSON.parse(result.rows.item(0).json).refs;
-          sql = 'UPDATE ' + ATTACH_STORE + ' SET json=?, body=? WHERE digest=?';
-          tx.executeSql(sql, [JSON.stringify(newAtt), data, digest],
-            function () {
-            callback();
-          });
-        }
-      });
-    }
-
-    preprocessAttachments(function () {
-      db.transaction(function (txn) {
-        tx = txn;
-        fetchExistingDocs(processDocs);
-      }, unknownError(callback), function () {
-        docCount = -1;
-      });
-    });
-  };
-
-  api._get = function (id, opts, callback) {
-    opts = utils.clone(opts);
-    var doc;
-    var metadata;
-    var err;
-    if (!opts.ctx) {
-      db.readTransaction(function (txn) {
-        opts.ctx = txn;
-        api._get(id, opts, callback);
-      });
-      return;
-    }
-    var tx = opts.ctx;
-
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: tx});
-    }
-
-    var sql;
-    var sqlArgs;
-    if (opts.rev) {
-      sql = select(
-        SELECT_DOCS,
-        [DOC_STORE, BY_SEQ_STORE],
-        DOC_STORE + '.id=' + BY_SEQ_STORE + '.doc_id',
-        [BY_SEQ_STORE + '.doc_id=?', BY_SEQ_STORE + '.rev=?']);
-      sqlArgs = [id, opts.rev];
-    } else {
-      sql = select(
-        SELECT_DOCS,
-        [DOC_STORE, BY_SEQ_STORE],
-        DOC_STORE_AND_BY_SEQ_JOINER,
-        DOC_STORE + '.id=?');
-      sqlArgs = [id];
-    }
-    tx.executeSql(sql, sqlArgs, function (a, results) {
-      if (!results.rows.length) {
-        err = errors.MISSING_DOC;
-        return finish();
-      }
-      var item = results.rows.item(0);
-      metadata = vuvuzela.parse(item.metadata);
-      if (item.deleted && !opts.rev) {
-        err = errors.error(errors.MISSING_DOC, 'deleted');
-        return finish();
-      }
-      doc = unstringifyDoc(item.data, metadata.id, item.rev);
-      finish();
-    });
-  };
-
-  function countDocs(tx, callback) {
-
-    if (docCount !== -1) {
-      return callback(docCount);
-    }
-
-    // count the total rows
-    var sql = select(
-      'COUNT(' + DOC_STORE + '.id) AS \'num\'',
-      [DOC_STORE, BY_SEQ_STORE],
-      DOC_STORE_AND_BY_SEQ_JOINER,
-      BY_SEQ_STORE + '.deleted=0');
-
-    tx.executeSql(sql, [], function (tx, result) {
-      docCount = result.rows.item(0).num;
-      callback(docCount);
-    });
-  }
-
-  api._allDocs = function (opts, callback) {
-    var results = [];
-    var totalRows;
-
-    var start = 'startkey' in opts ? opts.startkey : false;
-    var end = 'endkey' in opts ? opts.endkey : false;
-    var key = 'key' in opts ? opts.key : false;
-    var descending = 'descending' in opts ? opts.descending : false;
-    var limit = 'limit' in opts ? opts.limit : -1;
-    var offset = 'skip' in opts ? opts.skip : 0;
-    var inclusiveEnd = opts.inclusive_end !== false;
-
-    var sqlArgs = [];
-    var criteria = [];
-
-    if (key !== false) {
-      criteria.push(DOC_STORE + '.id = ?');
-      sqlArgs.push(key);
-    } else if (start !== false || end !== false) {
-      if (start !== false) {
-        criteria.push(DOC_STORE + '.id ' + (descending ? '<=' : '>=') + ' ?');
-        sqlArgs.push(start);
-      }
-      if (end !== false) {
-        var comparator = descending ? '>' : '<';
-        if (inclusiveEnd) {
-          comparator += '=';
-        }
-        criteria.push(DOC_STORE + '.id ' + comparator + ' ?');
-        sqlArgs.push(end);
-      }
-      if (key !== false) {
-        criteria.push(DOC_STORE + '.id = ?');
-        sqlArgs.push(key);
-      }
-    }
-
-    if (opts.deleted !== 'ok') {
-      // report deleted if keys are specified
-      criteria.push(BY_SEQ_STORE + '.deleted = 0');
-    }
-
-    db.readTransaction(function (tx) {
-
-      // first count up the total rows
-      countDocs(tx, function (count) {
-        totalRows = count;
-
-        if (limit === 0) {
-          return;
-        }
-
-        // then actually fetch the documents
-        var sql = select(
-          SELECT_DOCS,
-          [DOC_STORE, BY_SEQ_STORE],
-          DOC_STORE_AND_BY_SEQ_JOINER,
-          criteria,
-          DOC_STORE + '.id ' + (descending ? 'DESC' : 'ASC')
-          );
-        sql += ' LIMIT ' + limit + ' OFFSET ' + offset;
-
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var item = result.rows.item(i);
-            var metadata = vuvuzela.parse(item.metadata);
-            var data = unstringifyDoc(item.data, metadata.id, item.rev);
-            var winningRev = data._rev;
-            var doc = {
-              id: metadata.id,
-              key: metadata.id,
-              value: {rev: winningRev}
-            };
-            if (opts.include_docs) {
-              doc.doc = data;
-              doc.doc._rev = winningRev;
-              if (opts.conflicts) {
-                doc.doc._conflicts = merge.collectConflicts(metadata);
-              }
-              for (var att in doc.doc._attachments) {
-                if (doc.doc._attachments.hasOwnProperty(att)) {
-                  doc.doc._attachments[att].stub = true;
-                }
-              }
-            }
-            if (item.deleted) {
-              if (opts.deleted === 'ok') {
-                doc.value.deleted = true;
-                doc.doc = null;
-              } else {
-                continue;
-              }
-            }
-            results.push(doc);
-          }
-        });
-      });
-    }, unknownError(callback), function () {
-      callback(null, {
-        total_rows: totalRows,
-        offset: opts.skip,
-        rows: results
-      });
-    });
-  };
-
-  api._changes = function (opts) {
-    opts = utils.clone(opts);
-
-    if (opts.continuous) {
-      var id = name + ':' + utils.uuid();
-      WebSqlPouch.Changes.addListener(name, id, api, opts);
-      WebSqlPouch.Changes.notify(name);
-      return {
-        cancel: function () {
-          WebSqlPouch.Changes.removeListener(name, id);
-        }
-      };
-    }
-
-    var descending = opts.descending;
-
-    // Ignore the `since` parameter when `descending` is true
-    opts.since = opts.since && !descending ? opts.since : 0;
-
-    var limit = 'limit' in opts ? opts.limit : -1;
-    if (limit === 0) {
-      limit = 1; // per CouchDB _changes spec
-    }
-
-    var returnDocs;
-    if ('returnDocs' in opts) {
-      returnDocs = opts.returnDocs;
-    } else {
-      returnDocs = true;
-    }
-    var results = [];
-    var numResults = 0;
-    function fetchChanges() {
-
-      var criteria = [
-        DOC_STORE + '.winningseq > ' + opts.since
-      ];
-      var sqlArgs = [];
-      if (opts.doc_ids) {
-        criteria.push(DOC_STORE + '.id IN (' + opts.doc_ids.map(function () {
-          return '?';
-        }).join(',') + ')');
-        sqlArgs = opts.doc_ids;
-      }
-
-      var sql = select(SELECT_DOCS, [DOC_STORE, BY_SEQ_STORE],
-        DOC_STORE_AND_BY_SEQ_JOINER, criteria,
-        DOC_STORE + '.winningseq ' + (descending ? 'DESC' : 'ASC'));
-
-      var filter = utils.filterChange(opts);
-      if (!opts.view && !opts.filter) {
-        // we can just limit in the query
-        sql += ' LIMIT ' + limit;
-      }
-
-      db.readTransaction(function (tx) {
-        tx.executeSql(sql, sqlArgs, function (tx, result) {
-          var lastSeq = 0;
-          for (var i = 0, l = result.rows.length; i < l; i++) {
-            var res = result.rows.item(i);
-            var metadata = vuvuzela.parse(res.metadata);
-            if (lastSeq < res.seq) {
-              lastSeq = res.seq;
-            }
-            var doc = unstringifyDoc(res.data, metadata.id, res.rev);
-            var change = opts.processChange(doc, metadata, opts);
-            change.seq = res.seq;
-            if (filter(change)) {
-              numResults++;
-              if (returnDocs) {
-                results.push(change);
-              }
-              opts.onChange(change);
-            }
-            if (numResults === limit) {
-              break;
-            }
-          }
-          if (!opts.continuous) {
-            opts.complete(null, {
-              results: results,
-              last_seq: lastSeq
-            });
-          }
-        });
-      });
-    }
-
-    fetchChanges();
-  };
-
-  api._close = function (callback) {
-    //WebSQL databases do not need to be closed
-    callback();
-  };
-
-  api._getAttachment = function (attachment, opts, callback) {
-    var res;
-    var tx = opts.ctx;
-    var digest = attachment.digest;
-    var type = attachment.content_type;
-    var sql = 'SELECT hex(body) as body FROM ' + ATTACH_STORE +
-              ' WHERE digest=?';
-    tx.executeSql(sql, [digest], function (tx, result) {
-      // sqlite normally stores data as utf8, so even the hex() function
-      // "encodes" the binary data in utf8/16 before returning it. yet hex()
-      // is the only way to get the full data, so we do this.
-      var data = parseHexString(result.rows.item(0).body, encoding);
-      if (opts.encode) {
-        res = btoa(data);
-      } else {
-        data = utils.fixBinary(data);
-        res = utils.createBlob([data], {type: type});
-      }
-      callback(null, res);
-    });
-  };
-
-  api._getRevisionTree = function (docId, callback) {
-    db.readTransaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          callback(errors.MISSING_DOC);
-        } else {
-          var data = vuvuzela.parse(result.rows.item(0).metadata);
-          callback(null, data.rev_tree);
-        }
-      });
-    });
-  };
-
-  api._doCompaction = function (docId, rev_tree, revs, callback) {
-    if (!revs.length) {
-      return callback();
-    }
-    db.transaction(function (tx) {
-      var sql = 'SELECT json AS metadata FROM ' + DOC_STORE + ' WHERE id = ?';
-      tx.executeSql(sql, [docId], function (tx, result) {
-        if (!result.rows.length) {
-          return utils.call(callback);
-        }
-        var metadata = vuvuzela.parse(result.rows.item(0).metadata);
-        metadata.rev_tree = rev_tree;
-
-        var numDone = 0;
-        revs.forEach(function (rev) {
-          var sql = 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE doc_id=? AND rev=?';
-          tx.executeSql(sql, [docId, rev], function (tx) {
-            if (++numDone === revs.length) {
-              var sql = 'UPDATE ' + DOC_STORE + ' SET json = ? WHERE id = ?';
-              tx.executeSql(sql, [vuvuzela.stringify(metadata), docId],
-                function () {
-                callback();
-              });
-            }
-          });
-        });
-      });
-    });
-  };
-
-  api._getLocal = function (id, callback) {
-    db.readTransaction(function (tx) {
-      var sql = 'SELECT json, rev FROM ' + LOCAL_STORE + ' WHERE id=?';
-      tx.executeSql(sql, [id], function (tx, res) {
-        if (res.rows.length) {
-          var item = res.rows.item(0);
-          var doc = unstringifyDoc(item.json, id, item.rev);
-          callback(null, doc);
-        } else {
-          callback(errors.MISSING_DOC);
-        }
-      });
-    });
-  };
-
-  api._putLocal = function (doc, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    delete doc._revisions; // ignore this, trust the rev
-    var oldRev = doc._rev;
-    var id = doc._id;
-    var newRev;
-    if (!oldRev) {
-      newRev = doc._rev = '0-1';
-    } else {
-      newRev = doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
-    }
-    var json = stringifyDoc(doc);
-
-    var ret;
-    function putLocal(tx) {
-      var sql;
-      var values;
-      if (oldRev) {
-        sql = 'UPDATE ' + LOCAL_STORE + ' SET rev=?, json=? ' +
-          'WHERE id=? AND rev=?';
-        values = [newRev, json, id, oldRev];
-      } else {
-        sql = 'INSERT INTO ' + LOCAL_STORE + ' (id, rev, json) VALUES (?,?,?)';
-        values = [id, newRev, json];
-      }
-      tx.executeSql(sql, values, function (tx, res) {
-        if (res.rowsAffected) {
-          ret = {ok: true, id: id, rev: newRev};
-          if (opts.ctx) { // return immediately
-            callback(null, ret);
-          }
-        } else {
-          callback(errors.REV_CONFLICT);
-        }
-      }, function () {
-        callback(errors.REV_CONFLICT);
-        return false; // ack that we handled the error
-      });
-    }
-
-    if (opts.ctx) {
-      putLocal(opts.ctx);
-    } else {
-      db.transaction(function (tx) {
-        putLocal(tx);
-      }, unknownError(callback), function () {
-        if (ret) {
-          callback(null, ret);
-        }
-      });
-    }
-  };
-
-  api._removeLocal = function (doc, callback) {
-    var ret;
-    db.transaction(function (tx) {
-      var sql = 'DELETE FROM ' + LOCAL_STORE + ' WHERE id=? AND rev=?';
-      var params = [doc._id, doc._rev];
-      tx.executeSql(sql, params, function (tx, res) {
-        if (!res.rowsAffected) {
-          return callback(errors.REV_CONFLICT);
-        }
-        ret = {ok: true, id: doc._id, rev: '0-0'};
-      });
-    }, unknownError(callback), function () {
-      callback(null, ret);
-    });
-  };
-}
-
-WebSqlPouch.valid = function () {
-  if (typeof global !== 'undefined') {
-    if (global.navigator &&
-        global.navigator.sqlitePlugin &&
-        global.navigator.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.sqlitePlugin && global.sqlitePlugin.openDatabase) {
-      return true;
-    } else if (global.openDatabase) {
-      return true;
-    }
-  }
-  return false;
-};
-
-WebSqlPouch.destroy = utils.toPromise(function (name, opts, callback) {
-  WebSqlPouch.Changes.removeAllListeners(name);
-  var size = getSize(opts);
-  var db = openDB(name, POUCH_VERSION, name, size);
-  db.transaction(function (tx) {
-    var stores = [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, META_STORE,
-      LOCAL_STORE];
-    stores.forEach(function (store) {
-      tx.executeSql('DROP TABLE IF EXISTS ' + store, []);
-    });
-  }, unknownError(callback), function () {
-    if (utils.hasLocalStorage()) {
-      delete global.localStorage['_pouch__websqldb_' + name];
-      delete global.localStorage[name];
-    }
-    callback(null, {'ok': true});
-  });
-});
-
-WebSqlPouch.Changes = new utils.Changes();
-
-module.exports = WebSqlPouch;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"../deps/errors":11,"../merge":18,"../utils":23,"vuvuzela":58}],6:[function(_dereq_,module,exports){
-'use strict';
-var utils = _dereq_('./utils');
-var merge = _dereq_('./merge');
-var errors = _dereq_('./deps/errors');
-var EE = _dereq_('events').EventEmitter;
-var evalFilter = _dereq_('./evalFilter');
-var evalView = _dereq_('./evalView');
-module.exports = Changes;
-utils.inherits(Changes, EE);
-
-function Changes(db, opts, callback) {
-  EE.call(this);
-  var self = this;
-  this.db = db;
-  opts = opts ? utils.clone(opts) : {};
-  var oldComplete = callback || opts.complete || function () {};
-  var complete = opts.complete = utils.once(function (err, resp) {
-    if (err) {
-      self.emit('error', err);
-    } else {
-      self.emit('complete', resp);
-    }
-    self.removeAllListeners();
-    db.removeListener('destroyed', onDestroy);
-  });
-  if (oldComplete) {
-    self.on('complete', function (resp) {
-      oldComplete(null, resp);
-    });
-    self.on('error', function (err) {
-      oldComplete(err);
-    });
-  }
-  var oldOnChange = opts.onChange;
-  if (oldOnChange) {
-    self.on('change', oldOnChange);
-  }
-  function onDestroy() {
-    self.cancel();
-  }
-  db.once('destroyed', onDestroy);
-
-  opts.onChange = function (change) {
-    if (opts.isCancelled) {
-      return;
-    }
-    self.emit('change', change);
-    if (self.startSeq && self.startSeq <= change.seq) {
-      self.emit('uptodate');
-      self.startSeq = false;
-    }
-    if (change.deleted) {
-      self.emit('delete', change);
-    } else if (change.changes.length === 1 &&
-      change.changes[0].rev.slice(0, 2) === '1-') {
-      self.emit('create', change);
-    } else {
-      self.emit('update', change);
-    }
-  };
-
-  var promise = new utils.Promise(function (fulfill, reject) {
-    opts.complete = function (err, res) {
-      if (err) {
-        reject(err);
-      } else {
-        fulfill(res);
-      }
-    };
-  });
-  self.once('cancel', function () {
-    if (oldOnChange) {
-      self.removeListener('change', oldOnChange);
-    }
-    opts.complete(null, {status: 'cancelled'});
-  });
-  this.then = promise.then.bind(promise);
-  this['catch'] = promise['catch'].bind(promise);
-  this.then(function (result) {
-    complete(null, result);
-  }, complete);
-
-
-
-  if (!db.taskqueue.isReady) {
-    db.taskqueue.addTask(function () {
-      if (self.isCancelled) {
-        self.emit('cancel');
-      } else {
-        self.doChanges(opts);
-      }
-    });
-  } else {
-    self.doChanges(opts);
-  }
-}
-Changes.prototype.cancel = function () {
-  this.isCancelled = true;
-  if (this.db.taskqueue.isReady) {
-    this.emit('cancel');
-  }
-};
-function processChange(doc, metadata, opts) {
-  var changeList = [{rev: doc._rev}];
-  if (opts.style === 'all_docs') {
-    changeList = merge.collectLeaves(metadata.rev_tree)
-    .map(function (x) { return {rev: x.rev}; });
-  }
-  var change = {
-    id: metadata.id,
-    changes: changeList,
-    doc: doc
-  };
-
-  if (utils.isDeleted(metadata, doc._rev)) {
-    change.deleted = true;
-  }
-  if (opts.conflicts) {
-    change.doc._conflicts = merge.collectConflicts(metadata);
-    if (!change.doc._conflicts.length) {
-      delete change.doc._conflicts;
-    }
-  }
-  return change;
-}
-
-Changes.prototype.doChanges = function (opts) {
-  var self = this;
-  var callback = opts.complete;
-
-  opts = utils.clone(opts);
-  if ('live' in opts && !('continuous' in opts)) {
-    opts.continuous = opts.live;
-  }
-  opts.processChange = processChange;
-
-  if (opts.since === 'latest') {
-    opts.since = 'now';
-  }
-  if (!opts.since) {
-    opts.since = 0;
-  }
-  if (opts.since === 'now') {
-    this.db.info().then(function (info) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      opts.since = info.update_seq  - 1;
-      self.doChanges(opts);
-    }, callback);
-    return;
-  }
-
-  if (opts.continuous && opts.since !== 'now') {
-    this.db.info().then(function (info) {
-      self.startSeq = info.update_seq - 1;
-    }, function (err) {
-      if (err.id === 'idbNull') {
-        //db closed before this returned
-        //thats ok
-        return;
-      }
-      throw err;
-    });
-  }
-
-  if (this.db.type() !== 'http' &&
-    opts.filter && typeof opts.filter === 'string') {
-    return this.filterChanges(opts);
-  }
-
-  if (!('descending' in opts)) {
-    opts.descending = false;
-  }
-
-  // 0 and 1 should return 1 document
-  opts.limit = opts.limit === 0 ? 1 : opts.limit;
-  opts.complete = callback;
-  var newPromise = this.db._changes(opts);
-  if (newPromise && typeof newPromise.cancel === 'function') {
-    var cancel = self.cancel;
-    self.cancel = utils.getArguments(function (args) {
-      newPromise.cancel();
-      cancel.apply(this, args);
-    });
-  }
-};
-
-Changes.prototype.filterChanges = function (opts) {
-  var self = this;
-  var callback = opts.complete;
-  if (opts.filter === '_view') {
-    if (!opts.view || typeof opts.view !== 'string') {
-      var err = new  Error('`view` filter parameter is not provided.');
-      err.status = errors.BAD_REQUEST.status;
-      err.name = errors.BAD_REQUEST.name;
-      err.error = true;
-      callback(err);
-      return;
-    }
-    // fetch a view from a design doc, make it behave like a filter
-    var viewName = opts.view.split('/');
-    this.db.get('_design/' + viewName[0], function (err, ddoc) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      if (err) {
-        callback(err);
-        return;
-      }
-      if (ddoc && ddoc.views && ddoc.views[viewName[1]]) {
-        
-        var filter = evalView(ddoc.views[viewName[1]].map);
-        opts.filter = filter;
-        self.doChanges(opts);
-        return;
-      }
-      var msg = ddoc.views ? 'missing json key: ' + viewName[1] :
-        'missing json key: views';
-      if (!err) {
-        err = new  Error(msg);
-        err.status = errors.MISSING_DOC.status;
-        err.name = errors.MISSING_DOC.name;
-        err.error = true;
-      }
-      callback(err);
-      return;
-    });
-  } else {
-    // fetch a filter from a design doc
-    var filterName = opts.filter.split('/');
-    this.db.get('_design/' + filterName[0], function (err, ddoc) {
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      if (err) {
-        callback(err);
-        return;
-      }
-      if (ddoc && ddoc.filters && ddoc.filters[filterName[1]]) {
-        var filter = evalFilter(ddoc.filters[filterName[1]]);
-        opts.filter = filter;
-        self.doChanges(opts);
-        return;
-      } else {
-        var msg = (ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
-          : 'missing json key: filters';
-        if (!err) {
-          err = new  Error(msg);
-          err.status = errors.MISSING_DOC.status;
-          err.name = errors.MISSING_DOC.name;
-          err.error = true;
-        }
-        callback(err);
-        return;
-      }
-    });
-  }
-};
-},{"./deps/errors":11,"./evalFilter":15,"./evalView":16,"./merge":18,"./utils":23,"events":27}],7:[function(_dereq_,module,exports){
-(function (global){
-/*globals cordova */
-"use strict";
-
-var Adapter = _dereq_('./adapter');
-var utils = _dereq_('./utils');
-var TaskQueue = _dereq_('./taskqueue');
-var Promise = utils.Promise;
-
-function defaultCallback(err) {
-  if (err && global.debug) {
-    console.error(err);
-  }
-}
-
-utils.inherits(PouchDBVersion306, Adapter);
-function PouchDBVersion306(name, opts, callback) {
-
-  if (!(this instanceof PouchDBVersion306)) {
-    return new PouchDBVersion306(name, opts, callback);
-  }
-  var self = this;
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (name && typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-  if (typeof callback === 'undefined') {
-    callback = defaultCallback;
-  }
-  opts = opts || {};
-  var oldCB = callback;
-  self.auto_compaction = opts.auto_compaction;
-  self.prefix = PouchDBVersion306.prefix;
-  Adapter.call(self);
-  self.taskqueue = new TaskQueue();
-  var promise = new Promise(function (fulfill, reject) {
-    callback = function (err, resp) {
-      if (err) {
-        return reject(err);
-      }
-      delete resp.then;
-      fulfill(resp);
-    };
-  
-    opts = utils.clone(opts);
-    var originalName = opts.name || name;
-    var backend, error;
-    (function () {
-      try {
-
-        if (typeof originalName !== 'string') {
-          error = new Error('Missing/invalid DB name');
-          error.code = 400;
-          throw error;
-        }
-
-        backend = PouchDBVersion306.parseAdapter(originalName, opts);
-        
-        opts.originalName = originalName;
-        opts.name = backend.name;
-        if (opts.prefix && backend.adapter !== 'http' &&
-            backend.adapter !== 'https') {
-          opts.name = opts.prefix + opts.name;
-        }
-        opts.adapter = opts.adapter || backend.adapter;
-        self._adapter = opts.adapter;
-        self._db_name = originalName;
-        if (!PouchDBVersion306.adapters[opts.adapter]) {
-          error = new Error('Adapter is missing');
-          error.code = 404;
-          throw error;
-        }
-
-        if (!PouchDBVersion306.adapters[opts.adapter].valid()) {
-          error = new Error('Invalid Adapter');
-          error.code = 404;
-          throw error;
-        }
-      } catch (err) {
-        self.taskqueue.fail(err);
-        self.changes = utils.toPromise(function (opts) {
-          if (opts.complete) {
-            opts.complete(err);
-          }
-        });
-      }
-    }());
-    if (error) {
-      return reject(error); // constructor error, see above
-    }
-    self.adapter = opts.adapter;
-
-    // needs access to PouchDBVersion306;
-    self.replicate = {};
-
-    self.replicate.from = function (url, opts, callback) {
-      return self.constructor.replicate(url, self, opts, callback);
-    };
-
-    self.replicate.to = function (url, opts, callback) {
-      return self.constructor.replicate(self, url, opts, callback);
-    };
-
-    self.sync = function (dbName, opts, callback) {
-      return self.constructor.sync(self, dbName, opts, callback);
-    };
-
-    self.replicate.sync = self.sync;
-
-    self.destroy = utils.adapterFun('destroy', function (callback) {
-      var self = this;
-      self.info(function (err, info) {
-        if (err) {
-          return callback(err);
-        }
-        self.constructor.destroy(info.db_name, callback);
-      });
-    });
-
-    PouchDBVersion306.adapters[opts.adapter].call(self, opts, function (err, db) {
-      if (err) {
-        if (callback) {
-          self.taskqueue.fail(err);
-          callback(err);
-        }
-        return;
-      }
-      function destructionListener(event) {
-        if (event === 'destroyed') {
-          self.emit('destroyed');
-          PouchDBVersion306.removeListener(originalName, destructionListener);
-        }
-      }
-      PouchDBVersion306.on(originalName, destructionListener);
-      self.emit('created', self);
-      PouchDBVersion306.emit('created', opts.originalName);
-      self.taskqueue.ready(self);
-      callback(null, self);
-      
-    });
-    if (opts.skipSetup) {
-      self.taskqueue.ready(self);
-    }
-
-    if (utils.isCordova()) {
-      //to inform websql adapter that we can use api
-      cordova.fireWindowEvent(opts.name + "_pouch", {});
-    }
-  });
-  promise.then(function (resp) {
-    oldCB(null, resp);
-  }, oldCB);
-  self.then = promise.then.bind(promise);
-  self["catch"] = promise["catch"].bind(promise);
-
-}
-
-module.exports = PouchDBVersion306;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./adapter":1,"./taskqueue":22,"./utils":23}],8:[function(_dereq_,module,exports){
-"use strict";
-
-var createBlob = _dereq_('./blob.js');
-var errors = _dereq_('./errors');
-var utils = _dereq_("../utils");
-var hasUpload;
-
-function ajax(options, adapterCallback) {
-
-  var requestCompleted = false;
-  var callback = utils.getArguments(function (args) {
-    if (requestCompleted) {
-      return;
-    }
-    adapterCallback.apply(this, args);
-    requestCompleted = true;
-  });
-
-  if (typeof options === "function") {
-    callback = options;
-    options = {};
-  }
-
-  options = utils.clone(options);
-
-  var defaultOptions = {
-    method : "GET",
-    headers: {},
-    json: true,
-    processData: true,
-    timeout: 10000,
-    cache: false
-  };
-
-  options = utils.extend(true, defaultOptions, options);
-
-  // cache-buster, specifically designed to work around IE's aggressive caching
-  // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/
-  if (options.method === 'GET' && !options.cache) {
-    var hasArgs = options.url.indexOf('?') !== -1;
-    options.url += (hasArgs ? '&' : '?') + '_nonce=' + utils.uuid(16);
-  }
-
-  function onSuccess(obj, resp, cb) {
-    if (!options.binary && !options.json && options.processData &&
-      typeof obj !== 'string') {
-      obj = JSON.stringify(obj);
-    } else if (!options.binary && options.json && typeof obj === 'string') {
-      try {
-        obj = JSON.parse(obj);
-      } catch (e) {
-        // Probably a malformed JSON from server
-        return cb(e);
-      }
-    }
-    if (Array.isArray(obj)) {
-      obj = obj.map(function (v) {
-        var obj;
-        if (v.ok) {
-          return v;
-        } else if (v.error && v.error === 'conflict') {
-          obj = errors.REV_CONFLICT;
-          obj.id = v.id;
-          return obj;
-        } else if (v.error && v.error === 'forbidden') {
-          obj = errors.FORBIDDEN;
-          obj.id = v.id;
-          obj.reason = v.reason;
-          return obj;
-        } else if (v.missing) {
-          obj = errors.MISSING_DOC;
-          obj.missing = v.missing;
-          return obj;
-        } else {
-          return v;
-        }
-      });
-    }
-    cb(null, obj, resp);
-  }
-
-  function onError(err, cb) {
-    var errParsed, errObj, errType, key;
-    try {
-      errParsed = JSON.parse(err.responseText);
-      //would prefer not to have a try/catch clause
-      for (key in errors) {
-        if (errors.hasOwnProperty(key) &&
-            errors[key].name === errParsed.error) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType, errParsed.reason);
-    } catch (e) {
-      for (var key in errors) {
-        if (errors.hasOwnProperty(key) && errors[key].status === err.status) {
-          errType = errors[key];
-          break;
-        }
-      }
-      if (!errType) {
-        errType = errors.UNKNOWN_ERROR;
-        if (err.status) {
-          errType.status = err.status;
-        }
-        if (err.statusText) {
-          err.name = err.statusText;
-        }
-      }
-      errObj = errors.error(errType);
-    }
-    if (err.withCredentials && err.status === 0) {
-      // apparently this is what we get when the method
-      // is reported as not allowed by CORS. so fudge it
-      errObj.status = 405;
-      errObj.statusText = "Method Not Allowed";
-    }
-    cb(errObj);
-  }
-
-  var timer;
-  var xhr;
-  if (options.xhr) {
-    xhr = new options.xhr();
-  } else {
-    xhr = new XMLHttpRequest();
-  }
-  xhr.open(options.method, options.url);
-  xhr.withCredentials = true;
-
-  if (options.json) {
-    options.headers.Accept = 'application/json';
-    options.headers['Content-Type'] = options.headers['Content-Type'] ||
-      'application/json';
-    if (options.body &&
-        options.processData &&
-        typeof options.body !== "string") {
-      options.body = JSON.stringify(options.body);
-    }
-  }
-
-  if (options.binary) {
-    xhr.responseType = 'arraybuffer';
-  }
-
-  var createCookie = function (name, value, days) {
-    var expires = "";
-    if (days) {
-      var date = new Date();
-      date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
-      expires = "; expires=" + date.toGMTString();
-    }
-    document.cookie = name + "=" + value + expires + "; path=/";
-  };
-
-  for (var key in options.headers) {
-    if (key === 'Cookie') {
-      var cookie = options.headers[key].split('=');
-      createCookie(cookie[0], cookie[1], 10);
-    } else {
-      xhr.setRequestHeader(key, options.headers[key]);
-    }
-  }
-
-  if (!("body" in options)) {
-    options.body = null;
-  }
-
-  var abortReq = function () {
-    if (requestCompleted) {
-      return;
-    }
-    xhr.abort();
-    onError(xhr, callback);
-  };
-
-  xhr.onreadystatechange = function () {
-    if (xhr.readyState !== 4 || requestCompleted) {
-      return;
-    }
-    clearTimeout(timer);
-    if (xhr.status >= 200 && xhr.status < 300) {
-      var data;
-      if (options.binary) {
-        data = createBlob([xhr.response || ''], {
-          type: xhr.getResponseHeader('Content-Type')
-        });
-      } else {
-        data = xhr.responseText;
-      }
-      onSuccess(data, xhr, callback);
-    } else {
-      onError(xhr, callback);
-    }
-  };
-
-  if (options.timeout > 0) {
-    timer = setTimeout(abortReq, options.timeout);
-    xhr.onprogress = function () {
-      clearTimeout(timer);
-      timer = setTimeout(abortReq, options.timeout);
-    };
-    if (typeof hasUpload === 'undefined') {
-      // IE throws an error if you try to access it directly
-      hasUpload = Object.keys(xhr).indexOf('upload') !== -1;
-    }
-    if (hasUpload) { // does not exist in ie9
-      xhr.upload.onprogress = xhr.onprogress;
-    }
-  }
-  if (options.body && (options.body instanceof Blob)) {
-    var reader = new FileReader();
-    reader.onloadend = function (e) {
-
-      var binary = "";
-      var bytes = new Uint8Array(this.result);
-      var length = bytes.byteLength;
-
-      for (var i = 0; i < length; i++) {
-        binary += String.fromCharCode(bytes[i]);
-      }
-
-      binary = utils.fixBinary(binary);
-      xhr.send(binary);
-    };
-    reader.readAsArrayBuffer(options.body);
-  } else {
-    xhr.send(options.body);
-  }
-  return {abort: abortReq};
-}
-
-module.exports = ajax;
-
-},{"../utils":23,"./blob.js":9,"./errors":11}],9:[function(_dereq_,module,exports){
-(function (global){
-"use strict";
-
-//Abstracts constructing a Blob object, so it also works in older
-//browsers that don't support the native Blob constructor. (i.e.
-//old QtWebKit versions, at least).
-function createBlob(parts, properties) {
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var BlobBuilder = global.BlobBuilder ||
-                      global.MSBlobBuilder ||
-                      global.MozBlobBuilder ||
-                      global.WebKitBlobBuilder;
-    var builder = new BlobBuilder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
-  }
-}
-
-module.exports = createBlob;
-
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],10:[function(_dereq_,module,exports){
-'use strict';
-exports.Map = LazyMap; // TODO: use ES6 map
-exports.Set = LazySet; // TODO: use ES6 set
-// based on https://github.com/montagejs/collections
-function LazyMap() {
-  this.store = {};
-}
-LazyMap.prototype.mangle = function (key) {
-  if (typeof key !== "string") {
-    throw new TypeError("key must be a string but Got " + key);
-  }
-  return '$' + key;
-};
-LazyMap.prototype.unmangle = function (key) {
-  return key.substring(1);
-};
-LazyMap.prototype.get = function (key) {
-  var mangled = this.mangle(key);
-  if (mangled in this.store) {
-    return this.store[mangled];
-  } else {
-    return void 0;
-  }
-};
-LazyMap.prototype.set = function (key, value) {
-  var mangled = this.mangle(key);
-  this.store[mangled] = value;
-  return true;
-};
-LazyMap.prototype.has = function (key) {
-  var mangled = this.mangle(key);
-  return mangled in this.store;
-};
-LazyMap.prototype["delete"] = function (key) {
-  var mangled = this.mangle(key);
-  if (mangled in this.store) {
-    delete this.store[mangled];
-    return true;
-  }
-  return false;
-};
-LazyMap.prototype.forEach = function (cb) {
-  var self = this;
-  var keys = Object.keys(self.store);
-  keys.forEach(function (key) {
-    var value = self.store[key];
-    key = self.unmangle(key);
-    cb(value, key);
-  });
-};
-
-function LazySet() {
-  this.store = new LazyMap();
-}
-LazySet.prototype.add = function (key) {
-  return this.store.set(key, true);
-};
-LazySet.prototype.has = function (key) {
-  return this.store.has(key);
-};
-LazySet.prototype["delete"] = function (key) {
-  return this.store["delete"](key);
-};
-},{}],11:[function(_dereq_,module,exports){
-"use strict";
-
-function PouchError(opts) {
-  this.status = opts.status;
-  this.name = opts.error;
-  this.message = opts.reason;
-  this.error = true;
-}
-
-PouchError.prototype__proto__ = Error.prototype;
-
-PouchError.prototype.toString = function () {
-  return JSON.stringify({
-    status: this.status,
-    name: this.name,
-    message: this.message
-  });
-};
-
-exports.UNAUTHORIZED = new PouchError({
-  status: 401,
-  error: 'unauthorized',
-  reason: "Name or password is incorrect."
-});
-exports.MISSING_BULK_DOCS = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: "Missing JSON list of 'docs'"
-});
-exports.MISSING_DOC = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'missing'
-});
-exports.REV_CONFLICT = new PouchError({
-  status: 409,
-  error: 'conflict',
-  reason: 'Document update conflict'
-});
-exports.INVALID_ID = new PouchError({
-  status: 400,
-  error: 'invalid_id',
-  reason: '_id field must contain a string'
-});
-exports.MISSING_ID = new PouchError({
-  status: 412,
-  error: 'missing_id',
-  reason: '_id is required for puts'
-});
-exports.RESERVED_ID = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Only reserved document ids may start with underscore.'
-});
-exports.NOT_OPEN = new PouchError({
-  status: 412,
-  error: 'precondition_failed',
-  reason: 'Database not open'
-});
-exports.UNKNOWN_ERROR = new PouchError({
-  status: 500,
-  error: 'unknown_error',
-  reason: 'Database encountered an unknown error'
-});
-exports.BAD_ARG = new PouchError({
-  status: 500,
-  error: 'badarg',
-  reason: 'Some query argument is invalid'
-});
-exports.INVALID_REQUEST = new PouchError({
-  status: 400,
-  error: 'invalid_request',
-  reason: 'Request was invalid'
-});
-exports.QUERY_PARSE_ERROR = new PouchError({
-  status: 400,
-  error: 'query_parse_error',
-  reason: 'Some query parameter is invalid'
-});
-exports.DOC_VALIDATION = new PouchError({
-  status: 500,
-  error: 'doc_validation',
-  reason: 'Bad special document member'
-});
-exports.BAD_REQUEST = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Something wrong with the request'
-});
-exports.NOT_AN_OBJECT = new PouchError({
-  status: 400,
-  error: 'bad_request',
-  reason: 'Document must be a JSON object'
-});
-exports.DB_MISSING = new PouchError({
-  status: 404,
-  error: 'not_found',
-  reason: 'Database not found'
-});
-exports.IDB_ERROR = new PouchError({
-  status: 500,
-  error: 'indexed_db_went_bad',
-  reason: 'unknown'
-});
-exports.WSQ_ERROR = new PouchError({
-  status: 500,
-  error: 'web_sql_went_bad',
-  reason: 'unknown'
-});
-exports.LDB_ERROR = new PouchError({
-  status: 500,
-  error: 'levelDB_went_went_bad',
-  reason: 'unknown'
-});
-exports.FORBIDDEN = new PouchError({
-  status: 403,
-  error: 'forbidden',
-  reason: 'Forbidden by design doc validate_doc_update function'
-});
-exports.error = function (error, reason, name) {
-  function CustomPouchError(msg) {
-    this.message = reason;
-    if (name) {
-      this.name = name;
-    }
-  }
-  CustomPouchError.prototype = error;
-  return new CustomPouchError(reason);
-};
-
-},{}],12:[function(_dereq_,module,exports){
-(function (process,global){
-'use strict';
-
-var crypto = _dereq_('crypto');
-var Md5 = _dereq_('spark-md5');
-var setImmediateShim = global.setImmediate || global.setTimeout;
-
-function sliceShim(arrayBuffer, begin, end) {
-  if (typeof arrayBuffer.slice === 'function') {
-    if (!begin) {
-      return arrayBuffer.slice();
-    } else if (!end) {
-      return arrayBuffer.slice(begin);
-    } else {
-      return arrayBuffer.slice(begin, end);
-    }
-  }
-  //
-  // shim for IE courtesy of http://stackoverflow.com/a/21440217
-  //
-
-  //If `begin`/`end` is unspecified, Chrome assumes 0, so we do the same
-  //Chrome also converts the values to integers via flooring
-  begin = Math.floor(begin || 0);
-  end = Math.floor(end || 0);
-
-  var len = arrayBuffer.byteLength;
-
-  //If either `begin` or `end` is negative, it refers to an
-  //index from the end of the array, as opposed to from the beginning.
-  //The range specified by the `begin` and `end` values is clamped to the
-  //valid index range for the current array.
-  begin = begin < 0 ? Math.max(begin + len, 0) : Math.min(len, begin);
-  end = end < 0 ? Math.max(end + len, 0) : Math.min(len, end);
-
-  //If the computed length of the new ArrayBuffer would be negative, it
-  //is clamped to zero.
-  if (end - begin <= 0) {
-    return new ArrayBuffer(0);
-  }
-
-  var result = new ArrayBuffer(end - begin);
-  var resultBytes = new Uint8Array(result);
-  var sourceBytes = new Uint8Array(arrayBuffer, begin, end - begin);
-
-  resultBytes.set(sourceBytes);
-
-  return result;
-}
-
-// convert a 64-bit int to a binary string
-function intToString(int) {
-  var bytes = [
-    (int & 0xff),
-    ((int >>> 8) & 0xff),
-    ((int >>> 16) & 0xff),
-    ((int >>> 24) & 0xff)
-  ];
-  return bytes.map(function (byte) {
-    return String.fromCharCode(byte);
-  }).join('');
-}
-
-// convert an array of 64-bit ints into
-// a base64-encoded string
-function rawToBase64(raw) {
-  var res = '';
-  for (var i = 0; i < raw.length; i++) {
-    res += intToString(raw[i]);
-  }
-  return global.btoa(res);
-}
-
-module.exports = function (data, callback) {
-  if (!process.browser) {
-    var base64 = crypto.createHash('md5').update(data).digest('base64');
-    callback(null, base64);
-    return;
-  }
-  var inputIsString = typeof data === 'string';
-  var len = inputIsString ? data.length : data.byteLength;
-  var chunkSize = Math.min(524288, len);
-  var chunks = Math.ceil(len / chunkSize);
-  var currentChunk = 0;
-  var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
-
-  function append(buffer, data, start, end) {
-    if (inputIsString) {
-      buffer.appendBinary(data.substring(start, end));
-    } else {
-      buffer.append(sliceShim(data, start, end));
-    }
-  }
-
-  function loadNextChunk() {
-    var start = currentChunk * chunkSize;
-    var end = start + chunkSize;
-    if ((start + chunkSize) >= data.size) {
-      end = data.size;
-    }
-    currentChunk++;
-    if (currentChunk < chunks) {
-      append(buffer, data, start, end);
-      setImmediateShim(loadNextChunk);
-    } else {
-      append(buffer, data, start, end);
-      var raw = buffer.end(true);
-      var base64 = rawToBase64(raw);
-      callback(null, base64);
-      buffer.destroy();
-    }
-  }
-  loadNextChunk();
-};
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"crypto":26,"spark-md5":57}],13:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('../utils').Promise;
-
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    if (docId && typeof docId === 'object') {
-      docId = docId._id;
-    }
-    if (typeof docId !== 'string') {
-      return reject(new Error('doc id is required'));
-    }
-
-    db.get(docId, function (err, doc) {
-      if (err) {
-        if (err.status !== 404) {
-          return reject(err);
-        }
-        return fulfill(tryAndPut(db, diffFun({_id : docId}), diffFun));
-      }
-      var newDoc = diffFun(doc);
-      if (!newDoc) {
-        return fulfill(doc);
-      }
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
-  });
-}
-
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc)["catch"](function (err) {
-    if (err.status !== 409) {
-      throw err;
-    }
-    return upsert(db, doc, diffFun);
-  });
-}
-
-module.exports = function (db, docId, diffFun, cb) {
-  if (typeof cb === 'function') {
-    upsert(db, docId, diffFun).then(function (resp) {
-      cb(null, resp);
-    }, cb);
-  } else {
-    return upsert(db, docId, diffFun);
-  }
-};
-
-},{"../utils":23}],14:[function(_dereq_,module,exports){
-"use strict";
-
-// BEGIN Math.uuid.js
-
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- *   length - the desired number of characters
- *   radix  - the number of allowable values for each character.
- *
- * EXAMPLES:
- *   // No arguments  - returns RFC4122, version 4 ID
- *   >>> Math.uuid()
- *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- *   // One argument - returns ID of the specified length
- *   >>> Math.uuid(15)     // 15 character ID (default base=62)
- *   "VcydxgltxrVZSTV"
- *
- *   // Two arguments - returns ID of the specified length, and radix. 
- *   // (Radix must be <= 62)
- *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
- *   "01001010"
- *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
- *   "47473046"
- *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
- *   "098F4D35"
- */
-var chars = (
-  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
-  'abcdefghijklmnopqrstuvwxyz'
-).split('');
-function getValue(radix) {
-  return 0 | Math.random() * radix;
-}
-function uuid(len, radix) {
-  radix = radix || chars.length;
-  var out = '';
-  var i = -1;
-
-  if (len) {
-    // Compact form
-    while (++i < len) {
-      out += chars[getValue(radix)];
-    }
-    return out;
-  }
-    // rfc4122, version 4 form
-    // Fill in random data.  At i==19 set the high bits of clock sequence as
-    // per rfc4122, sec. 4.1.5
-  while (++i < 36) {
-    switch (i) {
-      case 8:
-      case 13:
-      case 18:
-      case 23:
-        out += '-';
-        break;
-      case 19:
-        out += chars[(getValue(16) & 0x3) | 0x8];
-        break;
-      default:
-        out += chars[getValue(16)];
-    }
-  }
-
-  return out;
-}
-
-
-
-module.exports = uuid;
-
-
-},{}],15:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = evalFilter;
-function evalFilter(input) {
-  /*jshint evil: true */
-  return eval([
-    '(function () { return ',
-    input,
-    ' })()'
-  ].join(''));
-}
-},{}],16:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = evalView;
-function evalView(input) {
-  /*jshint evil: true */
-  return eval([
-    '(function () {',
-    '  return function (doc) {',
-    '    var emitted = false;',
-    '    var emit = function (a, b) {',
-    '      emitted = true;',
-    '    };',
-    '    var view = ' + input + ';',
-    '    view(doc);',
-    '    if (emitted) {',
-    '      return true;',
-    '    }',
-    '  }',
-    '})()'
-  ].join('\n'));
-}
-},{}],17:[function(_dereq_,module,exports){
-(function (process){
-"use strict";
-
-var PouchDBVersion306 = _dereq_('./setup');
-
-module.exports = PouchDBVersion306;
-
-PouchDBVersion306.ajax = _dereq_('./deps/ajax');
-PouchDBVersion306.extend = _dereq_('pouchdb-extend');
-PouchDBVersion306.utils = _dereq_('./utils');
-PouchDBVersion306.Errors = _dereq_('./deps/errors');
-PouchDBVersion306.replicate = _dereq_('./replicate').replicate;
-PouchDBVersion306.sync = _dereq_('./sync');
-PouchDBVersion306.version = _dereq_('./version');
-var httpAdapter = _dereq_('./adapters/http');
-PouchDBVersion306.adapter('http', httpAdapter);
-PouchDBVersion306.adapter('https', httpAdapter);
-
-PouchDBVersion306.adapter('idb', _dereq_('./adapters/idb'));
-PouchDBVersion306.adapter('websql', _dereq_('./adapters/websql'));
-PouchDBVersion306.plugin(_dereq_('pouchdb-mapreduce'));
-
-if (!process.browser) {
-  var ldbAdapter = _dereq_('./adapters/leveldb');
-  PouchDBVersion306.adapter('ldb', ldbAdapter);
-  PouchDBVersion306.adapter('leveldb', ldbAdapter);
-}
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"./adapters/http":2,"./adapters/idb":3,"./adapters/leveldb":26,"./adapters/websql":5,"./deps/ajax":8,"./deps/errors":11,"./replicate":19,"./setup":20,"./sync":21,"./utils":23,"./version":24,"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"pouchdb-extend":48,"pouchdb-mapreduce":51}],18:[function(_dereq_,module,exports){
-'use strict';
-var extend = _dereq_('pouchdb-extend');
-
-
-// for a better overview of what this is doing, read:
-// https://github.com/apache/couchdb/blob/master/src/couchdb/couch_key_tree.erl
-//
-// But for a quick intro, CouchDB uses a revision tree to store a documents
-// history, A -> B -> C, when a document has conflicts, that is a branch in the
-// tree, A -> (B1 | B2 -> C), We store these as a nested array in the format
-//
-// KeyTree = [Path ... ]
-// Path = {pos: position_from_root, ids: Tree}
-// Tree = [Key, Opts, [Tree, ...]], in particular single node: [Key, []]
-
-// Turn a path as a flat array into a tree with a single branch
-function pathToTree(path) {
-  var doc = path.shift();
-  var root = [doc.id, doc.opts, []];
-  var leaf = root;
-  var nleaf;
-
-  while (path.length) {
-    doc = path.shift();
-    nleaf = [doc.id, doc.opts, []];
-    leaf[2].push(nleaf);
-    leaf = nleaf;
-  }
-  return root;
-}
-
-// Merge two trees together
-// The roots of tree1 and tree2 must be the same revision
-function mergeTree(in_tree1, in_tree2) {
-  var queue = [{tree1: in_tree1, tree2: in_tree2}];
-  var conflicts = false;
-  while (queue.length > 0) {
-    var item = queue.pop();
-    var tree1 = item.tree1;
-    var tree2 = item.tree2;
-
-    if (tree1[1].status || tree2[1].status) {
-      tree1[1].status =
-        (tree1[1].status ===  'available' ||
-         tree2[1].status === 'available') ? 'available' : 'missing';
-    }
-
-    for (var i = 0; i < tree2[2].length; i++) {
-      if (!tree1[2][0]) {
-        conflicts = 'new_leaf';
-        tree1[2][0] = tree2[2][i];
-        continue;
-      }
-
-      var merged = false;
-      for (var j = 0; j < tree1[2].length; j++) {
-        if (tree1[2][j][0] === tree2[2][i][0]) {
-          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
-          merged = true;
-        }
-      }
-      if (!merged) {
-        conflicts = 'new_branch';
-        tree1[2].push(tree2[2][i]);
-        tree1[2].sort();
-      }
-    }
-  }
-  return {conflicts: conflicts, tree: in_tree1};
-}
-
-function doMerge(tree, path, dontExpand) {
-  var restree = [];
-  var conflicts = false;
-  var merged = false;
-  var res;
-
-  if (!tree.length) {
-    return {tree: [path], conflicts: 'new_leaf'};
-  }
-
-  tree.forEach(function (branch) {
-    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
-      // Paths start at the same position and have the same root, so they need
-      // merged
-      res = mergeTree(branch.ids, path.ids);
-      restree.push({pos: branch.pos, ids: res.tree});
-      conflicts = conflicts || res.conflicts;
-      merged = true;
-    } else if (dontExpand !== true) {
-      // The paths start at a different position, take the earliest path and
-      // traverse up until it as at the same point from root as the path we
-      // want to merge.  If the keys match we return the longer path with the
-      // other merged After stemming we dont want to expand the trees
-
-      var t1 = branch.pos < path.pos ? branch : path;
-      var t2 = branch.pos < path.pos ? path : branch;
-      var diff = t2.pos - t1.pos;
-
-      var candidateParents = [];
-
-      var trees = [];
-      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
-      while (trees.length > 0) {
-        var item = trees.pop();
-        if (item.diff === 0) {
-          if (item.ids[0] === t2.ids[0]) {
-            candidateParents.push(item);
-          }
-          continue;
-        }
-        if (!item.ids) {
-          continue;
-        }
-        /*jshint loopfunc:true */
-        item.ids[2].forEach(function (el, idx) {
-          trees.push(
-            {ids: el, diff: item.diff - 1, parent: item.ids, parentIdx: idx});
-        });
-      }
-
-      var el = candidateParents[0];
-
-      if (!el) {
-        restree.push(branch);
-      } else {
-        res = mergeTree(el.ids, t2.ids);
-        el.parent[2][el.parentIdx] = res.tree;
-        restree.push({pos: t1.pos, ids: t1.ids});
-        conflicts = conflicts || res.conflicts;
-        merged = true;
-      }
-    } else {
-      restree.push(branch);
-    }
-  });
-
-  // We didnt find
-  if (!merged) {
-    restree.push(path);
-  }
-
-  restree.sort(function (a, b) {
-    return a.pos - b.pos;
-  });
-
-  return {
-    tree: restree,
-    conflicts: conflicts || 'internal_node'
-  };
-}
-
-// To ensure we dont grow the revision tree infinitely, we stem old revisions
-function stem(tree, depth) {
-  // First we break out the tree into a complete list of root to leaf paths,
-  // we cut off the start of the path and generate a new set of flat trees
-  var stemmedPaths = PouchMerge.rootToLeaf(tree).map(function (path) {
-    var stemmed = path.ids.slice(-depth);
-    return {
-      pos: path.pos + (path.ids.length - stemmed.length),
-      ids: pathToTree(stemmed)
-    };
-  });
-  // Then we remerge all those flat trees together, ensuring that we dont
-  // connect trees that would go beyond the depth limit
-  return stemmedPaths.reduce(function (prev, current, i, arr) {
-    return doMerge(prev, current, true).tree;
-  }, [stemmedPaths.shift()]);
-}
-
-var PouchMerge = {};
-
-PouchMerge.merge = function (tree, path, depth) {
-  // Ugh, nicer way to not modify arguments in place?
-  tree = extend(true, [], tree);
-  path = extend(true, {}, path);
-  var newTree = doMerge(tree, path);
-  return {
-    tree: stem(newTree.tree, depth),
-    conflicts: newTree.conflicts
-  };
-};
-
-// We fetch all leafs of the revision tree, and sort them based on tree length
-// and whether they were deleted, undeleted documents with the longest revision
-// tree (most edits) win
-// The final sort algorithm is slightly documented in a sidebar here:
-// http://guide.couchdb.org/draft/conflicts.html
-PouchMerge.winningRev = function (metadata) {
-  var leafs = [];
-  PouchMerge.traverseRevTree(metadata.rev_tree,
-                              function (isLeaf, pos, id, something, opts) {
-    if (isLeaf) {
-      leafs.push({pos: pos, id: id, deleted: !!opts.deleted});
-    }
-  });
-  leafs.sort(function (a, b) {
-    if (a.deleted !== b.deleted) {
-      return a.deleted > b.deleted ? 1 : -1;
-    }
-    if (a.pos !== b.pos) {
-      return b.pos - a.pos;
-    }
-    return a.id < b.id ? 1 : -1;
-  });
-
-  return leafs[0].pos + '-' + leafs[0].id;
-};
-
-// Pretty much all below can be combined into a higher order function to
-// traverse revisions
-// The return value from the callback will be passed as context to all
-// children of that node
-PouchMerge.traverseRevTree = function (revs, callback) {
-  var toVisit = revs.slice();
-
-  var node;
-  while ((node = toVisit.pop())) {
-    var pos = node.pos;
-    var tree = node.ids;
-    var branches = tree[2];
-    var newCtx =
-      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
-    for (var i = 0, len = branches.length; i < len; i++) {
-      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
-    }
-  }
-};
-
-PouchMerge.collectLeaves = function (revs) {
-  var leaves = [];
-  PouchMerge.traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
-    if (isLeaf) {
-      leaves.unshift({rev: pos + "-" + id, pos: pos, opts: opts});
-    }
-  });
-  leaves.sort(function (a, b) {
-    return b.pos - a.pos;
-  });
-  leaves.map(function (leaf) { delete leaf.pos; });
-  return leaves;
-};
-
-// returns revs of all conflicts that is leaves such that
-// 1. are not deleted and
-// 2. are different than winning revision
-PouchMerge.collectConflicts = function (metadata) {
-  var win = PouchMerge.winningRev(metadata);
-  var leaves = PouchMerge.collectLeaves(metadata.rev_tree);
-  var conflicts = [];
-  leaves.forEach(function (leaf) {
-    if (leaf.rev !== win && !leaf.opts.deleted) {
-      conflicts.push(leaf.rev);
-    }
-  });
-  return conflicts;
-};
-
-PouchMerge.rootToLeaf = function (tree) {
-  var paths = [];
-  PouchMerge.traverseRevTree(tree, function (isLeaf, pos, id, history, opts) {
-    history = history ? history.slice(0) : [];
-    history.push({id: id, opts: opts});
-    if (isLeaf) {
-      var rootPos = pos + 1 - history.length;
-      paths.unshift({pos: rootPos, ids: history});
-    }
-    return history;
-  });
-  return paths;
-};
-
-
-module.exports = PouchMerge;
-
-},{"pouchdb-extend":48}],19:[function(_dereq_,module,exports){
-'use strict';
-
-var utils = _dereq_('./utils');
-var EE = _dereq_('events').EventEmitter;
-
-var MAX_SIMULTANEOUS_REVS = 50;
-
-// We create a basic promise so the caller can cancel the replication possibly
-// before we have actually started listening to changes etc
-utils.inherits(Replication, EE);
-function Replication(opts) {
-  EE.call(this);
-  this.cancelled = false;
-  var self = this;
-  var promise = new utils.Promise(function (fulfill, reject) {
-    self.once('complete', fulfill);
-    self.once('error', reject);
-  });
-  self.then = function (resolve, reject) {
-    return promise.then(resolve, reject);
-  };
-  self["catch"] = function (reject) {
-    return promise["catch"](reject);
-  };
-  // As we allow error handling via "error" event as well,
-  // put a stub in here so that rejecting never throws UnhandledError.
-  self["catch"](function (err) {});
-}
-
-Replication.prototype.cancel = function () {
-  this.cancelled = true;
-  this.emit('cancel');
-};
-
-Replication.prototype.ready = function (src, target) {
-  var self = this;
-  function onDestroy() {
-    self.cancel();
-  }
-  src.once('destroyed', onDestroy);
-  target.once('destroyed', onDestroy);
-  function cleanup() {
-    src.removeListener('destroyed', onDestroy);
-    target.removeListener('destroyed', onDestroy);
-  }
-  this.then(cleanup, cleanup);
-};
-
-
-// TODO: check CouchDB's replication id generation
-// Generate a unique id particular to this replication
-function genReplicationId(src, target, opts) {
-  var filterFun = opts.filter ? opts.filter.toString() : '';
-  return src.id().then(function (src_id) {
-    return target.id().then(function (target_id) {
-      var queryData = src_id + target_id + filterFun +
-        JSON.stringify(opts.query_params) + opts.doc_ids;
-      return utils.MD5(queryData).then(function (md5) {
-        // can't use straight-up md5 alphabet, because
-        // the char '/' is interpreted as being for attachments,
-        // and + is also not url-safe
-        md5 = md5.replace(/\//g, '.').replace(/\+/g, '_');
-        return '_local/' + md5;
-      });
-    });
-  });
-}
-
-
-function updateCheckpoint(db, id, checkpoint, returnValue) {
-    return db.get(id)["catch"](function (err) {
-      if (err.status === 404) {
-        return {_id: id};
-      }
-      throw err;
-    }).then(function (doc) {
-      if (returnValue.cancelled) {
-        return;
-      }
-      doc.last_seq = checkpoint;
-      return db.put(doc);
-    });
-  }
-
-function Checkpointer(src, target, id, returnValue) {
-  this.src = src;
-  this.target = target;
-  this.id = id;
-  this.returnValue = returnValue;
-}
-
-Checkpointer.prototype.writeCheckpoint = function (checkpoint) {
-  var self = this;
-  return this.updateTarget(checkpoint).then(function () {
-    return self.updateSource(checkpoint);
-  });
-};
-Checkpointer.prototype.updateTarget = function (checkpoint) {
-  return updateCheckpoint(this.target, this.id, checkpoint, this.returnValue);
-};
-Checkpointer.prototype.updateSource = function (checkpoint) {
-  var self = this;
-  if (this.readOnlySource) {
-    return utils.Promise.resolve(true);
-  }
-  return updateCheckpoint(this.src, this.id, checkpoint, this.returnValue)[
-    "catch"](function (err) {
-    var isForbidden = typeof err.status === 'number' &&
-      Math.floor(err.status / 100) === 4;
-    if (isForbidden) {
-      self.readOnlySource = true;
-      return true;
-    }
-    throw err;
-  });
-};
-Checkpointer.prototype.getCheckpoint = function () {
-  var self = this;
-  return self.target.get(self.id).then(function (targetDoc) {
-    return self.src.get(self.id).then(function (sourceDoc) {
-      if (targetDoc.last_seq === sourceDoc.last_seq) {
-        return sourceDoc.last_seq;
-      }
-      return 0;
-    }, function (err) {
-      if (err.status === 404 && targetDoc.last_seq) {
-        return self.src.put({
-          _id: self.id,
-          last_seq: 0
-        }).then(function () {
-          return 0;
-        }, function (err) {
-          if (err.status === 401) {
-            self.readOnlySource = true;
-            return targetDoc.last_seq;
-          }
-          return 0;
-        });
-      }
-      throw err;
-    });
-  })["catch"](function (err) {
-    if (err.status !== 404) {
-      throw err;
-    }
-    return 0;
-  });
-};
-function replicate(repId, src, target, opts, returnValue) {
-  var batches = [];               // list of batches to be processed
-  var currentBatch;               // the batch currently being processed
-  var pendingBatch = {
-    seq: 0,
-    changes: [],
-    docs: []
-  }; // next batch, not yet ready to be processed
-  var writingCheckpoint = false;  // true while checkpoint is being written
-  var changesCompleted = false;   // true when all changes received
-  var replicationCompleted = false; // true when replication has completed
-  var last_seq = 0;
-  var continuous = opts.continuous || opts.live || false;
-  var batch_size = opts.batch_size || 100;
-  var batches_limit = opts.batches_limit || 10;
-  var changesPending = false;     // true while src.changes is running
-  var doc_ids = opts.doc_ids;
-  var checkpointer = new Checkpointer(src, target, repId, returnValue);
-  var result = {
-    ok: true,
-    start_time: new Date(),
-    docs_read: 0,
-    docs_written: 0,
-    doc_write_failures: 0,
-    errors: []
-  };
-  var changesOpts = {};
-  returnValue.ready(src, target);
-
-
-  function writeDocs() {
-    if (currentBatch.docs.length === 0) {
-      return;
-    }
-    var docs = currentBatch.docs;
-    return target.bulkDocs({
-      docs: docs
-    }, {
-      new_edits: false
-    }).then(function (res) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      var errors = [];
-      res.forEach(function (res) {
-        if (res.error) {
-          result.doc_write_failures++;
-          var error = new Error(res.reason || res.message || 'Unknown reason');
-          error.name = res.name || res.error;
-          errors.push(error);
-        }
-      });
-      result.errors = result.errors.concat(errors);
-      result.docs_written += currentBatch.docs.length - errors.length;
-      var non403s = errors.filter(function (error) {
-        return error.name !== 'unauthorized' && error.name !== 'forbidden';
-      });
-      if (non403s.length > 0) {
-        var error = new Error('bulkDocs error');
-        error.other_errors = errors;
-        abortReplication('target.bulkDocs failed to write docs', error);
-        throw new Error('bulkWrite partial failure');
-      }
-    }, function (err) {
-      result.doc_write_failures += docs.length;
-      throw err;
-    });
-  }
-
-
-  function getNextDoc() {
-    var diffs = currentBatch.diffs;
-    var id = Object.keys(diffs)[0];
-    var allMissing = diffs[id].missing;
-    // avoid url too long error by batching
-    var missingBatches = [];
-    for (var i = 0; i < allMissing.length; i += MAX_SIMULTANEOUS_REVS) {
-      missingBatches.push(allMissing.slice(i, Math.min(allMissing.length,
-        i + MAX_SIMULTANEOUS_REVS)));
-    }
-
-    return utils.Promise.all(missingBatches.map(function (missing) {
-      return src.get(id, {revs: true, open_revs: missing, attachments: true})
-        .then(function (docs) {
-          docs.forEach(function (doc) {
-            if (returnValue.cancelled) {
-              return completeReplication();
-            }
-            if (doc.ok) {
-              result.docs_read++;
-              currentBatch.pendingRevs++;
-              currentBatch.docs.push(doc.ok);
-              delete diffs[doc.ok._id];
-            }
-          });
-        });
-    }));
-  }
-
-  function getAllDocs() {
-    if (Object.keys(currentBatch.diffs).length > 0) {
-      return getNextDoc().then(getAllDocs);
-    } else {
-      return utils.Promise.resolve();
-    }
-  }
-
-
-  function getRevisionOneDocs() {
-    // filter out the generation 1 docs and get them
-    // leaving the non-generation one docs to be got otherwise
-    var ids = Object.keys(currentBatch.diffs).filter(function (id) {
-      var missing = currentBatch.diffs[id].missing;
-      return missing.length === 1 && missing[0].slice(0, 2) === '1-';
-    });
-    return src.allDocs({
-      keys: ids,
-      include_docs: true
-    }).then(function (res) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw (new Error('cancelled'));
-      }
-      res.rows.forEach(function (row) {
-        if (row.doc && !row.deleted &&
-          row.value.rev.slice(0, 2) === '1-' && (
-            !row.doc._attachments ||
-            Object.keys(row.doc._attachments).length === 0
-          )
-        ) {
-          result.docs_read++;
-          currentBatch.pendingRevs++;
-          currentBatch.docs.push(row.doc);
-          delete currentBatch.diffs[row.id];
-        }
-      });
-    });
-  }
-
-
-  function getDocs() {
-    return getRevisionOneDocs().then(getAllDocs);
-  }
-
-
-  function finishBatch() {
-    writingCheckpoint = true;
-    return checkpointer.writeCheckpoint(
-      currentBatch.seq
-    ).then(function (res) {
-      writingCheckpoint = false;
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      result.last_seq = last_seq = currentBatch.seq;
-      returnValue.emit('change', utils.clone(result));
-      currentBatch = undefined;
-      getChanges();
-    })["catch"](function (err) {
-      writingCheckpoint = false;
-      abortReplication('writeCheckpoint completed with error', err);
-      throw err;
-    });
-  }
-
-
-  function getDiffs() {
-    var diff = {};
-    currentBatch.changes.forEach(function (change) {
-      diff[change.id] = change.changes.map(function (x) {
-        return x.rev;
-      });
-    });
-    return target.revsDiff(diff).then(function (diffs) {
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      // currentBatch.diffs elements are deleted as the documents are written
-      currentBatch.diffs = diffs;
-      currentBatch.pendingRevs = 0;
-    });
-  }
-
-
-  function startNextBatch() {
-    if (returnValue.cancelled || currentBatch) {
-      return;
-    }
-    if (batches.length === 0) {
-      processPendingBatch(true);
-      return;
-    }
-    currentBatch = batches.shift();
-    getDiffs()
-    .then(getDocs)
-    .then(writeDocs)
-    .then(finishBatch)
-    .then(startNextBatch)[
-    "catch"](function (err) {
-      abortReplication('batch processing terminated with error', err);
-    });
-  }
-
-
-  function processPendingBatch(immediate) {
-    if (pendingBatch.changes.length === 0) {
-      if (batches.length === 0 && !currentBatch) {
-        if ((continuous && changesOpts.live) || changesCompleted) {
-          returnValue.emit('uptodate', utils.clone(result));
-        }
-        if (changesCompleted) {
-          completeReplication();
-        }
-      }
-      return;
-    }
-    if (
-      immediate ||
-      changesCompleted ||
-      pendingBatch.changes.length >= batch_size
-    ) {
-      batches.push(pendingBatch);
-      pendingBatch = {
-        seq: 0,
-        changes: [],
-        docs: []
-      };
-      startNextBatch();
-    }
-  }
-
-
-  function abortReplication(reason, err) {
-    if (replicationCompleted) {
-      return;
-    }
-    result.ok = false;
-    result.status = 'aborted';
-    result.errors.push(err);
-    batches = [];
-    pendingBatch = {
-      seq: 0,
-      changes: [],
-      docs: []
-    };
-    completeReplication();
-  }
-
-
-  function completeReplication() {
-    if (replicationCompleted) {
-      return;
-    }
-    if (returnValue.cancelled) {
-      result.status = 'cancelled';
-      if (writingCheckpoint) {
-        return;
-      }
-    }
-    result.status = result.status || 'complete';
-    result.end_time = new Date();
-    result.last_seq = last_seq;
-    replicationCompleted = returnValue.cancelled = true;
-    var non403s = result.errors.filter(function (error) {
-      return error.name !== 'unauthorized' && error.name !== 'forbidden';
-    });
-    if (non403s.length > 0) {
-      var error = result.errors.pop();
-      if (result.errors.length > 0) {
-        error.other_errors = result.errors;
-      }
-      error.result = result;
-      returnValue.emit('error', error);
-    } else {
-      returnValue.emit('complete', result);
-    }
-    returnValue.removeAllListeners();
-  }
-
-
-  function onChange(change) {
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    if (
-      pendingBatch.changes.length === 0 &&
-      batches.length === 0 &&
-      !currentBatch
-    ) {
-      returnValue.emit('outofdate', utils.clone(result));
-    }
-    pendingBatch.seq = change.seq;
-    pendingBatch.changes.push(change);
-    processPendingBatch(batches.length === 0);
-  }
-
-
-  function onChangesComplete(changes) {
-    changesPending = false;
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    if (changesOpts.since < changes.last_seq) {
-      changesOpts.since = changes.last_seq;
-      getChanges();
-    } else {
-      if (continuous) {
-        changesOpts.live = true;
-        getChanges();
-      } else {
-        changesCompleted = true;
-      }
-    }
-    processPendingBatch(true);
-  }
-
-
-  function onChangesError(err) {
-    changesPending = false;
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    abortReplication('changes rejected', err);
-  }
-
-
-  function getChanges() {
-    if (!(
-      !changesPending &&
-      !changesCompleted &&
-      batches.length < batches_limit
-    )) {
-      return;
-    }
-    changesPending = true;
-    function abortChanges() {
-      changes.cancel();
-    }
-    function removeListener() {
-      returnValue.removeListener('cancel', abortChanges);
-    }
-    returnValue.once('cancel', abortChanges);
-    var changes = src.changes(changesOpts)
-    .on('change', onChange);
-    changes.then(removeListener, removeListener);
-    changes.then(onChangesComplete)[
-    "catch"](onChangesError);
-  }
-
-
-  function startChanges() {
-    checkpointer.getCheckpoint().then(function (checkpoint) {
-      last_seq = checkpoint;
-      changesOpts = {
-        since: last_seq,
-        limit: batch_size,
-        batch_size: batch_size,
-        style: 'all_docs',
-        doc_ids: doc_ids,
-        returnDocs: false
-      };
-      if (opts.filter) {
-        changesOpts.filter = opts.filter;
-      }
-      if (opts.query_params) {
-        changesOpts.query_params = opts.query_params;
-      }
-      getChanges();
-    })["catch"](function (err) {
-      abortReplication('getCheckpoint rejected with ', err);
-    });
-  }
-
-
-  returnValue.once('cancel', completeReplication);
-
-  if (typeof opts.onChange === 'function') {
-    returnValue.on('change', opts.onChange);
-  }
-
-  if (typeof opts.complete === 'function') {
-    returnValue.once('error', opts.complete);
-    returnValue.once('complete', function (result) {
-      opts.complete(null, result);
-    });
-  }
-
-  if (typeof opts.since === 'undefined') {
-    startChanges();
-  } else {
-    writingCheckpoint = true;
-    checkpointer.writeCheckpoint(opts.since).then(function (res) {
-      writingCheckpoint = false;
-      if (returnValue.cancelled) {
-        completeReplication();
-        return;
-      }
-      last_seq = opts.since;
-      startChanges();
-    })["catch"](function (err) {
-      writingCheckpoint = false;
-      abortReplication('writeCheckpoint completed with error', err);
-      throw err;
-    });
-  }
-}
-
-exports.toPouch = toPouch;
-function toPouch(db, opts) {
-  var PouchConstructor = opts.PouchConstructor;
-  if (typeof db === 'string') {
-    return new PouchConstructor(db);
-  } else if (db.then) {
-    return db;
-  } else {
-    return utils.Promise.resolve(db);
-  }
-}
-
-
-exports.replicate = replicateWrapper;
-function replicateWrapper(src, target, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof opts === 'undefined') {
-    opts = {};
-  }
-  if (!opts.complete) {
-    opts.complete = callback || function () {};
-  }
-  opts = utils.clone(opts);
-  opts.continuous = opts.continuous || opts.live;
-  /*jshint validthis:true */
-  opts.PouchConstructor = opts.PouchConstructor || this;
-  var replicateRet = new Replication(opts);
-  toPouch(src, opts).then(function (src) {
-    return toPouch(target, opts).then(function (target) {
-      return genReplicationId(src, target, opts).then(function (repId) {
-        replicate(repId, src, target, opts, replicateRet);
-      });
-    });
-  })["catch"](function (err) {
-    replicateRet.emit('error', err);
-    opts.complete(err);
-  });
-  return replicateRet;
-}
-
-},{"./utils":23,"events":27}],20:[function(_dereq_,module,exports){
-(function (global){
-"use strict";
-
-var PouchDBVersion306 = _dereq_("./constructor");
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-var EventEmitter = _dereq_('events').EventEmitter;
-PouchDBVersion306.adapters = {};
-PouchDBVersion306.preferredAdapters = _dereq_('./adapters/preferredAdapters.js');
-
-PouchDBVersion306.prefix = '_pouch_';
-
-var eventEmitter = new EventEmitter();
-
-var eventEmitterMethods = [
-  'on',
-  'addListener',
-  'emit',
-  'listeners',
-  'once',
-  'removeAllListeners',
-  'removeListener',
-  'setMaxListeners'
-];
-
-eventEmitterMethods.forEach(function (method) {
-  PouchDBVersion306[method] = eventEmitter[method].bind(eventEmitter);
-});
-PouchDBVersion306.setMaxListeners(0);
-PouchDBVersion306.parseAdapter = function (name, opts) {
-  var match = name.match(/([a-z\-]*):\/\/(.*)/);
-  var adapter, adapterName;
-  if (match) {
-    // the http adapter expects the fully qualified name
-    name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
-    adapter = match[1];
-    if (!PouchDBVersion306.adapters[adapter].valid()) {
-      throw 'Invalid adapter';
-    }
-    return {name: name, adapter: match[1]};
-  }
-
-  // check for browsers that have been upgraded from websql-only to websql+idb
-  var skipIdb = 'idb' in PouchDBVersion306.adapters && 'websql' in PouchDBVersion306.adapters &&
-    utils.hasLocalStorage() &&
-    global.localStorage['_pouch__websqldb_' + PouchDBVersion306.prefix + name];
-
-  if (typeof opts !== 'undefined' && opts.db) {
-    adapterName = 'leveldb';
-  } else {
-    for (var i = 0; i < PouchDBVersion306.preferredAdapters.length; ++i) {
-      adapterName = PouchDBVersion306.preferredAdapters[i];
-      if (adapterName in PouchDBVersion306.adapters) {
-        if (skipIdb && adapterName === 'idb') {
-          continue; // keep using websql to avoid user data loss
-        }
-        break;
-      }
-    }
-  }
-
-  adapter = PouchDBVersion306.adapters[adapterName];
-  if (adapterName && adapter) {
-    var use_prefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-
-    return {
-      name: use_prefix ? PouchDBVersion306.prefix + name : name,
-      adapter: adapterName
-    };
-  }
-
-  throw 'No valid adapter found';
-};
-
-PouchDBVersion306.destroy = utils.toPromise(function (name, opts, callback) {
-  if (typeof opts === 'function' || typeof opts === 'undefined') {
-    callback = opts;
-    opts = {};
-  }
-
-  if (name && typeof name === 'object') {
-    opts = name;
-    name = undefined;
-  }
-
-  var backend = PouchDBVersion306.parseAdapter(opts.name || name, opts);
-  var dbName = backend.name;
-  var adapter = PouchDBVersion306.adapters[backend.adapter];
-  var usePrefix = 'use_prefix' in adapter ? adapter.use_prefix : true;
-  var baseName = usePrefix ?
-    dbName.replace(new RegExp('^' + PouchDBVersion306.prefix), '') : dbName;
-  var fullName = (backend.adapter === 'http' || backend.adapter === 'https' ?
-      '' : (opts.prefix || '')) + dbName;
-  function destroyDb() {
-    // call destroy method of the particular adaptor
-    adapter.destroy(fullName, opts, function (err, resp) {
-      if (err) {
-        callback(err);
-      } else {
-        PouchDBVersion306.emit('destroyed', name);
-        //so we don't have to sift through all dbnames
-        PouchDBVersion306.emit(name, 'destroyed');
-        callback(null, resp || { 'ok': true });
-      }
-    });
-  }
-
-  var createOpts = utils.extend(true, {}, opts, {adapter : backend.adapter});
-  new PouchDBVersion306(baseName, createOpts, function (err, db) {
-    if (err) {
-      return callback(err);
-    }
-    db.get('_local/_pouch_dependentDbs', function (err, localDoc) {
-      if (err) {
-        if (err.status !== 404) {
-          return callback(err);
-        } else { // no dependencies
-          return destroyDb();
-        }
-      }
-      var dependentDbs = localDoc.dependentDbs;
-      var deletedMap = Object.keys(dependentDbs).map(function (name) {
-        var trueName = usePrefix ?
-          name.replace(new RegExp('^' + PouchDBVersion306.prefix), '') : name;
-        var subOpts = utils.extend(true, opts, {adapter: backend.adapter});
-        return PouchDBVersion306.destroy(trueName, subOpts);
-      });
-      Promise.all(deletedMap).then(destroyDb, function (error) {
-        callback(error);
-      });
-    });
-  });
-});
-
-PouchDBVersion306.allDbs = utils.toPromise(function (callback) {
-  var err = new Error('allDbs method removed');
-  err.stats = '400';
-  callback(err);
-});
-PouchDBVersion306.adapter = function (id, obj) {
-  if (obj.valid()) {
-    PouchDBVersion306.adapters[id] = obj;
-  }
-};
-
-PouchDBVersion306.plugin = function (obj) {
-  Object.keys(obj).forEach(function (id) {
-    PouchDBVersion306.prototype[id] = obj[id];
-  });
-};
-
-PouchDBVersion306.defaults = function (defaultOpts) {
-  function PouchAlt(name, opts, callback) {
-    if (typeof opts === 'function' || typeof opts === 'undefined') {
-      callback = opts;
-      opts = {};
-    }
-    if (name && typeof name === 'object') {
-      opts = name;
-      name = undefined;
-    }
-
-    opts = utils.extend(true, {}, defaultOpts, opts);
-    PouchDBVersion306.call(this, name, opts, callback);
-  }
-
-  utils.inherits(PouchAlt, PouchDBVersion306);
-
-  PouchAlt.destroy = utils.toPromise(function (name, opts, callback) {
-    if (typeof opts === 'function' || typeof opts === 'undefined') {
-      callback = opts;
-      opts = {};
-    }
-
-    if (name && typeof name === 'object') {
-      opts = name;
-      name = undefined;
-    }
-    opts = utils.extend(true, {}, defaultOpts, opts);
-    return PouchDBVersion306.destroy(name, opts, callback);
-  });
-
-  eventEmitterMethods.forEach(function (method) {
-    PouchAlt[method] = eventEmitter[method].bind(eventEmitter);
-  });
-  PouchAlt.setMaxListeners(0);
-
-  PouchAlt.preferredAdapters = PouchDBVersion306.preferredAdapters.slice();
-  Object.keys(PouchDBVersion306).forEach(function (key) {
-    if (!(key in PouchAlt)) {
-      PouchAlt[key] = PouchDBVersion306[key];
-    }
-  });
-
-  return PouchAlt;
-};
-
-module.exports = PouchDBVersion306;
-
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./adapters/preferredAdapters.js":4,"./constructor":7,"./utils":23,"events":27}],21:[function(_dereq_,module,exports){
-'use strict';
-var utils = _dereq_('./utils');
-var replication = _dereq_('./replicate');
-var replicate = replication.replicate;
-var EE = _dereq_('events').EventEmitter;
-
-utils.inherits(Sync, EE);
-module.exports = sync;
-function sync(src, target, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof opts === 'undefined') {
-    opts = {};
-  }
-  opts = utils.clone(opts);
-  /*jshint validthis:true */
-  opts.PouchConstructor = opts.PouchConstructor || this;
-  src = replication.toPouch(src, opts);
-  target = replication.toPouch(target, opts);
-  return new Sync(src, target, opts, callback);
-}
-function Sync(src, target, opts, callback) {
-  var self = this;
-  this.canceled = false;
-  
-  var onChange, complete;
-  if ('onChange' in opts) {
-    onChange = opts.onChange;
-    delete opts.onChange;
-  }
-  if (typeof callback === 'function' && !opts.complete) {
-    complete = callback;
-  } else if ('complete' in opts) {
-    complete = opts.complete;
-    delete opts.complete;
-  }
-
-  this.push = replicate(src, target, opts);
-
-  this.pull = replicate(target, src, opts);
-  var emittedCancel = false;
-  function onCancel(data) {
-    if (!emittedCancel) {
-      emittedCancel = true;
-      self.emit('cancel', data);
-    }
-  }
-
-  function pullChange(change) {
-    self.emit('change', {
-      direction: 'pull',
-      change: change
-    });
-  }
-  function pushChange(change) {
-    self.emit('change', {
-      direction: 'push',
-      change: change
-    });
-  }
-  var listeners = {};
-
-  var removed = {};
-  function removeAll(type) { // type is 'push' or 'pull'
-    return function (event, func) {
-      var isChange = event === 'change' &&
-        (func === pullChange || func === pushChange);
-      var isCancel = event === 'cancel' && func === onCancel;
-      var isOtherEvent = event in listeners && func === listeners[event];
-
-      if (isChange || isCancel || isOtherEvent) {
-        if (!(event in removed)) {
-          removed[event] = {};
-        }
-        removed[event][type] = true;
-        if (Object.keys(removed[event]).length === 2) {
-          // both push and pull have asked to be removed
-          self.removeAllListeners(event);
-        }
-      }
-    };
-  }
-
-  this.on('newListener', function (event) {
-    if (event === 'change') {
-      self.pull.on('change', pullChange);
-      self.push.on('change', pushChange);
-    } else if (event === 'cancel') {
-      self.pull.on('cancel', onCancel);
-      self.push.on('cancel', onCancel);
-    } else if (event !== 'error' &&
-      event !== 'removeListener' &&
-      event !== 'complete' && !(event in listeners)) {
-      listeners[event] = function (e) {
-        self.emit(event, e);
-      };
-      self.pull.on(event, listeners[event]);
-      self.push.on(event, listeners[event]);
-    }
-  });
-
-  this.on('removeListener', function (event) {
-    if (event === 'change') {
-      self.pull.removeListener('change', pullChange);
-      self.push.removeListener('change', pushChange);
-    } else if (event === 'cancel') {
-      self.pull.removeListener('cancel', onCancel);
-      self.push.removeListener('cancel', onCancel);
-    } else if (event in listeners) {
-      if (typeof listeners[event] === 'function') {
-        self.pull.removeListener(event, listeners[event]);
-        self.push.removeListener(event, listeners[event]);
-        delete listeners[event];
-      }
-    }
-  });
-
-  this.pull.on('removeListener', removeAll('pull'));
-  this.push.on('removeListener', removeAll('push'));
-
-  var promise = utils.Promise.all([
-    this.push,
-    this.pull
-  ]).then(function (resp) {
-    var out = {
-      push: resp[0],
-      pull: resp[1]
-    };
-    self.emit('complete', out);
-    if (complete) {
-      complete(null, out);
-    }
-    self.removeAllListeners();
-    return out;
-  }, function (err) {
-    self.cancel();
-    self.emit('error', err);
-    if (complete) {
-      complete(err);
-    }
-    self.removeAllListeners();
-    throw err;
-  });
-
-  this.then = function (success, err) {
-    return promise.then(success, err);
-  };
-
-  this["catch"] = function (err) {
-    return promise["catch"](err);
-  };
-}
-
-Sync.prototype.cancel = function () {
-  if (!this.canceled) {
-    this.canceled = true;
-    this.push.cancel();
-    this.pull.cancel();
-  }
-};
-
-},{"./replicate":19,"./utils":23,"events":27}],22:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = TaskQueue;
-
-function TaskQueue() {
-  this.isReady = false;
-  this.failed = false;
-  this.queue = [];
-}
-
-TaskQueue.prototype.execute = function () {
-  var d, func;
-  if (this.failed) {
-    while ((d = this.queue.shift())) {
-      if (typeof d === 'function') {
-        d(this.failed);
-        continue;
-      }
-      func = d.parameters[d.parameters.length - 1];
-      if (typeof func === 'function') {
-        func(this.failed);
-      } else if (d.name === 'changes' && typeof func.complete === 'function') {
-        func.complete(this.failed);
-      }
-    }
-  } else if (this.isReady) {
-    while ((d = this.queue.shift())) {
-
-      if (typeof d === 'function') {
-        d();
-      } else {
-        d.task = this.db[d.name].apply(this.db, d.parameters);
-      }
-    }
-  }
-};
-
-TaskQueue.prototype.fail = function (err) {
-  this.failed = err;
-  this.execute();
-};
-
-TaskQueue.prototype.ready = function (db) {
-  if (this.failed) {
-    return false;
-  } else if (arguments.length === 0) {
-    return this.isReady;
-  }
-  this.isReady = db ? true: false;
-  this.db = db;
-  this.execute();
-};
-
-TaskQueue.prototype.addTask = function (name, parameters) {
-  if (typeof name === 'function') {
-    this.queue.push(name);
-    if (this.failed) {
-      this.execute();
-    }
-  } else {
-    var task = { name: name, parameters: parameters };
-    this.queue.push(task);
-    if (this.failed) {
-      this.execute();
-    }
-    return task;
-  }
-};
-
-},{}],23:[function(_dereq_,module,exports){
-(function (process,global){
-/*jshint strict: false */
-/*global chrome */
-var merge = _dereq_('./merge');
-exports.extend = _dereq_('pouchdb-extend');
-exports.ajax = _dereq_('./deps/ajax');
-exports.createBlob = _dereq_('./deps/blob');
-exports.uuid = _dereq_('./deps/uuid');
-exports.getArguments = _dereq_('argsarray');
-var buffer = _dereq_('./deps/buffer');
-var errors = _dereq_('./deps/errors');
-var EventEmitter = _dereq_('events').EventEmitter;
-var collections = _dereq_('./deps/collections');
-exports.Map = collections.Map;
-exports.Set = collections.Set;
-
-if (typeof global.Promise === 'function') {
-  exports.Promise = global.Promise;
-} else {
-  exports.Promise = _dereq_('bluebird');
-}
-var Promise = exports.Promise;
-
-function toObject(array) {
-  var obj = {};
-  array.forEach(function (item) { obj[item] = true; });
-  return obj;
-}
-// List of top level reserved words for doc
-var reservedWords = toObject([
-  '_id',
-  '_rev',
-  '_attachments',
-  '_deleted',
-  '_revisions',
-  '_revs_info',
-  '_conflicts',
-  '_deleted_conflicts',
-  '_local_seq',
-  '_rev_tree',
-  //replication documents
-  '_replication_id',
-  '_replication_state',
-  '_replication_state_time',
-  '_replication_state_reason',
-  '_replication_stats'
-]);
-
-// List of reserved words that should end up the document
-var dataWords = toObject([
-  '_attachments',
-  //replication documents
-  '_replication_id',
-  '_replication_state',
-  '_replication_state_time',
-  '_replication_state_reason',
-  '_replication_stats'
-]);
-
-exports.clone = function (obj) {
-  return exports.extend(true, {}, obj);
-};
-exports.inherits = _dereq_('inherits');
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or
-//     '_local'
-//   - any other string value is a valid id
-// Returns the specific error object for each case
-exports.invalidIdError = function (id) {
-  var err;
-  if (!id) {
-    err = new TypeError(errors.MISSING_ID.message);
-    err.status = 412;
-  } else if (typeof id !== 'string') {
-    err = new TypeError(errors.INVALID_ID.message);
-    err.status = 400;
-  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
-    err = new TypeError(errors.RESERVED_ID.message);
-    err.status = 400;
-  }
-  if (err) {
-    throw err;
-  }
-};
-
-function isChromeApp() {
-  return (typeof chrome !== "undefined" &&
-          typeof chrome.storage !== "undefined" &&
-          typeof chrome.storage.local !== "undefined");
-}
-
-// Pretty dumb name for a function, just wraps callback calls so we dont
-// to if (callback) callback() everywhere
-exports.call = exports.getArguments(function (args) {
-  if (!args.length) {
-    return;
-  }
-  var fun = args.shift();
-  if (typeof fun === 'function') {
-    fun.apply(this, args);
-  }
-});
-
-exports.isLocalId = function (id) {
-  return (/^_local/).test(id);
-};
-
-// check if a specific revision of a doc has been deleted
-//  - metadata: the metadata object from the doc store
-//  - rev: (optional) the revision to check. defaults to winning revision
-exports.isDeleted = function (metadata, rev) {
-  if (!rev) {
-    rev = merge.winningRev(metadata);
-  }
-  var dashIndex = rev.indexOf('-');
-  if (dashIndex !== -1) {
-    rev = rev.substring(dashIndex + 1);
-  }
-  var deleted = false;
-  merge.traverseRevTree(metadata.rev_tree,
-  function (isLeaf, pos, id, acc, opts) {
-    if (id === rev) {
-      deleted = !!opts.deleted;
-    }
-  });
-
-  return deleted;
-};
-
-exports.filterChange = function (opts) {
-  return function (change) {
-    var req = {};
-    var hasFilter = opts.filter && typeof opts.filter === 'function';
-
-    req.query = opts.query_params;
-    if (opts.filter && hasFilter && !opts.filter.call(this, change.doc, req)) {
-      return false;
-    }
-    if (opts.doc_ids && opts.doc_ids.indexOf(change.id) === -1) {
-      return false;
-    }
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else {
-      for (var att in change.doc._attachments) {
-        if (change.doc._attachments.hasOwnProperty(att)) {
-          change.doc._attachments[att].stub = true;
-        }
-      }
-    }
-    return true;
-  };
-};
-
-// Preprocess documents, parse their revisions, assign an id and a
-// revision for new writes that are missing them, etc
-exports.parseDoc = function (doc, newEdits) {
-  var nRevNum;
-  var newRevId;
-  var revInfo;
-  var error;
-  var opts = {status: 'available'};
-  if (doc._deleted) {
-    opts.deleted = true;
-  }
-
-  if (newEdits) {
-    if (!doc._id) {
-      doc._id = exports.uuid();
-    }
-    newRevId = exports.uuid(32, 16).toLowerCase();
-    if (doc._rev) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        var err = new TypeError("invalid value for property '_rev'");
-        err.status = 400;
-      }
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], {status: 'missing'}, [[newRevId, opts, []]]]
-      }];
-      nRevNum = parseInt(revInfo[1], 10) + 1;
-    } else {
-      doc._rev_tree = [{
-        pos: 1,
-        ids : [newRevId, opts, []]
-      }];
-      nRevNum = 1;
-    }
-  } else {
-    if (doc._revisions) {
-      doc._rev_tree = [{
-        pos: doc._revisions.start - doc._revisions.ids.length + 1,
-        ids: doc._revisions.ids.reduce(function (acc, x) {
-          if (acc === null) {
-            return [x, opts, []];
-          } else {
-            return [x, {status: 'missing'}, [acc]];
-          }
-        }, null)
-      }];
-      nRevNum = doc._revisions.start;
-      newRevId = doc._revisions.ids[0];
-    }
-    if (!doc._rev_tree) {
-      revInfo = /^(\d+)-(.+)$/.exec(doc._rev);
-      if (!revInfo) {
-        error = new TypeError(errors.BAD_ARG.message);
-        error.status = errors.BAD_ARG.status;
-        throw error;
-      }
-      nRevNum = parseInt(revInfo[1], 10);
-      newRevId = revInfo[2];
-      doc._rev_tree = [{
-        pos: parseInt(revInfo[1], 10),
-        ids: [revInfo[2], opts, []]
-      }];
-    }
-  }
-
-  exports.invalidIdError(doc._id);
-
-  doc._rev = [nRevNum, newRevId].join('-');
-
-  var result = {metadata : {}, data : {}};
-  for (var key in doc) {
-    if (doc.hasOwnProperty(key)) {
-      var specialKey = key[0] === '_';
-      if (specialKey && !reservedWords[key]) {
-        error = new Error(errors.DOC_VALIDATION.message + ': ' + key);
-        error.status = errors.DOC_VALIDATION.status;
-        throw error;
-      } else if (specialKey && !dataWords[key]) {
-        result.metadata[key.slice(1)] = doc[key];
-      } else {
-        result.data[key] = doc[key];
-      }
-    }
-  }
-  return result;
-};
-
-exports.isCordova = function () {
-  return (typeof cordova !== "undefined" ||
-          typeof PhoneGap !== "undefined" ||
-          typeof phonegap !== "undefined");
-};
-
-exports.hasLocalStorage = function () {
-  if (isChromeApp()) {
-    return false;
-  }
-  try {
-    return global.localStorage;
-  } catch (e) {
-    return false;
-  }
-};
-exports.Changes = Changes;
-exports.inherits(Changes, EventEmitter);
-function Changes() {
-  if (!(this instanceof Changes)) {
-    return new Changes();
-  }
-  var self = this;
-  EventEmitter.call(this);
-  this.isChrome = isChromeApp();
-  this.listeners = {};
-  this.hasLocal = false;
-  if (!this.isChrome) {
-    this.hasLocal = exports.hasLocalStorage();
-  }
-  if (this.isChrome) {
-    chrome.storage.onChanged.addListener(function (e) {
-      // make sure it's event addressed to us
-      if (e.db_name != null) {
-        //object only has oldValue, newValue members
-        self.emit(e.dbName.newValue);
-      }
-    });
-  } else if (this.hasLocal) {
-    if (global.addEventListener) {
-      global.addEventListener("storage", function (e) {
-        self.emit(e.key);
-      });
-    } else {
-      global.attachEvent("storage", function (e) {
-        self.emit(e.key);
-      });
-    }
-  }
-
-}
-Changes.prototype.addListener = function (dbName, id, db, opts) {
-  if (this.listeners[id]) {
-    return;
-  }
-  function eventFunction() {
-    db.changes({
-      include_docs: opts.include_docs,
-      conflicts: opts.conflicts,
-      continuous: false,
-      descending: false,
-      filter: opts.filter,
-      view: opts.view,
-      since: opts.since,
-      query_params: opts.query_params,
-      onChange: function (c) {
-        if (c.seq > opts.since && !opts.cancelled) {
-          opts.since = c.seq;
-          exports.call(opts.onChange, c);
-        }
-      }
-    });
-  }
-  this.listeners[id] = eventFunction;
-  this.on(dbName, eventFunction);
-};
-
-Changes.prototype.removeListener = function (dbName, id) {
-  if (!(id in this.listeners)) {
-    return;
-  }
-  EventEmitter.prototype.removeListener.call(this, dbName,
-    this.listeners[id]);
-};
-
-
-Changes.prototype.notifyLocalWindows = function (dbName) {
-  //do a useless change on a storage thing
-  //in order to get other windows's listeners to activate
-  if (this.isChrome) {
-    chrome.storage.local.set({dbName: dbName});
-  } else if (this.hasLocal) {
-    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
-  }
-};
-
-Changes.prototype.notify = function (dbName) {
-  this.emit(dbName);
-  this.notifyLocalWindows(dbName);
-};
-
-if (!process.browser || !('atob' in global)) {
-  exports.atob = function (str) {
-    var base64 = new buffer(str, 'base64');
-    // Node.js will just skip the characters it can't encode instead of
-    // throwing and exception
-    if (base64.toString('base64') !== str) {
-      throw ("Cannot base64 encode full string");
-    }
-    return base64.toString('binary');
-  };
-} else {
-  exports.atob = function (str) {
-    return atob(str);
-  };
-}
-
-if (!process.browser || !('btoa' in global)) {
-  exports.btoa = function (str) {
-    return new buffer(str, 'binary').toString('base64');
-  };
-} else {
-  exports.btoa = function (str) {
-    return btoa(str);
-  };
-}
-
-// From http://stackoverflow.com/questions/14967647/ (continues on next line)
-// encode-decode-image-with-base64-breaks-image (2013-04-21)
-exports.fixBinary = function (bin) {
-  if (!process.browser) {
-    // don't need to do this in Node
-    return bin;
-  }
-
-  var length = bin.length;
-  var buf = new ArrayBuffer(length);
-  var arr = new Uint8Array(buf);
-  for (var i = 0; i < length; i++) {
-    arr[i] = bin.charCodeAt(i);
-  }
-  return buf;
-};
-
-exports.once = function (fun) {
-  var called = false;
-  return exports.getArguments(function (args) {
-    if (called) {
-      if (typeof console.trace === 'function') {
-        console.trace();
-      }
-      throw new Error('once called  more than once');
-    } else {
-      called = true;
-      fun.apply(this, args);
-    }
-  });
-};
-
-exports.toPromise = function (func) {
-  //create the function we will be returning
-  return exports.getArguments(function (args) {
-    var self = this;
-    var tempCB =
-      (typeof args[args.length - 1] === 'function') ? args.pop() : false;
-    // if the last argument is a function, assume its a callback
-    var usedCB;
-    if (tempCB) {
-      // if it was a callback, create a new callback which calls it,
-      // but do so async so we don't trap any errors
-      usedCB = function (err, resp) {
-        process.nextTick(function () {
-          tempCB(err, resp);
-        });
-      };
-    }
-    var promise = new Promise(function (fulfill, reject) {
-      var resp;
-      try {
-        var callback = exports.once(function (err, mesg) {
-          if (err) {
-            reject(err);
-          } else {
-            fulfill(mesg);
-          }
-        });
-        // create a callback for this invocation
-        // apply the function in the orig context
-        args.push(callback);
-        resp = func.apply(self, args);
-        if (resp && typeof resp.then === 'function') {
-          fulfill(resp);
-        }
-      } catch (e) {
-        reject(e);
-      }
-    });
-    // if there is a callback, call it back
-    if (usedCB) {
-      promise.then(function (result) {
-        usedCB(null, result);
-      }, usedCB);
-    }
-    promise.cancel = function () {
-      return this;
-    };
-    return promise;
-  });
-};
-
-exports.adapterFun = function (name, callback) {
-  return exports.toPromise(exports.getArguments(function (args) {
-    if (this._closed) {
-      return Promise.reject(new Error('database is closed'));
-    }
-    var self = this;
-    if (!this.taskqueue.isReady) {
-      return new exports.Promise(function (fulfill, reject) {
-        self.taskqueue.addTask(function (failed) {
-          if (failed) {
-            reject(failed);
-          } else {
-            fulfill(self[name].apply(self, args));
-          }
-        });
-      });
-    }
-    return callback.apply(this, args);
-  }));
-};
-//Can't find original post, but this is close
-//http://stackoverflow.com/questions/6965107/ (continues on next line)
-//converting-between-strings-and-arraybuffers
-exports.arrayBufferToBinaryString = function (buffer) {
-  var binary = "";
-  var bytes = new Uint8Array(buffer);
-  var length = bytes.byteLength;
-  for (var i = 0; i < length; i++) {
-    binary += String.fromCharCode(bytes[i]);
-  }
-  return binary;
-};
-
-exports.cancellableFun = function (fun, self, opts) {
-
-  opts = opts ? exports.clone(true, {}, opts) : {};
-
-  var emitter = new EventEmitter();
-  var oldComplete = opts.complete || function () { };
-  var complete = opts.complete = exports.once(function (err, resp) {
-    if (err) {
-      oldComplete(err);
-    } else {
-      emitter.emit('end', resp);
-      oldComplete(null, resp);
-    }
-    emitter.removeAllListeners();
-  });
-  var oldOnChange = opts.onChange || function () {};
-  var lastChange = 0;
-  self.on('destroyed', function () {
-    emitter.removeAllListeners();
-  });
-  opts.onChange = function (change) {
-    oldOnChange(change);
-    if (change.seq <= lastChange) {
-      return;
-    }
-    lastChange = change.seq;
-    emitter.emit('change', change);
-    if (change.deleted) {
-      emitter.emit('delete', change);
-    } else if (change.changes.length === 1 &&
-      change.changes[0].rev.slice(0, 1) === '1-') {
-      emitter.emit('create', change);
-    } else {
-      emitter.emit('update', change);
-    }
-  };
-  var promise = new Promise(function (fulfill, reject) {
-    opts.complete = function (err, res) {
-      if (err) {
-        reject(err);
-      } else {
-        fulfill(res);
-      }
-    };
-  });
-
-  promise.then(function (result) {
-    complete(null, result);
-  }, complete);
-
-  // this needs to be overwridden by caller, dont fire complete until
-  // the task is ready
-  promise.cancel = function () {
-    promise.isCancelled = true;
-    if (self.taskqueue.isReady) {
-      opts.complete(null, {status: 'cancelled'});
-    }
-  };
-
-  if (!self.taskqueue.isReady) {
-    self.taskqueue.addTask(function () {
-      if (promise.isCancelled) {
-        opts.complete(null, {status: 'cancelled'});
-      } else {
-        fun(self, opts, promise);
-      }
-    });
-  } else {
-    fun(self, opts, promise);
-  }
-  promise.on = emitter.on.bind(emitter);
-  promise.once = emitter.once.bind(emitter);
-  promise.addListener = emitter.addListener.bind(emitter);
-  promise.removeListener = emitter.removeListener.bind(emitter);
-  promise.removeAllListeners = emitter.removeAllListeners.bind(emitter);
-  promise.setMaxListeners = emitter.setMaxListeners.bind(emitter);
-  promise.listeners = emitter.listeners.bind(emitter);
-  promise.emit = emitter.emit.bind(emitter);
-  return promise;
-};
-
-exports.MD5 = exports.toPromise(_dereq_('./deps/md5'));
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./deps/ajax":8,"./deps/blob":9,"./deps/buffer":26,"./deps/collections":10,"./deps/errors":11,"./deps/md5":12,"./deps/uuid":14,"./merge":18,"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"argsarray":25,"bluebird":33,"events":27,"inherits":29,"pouchdb-extend":48}],24:[function(_dereq_,module,exports){
-module.exports = "3.0.6";
-
-},{}],25:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = argsArray;
-
-function argsArray(fun) {
-  return function () {
-    var len = arguments.length;
-    if (len) {
-      var args = [];
-      var i = -1;
-      while (++i < len) {
-        args[i] = arguments[i];
-      }
-      return fun.call(this, args);
-    } else {
-      return fun.call(this, []);
-    }
-  };
-}
-},{}],26:[function(_dereq_,module,exports){
-
-},{}],27:[function(_dereq_,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
-  this._events = this._events || {};
-  this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
-  if (!isNumber(n) || n < 0 || isNaN(n))
-    throw TypeError('n must be a positive number');
-  this._maxListeners = n;
-  return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
-  var er, handler, len, args, i, listeners;
-
-  if (!this._events)
-    this._events = {};
-
-  // If there is no 'error' event listener then throw.
-  if (type === 'error') {
-    if (!this._events.error ||
-        (isObject(this._events.error) && !this._events.error.length)) {
-      er = arguments[1];
-      if (er instanceof Error) {
-        throw er; // Unhandled 'error' event
-      }
-      throw TypeError('Uncaught, unspecified "error" event.');
-    }
-  }
-
-  handler = this._events[type];
-
-  if (isUndefined(handler))
-    return false;
-
-  if (isFunction(handler)) {
-    switch (arguments.length) {
-      // fast cases
-      case 1:
-        handler.call(this);
-        break;
-      case 2:
-        handler.call(this, arguments[1]);
-        break;
-      case 3:
-        handler.call(this, arguments[1], arguments[2]);
-        break;
-      // slower
-      default:
-        len = arguments.length;
-        args = new Array(len - 1);
-        for (i = 1; i < len; i++)
-          args[i - 1] = arguments[i];
-        handler.apply(this, args);
-    }
-  } else if (isObject(handler)) {
-    len = arguments.length;
-    args = new Array(len - 1);
-    for (i = 1; i < len; i++)
-      args[i - 1] = arguments[i];
-
-    listeners = handler.slice();
-    len = listeners.length;
-    for (i = 0; i < len; i++)
-      listeners[i].apply(this, args);
-  }
-
-  return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
-  var m;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events)
-    this._events = {};
-
-  // To avoid recursion in the case that type === "newListener"! Before
-  // adding it to the listeners, first emit "newListener".
-  if (this._events.newListener)
-    this.emit('newListener', type,
-              isFunction(listener.listener) ?
-              listener.listener : listener);
-
-  if (!this._events[type])
-    // Optimize the case of one listener. Don't need the extra array object.
-    this._events[type] = listener;
-  else if (isObject(this._events[type]))
-    // If we've already got an array, just append.
-    this._events[type].push(listener);
-  else
-    // Adding the second element, need to change to array.
-    this._events[type] = [this._events[type], listener];
-
-  // Check for listener leak
-  if (isObject(this._events[type]) && !this._events[type].warned) {
-    var m;
-    if (!isUndefined(this._maxListeners)) {
-      m = this._maxListeners;
-    } else {
-      m = EventEmitter.defaultMaxListeners;
-    }
-
-    if (m && m > 0 && this._events[type].length > m) {
-      this._events[type].warned = true;
-      console.error('(node) warning: possible EventEmitter memory ' +
-                    'leak detected. %d listeners added. ' +
-                    'Use emitter.setMaxListeners() to increase limit.',
-                    this._events[type].length);
-      if (typeof console.trace === 'function') {
-        // not supported in IE 10
-        console.trace();
-      }
-    }
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  var fired = false;
-
-  function g() {
-    this.removeListener(type, g);
-
-    if (!fired) {
-      fired = true;
-      listener.apply(this, arguments);
-    }
-  }
-
-  g.listener = listener;
-  this.on(type, g);
-
-  return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
-  var list, position, length, i;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events || !this._events[type])
-    return this;
-
-  list = this._events[type];
-  length = list.length;
-  position = -1;
-
-  if (list === listener ||
-      (isFunction(list.listener) && list.listener === listener)) {
-    delete this._events[type];
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-
-  } else if (isObject(list)) {
-    for (i = length; i-- > 0;) {
-      if (list[i] === listener ||
-          (list[i].listener && list[i].listener === listener)) {
-        position = i;
-        break;
-      }
-    }
-
-    if (position < 0)
-      return this;
-
-    if (list.length === 1) {
-      list.length = 0;
-      delete this._events[type];
-    } else {
-      list.splice(position, 1);
-    }
-
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
-  var key, listeners;
-
-  if (!this._events)
-    return this;
-
-  // not listening for removeListener, no need to emit
-  if (!this._events.removeListener) {
-    if (arguments.length === 0)
-      this._events = {};
-    else if (this._events[type])
-      delete this._events[type];
-    return this;
-  }
-
-  // emit removeListener for all listeners on all events
-  if (arguments.length === 0) {
-    for (key in this._events) {
-      if (key === 'removeListener') continue;
-      this.removeAllListeners(key);
-    }
-    this.removeAllListeners('removeListener');
-    this._events = {};
-    return this;
-  }
-
-  listeners = this._events[type];
-
-  if (isFunction(listeners)) {
-    this.removeListener(type, listeners);
-  } else {
-    // LIFO order
-    while (listeners.length)
-      this.removeListener(type, listeners[listeners.length - 1]);
-  }
-  delete this._events[type];
-
-  return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
-  var ret;
-  if (!this._events || !this._events[type])
-    ret = [];
-  else if (isFunction(this._events[type]))
-    ret = [this._events[type]];
-  else
-    ret = this._events[type].slice();
-  return ret;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
-  var ret;
-  if (!emitter._events || !emitter._events[type])
-    ret = 0;
-  else if (isFunction(emitter._events[type]))
-    ret = 1;
-  else
-    ret = emitter._events[type].length;
-  return ret;
-};
-
-function isFunction(arg) {
-  return typeof arg === 'function';
-}
-
-function isNumber(arg) {
-  return typeof arg === 'number';
-}
-
-function isObject(arg) {
-  return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
-  return arg === void 0;
-}
-
-},{}],28:[function(_dereq_,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
-    var canSetImmediate = typeof window !== 'undefined'
-    && window.setImmediate;
-    var canPost = typeof window !== 'undefined'
-    && window.postMessage && window.addEventListener
-    ;
-
-    if (canSetImmediate) {
-        return function (f) { return window.setImmediate(f) };
-    }
-
-    if (canPost) {
-        var queue = [];
-        window.addEventListener('message', function (ev) {
-            var source = ev.source;
-            if ((source === window || source === null) && ev.data === 'process-tick') {
-                ev.stopPropagation();
-                if (queue.length > 0) {
-                    var fn = queue.shift();
-                    fn();
-                }
-            }
-        }, true);
-
-        return function nextTick(fn) {
-            queue.push(fn);
-            window.postMessage('process-tick', '*');
-        };
-    }
-
-    return function nextTick(fn) {
-        setTimeout(fn, 0);
-    };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-}
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-
-},{}],29:[function(_dereq_,module,exports){
-if (typeof Object.create === 'function') {
-  // implementation from standard node.js 'util' module
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    ctor.prototype = Object.create(superCtor.prototype, {
-      constructor: {
-        value: ctor,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-  };
-} else {
-  // old school shim for old browsers
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    var TempCtor = function () {}
-    TempCtor.prototype = superCtor.prototype
-    ctor.prototype = new TempCtor()
-    ctor.prototype.constructor = ctor
-  }
-}
-
-},{}],30:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = INTERNAL;
-
-function INTERNAL() {}
-},{}],31:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('./promise');
-var reject = _dereq_('./reject');
-var resolve = _dereq_('./resolve');
-var INTERNAL = _dereq_('./INTERNAL');
-var handlers = _dereq_('./handlers');
-module.exports = all;
-function all(iterable) {
-  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
-    return reject(new TypeError('must be an array'));
-  }
-
-  var len = iterable.length;
-  var called = false;
-  if (!len) {
-    return resolve([]);
-  }
-
-  var values = new Array(len);
-  var resolved = 0;
-  var i = -1;
-  var promise = new Promise(INTERNAL);
-  
-  while (++i < len) {
-    allResolver(iterable[i], i);
-  }
-  return promise;
-  function allResolver(value, i) {
-    resolve(value).then(resolveFromAll, function (error) {
-      if (!called) {
-        called = true;
-        handlers.reject(promise, error);
-      }
-    });
-    function resolveFromAll(outValue) {
-      values[i] = outValue;
-      if (++resolved === len & !called) {
-        called = true;
-        handlers.resolve(promise, values);
-      }
-    }
-  }
-}
-},{"./INTERNAL":30,"./handlers":32,"./promise":34,"./reject":37,"./resolve":38}],32:[function(_dereq_,module,exports){
-'use strict';
-var tryCatch = _dereq_('./tryCatch');
-var resolveThenable = _dereq_('./resolveThenable');
-var states = _dereq_('./states');
-
-exports.resolve = function (self, value) {
-  var result = tryCatch(getThen, value);
-  if (result.status === 'error') {
-    return exports.reject(self, result.value);
-  }
-  var thenable = result.value;
-
-  if (thenable) {
-    resolveThenable.safely(self, thenable);
-  } else {
-    self.state = states.FULFILLED;
-    self.outcome = value;
-    var i = -1;
-    var len = self.queue.length;
-    while (++i < len) {
-      self.queue[i].callFulfilled(value);
-    }
-  }
-  return self;
-};
-exports.reject = function (self, error) {
-  self.state = states.REJECTED;
-  self.outcome = error;
-  var i = -1;
-  var len = self.queue.length;
-  while (++i < len) {
-    self.queue[i].callRejected(error);
-  }
-  return self;
-};
-
-function getThen(obj) {
-  // Make sure we only access the accessor once as required by the spec
-  var then = obj && obj.then;
-  if (obj && typeof obj === 'object' && typeof then === 'function') {
-    return function appyThen() {
-      then.apply(obj, arguments);
-    };
-  }
-}
-},{"./resolveThenable":39,"./states":40,"./tryCatch":41}],33:[function(_dereq_,module,exports){
-module.exports = exports = _dereq_('./promise');
-
-exports.resolve = _dereq_('./resolve');
-exports.reject = _dereq_('./reject');
-exports.all = _dereq_('./all');
-exports.race = _dereq_('./race');
-},{"./all":31,"./promise":34,"./race":36,"./reject":37,"./resolve":38}],34:[function(_dereq_,module,exports){
-'use strict';
-
-var unwrap = _dereq_('./unwrap');
-var INTERNAL = _dereq_('./INTERNAL');
-var resolveThenable = _dereq_('./resolveThenable');
-var states = _dereq_('./states');
-var QueueItem = _dereq_('./queueItem');
-
-module.exports = Promise;
-function Promise(resolver) {
-  if (!(this instanceof Promise)) {
-    return new Promise(resolver);
-  }
-  if (typeof resolver !== 'function') {
-    throw new TypeError('reslover must be a function');
-  }
-  this.state = states.PENDING;
-  this.queue = [];
-  this.outcome = void 0;
-  if (resolver !== INTERNAL) {
-    resolveThenable.safely(this, resolver);
-  }
-}
-
-Promise.prototype['catch'] = function (onRejected) {
-  return this.then(null, onRejected);
-};
-Promise.prototype.then = function (onFulfilled, onRejected) {
-  if (typeof onFulfilled !== 'function' && this.state === states.FULFILLED ||
-    typeof onRejected !== 'function' && this.state === states.REJECTED) {
-    return this;
-  }
-  var promise = new Promise(INTERNAL);
-
-  
-  if (this.state !== states.PENDING) {
-    var resolver = this.state === states.FULFILLED ? onFulfilled: onRejected;
-    unwrap(promise, resolver, this.outcome);
-  } else {
-    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
-  }
-
-  return promise;
-};
-
-},{"./INTERNAL":30,"./queueItem":35,"./resolveThenable":39,"./states":40,"./unwrap":42}],35:[function(_dereq_,module,exports){
-'use strict';
-var handlers = _dereq_('./handlers');
-var unwrap = _dereq_('./unwrap');
-
-module.exports = QueueItem;
-function QueueItem(promise, onFulfilled, onRejected) {
-  this.promise = promise;
-  if (typeof onFulfilled === 'function') {
-    this.onFulfilled = onFulfilled;
-    this.callFulfilled = this.otherCallFulfilled;
-  }
-  if (typeof onRejected === 'function') {
-    this.onRejected = onRejected;
-    this.callRejected = this.otherCallRejected;
-  }
-}
-QueueItem.prototype.callFulfilled = function (value) {
-  handlers.resolve(this.promise, value);
-};
-QueueItem.prototype.otherCallFulfilled = function (value) {
-  unwrap(this.promise, this.onFulfilled, value);
-};
-QueueItem.prototype.callRejected = function (value) {
-  handlers.reject(this.promise, value);
-};
-QueueItem.prototype.otherCallRejected = function (value) {
-  unwrap(this.promise, this.onRejected, value);
-};
-},{"./handlers":32,"./unwrap":42}],36:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('./promise');
-var reject = _dereq_('./reject');
-var resolve = _dereq_('./resolve');
-var INTERNAL = _dereq_('./INTERNAL');
-var handlers = _dereq_('./handlers');
-module.exports = race;
-function race(iterable) {
-  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
-    return reject(new TypeError('must be an array'));
-  }
-
-  var len = iterable.length;
-  var called = false;
-  if (!len) {
-    return resolve([]);
-  }
-
-  var resolved = 0;
-  var i = -1;
-  var promise = new Promise(INTERNAL);
-  
-  while (++i < len) {
-    resolver(iterable[i]);
-  }
-  return promise;
-  function resolver(value) {
-    resolve(value).then(function (response) {
-      if (!called) {
-        called = true;
-        handlers.resolve(promise, response);
-      }
-    }, function (error) {
-      if (!called) {
-        called = true;
-        handlers.reject(promise, error);
-      }
-    });
-  }
-}
-},{"./INTERNAL":30,"./handlers":32,"./promise":34,"./reject":37,"./resolve":38}],37:[function(_dereq_,module,exports){
-'use strict';
-
-var Promise = _dereq_('./promise');
-var INTERNAL = _dereq_('./INTERNAL');
-var handlers = _dereq_('./handlers');
-module.exports = reject;
-
-function reject(reason) {
-	var promise = new Promise(INTERNAL);
-	return handlers.reject(promise, reason);
-}
-},{"./INTERNAL":30,"./handlers":32,"./promise":34}],38:[function(_dereq_,module,exports){
-'use strict';
-
-var Promise = _dereq_('./promise');
-var INTERNAL = _dereq_('./INTERNAL');
-var handlers = _dereq_('./handlers');
-module.exports = resolve;
-
-var FALSE = handlers.resolve(new Promise(INTERNAL), false);
-var NULL = handlers.resolve(new Promise(INTERNAL), null);
-var UNDEFINED = handlers.resolve(new Promise(INTERNAL), void 0);
-var ZERO = handlers.resolve(new Promise(INTERNAL), 0);
-var EMPTYSTRING = handlers.resolve(new Promise(INTERNAL), '');
-
-function resolve(value) {
-  if (value) {
-    if (value instanceof Promise) {
-      return value;
-    }
-    return handlers.resolve(new Promise(INTERNAL), value);
-  }
-  var valueType = typeof value;
-  switch (valueType) {
-    case 'boolean':
-      return FALSE;
-    case 'undefined':
-      return UNDEFINED;
-    case 'object':
-      return NULL;
-    case 'number':
-      return ZERO;
-    case 'string':
-      return EMPTYSTRING;
-  }
-}
-},{"./INTERNAL":30,"./handlers":32,"./promise":34}],39:[function(_dereq_,module,exports){
-'use strict';
-var handlers = _dereq_('./handlers');
-var tryCatch = _dereq_('./tryCatch');
-function safelyResolveThenable(self, thenable) {
-  // Either fulfill, reject or reject with error
-  var called = false;
-  function onError(value) {
-    if (called) {
-      return;
-    }
-    called = true;
-    handlers.reject(self, value);
-  }
-
-  function onSuccess(value) {
-    if (called) {
-      return;
-    }
-    called = true;
-    handlers.resolve(self, value);
-  }
-
-  function tryToUnwrap() {
-    thenable(onSuccess, onError);
-  }
-  
-  var result = tryCatch(tryToUnwrap);
-  if (result.status === 'error') {
-    onError(result.value);
-  }
-}
-exports.safely = safelyResolveThenable;
-},{"./handlers":32,"./tryCatch":41}],40:[function(_dereq_,module,exports){
-// Lazy man's symbols for states
-
-exports.REJECTED = ['REJECTED'];
-exports.FULFILLED = ['FULFILLED'];
-exports.PENDING = ['PENDING'];
-},{}],41:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = tryCatch;
-
-function tryCatch(func, value) {
-  var out = {};
-  try {
-    out.value = func(value);
-    out.status = 'success';
-  } catch (e) {
-    out.status = 'error';
-    out.value = e;
-  }
-  return out;
-}
-},{}],42:[function(_dereq_,module,exports){
-'use strict';
-
-var immediate = _dereq_('immediate');
-var handlers = _dereq_('./handlers');
-module.exports = unwrap;
-
-function unwrap(promise, func, value) {
-  immediate(function () {
-    var returnValue;
-    try {
-      returnValue = func(value);
-    } catch (e) {
-      return handlers.reject(promise, e);
-    }
-    if (returnValue === promise) {
-      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
-    } else {
-      handlers.resolve(promise, returnValue);
-    }
-  });
-}
-},{"./handlers":32,"immediate":43}],43:[function(_dereq_,module,exports){
-'use strict';
-var types = [
-  _dereq_('./nextTick'),
-  _dereq_('./mutation.js'),
-  _dereq_('./messageChannel'),
-  _dereq_('./stateChange'),
-  _dereq_('./timeout')
-];
-var draining;
-var queue = [];
-function drainQueue() {
-  draining = true;
-  var i, oldQueue;
-  var len = queue.length;
-  while (len) {
-    oldQueue = queue;
-    queue = [];
-    i = -1;
-    while (++i < len) {
-      oldQueue[i]();
-    }
-    len = queue.length;
-  }
-  draining = false;
-}
-var scheduleDrain;
-var i = -1;
-var len = types.length;
-while (++ i < len) {
-  if (types[i] && types[i].test && types[i].test()) {
-    scheduleDrain = types[i].install(drainQueue);
-    break;
-  }
-}
-module.exports = immediate;
-function immediate(task) {
-  if (queue.push(task) === 1 && !draining) {
-    scheduleDrain();
-  }
-}
-},{"./messageChannel":44,"./mutation.js":45,"./nextTick":26,"./stateChange":46,"./timeout":47}],44:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-exports.test = function () {
-  if (global.setImmediate) {
-    // we can only get here in IE10
-    // which doesn't handel postMessage well
-    return false;
-  }
-  return typeof global.MessageChannel !== 'undefined';
-};
-
-exports.install = function (func) {
-  var channel = new global.MessageChannel();
-  channel.port1.onmessage = func;
-  return function () {
-    channel.port2.postMessage(0);
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],45:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-//based off rsvp https://github.com/tildeio/rsvp.js
-//license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
-//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js
-
-var Mutation = global.MutationObserver || global.WebKitMutationObserver;
-
-exports.test = function () {
-  return Mutation;
-};
-
-exports.install = function (handle) {
-  var called = 0;
-  var observer = new Mutation(handle);
-  var element = global.document.createTextNode('');
-  observer.observe(element, {
-    characterData: true
-  });
-  return function () {
-    element.data = (called = ++called % 2);
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],46:[function(_dereq_,module,exports){
-(function (global){
-'use strict';
-
-exports.test = function () {
-  return 'document' in global && 'onreadystatechange' in global.document.createElement('script');
-};
-
-exports.install = function (handle) {
-  return function () {
-
-    // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-    // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-    var scriptEl = global.document.createElement('script');
-    scriptEl.onreadystatechange = function () {
-      handle();
-
-      scriptEl.onreadystatechange = null;
-      scriptEl.parentNode.removeChild(scriptEl);
-      scriptEl = null;
-    };
-    global.document.documentElement.appendChild(scriptEl);
-
-    return handle;
-  };
-};
-}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],47:[function(_dereq_,module,exports){
-'use strict';
-exports.test = function () {
-  return true;
-};
-
-exports.install = function (t) {
-  return function () {
-    setTimeout(t, 0);
-  };
-};
-},{}],48:[function(_dereq_,module,exports){
-"use strict";
-
-// Extends method
-// (taken from http://code.jquery.com/jquery-1.9.0.js)
-// Populate the class2type map
-var class2type = {};
-
-var types = [
-  "Boolean", "Number", "String", "Function", "Array",
-  "Date", "RegExp", "Object", "Error"
-];
-for (var i = 0; i < types.length; i++) {
-  var typename = types[i];
-  class2type["[object " + typename + "]"] = typename.toLowerCase();
-}
-
-var core_toString = class2type.toString;
-var core_hasOwn = class2type.hasOwnProperty;
-
-function type(obj) {
-  if (obj === null) {
-    return String(obj);
-  }
-  return typeof obj === "object" || typeof obj === "function" ?
-    class2type[core_toString.call(obj)] || "object" :
-    typeof obj;
-}
-
-function isWindow(obj) {
-  return obj !== null && obj === obj.window;
-}
-
-function isPlainObject(obj) {
-  // Must be an Object.
-  // Because of IE, we also have to check the presence of
-  // the constructor property.
-  // Make sure that DOM nodes and window objects don't pass through, as well
-  if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
-    return false;
-  }
-
-  try {
-    // Not own constructor property must be Object
-    if (obj.constructor &&
-      !core_hasOwn.call(obj, "constructor") &&
-      !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
-      return false;
-    }
-  } catch ( e ) {
-    // IE8,9 Will throw exceptions on certain host objects #9897
-    return false;
-  }
-
-  // Own properties are enumerated firstly, so to speed up,
-  // if last one is own, then all properties are own.
-  var key;
-  for (key in obj) {}
-
-  return key === undefined || core_hasOwn.call(obj, key);
-}
-
-
-function isFunction(obj) {
-  return type(obj) === "function";
-}
-
-var isArray = Array.isArray || function (obj) {
-  return type(obj) === "array";
-};
-
-function extend() {
-  // originally extend() was recursive, but this ended up giving us
-  // "call stack exceeded", so it's been unrolled to use a literal stack
-  // (see https://github.com/pouchdb/pouchdb/issues/2543)
-  var stack = [];
-  var i = -1;
-  var len = arguments.length;
-  var args = new Array(len);
-  while (++i < len) {
-    args[i] = arguments[i];
-  }
-  var container = {};
-  stack.push({args: args, result: {container: container, key: 'key'}});
-  var next;
-  while ((next = stack.pop())) {
-    extendInner(stack, next.args, next.result);
-  }
-  return container.key;
-}
-
-function extendInner(stack, args, result) {
-  var options, name, src, copy, copyIsArray, clone,
-    target = args[0] || {},
-    i = 1,
-    length = args.length,
-    deep = false,
-    numericStringRegex = /\d+/,
-    optionsIsArray;
-
-  // Handle a deep copy situation
-  if (typeof target === "boolean") {
-    deep = target;
-    target = args[1] || {};
-    // skip the boolean and the target
-    i = 2;
-  }
-
-  // Handle case when target is a string or something (possible in deep copy)
-  if (typeof target !== "object" && !isFunction(target)) {
-    target = {};
-  }
-
-  // extend jQuery itself if only one argument is passed
-  if (length === i) {
-    /* jshint validthis: true */
-    target = this;
-    --i;
-  }
-
-  for (; i < length; i++) {
-    // Only deal with non-null/undefined values
-    if ((options = args[i]) != null) {
-      optionsIsArray = isArray(options);
-      // Extend the base object
-      for (name in options) {
-        //if (options.hasOwnProperty(name)) {
-        if (!(name in Object.prototype)) {
-          if (optionsIsArray && !numericStringRegex.test(name)) {
-            continue;
-          }
-
-          src = target[name];
-          copy = options[name];
-
-          // Prevent never-ending loop
-          if (target === copy) {
-            continue;
-          }
-
-          // Recurse if we're merging plain objects or arrays
-          if (deep && copy && (isPlainObject(copy) ||
-              (copyIsArray = isArray(copy)))) {
-            if (copyIsArray) {
-              copyIsArray = false;
-              clone = src && isArray(src) ? src : [];
-
-            } else {
-              clone = src && isPlainObject(src) ? src : {};
-            }
-
-            // Never move original objects, clone them
-            stack.push({
-              args: [deep, clone, copy],
-              result: {
-                container: target,
-                key: name
-              }
-            });
-
-          // Don't bring in undefined values
-          } else if (copy !== undefined) {
-            if (!(isArray(options) && isFunction(copy))) {
-              target[name] = copy;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // "Return" the modified object by setting the key
-  // on the given container
-  result.container[result.key] = target;
-}
-
-
-module.exports = extend;
-
-
-
-},{}],49:[function(_dereq_,module,exports){
-'use strict';
-
-var upsert = _dereq_('./upsert');
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-
-module.exports = function (opts) {
-  var sourceDB = opts.db;
-  var viewName = opts.viewName;
-  var mapFun = opts.map;
-  var reduceFun = opts.reduce;
-  var temporary = opts.temporary;
-
-  // the "undefined" part is for backwards compatibility
-  var viewSignature = mapFun.toString() + (reduceFun && reduceFun.toString()) +
-    'undefined';
-
-  if (!temporary && sourceDB._cachedViews) {
-    var cachedView = sourceDB._cachedViews[viewSignature];
-    if (cachedView) {
-      return Promise.resolve(cachedView);
-    }
-  }
-
-  return sourceDB.info().then(function (info) {
-
-    var depDbName = info.db_name + '-mrview-' +
-      (temporary ? 'temp' : utils.MD5(viewSignature));
-
-    // save the view name in the source PouchDBVersion306 so it can be cleaned up if necessary
-    // (e.g. when the _design doc is deleted, remove all associated view data)
-    function diffFunction(doc) {
-      doc.views = doc.views || {};
-      var fullViewName = viewName;
-      if (fullViewName.indexOf('/') === -1) {
-        fullViewName = viewName + '/' + viewName;
-      }
-      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
-      /* istanbul ignore if */
-      if (depDbs[depDbName]) {
-        return; // no update necessary
-      }
-      depDbs[depDbName] = true;
-      return doc;
-    }
-    return upsert(sourceDB, '_local/mrviews', diffFunction).then(function () {
-      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
-        var db = res.db;
-        db.auto_compaction = true;
-        var view = {
-          name: depDbName,
-          db: db, 
-          sourceDB: sourceDB,
-          adapter: sourceDB.adapter,
-          mapFun: mapFun,
-          reduceFun: reduceFun
-        };
-        return view.db.get('_local/lastSeq')["catch"](function (err) {
-          /* istanbul ignore if */
-          if (err.status !== 404) {
-            throw err;
-          }
-        }).then(function (lastSeqDoc) {
-          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
-          if (!temporary) {
-            sourceDB._cachedViews = sourceDB._cachedViews || {};
-            sourceDB._cachedViews[viewSignature] = view;
-            view.db.on('destroyed', function () {
-              delete sourceDB._cachedViews[viewSignature];
-            });
-          }
-          return view;
-        });
-      });
-    });
-  });
-};
-
-},{"./upsert":55,"./utils":56}],50:[function(_dereq_,module,exports){
-'use strict';
-
-module.exports = function (func, emit, sum, log, isArray, toJSON) {
-  /*jshint evil:true,unused:false */
-  return eval("'use strict'; (" + func.replace(/;\s*$/, "") + ");");
-};
-
-},{}],51:[function(_dereq_,module,exports){
-(function (process){
-'use strict';
-
-var pouchCollate = _dereq_('pouchdb-collate');
-var TaskQueue = _dereq_('./taskqueue');
-var collate = pouchCollate.collate;
-var toIndexableString = pouchCollate.toIndexableString;
-var normalizeKey = pouchCollate.normalizeKey;
-var createView = _dereq_('./create-view');
-var evalFunc = _dereq_('./evalfunc');
-var log; 
-/* istanbul ignore else */
-if ((typeof console !== 'undefined') && (typeof console.log === 'function')) {
-  log = Function.prototype.bind.call(console.log, console);
-} else {
-  log = function () {};
-}
-var utils = _dereq_('./utils');
-var Promise = utils.Promise;
-var mainQueue = new TaskQueue();
-var tempViewQueue = new TaskQueue();
-var CHANGES_BATCH_SIZE = 50;
-
-function parseViewName(name) {
-  // can be either 'ddocname/viewname' or just 'viewname'
-  // (where the ddoc name is the same)
-  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
-}
-
-function tryCode(db, fun, args) {
-  // emit an event if there was an error thrown by a map/reduce function.
-  // putting try/catches in a single function also avoids deoptimizations.
-  try {
-    return {
-      output : fun.apply(null, args)
-    };
-  } catch (e) {
-    db.emit('error', e);
-    return {error : e};
-  }
-}
-
-function sortByKeyThenValue(x, y) {
-  var keyCompare = collate(x.key, y.key);
-  return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
-}
-
-function sliceResults(results, limit, skip) {
-  skip = skip || 0;
-  if (typeof limit === 'number') {
-    return results.slice(skip, limit + skip);
-  } else if (skip > 0) {
-    return results.slice(skip);
-  }
-  return results;
-}
-
-function createBuiltInError(name) {
-  var error = new Error('builtin ' + name +
-    ' function requires map values to be numbers' +
-    ' or number arrays');
-  error.name = 'invalid_value';
-  error.status = 500;
-  return error;
-}
-
-function sum(values) {
-  var result = 0;
-  for (var i = 0, len = values.length; i < len; i++) {
-    var num = values[i];
-    if (typeof num !== 'number') {
-      if (Array.isArray(num)) {
-        // lists of numbers are also allowed, sum them separately
-        result = typeof result === 'number' ? [result] : result;
-        for (var j = 0, jLen = num.length; j < jLen; j++) {
-          var jNum = num[j];
-          if (typeof jNum !== 'number') {
-            throw createBuiltInError('_sum');
-          } else if (typeof result[j] === 'undefined') {
-            result.push(jNum);
-          } else {
-            result[j] += jNum;
-          }
-        }
-      } else { // not array/number
-        throw createBuiltInError('_sum');
-      }
-    } else if (typeof result === 'number') {
-      result += num;
-    } else { // add number to array
-      result[0] += num;
-    }
-  }
-  return result;
-}
-
-var builtInReduce = {
-  _sum: function (keys, values) {
-    return sum(values);
-  },
-
-  _count: function (keys, values) {
-    return values.length;
-  },
-
-  _stats: function (keys, values) {
-    // no need to implement rereduce=true, because Pouch
-    // will never call it
-    function sumsqr(values) {
-      var _sumsqr = 0;
-      for (var i = 0, len = values.length; i < len; i++) {
-        var num = values[i];
-        _sumsqr += (num * num);
-      }
-      return _sumsqr;
-    }
-    return {
-      sum     : sum(values),
-      min     : Math.min.apply(null, values),
-      max     : Math.max.apply(null, values),
-      count   : values.length,
-      sumsqr : sumsqr(values)
-    };
-  }
-};
-
-function addHttpParam(paramName, opts, params, asJson) {
-  // add an http param from opts to params, optionally json-encoded
-  var val = opts[paramName];
-  if (typeof val !== 'undefined') {
-    if (asJson) {
-      val = encodeURIComponent(JSON.stringify(val));
-    }
-    params.push(paramName + '=' + val);
-  }
-}
-
-function checkQueryParseError(options, fun) {
-  var startkeyName = options.descending ? 'endkey' : 'startkey';
-  var endkeyName = options.descending ? 'startkey' : 'endkey';
-
-  if (typeof options[startkeyName] !== 'undefined' &&
-    typeof options[endkeyName] !== 'undefined' &&
-    collate(options[startkeyName], options[endkeyName]) > 0) {
-    throw new QueryParseError('No rows can match your key range, reverse your ' +
-        'start_key and end_key or set {descending : true}');
-  } else if (fun.reduce && options.reduce !== false) {
-    if (options.include_docs) {
-      throw new QueryParseError('{include_docs:true} is invalid for reduce');
-    } else if (options.keys && options.keys.length > 1 &&
-        !options.group && !options.group_level) {
-      throw new QueryParseError('Multi-key fetches for reduce views must use {group: true}');
-    }
-  }
-  if (options.group_level) {
-    if (typeof options.group_level !== 'number') {
-      throw new QueryParseError('Invalid value for integer: "' + options.group_level + '"');
-    }
-    if (options.group_level < 0) {
-      throw new QueryParseError('Invalid value for positive integer: ' +
-        '"' + options.group_level + '"');
-    }
-  }
-}
-
-function httpQuery(db, fun, opts) {
-  // List of parameters to add to the PUT request
-  var params = [];
-  var body;
-  var method = 'GET';
-
-  // If opts.reduce exists and is defined, then add it to the list
-  // of parameters.
-  // If reduce=false then the results are that of only the map function
-  // not the final result of map and reduce.
-  addHttpParam('reduce', opts, params);
-  addHttpParam('include_docs', opts, params);
-  addHttpParam('limit', opts, params);
-  addHttpParam('descending', opts, params);
-  addHttpParam('group', opts, params);
-  addHttpParam('group_level', opts, params);
-  addHttpParam('skip', opts, params);
-  addHttpParam('stale', opts, params);
-  addHttpParam('startkey', opts, params, true);
-  addHttpParam('endkey', opts, params, true);
-  addHttpParam('inclusive_end', opts, params);
-  addHttpParam('key', opts, params, true);
-
-  // Format the list of parameters into a valid URI query string
-  params = params.join('&');
-  params = params === '' ? '' : '?' + params;
-
-  // If keys are supplied, issue a POST request to circumvent GET query string limits
-  // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-  if (typeof opts.keys !== 'undefined') {
-    var MAX_URL_LENGTH = 2000;
-    // according to http://stackoverflow.com/a/417184/680742,
-    // the de facto URL length limit is 2000 characters
-
-    var keysAsString =
-      'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-    if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-      // If the keys are short enough, do a GET. we do this to work around
-      // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
-      params += (params[0] === '?' ? '&' : '?') + keysAsString;
-    } else {
-      method = 'POST';
-      if (typeof fun === 'string') {
-        body = JSON.stringify({keys: opts.keys});
-      } else { // fun is {map : mapfun}, so append to this
-        fun.keys = opts.keys;
-      }
-    }
-  }
-
-  // We are referencing a query defined in the design doc
-  if (typeof fun === 'string') {
-    var parts = parseViewName(fun);
-    return db.request({
-      method: method,
-      url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
-      body: body
-    });
-  }
-
-  // We are using a temporary view, terrible for performance but good for testing
-  body = body || {};
-  Object.keys(fun).forEach(function (key) {
-    if (Array.isArray(fun[key])) {
-      body[key] = fun[key];
-    } else {
-      body[key] = fun[key].toString();
-    }
-  });
-  return db.request({
-    method: 'POST',
-    url: '_temp_view' + params,
-    body: body
-  });
-}
-
-function defaultsTo(value) {
-  return function (reason) {
-    /* istanbul ignore else */
-    if (reason.status === 404) {
-      return value;
-    } else {
-      throw reason;
-    }
-  };
-}
-
-// returns a promise for a list of docs to update, based on the input docId.
-// we update the metaDoc first (i.e. the doc that points from the sourceDB
-// document Id to the ids of the documents in the mrview database), then
-// the key/value docs.  that way, if lightning strikes the user's computer
-// in the middle of an update, we don't write any docs that we wouldn't
-// be able to find later using the metaDoc.
-function getDocsToPersist(docId, view, docIdsToEmits) {
-  var metaDocId = '_local/doc_' + docId;
-  return view.db.get(metaDocId)[
-    "catch"](defaultsTo({_id: metaDocId, keys: []}))
-    .then(function (metaDoc) {
-      return Promise.resolve().then(function () {
-        if (metaDoc.keys.length) {
-          return view.db.allDocs({
-            keys: metaDoc.keys,
-            include_docs: true
-          });
-        }
-        return {rows: []}; // no keys, no need for a lookup
-      }).then(function (res) {
-        var kvDocs = res.rows.map(function (row) {
-          return row.doc;
-        }).filter(function (row) {
-          return row;
-        });
-
-        var indexableKeysToKeyValues = docIdsToEmits[docId];
-        var oldKeysMap = {};
-        kvDocs.forEach(function (kvDoc) {
-          oldKeysMap[kvDoc._id] = true;
-          kvDoc._deleted = !indexableKeysToKeyValues[kvDoc._id];
-          if (!kvDoc._deleted) {
-            var keyValue = indexableKeysToKeyValues[kvDoc._id];
-            if ('value' in keyValue) {
-              kvDoc.value = keyValue.value;
-            }
-          }
-        });
-
-        var newKeys = Object.keys(indexableKeysToKeyValues);
-        newKeys.forEach(function (key) {
-          if (!oldKeysMap[key]) {
-            // new doc
-            var kvDoc = {
-              _id: key
-            };
-            var keyValue = indexableKeysToKeyValues[key];
-            if ('value' in keyValue) {
-              kvDoc.value = keyValue.value;
-            }
-            kvDocs.push(kvDoc);
-          }
-        });
-        metaDoc.keys = utils.uniq(newKeys.concat(metaDoc.keys));
-        kvDocs.splice(0, 0, metaDoc);
-
-        return kvDocs;
-      });
-    });
-}
-
-// updates all emitted key/value docs and metaDocs in the mrview database
-// for the given batch of documents from the source database
-function saveKeyValues(view, docIdsToEmits, seq) {
-  var seqDocId = '_local/lastSeq';
-  return view.db.get(seqDocId)[
-  "catch"](defaultsTo({_id: seqDocId, seq: 0}))
-  .then(function (lastSeqDoc) {
-    var docIds = Object.keys(docIdsToEmits);
-    return Promise.all(docIds.map(function (docId) {
-        return getDocsToPersist(docId, view, docIdsToEmits);
-      })).then(function (listOfDocsToPersist) {
-        var docsToPersist = [];
-        listOfDocsToPersist.forEach(function (docList) {
-          docsToPersist = docsToPersist.concat(docList);
-        });
-
-        // update the seq doc last, so that if a meteor strikes the user's
-        // computer in the middle of an update, we can apply the idempotent
-        // batch update operation again
-        lastSeqDoc.seq = seq;
-        docsToPersist.push(lastSeqDoc);
-
-        return view.db.bulkDocs({docs : docsToPersist});
-      });
-  });
-}
-
-var updateView = utils.sequentialize(mainQueue, function (view) {
-  // bind the emit function once
-  var mapResults;
-  var doc;
-
-  function emit(key, value) {
-    var output = { id: doc._id, key: normalizeKey(key) };
-    // Don't explicitly store the value unless it's defined and non-null.
-    // This saves on storage space, because often people don't use it.
-    if (typeof value !== 'undefined' && value !== null) {
-      output.value = normalizeKey(value);
-    }
-    mapResults.push(output);
-  }
-
-  var mapFun;
-  // for temp_views one can use emit(doc, emit), see #38
-  if (typeof view.mapFun === "function" && view.mapFun.length === 2) {
-    var origMap = view.mapFun;
-    mapFun = function (doc) {
-      return origMap(doc, emit);
-    };
-  } else {
-    mapFun = evalFunc(view.mapFun.toString(), emit, sum, log, Array.isArray, JSON.parse);
-  }
-
-  var currentSeq = view.seq || 0;
-
-  function processChange(docIdsToEmits, seq) {
-    return function () {
-      return saveKeyValues(view, docIdsToEmits, seq);
-    };
-  }
-  var queue = new TaskQueue();
-  // TODO(neojski): https://github.com/daleharvey/pouchdb/issues/1521
-
-  return new Promise(function (resolve, reject) {
-
-    function complete() {
-      queue.finish().then(function () {
-        view.seq = currentSeq;
-        resolve();
-      });
-    }
-
-    function processNextBatch() {
-      view.sourceDB.changes({
-        conflicts: true,
-        include_docs: true,
-        since : currentSeq,
-        limit : CHANGES_BATCH_SIZE
-      }).on('complete', function (response) {
-        var results = response.results;
-        if (!results.length) {
-          return complete();
-        }
-        var docIdsToEmits = {};
-        for (var i = 0, l = results.length; i < l; i++) {
-          var change = results[i];
-          if (change.doc._id[0] !== '_') {
-            mapResults = [];
-            doc = change.doc;
-
-            if (!doc._deleted) {
-              tryCode(view.sourceDB, mapFun, [doc]);
-            }
-            mapResults.sort(sortByKeyThenValue);
-
-            var indexableKeysToKeyValues = {};
-            var lastKey;
-            for (var j = 0, jl = mapResults.length; j < jl; j++) {
-              var obj = mapResults[j];
-              var complexKey = [obj.key, obj.id];
-              if (obj.key === lastKey) {
-                complexKey.push(j); // dup key+id, so make it unique
-              }
-              var indexableKey = toIndexableString(complexKey);
-              indexableKeysToKeyValues[indexableKey] = obj;
-              lastKey = obj.key;
-            }
-            docIdsToEmits[change.doc._id] = indexableKeysToKeyValues;
-          }
-          currentSeq = change.seq;
-        }
-        queue.add(processChange(docIdsToEmits, currentSeq));
-        if (results.length < CHANGES_BATCH_SIZE) {
-          return complete();
-        }
-        return processNextBatch();
-      }).on('error', onError);
-      /* istanbul ignore next */
-      function onError(err) {
-        reject(err);
-      }
-    }
-    processNextBatch();
-  });
-});
-
-function reduceView(view, results, options) {
-  if (options.group_level === 0) {
-    delete options.group_level;
-  }
-
-  var shouldGroup = options.group || options.group_level;
-
-  var reduceFun;
-  if (builtInReduce[view.reduceFun]) {
-    reduceFun = builtInReduce[view.reduceFun];
-  } else {
-    reduceFun = evalFunc(
-      view.reduceFun.toString(), null, sum, log, Array.isArray, JSON.parse);
-  }
-
-  var groups = [];
-  var lvl = options.group_level;
-  results.forEach(function (e) {
-    var last = groups[groups.length - 1];
-    var key = shouldGroup ? e.key : null;
-
-    // only set group_level for array keys
-    if (shouldGroup && Array.isArray(key) && typeof lvl === 'number') {
-      key = key.length > lvl ? key.slice(0, lvl) : key;
-    }
-
-    if (last && collate(last.key[0][0], key) === 0) {
-      last.key.push([key, e.id]);
-      last.value.push(e.value);
-      return;
-    }
-    groups.push({key: [
-      [key, e.id]
-    ], value: [e.value]});
-  });
-  for (var i = 0, len = groups.length; i < len; i++) {
-    var e = groups[i];
-    var reduceTry = tryCode(view.sourceDB, reduceFun, [e.key, e.value, false]);
-    // CouchDB typically just sets the value to null if reduce errors out
-    e.value = reduceTry.error ? null : reduceTry.output;
-    e.key = e.key[0][0];
-  }
-  // no total_rows/offset when reducing
-  return {rows: sliceResults(groups, options.limit, options.skip)};
-}
-
-var queryView = utils.sequentialize(mainQueue, function (view, opts) {
-  var totalRows;
-  var shouldReduce = view.reduceFun && opts.reduce !== false;
-  var skip = opts.skip || 0;
-  if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
-    // equivalent query
-    opts.limit = 0;
-    delete opts.keys;
-  }
-
-  function fetchFromView(viewOpts) {
-    viewOpts.include_docs = true;
-    return view.db.allDocs(viewOpts).then(function (res) {
-      totalRows = res.total_rows;
-      return res.rows.map(function (result) {
-
-        // implicit migration - in older versions of PouchDBVersion306,
-        // we explicitly stored the doc as {id: ..., key: ..., value: ...}
-        // this is tested in a migration test
-        /* istanbul ignore next */
-        if ('value' in result.doc && typeof result.doc.value === 'object' &&
-            result.doc.value !== null) {
-          var keys = Object.keys(result.doc.value).sort();
-          // this detection method is not perfect, but it's unlikely the user
-          // emitted a value which was an object with these 3 exact keys
-          var expectedKeys = ['id', 'key', 'value'];
-          if (!(keys < expectedKeys || keys > expectedKeys)) {
-            return result.doc.value;
-          }
-        }
-
-        var parsedKeyAndDocId = pouchCollate.parseIndexableString(result.doc._id);
-        return {
-          key: parsedKeyAndDocId[0],
-          id: parsedKeyAndDocId[1],
-          value: ('value' in result.doc ? result.doc.value : null)
-        };
-      });
-    });
-  }
-
-  function onMapResultsReady(results) {
-    var res;
-    if (shouldReduce) {
-      res = reduceView(view, results, opts);
-    } else {
-      res = {
-        total_rows: totalRows,
-        offset: skip,
-        rows: results
-      };
-    }
-    if (opts.include_docs) {
-      var getDocsPromises = results.map(function (row) {
-        var val = row.value;
-        var docId = (val && typeof val === 'object' && val._id) || row.id;
-        return view.sourceDB.get(docId).then(function (joinedDoc) {
-          row.doc = joinedDoc;
-        }, function () {
-          // document error = don't join
-        });
-      });
-      return Promise.all(getDocsPromises).then(function () {
-        return res;
-      });
-    } else {
-      return res;
-    }
-  }
-
-  var flatten = function (array) {
-    return array.reduce(function (prev, cur) {
-      return prev.concat(cur);
-    });
-  };
-
-  if (typeof opts.keys !== 'undefined') {
-    var keys = opts.keys;
-    var fetchPromises = keys.map(function (key) {
-      var viewOpts = {
-        startkey : toIndexableString([key]),
-        endkey   : toIndexableString([key, {}])
-      };
-      return fetchFromView(viewOpts);
-    });
-    return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
-  } else { // normal query, no 'keys'
-    var viewOpts = {
-      descending : opts.descending
-    };
-    if (typeof opts.startkey !== 'undefined') {
-      viewOpts.startkey = opts.descending ?
-        toIndexableString([opts.startkey, {}]) :
-        toIndexableString([opts.startkey]);
-    }
-    if (typeof opts.endkey !== 'undefined') {
-      var inclusiveEnd = opts.inclusive_end !== false;
-      if (opts.descending) {
-        inclusiveEnd = !inclusiveEnd;
-      }
-
-      viewOpts.endkey = toIndexableString(inclusiveEnd ? [opts.endkey, {}] : [opts.endkey]);
-    }
-    if (typeof opts.key !== 'undefined') {
-      var keyStart = toIndexableString([opts.key]);
-      var keyEnd = toIndexableString([opts.key, {}]);
-      if (viewOpts.descending) {
-        viewOpts.endkey = keyStart;
-        viewOpts.startkey = keyEnd;
-      } else {
-        viewOpts.startkey = keyStart;
-        viewOpts.endkey = keyEnd;
-      }
-    }
-    if (!shouldReduce) {
-      if (typeof opts.limit === 'number') {
-        viewOpts.limit = opts.limit;
-      }
-      viewOpts.skip = skip;
-    }
-    return fetchFromView(viewOpts).then(onMapResultsReady);
-  }
-});
-
-function httpViewCleanup(db) {
-  return db.request({
-    method: 'POST',
-    url: '_view_cleanup'
-  });
-}
-
-var localViewCleanup = utils.sequentialize(mainQueue, function (db) {
-  return db.get('_local/mrviews').then(function (metaDoc) {
-    var docsToViews = {};
-    Object.keys(metaDoc.views).forEach(function (fullViewName) {
-      var parts = parseViewName(fullViewName);
-      var designDocName = '_design/' + parts[0];
-      var viewName = parts[1];
-      docsToViews[designDocName] = docsToViews[designDocName] || {};
-      docsToViews[designDocName][viewName] = true;
-    });
-    var opts = {
-      keys : Object.keys(docsToViews),
-      include_docs : true
-    };
-    return db.allDocs(opts).then(function (res) {
-      var viewsToStatus = {};
-      res.rows.forEach(function (row) {
-        var ddocName = row.key.substring(8);
-        Object.keys(docsToViews[row.key]).forEach(function (viewName) {
-          var fullViewName = ddocName + '/' + viewName;
-          /* istanbul ignore if */
-          if (!metaDoc.views[fullViewName]) {
-            // new format, without slashes, to support PouchDBVersion306 2.2.0
-            // migration test in pouchdb's browser.migration.js verifies this
-            fullViewName = viewName;
-          }
-          var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
-          // design doc deleted, or view function nonexistent
-          var statusIsGood = row.doc && row.doc.views && row.doc.views[viewName];
-          viewDBNames.forEach(function (viewDBName) {
-            viewsToStatus[viewDBName] = viewsToStatus[viewDBName] || statusIsGood;
-          });
-        });
-      });
-      var dbsToDelete = Object.keys(viewsToStatus).filter(function (viewDBName) {
-        return !viewsToStatus[viewDBName];
-      });
-      var destroyPromises = dbsToDelete.map(function (viewDBName) {
-        return db.constructor.destroy(viewDBName, {adapter : db.adapter});
-      });
-      return Promise.all(destroyPromises).then(function () {
-        return {ok: true};
-      });
-    });
-  }, defaultsTo({ok: true}));
-});
-
-exports.viewCleanup = utils.callbackify(function () {
-  var db = this;
-  if (db.type() === 'http') {
-    return httpViewCleanup(db);
-  }
-  return localViewCleanup(db);
-});
-
-function queryPromised(db, fun, opts) {
-  if (db.type() === 'http') {
-    return httpQuery(db, fun, opts);
-  }
-
-  if (typeof fun !== 'string') {
-    // temp_view
-    checkQueryParseError(opts, fun);
-
-    var createViewOpts = {
-      db : db,
-      viewName : 'temp_view/temp_view',
-      map : fun.map,
-      reduce : fun.reduce,
-      temporary : true
-    };
-    tempViewQueue.add(function () {
-      return createView(createViewOpts).then(function (view) {
-        function cleanup() {
-          return view.db.destroy();
-        }
-        return utils.fin(updateView(view).then(function () {
-          return queryView(view, opts);
-        }), cleanup);
-      });
-    });
-    return tempViewQueue.finish();
-  } else {
-    // persistent view
-    var fullViewName = fun;
-    var parts = parseViewName(fullViewName);
-    var designDocName = parts[0];
-    var viewName = parts[1];
-    return db.get('_design/' + designDocName).then(function (doc) {
-      var fun = doc.views && doc.views[viewName];
-
-      if (!fun || typeof fun.map !== 'string') {
-        throw new NotFoundError('ddoc ' + designDocName + ' has no view named ' +
-          viewName);
-      }
-      checkQueryParseError(opts, fun);
-
-      var createViewOpts = {
-        db : db,
-        viewName : fullViewName,
-        map : fun.map,
-        reduce : fun.reduce
-      };
-      return createView(createViewOpts).then(function (view) {
-        if (opts.stale === 'ok' || opts.stale === 'update_after') {
-          if (opts.stale === 'update_after') {
-            process.nextTick(function () {
-              updateView(view);
-            });
-          }
-          return queryView(view, opts);
-        } else { // stale not ok
-          return updateView(view).then(function () {
-            return queryView(view, opts);
-          });
-        }
-      });
-    });
-  }
-}
-
-exports.query = function (fun, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  opts = utils.extend(true, {}, opts);
-
-  if (typeof fun === 'function') {
-    fun = {map : fun};
-  }
-
-  var db = this;
-  var promise = Promise.resolve().then(function () {
-    return queryPromised(db, fun, opts);
-  });
-  utils.promisedCallback(promise, callback);
-  return promise;
-};
-
-function QueryParseError(message) {
-  this.status = 400;
-  this.name = 'query_parse_error';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, QueryParseError);
-  } catch (e) {}
-}
-
-utils.inherits(QueryParseError, Error);
-
-function NotFoundError(message) {
-  this.status = 404;
-  this.name = 'not_found';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, NotFoundError);
-  } catch (e) {}
-}
-
-utils.inherits(NotFoundError, Error);
-
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
-},{"./create-view":49,"./evalfunc":50,"./taskqueue":54,"./utils":56,"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"pouchdb-collate":52}],52:[function(_dereq_,module,exports){
-'use strict';
-
-var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
-var MAGNITUDE_DIGITS = 3; // ditto
-var SEP = ''; // set to '_' for easier debugging 
-
-var utils = _dereq_('./utils');
-
-exports.collate = function (a, b) {
-
-  if (a === b) {
-    return 0;
-  }
-
-  a = exports.normalizeKey(a);
-  b = exports.normalizeKey(b);
-
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  if (a === null) {
-    return 0;
-  }
-  switch (typeof a) {
-    case 'number':
-      return a - b;
-    case 'boolean':
-      return a === b ? 0 : (a < b ? -1 : 1);
-    case 'string':
-      return stringCollate(a, b);
-  }
-  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
-};
-
-// couch considers null/NaN/Infinity/-Infinity === undefined,
-// for the purposes of mapreduce indexes. also, dates get stringified.
-exports.normalizeKey = function (key) {
-  switch (typeof key) {
-    case 'undefined':
-      return null;
-    case 'number':
-      if (key === Infinity || key === -Infinity || isNaN(key)) {
-        return null;
-      }
-      return key;
-    case 'object':
-      var origKey = key;
-      if (Array.isArray(key)) {
-        var len = key.length;
-        key = new Array(len);
-        for (var i = 0; i < len; i++) {
-          key[i] = exports.normalizeKey(origKey[i]);
-        }
-      } else if (key instanceof Date) {
-        return key.toJSON();
-      } else if (key !== null) { // generic object
-        key = {};
-        for (var k in origKey) {
-          if (origKey.hasOwnProperty(k)) {
-            var val = origKey[k];
-            if (typeof val !== 'undefined') {
-              key[k] = exports.normalizeKey(val);
-            }
-          }
-        }
-      }
-  }
-  return key;
-};
-
-function indexify(key) {
-  if (key !== null) {
-    switch (typeof key) {
-      case 'boolean':
-        return key ? 1 : 0;
-      case 'number':
-        return numToIndexableString(key);
-      case 'string':
-        // We've to be sure that key does not contain \u0000
-        // Do order-preserving replacements:
-        // 0 -> 1, 1
-        // 1 -> 1, 2
-        // 2 -> 2, 2
-        return key
-          .replace(/\u0002/g, '\u0002\u0002')
-          .replace(/\u0001/g, '\u0001\u0002')
-          .replace(/\u0000/g, '\u0001\u0001');
-      case 'object':
-        var isArray = Array.isArray(key);
-        var arr = isArray ? key : Object.keys(key);
-        var i = -1;
-        var len = arr.length;
-        var result = '';
-        if (isArray) {
-          while (++i < len) {
-            result += exports.toIndexableString(arr[i]);
-          }
-        } else {
-          while (++i < len) {
-            var objKey = arr[i];
-            result += exports.toIndexableString(objKey) +
-                exports.toIndexableString(key[objKey]);
-          }
-        }
-        return result;
-    }
-  }
-  return '';
-}
-
-// convert the given key to a string that would be appropriate
-// for lexical sorting, e.g. within a database, where the
-// sorting is the same given by the collate() function.
-exports.toIndexableString = function (key) {
-  var zero = '\u0000';
-  key = exports.normalizeKey(key);
-  return collationIndex(key) + SEP + indexify(key) + zero;
-};
-
-function parseNumber(str, i) {
-  var originalIdx = i;
-  var num;
-  var zero = str[i] === '1';
-  if (zero) {
-    num = 0;
-    i++;
-  } else {
-    var neg = str[i] === '0';
-    i++;
-    var numAsString = '';
-    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
-    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
-    if (neg) {
-      magnitude = -magnitude;
-    }
-    i += MAGNITUDE_DIGITS;
-    while (true) {
-      var ch = str[i];
-      if (ch === '\u0000') {
-        break;
-      } else {
-        numAsString += ch;
-      }
-      i++;
-    }
-    numAsString = numAsString.split('.');
-    if (numAsString.length === 1) {
-      num = parseInt(numAsString, 10);
-    } else {
-      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
-    }
-    if (neg) {
-      num = num - 10;
-    }
-    if (magnitude !== 0) {
-      // parseFloat is more reliable than pow due to rounding errors
-      // e.g. Number.MAX_VALUE would return Infinity if we did
-      // num * Math.pow(10, magnitude);
-      num = parseFloat(num + 'e' + magnitude);
-    }
-  }
-  return {num: num, length : i - originalIdx};
-}
-
-// move up the stack while parsing
-// this function moved outside of parseIndexableString for performance
-function pop(stack, metaStack) {
-  var obj = stack.pop();
-
-  if (metaStack.length) {
-    var lastMetaElement = metaStack[metaStack.length - 1];
-    if (obj === lastMetaElement.element) {
-      // popping a meta-element, e.g. an object whose value is another object
-      metaStack.pop();
-      lastMetaElement = metaStack[metaStack.length - 1];
-    }
-    var element = lastMetaElement.element;
-    var lastElementIndex = lastMetaElement.index;
-    if (Array.isArray(element)) {
-      element.push(obj);
-    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
-      var key = stack.pop();
-      element[key] = obj;
-    } else {
-      stack.push(obj); // obj with key only
-    }
-  }
-}
-
-exports.parseIndexableString = function (str) {
-  var stack = [];
-  var metaStack = []; // stack for arrays and objects
-  var i = 0;
-
-  while (true) {
-    var collationIndex = str[i++];
-    if (collationIndex === '\u0000') {
-      if (stack.length === 1) {
-        return stack.pop();
-      } else {
-        pop(stack, metaStack);
-        continue;
-      }
-    }
-    switch (collationIndex) {
-      case '1':
-        stack.push(null);
-        break;
-      case '2':
-        stack.push(str[i] === '1');
-        i++;
-        break;
-      case '3':
-        var parsedNum = parseNumber(str, i);
-        stack.push(parsedNum.num);
-        i += parsedNum.length;
-        break;
-      case '4':
-        var parsedStr = '';
-        while (true) {
-          var ch = str[i];
-          if (ch === '\u0000') {
-            break;
-          }
-          parsedStr += ch;
-          i++;
-        }
-        // perform the reverse of the order-preserving replacement
-        // algorithm (see above)
-        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
-          .replace(/\u0001\u0002/g, '\u0001')
-          .replace(/\u0002\u0002/g, '\u0002');
-        stack.push(parsedStr);
-        break;
-      case '5':
-        var arrayElement = { element: [], index: stack.length };
-        stack.push(arrayElement.element);
-        metaStack.push(arrayElement);
-        break;
-      case '6':
-        var objElement = { element: {}, index: stack.length };
-        stack.push(objElement.element);
-        metaStack.push(objElement);
-        break;
-      default:
-        throw new Error(
-          'bad collationIndex or unexpectedly reached end of input: ' + collationIndex);
-    }
-  }
-};
-
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = exports.collate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-  }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
-}
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = exports.collate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = exports.collate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
-    }
-
-  }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
-}
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-// null/undefined/NaN/Infinity/-Infinity are all considered null
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  var idx = id.indexOf(typeof x);
-  //false if -1 otherwise true, but fast!!!!1
-  if (~idx) {
-    if (x === null) {
-      return 1;
-    }
-    if (Array.isArray(x)) {
-      return 5;
-    }
-    return idx < 3 ? (idx + 2) : (idx + 3);
-  }
-  if (Array.isArray(x)) {
-    return 5;
-  }
-}
-
-// conversion:
-// x yyy zz...zz
-// x = 0 for negative, 1 for 0, 2 for positive
-// y = exponent (for negative numbers negated) moved so that it's >= 0
-// z = mantisse
-function numToIndexableString(num) {
-
-  if (num === 0) {
-    return '1';
-  }
-
-  // convert number to exponential format for easier and
-  // more succinct string sorting
-  var expFormat = num.toExponential().split(/e\+?/);
-  var magnitude = parseInt(expFormat[1], 10);
-
-  var neg = num < 0;
-
-  var result = neg ? '0' : '2';
-
-  // first sort by magnitude
-  // it's easier if all magnitudes are positive
-  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
-  var magString = utils.padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
-
-  result += SEP + magString;
-
-  // then sort by the factor
-  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
-  if (neg) { // for negative reverse ordering
-    factor = 10 - factor;
-  }
-
-  var factorStr = factor.toFixed(20);
-
-  // strip zeros from the end
-  factorStr = factorStr.replace(/\.?0+$/, '');
-
-  result += SEP + factorStr;
-
-  return result;
-}
-
-},{"./utils":53}],53:[function(_dereq_,module,exports){
-'use strict';
-
-function pad(str, padWith, upToLength) {
-  var padding = '';
-  var targetLength = upToLength - str.length;
-  while (padding.length < targetLength) {
-    padding += padWith;
-  }
-  return padding;
-}
-
-exports.padLeft = function (str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return padding + str;
-};
-
-exports.padRight = function (str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return str + padding;
-};
-
-exports.stringLexCompare = function (a, b) {
-
-  var aLen = a.length;
-  var bLen = b.length;
-
-  var i;
-  for (i = 0; i < aLen; i++) {
-    if (i === bLen) {
-      // b is shorter substring of a
-      return 1;
-    }
-    var aChar = a.charAt(i);
-    var bChar = b.charAt(i);
-    if (aChar !== bChar) {
-      return aChar < bChar ? -1 : 1;
-    }
-  }
-
-  if (aLen < bLen) {
-    // a is shorter substring of b
-    return -1;
-  }
-
-  return 0;
-};
-
-/*
- * returns the decimal form for the given integer, i.e. writes
- * out all the digits (in base-10) instead of using scientific notation
- */
-exports.intToDecimalForm = function (int) {
-
-  var isNeg = int < 0;
-  var result = '';
-
-  do {
-    var remainder = isNeg ? -Math.ceil(int % 10) : Math.floor(int % 10);
-
-    result = remainder + result;
-    int = isNeg ? Math.ceil(int / 10) : Math.floor(int / 10);
-  } while (int);
-
-
-  if (isNeg && result !== '0') {
-    result = '-' + result;
-  }
-
-  return result;
-};
-},{}],54:[function(_dereq_,module,exports){
-'use strict';
-/*
- * Simple task queue to sequentialize actions. Assumes callbacks will eventually fire (once).
- */
-
-var Promise = _dereq_('./utils').Promise;
-
-function TaskQueue() {
-  this.promise = new Promise(function (fulfill) {fulfill(); });
-}
-TaskQueue.prototype.add = function (promiseFactory) {
-  this.promise = this.promise["catch"](function () {
-    // just recover
-  }).then(function () {
-    return promiseFactory();
-  });
-  return this.promise;
-};
-TaskQueue.prototype.finish = function () {
-  return this.promise;
-};
-
-module.exports = TaskQueue;
-
-},{"./utils":56}],55:[function(_dereq_,module,exports){
-'use strict';
-var Promise = _dereq_('./utils').Promise;
-
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    if (docId && typeof docId === 'object') {
-      docId = docId._id;
-    }
-    if (typeof docId !== 'string') {
-      return reject(new Error('doc id is required'));
-    }
-
-    db.get(docId, function (err, doc) {
-      if (err) {
-        if (err.status !== 404) {
-          return reject(err);
-        }
-        return fulfill(tryAndPut(db, diffFun({_id : docId}), diffFun));
-      }
-      var newDoc = diffFun(doc);
-      if (!newDoc) {
-        return fulfill(doc);
-      }
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
-  });
-}
-
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc)["catch"](function (err) {
-    if (err.status !== 409) {
-      throw err;
-    }
-    return upsert(db, doc, diffFun);
-  });
-}
-
-module.exports = upsert;
-
-},{"./utils":56}],56:[function(_dereq_,module,exports){
-(function (process,global){
-'use strict';
-/* istanbul ignore if */
-if (typeof global.Promise === 'function') {
-  exports.Promise = global.Promise;
-} else {
-  exports.Promise = _dereq_('lie');
-}
-// uniquify a list, similar to underscore's _.uniq
-exports.uniq = function (arr) {
-  var map = {};
-  arr.forEach(function (element) {
-    map[element] = true;
-  });
-  return Object.keys(map);
-};
-
-exports.inherits = _dereq_('inherits');
-exports.extend = _dereq_('pouchdb-extend');
-var argsarray = _dereq_('argsarray');
-
-exports.promisedCallback = function (promise, callback) {
-  if (callback) {
-    promise.then(function (res) {
-      process.nextTick(function () {
-        callback(null, res);
-      });
-    }, function (reason) {
-      process.nextTick(function () {
-        callback(reason);
-      });
-    });
-  }
-  return promise;
-};
-
-exports.callbackify = function (fun) {
-  return argsarray(function (args) {
-    var cb = args.pop();
-    var promise = fun.apply(this, args);
-    if (typeof cb === 'function') {
-      exports.promisedCallback(promise, cb);
-    }
-    return promise;
-  });
-};
-
-// Promise finally util similar to Q.finally
-exports.fin = function (promise, cb) {
-  return promise.then(function (res) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        return res;
-      });
-    }
-    return res;
-  }, function (reason) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        throw reason;
-      });
-    }
-    throw reason;
-  });
-};
-
-exports.sequentialize = function (queue, promiseFactory) {
-  return function () {
-    var args = arguments;
-    var that = this;
-    return queue.add(function () {
-      return promiseFactory.apply(that, args);
-    });
-  };
-};
-
-var crypto = _dereq_('crypto');
-var Md5 = _dereq_('spark-md5');
-
-exports.MD5 = function (string) {
-  /* istanbul ignore else */
-  if (!process.browser) {
-    return crypto.createHash('md5').update(string).digest('hex');
-  } else {
-    return Md5.hash(string);
-  }
-};
-}).call(this,_dereq_("/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"/Users/nolan/workspace/pouchdb/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":28,"argsarray":25,"crypto":26,"inherits":29,"lie":33,"pouchdb-extend":48,"spark-md5":57}],57:[function(_dereq_,module,exports){
-/*jshint bitwise:false*/
-/*global unescape*/
-
-(function (factory) {
-    if (typeof exports === 'object') {
-        // Node/CommonJS
-        module.exports = factory();
-    } else if (typeof define === 'function' && define.amd) {
-        // AMD
-        define(factory);
-    } else {
-        // Browser globals (with support for web workers)
-        var glob;
-        try {
-            glob = window;
-        } catch (e) {
-            glob = self;
-        }
-
-        glob.SparkMD5 = factory();
-    }
-}(function (undefined) {
-
-    'use strict';
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    /*
-     * Fastest md5 implementation around (JKM md5)
-     * Credits: Joseph Myers
-     *
-     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
-     * @see http://jsperf.com/md5-shootout/7
-     */
-
-    /* this function is much faster,
-      so if possible we use it. Some IEs
-      are the only ones I know of that
-      need the idiotic second function,
-      generated by an if clause.  */
-    var add32 = function (a, b) {
-        return (a + b) & 0xFFFFFFFF;
-    },
-
-    cmn = function (q, a, b, x, s, t) {
-        a = add32(add32(a, q), add32(x, t));
-        return add32((a << s) | (a >>> (32 - s)), b);
-    },
-
-    ff = function (a, b, c, d, x, s, t) {
-        return cmn((b & c) | ((~b) & d), a, b, x, s, t);
-    },
-
-    gg = function (a, b, c, d, x, s, t) {
-        return cmn((b & d) | (c & (~d)), a, b, x, s, t);
-    },
-
-    hh = function (a, b, c, d, x, s, t) {
-        return cmn(b ^ c ^ d, a, b, x, s, t);
-    },
-
-    ii = function (a, b, c, d, x, s, t) {
-        return cmn(c ^ (b | (~d)), a, b, x, s, t);
-    },
-
-    md5cycle = function (x, k) {
-        var a = x[0],
-            b = x[1],
-            c = x[2],
-            d = x[3];
-
-        a = ff(a, b, c, d, k[0], 7, -680876936);
-        d = ff(d, a, b, c, k[1], 12, -389564586);
-        c = ff(c, d, a, b, k[2], 17, 606105819);
-        b = ff(b, c, d, a, k[3], 22, -1044525330);
-        a = ff(a, b, c, d, k[4], 7, -176418897);
-        d = ff(d, a, b, c, k[5], 12, 1200080426);
-        c = ff(c, d, a, b, k[6], 17, -1473231341);
-        b = ff(b, c, d, a, k[7], 22, -45705983);
-        a = ff(a, b, c, d, k[8], 7, 1770035416);
-        d = ff(d, a, b, c, k[9], 12, -1958414417);
-        c = ff(c, d, a, b, k[10], 17, -42063);
-        b = ff(b, c, d, a, k[11], 22, -1990404162);
-        a = ff(a, b, c, d, k[12], 7, 1804603682);
-        d = ff(d, a, b, c, k[13], 12, -40341101);
-        c = ff(c, d, a, b, k[14], 17, -1502002290);
-        b = ff(b, c, d, a, k[15], 22, 1236535329);
-
-        a = gg(a, b, c, d, k[1], 5, -165796510);
-        d = gg(d, a, b, c, k[6], 9, -1069501632);
-        c = gg(c, d, a, b, k[11], 14, 643717713);
-        b = gg(b, c, d, a, k[0], 20, -373897302);
-        a = gg(a, b, c, d, k[5], 5, -701558691);
-        d = gg(d, a, b, c, k[10], 9, 38016083);
-        c = gg(c, d, a, b, k[15], 14, -660478335);
-        b = gg(b, c, d, a, k[4], 20, -405537848);
-        a = gg(a, b, c, d, k[9], 5, 568446438);
-        d = gg(d, a, b, c, k[14], 9, -1019803690);
-        c = gg(c, d, a, b, k[3], 14, -187363961);
-        b = gg(b, c, d, a, k[8], 20, 1163531501);
-        a = gg(a, b, c, d, k[13], 5, -1444681467);
-        d = gg(d, a, b, c, k[2], 9, -51403784);
-        c = gg(c, d, a, b, k[7], 14, 1735328473);
-        b = gg(b, c, d, a, k[12], 20, -1926607734);
-
-        a = hh(a, b, c, d, k[5], 4, -378558);
-        d = hh(d, a, b, c, k[8], 11, -2022574463);
-        c = hh(c, d, a, b, k[11], 16, 1839030562);
-        b = hh(b, c, d, a, k[14], 23, -35309556);
-        a = hh(a, b, c, d, k[1], 4, -1530992060);
-        d = hh(d, a, b, c, k[4], 11, 1272893353);
-        c = hh(c, d, a, b, k[7], 16, -155497632);
-        b = hh(b, c, d, a, k[10], 23, -1094730640);
-        a = hh(a, b, c, d, k[13], 4, 681279174);
-        d = hh(d, a, b, c, k[0], 11, -358537222);
-        c = hh(c, d, a, b, k[3], 16, -722521979);
-        b = hh(b, c, d, a, k[6], 23, 76029189);
-        a = hh(a, b, c, d, k[9], 4, -640364487);
-        d = hh(d, a, b, c, k[12], 11, -421815835);
-        c = hh(c, d, a, b, k[15], 16, 530742520);
-        b = hh(b, c, d, a, k[2], 23, -995338651);
-
-        a = ii(a, b, c, d, k[0], 6, -198630844);
-        d = ii(d, a, b, c, k[7], 10, 1126891415);
-        c = ii(c, d, a, b, k[14], 15, -1416354905);
-        b = ii(b, c, d, a, k[5], 21, -57434055);
-        a = ii(a, b, c, d, k[12], 6, 1700485571);
-        d = ii(d, a, b, c, k[3], 10, -1894986606);
-        c = ii(c, d, a, b, k[10], 15, -1051523);
-        b = ii(b, c, d, a, k[1], 21, -2054922799);
-        a = ii(a, b, c, d, k[8], 6, 1873313359);
-        d = ii(d, a, b, c, k[15], 10, -30611744);
-        c = ii(c, d, a, b, k[6], 15, -1560198380);
-        b = ii(b, c, d, a, k[13], 21, 1309151649);
-        a = ii(a, b, c, d, k[4], 6, -145523070);
-        d = ii(d, a, b, c, k[11], 10, -1120210379);
-        c = ii(c, d, a, b, k[2], 15, 718787259);
-        b = ii(b, c, d, a, k[9], 21, -343485551);
-
-        x[0] = add32(a, x[0]);
-        x[1] = add32(b, x[1]);
-        x[2] = add32(c, x[2]);
-        x[3] = add32(d, x[3]);
-    },
-
-    /* there needs to be support for Unicode here,
-       * unless we pretend that we can redefine the MD-5
-       * algorithm for multi-byte characters (perhaps
-       * by adding every four 16-bit characters and
-       * shortening the sum to 32 bits). Otherwise
-       * I suggest performing MD-5 as if every character
-       * was two bytes--e.g., 0040 0025 = @%--but then
-       * how will an ordinary MD-5 sum be matched?
-       * There is no way to standardize text to something
-       * like UTF-8 before transformation; speed cost is
-       * utterly prohibitive. The JavaScript standard
-       * itself needs to look at this: it should start
-       * providing access to strings as preformed UTF-8
-       * 8-bit unsigned value arrays.
-       */
-    md5blk = function (s) {
-        var md5blks = [],
-            i; /* Andy King said do it this way. */
-
-        for (i = 0; i < 64; i += 4) {
-            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
-        }
-        return md5blks;
-    },
-
-    md5blk_array = function (a) {
-        var md5blks = [],
-            i; /* Andy King said do it this way. */
-
-        for (i = 0; i < 64; i += 4) {
-            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
-        }
-        return md5blks;
-    },
-
-    md51 = function (s) {
-        var n = s.length,
-            state = [1732584193, -271733879, -1732584194, 271733878],
-            i,
-            length,
-            tail,
-            tmp,
-            lo,
-            hi;
-
-        for (i = 64; i <= n; i += 64) {
-            md5cycle(state, md5blk(s.substring(i - 64, i)));
-        }
-        s = s.substring(i - 64);
-        length = s.length;
-        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
-        }
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(state, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
-
-        // Beware that the final length might not fit in 32 bits so we take care of that
-        tmp = n * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
-
-        tail[14] = lo;
-        tail[15] = hi;
-
-        md5cycle(state, tail);
-        return state;
-    },
-
-    md51_array = function (a) {
-        var n = a.length,
-            state = [1732584193, -271733879, -1732584194, 271733878],
-            i,
-            length,
-            tail,
-            tmp,
-            lo,
-            hi;
-
-        for (i = 64; i <= n; i += 64) {
-            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
-        }
-
-        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
-        // containing the last element of the parent array if the sub array specified starts
-        // beyond the length of the parent array - weird.
-        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
-        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
-
-        length = a.length;
-        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= a[i] << ((i % 4) << 3);
-        }
-
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(state, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
-
-        // Beware that the final length might not fit in 32 bits so we take care of that
-        tmp = n * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
-
-        tail[14] = lo;
-        tail[15] = hi;
-
-        md5cycle(state, tail);
-
-        return state;
-    },
-
-    hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'],
-
-    rhex = function (n) {
-        var s = '',
-            j;
-        for (j = 0; j < 4; j += 1) {
-            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
-        }
-        return s;
-    },
-
-    hex = function (x) {
-        var i;
-        for (i = 0; i < x.length; i += 1) {
-            x[i] = rhex(x[i]);
-        }
-        return x.join('');
-    },
-
-    md5 = function (s) {
-        return hex(md51(s));
-    },
-
-
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * SparkMD5 OOP implementation.
-     *
-     * Use this class to perform an incremental md5, otherwise use the
-     * static methods instead.
-     */
-    SparkMD5 = function () {
-        // call reset to init the instance
-        this.reset();
-    };
-
-
-    // In some cases the fast add32 function cannot be used..
-    if (md5('hello') !== '5d41402abc4b2a76b9719d911017c592') {
-        add32 = function (x, y) {
-            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
-                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-            return (msw << 16) | (lsw & 0xFFFF);
-        };
-    }
-
-
-    /**
-     * Appends a string.
-     * A conversion will be applied if an utf8 string is detected.
-     *
-     * @param {String} str The string to be appended
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.append = function (str) {
-        // converts the string to utf8 bytes if necessary
-        if (/[\u0080-\uFFFF]/.test(str)) {
-            str = unescape(encodeURIComponent(str));
-        }
-
-        // then append as binary
-        this.appendBinary(str);
-
-        return this;
-    };
-
-    /**
-     * Appends a binary string.
-     *
-     * @param {String} contents The binary string to be appended
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.appendBinary = function (contents) {
-        this._buff += contents;
-        this._length += contents.length;
-
-        var length = this._buff.length,
-            i;
-
-        for (i = 64; i <= length; i += 64) {
-            md5cycle(this._state, md5blk(this._buff.substring(i - 64, i)));
-        }
-
-        this._buff = this._buff.substr(i - 64);
-
-        return this;
-    };
-
-    /**
-     * Finishes the incremental computation, reseting the internal state and
-     * returning the result.
-     * Use the raw parameter to obtain the raw result instead of the hex one.
-     *
-     * @param {Boolean} raw True to get the raw result, false to get the hex result
-     *
-     * @return {String|Array} The result
-     */
-    SparkMD5.prototype.end = function (raw) {
-        var buff = this._buff,
-            length = buff.length,
-            i,
-            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            ret;
-
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
-        }
-
-        this._finish(tail, length);
-        ret = !!raw ? this._state : hex(this._state);
-
-        this.reset();
-
-        return ret;
-    };
-
-    /**
-     * Finish the final calculation based on the tail.
-     *
-     * @param {Array}  tail   The tail (will be modified)
-     * @param {Number} length The length of the remaining buffer
-     */
-    SparkMD5.prototype._finish = function (tail, length) {
-        var i = length,
-            tmp,
-            lo,
-            hi;
-
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(this._state, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
-
-        // Do the final computation based on the tail and length
-        // Beware that the final length may not fit in 32 bits so we take care of that
-        tmp = this._length * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
-
-        tail[14] = lo;
-        tail[15] = hi;
-        md5cycle(this._state, tail);
-    };
-
-    /**
-     * Resets the internal state of the computation.
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.reset = function () {
-        this._buff = "";
-        this._length = 0;
-        this._state = [1732584193, -271733879, -1732584194, 271733878];
-
-        return this;
-    };
-
-    /**
-     * Releases memory used by the incremental buffer and other aditional
-     * resources. If you plan to use the instance again, use reset instead.
-     */
-    SparkMD5.prototype.destroy = function () {
-        delete this._state;
-        delete this._buff;
-        delete this._length;
-    };
-
-
-    /**
-     * Performs the md5 hash on a string.
-     * A conversion will be applied if utf8 string is detected.
-     *
-     * @param {String}  str The string
-     * @param {Boolean} raw True to get the raw result, false to get the hex result
-     *
-     * @return {String|Array} The result
-     */
-    SparkMD5.hash = function (str, raw) {
-        // converts the string to utf8 bytes if necessary
-        if (/[\u0080-\uFFFF]/.test(str)) {
-            str = unescape(encodeURIComponent(str));
-        }
-
-        var hash = md51(str);
-
-        return !!raw ? hash : hex(hash);
-    };
-
-    /**
-     * Performs the md5 hash on a binary string.
-     *
-     * @param {String}  content The binary string
-     * @param {Boolean} raw     True to get the raw result, false to get the hex result
-     *
-     * @return {String|Array} The result
-     */
-    SparkMD5.hashBinary = function (content, raw) {
-        var hash = md51(content);
-
-        return !!raw ? hash : hex(hash);
-    };
-
-    /**
-     * SparkMD5 OOP implementation for array buffers.
-     *
-     * Use this class to perform an incremental md5 ONLY for array buffers.
-     */
-    SparkMD5.ArrayBuffer = function () {
-        // call reset to init the instance
-        this.reset();
-    };
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Appends an array buffer.
-     *
-     * @param {ArrayBuffer} arr The array to be appended
-     *
-     * @return {SparkMD5.ArrayBuffer} The instance itself
-     */
-    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
-        // TODO: we could avoid the concatenation here but the algorithm would be more complex
-        //       if you find yourself needing extra performance, please make a PR.
-        var buff = this._concatArrayBuffer(this._buff, arr),
-            length = buff.length,
-            i;
-
-        this._length += arr.byteLength;
-
-        for (i = 64; i <= length; i += 64) {
-            md5cycle(this._state, md5blk_array(buff.subarray(i - 64, i)));
-        }
-
-        // Avoids IE10 weirdness (documented above)
-        this._buff = (i - 64) < length ? buff.subarray(i - 64) : new Uint8Array(0);
-
-        return this;
-    };
-
-    /**
-     * Finishes the incremental computation, reseting the internal state and
-     * returning the result.
-     * Use the raw parameter to obtain the raw result instead of the hex one.
-     *
-     * @param {Boolean} raw True to get the raw result, false to get the hex result
-     *
-     * @return {String|Array} The result
-     */
-    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
-        var buff = this._buff,
-            length = buff.length,
-            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            i,
-            ret;
-
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
-        }
-
-        this._finish(tail, length);
-        ret = !!raw ? this._state : hex(this._state);
-
-        this.reset();
-
-        return ret;
-    };
-
-    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
-
-    /**
-     * Resets the internal state of the computation.
-     *
-     * @return {SparkMD5.ArrayBuffer} The instance itself
-     */
-    SparkMD5.ArrayBuffer.prototype.reset = function () {
-        this._buff = new Uint8Array(0);
-        this._length = 0;
-        this._state = [1732584193, -271733879, -1732584194, 271733878];
-
-        return this;
-    };
-
-    /**
-     * Releases memory used by the incremental buffer and other aditional
-     * resources. If you plan to use the instance again, use reset instead.
-     */
-    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
-
-    /**
-     * Concats two array buffers, returning a new one.
-     *
-     * @param  {ArrayBuffer} first  The first array buffer
-     * @param  {ArrayBuffer} second The second array buffer
-     *
-     * @return {ArrayBuffer} The new array buffer
-     */
-    SparkMD5.ArrayBuffer.prototype._concatArrayBuffer = function (first, second) {
-        var firstLength = first.length,
-            result = new Uint8Array(firstLength + second.byteLength);
-
-        result.set(first);
-        result.set(new Uint8Array(second), firstLength);
-
-        return result;
-    };
-
-    /**
-     * Performs the md5 hash on an array buffer.
-     *
-     * @param {ArrayBuffer} arr The array buffer
-     * @param {Boolean}     raw True to get the raw result, false to get the hex result
-     *
-     * @return {String|Array} The result
-     */
-    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
-        var hash = md51_array(new Uint8Array(arr));
-
-        return !!raw ? hash : hex(hash);
-    };
-
-    return SparkMD5;
-}));
-
-},{}],58:[function(_dereq_,module,exports){
-'use strict';
-
-/**
- * Stringify/parse functions that don't operate
- * recursively, so they avoid call stack exceeded
- * errors.
- */
-exports.stringify = function stringify(input) {
-  var queue = [];
-  queue.push({obj: input});
-
-  var res = '';
-  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
-  while ((next = queue.pop())) {
-    obj = next.obj;
-    prefix = next.prefix || '';
-    val = next.val || '';
-    res += prefix;
-    if (val) {
-      res += val;
-    } else if (typeof obj !== 'object') {
-      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
-    } else if (obj === null) {
-      res += 'null';
-    } else if (Array.isArray(obj)) {
-      queue.push({val: ']'});
-      for (i = obj.length - 1; i >= 0; i--) {
-        arrayPrefix = i === 0 ? '' : ',';
-        queue.push({obj: obj[i], prefix: arrayPrefix});
-      }
-      queue.push({val: '['});
-    } else { // object
-      keys = [];
-      for (k in obj) {
-        if (obj.hasOwnProperty(k)) {
-          keys.push(k);
-        }
-      }
-      queue.push({val: '}'});
-      for (i = keys.length - 1; i >= 0; i--) {
-        key = keys[i];
-        value = obj[key];
-        objPrefix = (i > 0 ? ',' : '');
-        objPrefix += JSON.stringify(key) + ':';
-        queue.push({obj: value, prefix: objPrefix});
-      }
-      queue.push({val: '{'});
-    }
-  }
-  return res;
-};
-
-// Convenience function for the parse function.
-// This pop function is basically copied from
-// pouchCollate.parseIndexableString
-function pop(obj, stack, metaStack) {
-  var lastMetaElement = metaStack[metaStack.length - 1];
-  if (obj === lastMetaElement.element) {
-    // popping a meta-element, e.g. an object whose value is another object
-    metaStack.pop();
-    lastMetaElement = metaStack[metaStack.length - 1];
-  }
-  var element = lastMetaElement.element;
-  var lastElementIndex = lastMetaElement.index;
-  if (Array.isArray(element)) {
-    element.push(obj);
-  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
-    var key = stack.pop();
-    element[key] = obj;
-  } else {
-    stack.push(obj); // obj with key only
-  }
-}
-
-exports.parse = function (str) {
-  var stack = [];
-  var metaStack = []; // stack for arrays and objects
-  var i = 0;
-  var collationIndex,parsedNum,numChar;
-  var parsedString,lastCh,numConsecutiveSlashes,ch;
-  var arrayElement, objElement;
-  while (true) {
-    collationIndex = str[i++];
-    if (collationIndex === '}' ||
-        collationIndex === ']' ||
-        typeof collationIndex === 'undefined') {
-      if (stack.length === 1) {
-        return stack.pop();
-      } else {
-        pop(stack.pop(), stack, metaStack);
-        continue;
-      }
-    }
-    switch (collationIndex) {
-      case ' ':
-      case '\t':
-      case '\n':
-      case ':':
-      case ',':
-        break;
-      case 'n':
-        i += 3; // 'ull'
-        pop(null, stack, metaStack);
-        break;
-      case 't':
-        i += 3; // 'rue'
-        pop(true, stack, metaStack);
-        break;
-      case 'f':
-        i += 4; // 'alse'
-        pop(false, stack, metaStack);
-        break;
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-      case '-':
-        parsedNum = '';
-        i--;
-        while (true) {
-          numChar = str[i++];
-          if (/[\d\.\-e\+]/.test(numChar)) {
-            parsedNum += numChar;
-          } else {
-            i--;
-            break;
-          }
-        }
-        pop(parseFloat(parsedNum), stack, metaStack);
-        break;
-      case '"':
-        parsedString = '';
-        lastCh = void 0;
-        numConsecutiveSlashes = 0;
-        while (true) {
-          ch = str[i++];
-          if (ch !== '"' || (lastCh === '\\' &&
-              numConsecutiveSlashes % 2 === 1)) {
-            parsedString += ch;
-            lastCh = ch;
-            if (lastCh === '\\') {
-              numConsecutiveSlashes++;
-            } else {
-              numConsecutiveSlashes = 0;
-            }
-          } else {
-            break;
-          }
-        }
-        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
-        break;
-      case '[':
-        arrayElement = { element: [], index: stack.length };
-        stack.push(arrayElement.element);
-        metaStack.push(arrayElement);
-        break;
-      case '{':
-        objElement = { element: {}, index: stack.length };
-        stack.push(objElement.element);
-        metaStack.push(objElement);
-        break;
-      default:
-        throw new Error(
-          'unexpectedly reached end of input: ' + collationIndex);
-    }
-  }
-};
-
-},{}]},{},[17])
-(17)
-});
\ No newline at end of file
diff --git a/tests/integration/deps/pouchdb-3.2.0-postfixed.js b/tests/integration/deps/pouchdb-3.2.0-postfixed.js
deleted file mode 100644
index 6df27d6..0000000
--- a/tests/integration/deps/pouchdb-3.2.0-postfixed.js
+++ /dev/null
@@ -1,11 +0,0 @@
-//    PouchDBVersion320 3.2.0
-//    
-//    (c) 2012-2014 Dale Harvey and the PouchDBVersion320 team
-//    PouchDBVersion320 may be freely distributed under the Apache license, version 2.0.
-//    For all details and documentation:
-//    http://pouchdb.com
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.PouchDBVersion320=e()}}(function(){var define,module,exports;return function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t){"use strict";function n(e,t){for(var n=0;n<e.length;n++)if(t(e[n],n)===!0)return e[n];return!1}function r(e){return function(t,n){t||n[0]&&n[0].error?e(t||n[0]):e(null,n.length?n[0]:n)}}function o(e){var t={},n=[];return u.traverseRevTree(e,function(e,r,o,i){var s=r+"-"+o;return e&&(t[s]=0),void 0!==i&&n.push({from:i,to:s}),s}),n.reverse(),n.forEach(function(e){t[e.from]=void 0===t[e.from]?1+t[e.to]:Math.min(t[e.from],1+t[e.to])}),t}function i(e,t,n){var r="limit"in t?t.keys.slice(t.skip,t.limit+t.skip):t.skip>0?t.keys.slice(t.skip):t.keys;if(t.descending&&r.reverse(),!r.length)return e._allDocs({limit:0},n);var o={offset:t.skip};return h.all(r.map(function(n){var r=a.extend(!0,{key:n,deleted:"ok"},t);return["limit","skip","keys"].forEach(function(e){delete r[e]}),new h(function(t,i){e._allDocs(r,function(e,r){return e?i(e):(o.total_rows=r.total_rows,void t(r.rows[0]||{key:n,error:"not_found"}))})})})).then(function(e){return o.rows=e,o})}function s(){var e=this;f.call(this),e.autoCompact=function(t){return e.auto_compaction&&"http"!==e.type()?function(n,r){if(n)t(n);else{var o=r.length,i=function(){o--,o||t(null,r)};if(!r.length)return t(null,r);r.forEach(function(t){t.ok&&t.id?e.compactDocument(t.id,0,i):i()})}}:t};var t,n=0,r=["change","delete","create","update"];this.on("newListener",function(o){if(~r.indexOf(o)){if(n)return void n++;n++;var i=0;t=this.changes({conflicts:!0,include_docs:!0,continuous:!0,since:"now",onChange:function(t){t.seq<=i||(i=t.seq,e.emit("change",t),t.doc._deleted?e.emit("delete",t):"1"===t.doc._rev.split("-")[0]?e.emit("create",t):e.emit("update",t))}})}}),this.on("removeListener",function(e){~r.indexOf(e)&&(n--,n||t.cancel())})}var a=e("./utils"),u=e("./merge"),c=e("./deps/errors"),f=e("events").EventEmitter,l=e("./deps/upsert"),d=e("./changes"),h=a.Promise;a.inherits(s,f),t.exports=s,s.prototype.post=a.adapterFun("post",function(e,t,n){return"function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e)?n(c.NOT_AN_OBJECT):void this.bulkDocs({docs:[e]},t,this.autoCompact(r(n)))}),s.prototype.put=a.adapterFun("put",a.getArguments(function(e){var t,n,o,i,s=e.shift(),u="_id"in s;if("object"!=typeof s||Array.isArray(s))return(i=e.pop())(c.NOT_AN_OBJECT);for(s=a.clone(s);;)if(t=e.shift(),n=typeof t,"string"!==n||u?"string"!==n||!u||"_rev"in s?"object"===n?o=t:"function"===n&&(i=t):s._rev=t:(s._id=t,u=!0),!e.length)break;o=o||{};var f=a.invalidIdError(s._id);return f?i(f):a.isLocalId(s._id)&&"function"==typeof this._putLocal?s._deleted?this._removeLocal(s,i):this._putLocal(s,i):void this.bulkDocs({docs:[s]},o,this.autoCompact(r(i)))})),s.prototype.putAttachment=a.adapterFun("putAttachment",function(e,t,n,r,o,i){function s(e){return e._attachments=e._attachments||{},e._attachments[t]={content_type:o,data:r},a.put(e)}var a=this;return"function"==typeof o&&(i=o,o=r,r=n,n=null),"undefined"==typeof o&&(o=r,r=n,n=null),a.get(e).then(function(e){if(e._rev!==n)throw c.REV_CONFLICT;return s(e)},function(t){if(t.error===c.MISSING_DOC.error)return s({_id:e});throw t})}),s.prototype.removeAttachment=a.adapterFun("removeAttachment",function(e,t,n,r){var o=this;o.get(e,function(e,i){return e?void r(e):i._rev!==n?void r(c.REV_CONFLICT):i._attachments?(delete i._attachments[t],0===Object.keys(i._attachments).length&&delete i._attachments,void o.put(i,r)):r()})}),s.prototype.remove=a.adapterFun("remove",function(e,t,n,o){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof n&&(o=n,n={})):(i=e,"function"==typeof t?(o=t,n={}):(o=n,n=t)),n=a.clone(n||{}),n.was_delete=!0;var s={_id:i._id,_rev:i._rev||n.rev};return s._deleted=!0,a.isLocalId(s._id)&&"function"==typeof this._removeLocal?this._removeLocal(i,o):void this.bulkDocs({docs:[s]},n,r(o))}),s.prototype.revsDiff=a.adapterFun("revsDiff",function(e,t,n){function r(e,t){c.has(e)||c.set(e,{missing:[]}),c.get(e).missing.push(t)}function o(t,n){var o=e[t].slice(0);u.traverseRevTree(n,function(e,n,i,s,a){var u=n+"-"+i,c=o.indexOf(u);-1!==c&&(o.splice(c,1),"available"!==a.status&&r(t,u))}),o.forEach(function(e){r(t,e)})}"function"==typeof t&&(n=t,t={}),t=a.clone(t);var i=Object.keys(e);if(!i.length)return n(null,{});var s=0,c=new a.Map;i.map(function(t){this._getRevisionTree(t,function(r,a){if(r&&404===r.status&&"missing"===r.message)c.set(t,{missing:e[t]});else{if(r)return n(r);o(t,a)}if(++s===i.length){var u={};return c.forEach(function(e,t){u[t]=e}),n(null,u)}})},this)}),s.prototype.compactDocument=a.adapterFun("compactDocument",function(e,t,n){var r=this;this._getRevisionTree(e,function(i,s){if(i)return n(i);var a=o(s),c=[],f=[];Object.keys(a).forEach(function(e){a[e]>t&&c.push(e)}),u.traverseRevTree(s,function(e,t,n,r,o){var i=t+"-"+n;"available"===o.status&&-1!==c.indexOf(i)&&f.push(i)}),r._doCompaction(e,f,n)})}),s.prototype.compact=a.adapterFun("compact",function(e,t){"function"==typeof e&&(t=e,e={});var n=this;e=a.clone(e||{}),n.get("_local/compaction")["catch"](function(){return!1}).then(function(r){return"function"==typeof n._compact?(r&&r.last_seq&&(e.last_seq=r.last_seq),n._compact(e,t)):void 0})}),s.prototype._compact=function(e,t){function n(){l(c,"_local/compaction",function(e){return!e.last_seq||e.last_seq<i?(e.last_seq=i,e):!1},t)}function r(){a--,!a&&s&&n()}function o(e){a++,c.compactDocument(e.id,0).then(r,t)}var i,s=!1,a=0,u={returnDocs:!1},c=this;e.last_seq&&(u.since=e.last_seq),c.changes(u).on("change",o).on("complete",function(e){s=!0,i=e.last_seq,a||n()}).on("error",t)},s.prototype.get=a.adapterFun("get",function(e,t,r){function o(){var n=[],o=i.length;return o?void i.forEach(function(i){s.get(e,{rev:i,revs:t.revs,attachments:t.attachments},function(e,t){n.push(e?{missing:i}:{ok:t}),o--,o||r(null,n)})}):r(null,n)}if("function"==typeof t&&(r=t,t={}),"string"!=typeof e)return r(c.INVALID_ID);if(a.isLocalId(e)&&"function"==typeof this._getLocal)return this._getLocal(e,r);var i=[],s=this;if(!t.open_revs)return this._get(e,t,function(e,o){if(t=a.clone(t),e)return r(e);var i=o.doc;if(!i)return r(new Error("no doc!"));var c=o.metadata,f=o.ctx;if(t.conflicts){var l=u.collectConflicts(c);l.length&&(i._conflicts=l)}if(t.revs||t.revs_info){var d=u.rootToLeaf(c.rev_tree),h=n(d,function(e){return-1!==e.ids.map(function(e){return e.id}).indexOf(i._rev.split("-")[1])}),p=h.ids.map(function(e){return e.id}).indexOf(i._rev.split("-")[1])+1,v=h.ids.length-p;if(h.ids.splice(p,v),h.ids.reverse(),t.revs&&(i._revisions={start:h.pos+h.ids.length-1,ids:h.ids.map(function(e){return e.id})}),t.revs_info){var g=h.pos+h.ids.length;i._revs_info=h.ids.map(function(e){return g--,{rev:g+"-"+e.id,status:e.opts.status}})}}if(t.local_seq&&(i._local_seq=o.metadata.seq),t.attachments&&i._attachments){var y=i._attachments,m=Object.keys(y).length;if(0===m)return r(null,i);Object.keys(y).forEach(function(e){this._getAttachment(y[e],{encode:!0,ctx:f},function(t,n){var o=i._attachments[e];o.data=n,delete o.stub,delete o.length,--m||r(null,i)})},s)}else{if(i._attachments)for(var _ in i._attachments)i._attachments.hasOwnProperty(_)&&(i._attachments[_].stub=!0);r(null,i)}});if("all"===t.open_revs)this._getRevisionTree(e,function(e,t){e&&(t=[]),i=u.collectLeaves(t).map(function(e){return e.rev}),o()});else{if(!Array.isArray(t.open_revs))return r(c.error(c.UNKNOWN_ERROR,"function_clause"));i=t.open_revs;for(var f=0;f<i.length;f++){var l=i[f];if("string"!=typeof l||!/^\d+-/.test(l))return r(c.error(c.BAD_REQUEST,"Invalid rev format"))}o()}}),s.prototype.getAttachment=a.adapterFun("getAttachment",function(e,t,n,r){var o=this;n instanceof Function&&(r=n,n={}),n=a.clone(n),this._get(e,n,function(e,i){return e?r(e):i.doc._attachments&&i.doc._attachments[t]?(n.ctx=i.ctx,void o._getAttachment(i.doc._attachments[t],n,r)):r(c.MISSING_DOC)})}),s.prototype.allDocs=a.adapterFun("allDocs",function(e,t){if("function"==typeof e&&(t=e,e={}),e=a.clone(e),e.skip="undefined"!=typeof e.skip?e.skip:0,"keys"in e){if(!Array.isArray(e.keys))return t(new TypeError("options.keys must be an array"));var n=["startkey","endkey","key"].filter(function(t){return t in e})[0];if(n)return void t(c.error(c.QUERY_PARSE_ERROR,"Query parameter `"+n+"` is not compatible with multi-get"));if("http"!==this.type())return i(this,e,t)}return this._allDocs(e,t)}),s.prototype.changes=function(e,t){return"function"==typeof e&&(t=e,e={}),new d(this,e,t)},s.prototype.close=a.adapterFun("close",function(e){return this._closed=!0,this._close(e)}),s.prototype.info=a.adapterFun("info",function(e){var t=this;this._info(function(n,r){return n?e(n):(r.db_name=r.db_name||t._db_name,r.auto_compaction=!(!t._auto_compaction||"http"===t.type()),void e(null,r))})}),s.prototype.id=a.adapterFun("id",function(e){return this._id(e)}),s.prototype.type=function(){return"function"==typeof this._type?this._type():this.adapter},s.prototype.bulkDocs=a.adapterFun("bulkDocs",function(e,t,n){if("function"==typeof t&&(n=t,t={}),t=a.clone(t),Array.isArray(e)&&(e={docs:e}),!e||!e.docs||!Array.isArray(e.docs))return n(c.MISSING_BULK_DOCS);for(var r=0;r<e.docs.length;++r)if("object"!=typeof e.docs[r]||Array.isArray(e.docs[r]))return n(c.NOT_AN_OBJECT);return e=a.clone(e),"new_edits"in t||(t.new_edits="new_edits"in e?e.new_edits:!0),t.new_edits||"http"===this.type()||e.docs.sort(function(e,t){var n=a.compare(e._id,t._id);if(0!==n)return n;var r=e._revisions?e._revisions.start:0,o=t._revisions?t._revisions.start:0;return a.compare(r,o)}),e.docs.forEach(function(e){e._deleted&&delete e._attachments}),this._bulkDocs(e,t,this.autoCompact(function(e,r){return e?n(e):(t.new_edits||(r=r.filter(function(e){return e.error})),void n(null,r))}))}),s.prototype.registerDependentDatabase=a.adapterFun("registerDependentDatabase",function(e,t){function n(t){return t.dependentDbs=t.dependentDbs||{},t.dependentDbs[e]?!1:(t.dependentDbs[e]=!0,t)}var r={};this.__opts.db&&(r.db=this.__opts.db),this._adapter&&(r.adapter=this._adapter);var o=new this.constructor(e,r);l(this,"_local/_pouch_dependentDbs",n,function(e){return e?t(e):t(null,{db:o})})})},{"./changes":6,"./deps/errors":12,"./deps/upsert":16,"./merge":20,"./utils":25,events:33}],2:[function(e,t){(function(n,r){"use strict";function o(e){return/^_(design|local)/.test(e)?e:encodeURIComponent(e)}function i(e){return e._attachments&&Object.keys(e._attachments)?d.Promise.all(Object.keys(e._attachments).map(function(t){var n=e._attachments[t];if(n.data&&"string"!=typeof n.data){if(v)return new d.Promise(function(e){d.readAsBinaryString(n.data,function(t){n.data=d.btoa(t),e()})});n.data=n.data.toString("base64")}})):d.Promise.resolve()}function s(e,t){if(/http(s?):/.test(e)){var n=d.parseUri(e);n.remote=!0,(n.user||n.password)&&(n.auth={username:n.user,password:n.password});var r=n.path.replace(/(^\/|\/$)/g,"").split("/");if(n.db=r.pop(),n.path=r.join("/"),t=t||{},t=d.clone(t),n.headers=t.headers||{},t.auth||n.auth){var o=t.auth||n.auth,i=d.btoa(o.username+":"+o.password);n.headers.Authorization="Basic "+i}return t.headers&&(n.headers=t.headers),n}return{host:"",path:"/",db:e,auth:!1}}function a(e,t){return u(e,e.db+"/"+t)}function u(e,t){if(e.remote){var n=e.path?"/":"";return e.protocol+"://"+e.host+":"+e.port+"/"+e.path+n+t}return"/"+t}function c(e,t){function n(e,t){var n=d.extend({},_,e);return p(n.method+" "+n.url),d.ajax(n,t)}function c(e){return e.split("/").map(encodeURIComponent).join("/")}var g=this;g.getHost=e.getHost?e.getHost:s;var y=g.getHost(e.name,e),m=a(y,"");g.getUrl=function(){return m},g.getHeaders=function(){return d.clone(y.headers)};var _=e.ajax||{};e=d.clone(e);var b=function(){n({headers:y.headers,method:"PUT",url:m},function(e){e&&401===e.status?n({headers:y.headers,method:"HEAD",url:m},function(e){e?t(e):t(null,g)}):e&&412!==e.status?t(e):t(null,g)})};e.skipSetup||n({headers:y.headers,method:"GET",url:m},function(e){e?404===e.status?(d.explain404("PouchDBVersion320 is just detecting if the remote DB exists."),b()):t(e):t(null,g)}),g.type=function(){return"http"},g.id=d.adapterFun("id",function(e){n({headers:y.headers,method:"GET",url:u(y,"")},function(t,n){var r=n&&n.uuid?n.uuid+y.db:a(y,"");e(null,r)})}),g.request=d.adapterFun("request",function(e,t){e.headers=y.headers,e.url=a(y,e.url),n(e,t)}),g.compact=d.adapterFun("compact",function(e,t){"function"==typeof e&&(t=e,e={}),e=d.clone(e),n({headers:y.headers,url:a(y,"_compact"),method:"POST"},function(){function n(){g.info(function(r,o){o.compact_running?setTimeout(n,e.interval||200):t()})}"function"==typeof t&&n()})}),g._info=function(e){n({headers:y.headers,method:"GET",url:a(y,"")},function(t,n){t?e(t):(n.host=a(y,""),e(null,n))})},g.get=d.adapterFun("get",function(e,t,r){"function"==typeof t&&(r=t,t={}),t=d.clone(t),void 0===t.auto_encode&&(t.auto_encode=!0);var i=[];t.revs&&i.push("revs=true"),t.revs_info&&i.push("revs_info=true"),t.local_seq&&i.push("local_seq=true"),t.open_revs&&("all"!==t.open_revs&&(t.open_revs=JSON.stringify(t.open_revs)),i.push("open_revs="+t.open_revs)),t.attachments&&i.push("attachments=true"),t.rev&&i.push("rev="+t.rev),t.conflicts&&i.push("conflicts="+t.conflicts),i=i.join("&"),i=""===i?"":"?"+i,t.auto_encode&&(e=o(e));var s={headers:y.headers,method:"GET",url:a(y,e+i)},u=e.split("/");(u.length>1&&"_design"!==u[0]&&"_local"!==u[0]||u.length>2&&"_design"===u[0]&&"_local"!==u[0])&&(s.binary=!0),n(s,function(e,t,n){return e?r(e):void r(null,t,n)})}),g.remove=d.adapterFun("remove",function(e,t,r,i){var s;"string"==typeof t?(s={_id:e,_rev:t},"function"==typeof r&&(i=r,r={})):(s=e,"function"==typeof t?(i=t,r={}):(i=r,r=t));var u=s._rev||r.rev;n({headers:y.headers,method:"DELETE",url:a(y,o(s._id))+"?rev="+u},i)}),g.getAttachment=d.adapterFun("getAttachment",function(e,t,n,r){"function"==typeof n&&(r=n,n={}),n=d.clone(n),void 0===n.auto_encode&&(n.auto_encode=!0),n.auto_encode&&(e=o(e)),n.auto_encode=!1,g.get(e+"/"+c(t),n,r)}),g.removeAttachment=d.adapterFun("removeAttachment",function(e,t,r,i){var s=a(y,o(e)+"/"+c(t))+"?rev="+r;n({headers:y.headers,method:"DELETE",url:s},i)}),g.putAttachment=d.adapterFun("putAttachment",function(e,t,i,s,u,f){"function"==typeof u&&(f=u,u=s,s=i,i=null),"undefined"==typeof u&&(u=s,s=i,i=null);var l=o(e)+"/"+c(t),p=a(y,l);if(i&&(p+="?rev="+i),"string"==typeof s){var g;try{g=d.atob(s)}catch(m){return f(d.extend({},h.BAD_ARG,{reason:"Attachments need to be base64 encoded"}))}s=v?d.createBlob([d.fixBinary(g)],{type:u}):g?new r(g,"binary"):""}var _={headers:d.clone(y.headers),method:"PUT",url:p,processData:!1,body:s,timeout:6e4};_.headers["Content-Type"]=u,n(_,f)}),g.put=d.adapterFun("put",d.getArguments(function(e){var t,r,s,u=e.shift(),c="_id"in u,f=e.pop();return"object"!=typeof u||Array.isArray(u)?f(h.NOT_AN_OBJECT):(u=d.clone(u),void i(u).then(function(){for(;;)if(t=e.shift(),r=typeof t,"string"!==r||c?"string"!==r||!c||"_rev"in u?"object"===r&&(s=d.clone(t)):u._rev=t:(u._id=t,c=!0),!e.length)break;s=s||{};var i=d.invalidIdError(u._id);if(i)throw i;var l=[];s&&"undefined"!=typeof s.new_edits&&l.push("new_edits="+s.new_edits),l=l.join("&"),""!==l&&(l="?"+l),n({headers:y.headers,method:"PUT",url:a(y,o(u._id))+l,body:u},function(e,t){return e?f(e):(t.ok=!0,void f(null,t))})})["catch"](f))})),g.post=d.adapterFun("post",function(e,t,n){return"function"==typeof t&&(n=t,t={}),t=d.clone(t),"object"!=typeof e?n(h.NOT_AN_OBJECT):("_id"in e||(e._id=d.uuid()),void g.put(e,t,function(e,t){return e?n(e):(t.ok=!0,void n(null,t))}))}),g._bulkDocs=function(e,t,r){"undefined"!=typeof t.new_edits&&(e.new_edits=t.new_edits),d.Promise.all(e.docs.map(i)).then(function(){n({headers:y.headers,method:"POST",url:a(y,"_bulk_docs"),body:e},function(e,t){return e?r(e):(t.forEach(function(e){e.ok=!0}),void r(null,t))})})["catch"](r)},g.allDocs=d.adapterFun("allDocs",function(e,t){"function"==typeof e&&(t=e,e={}),e=d.clone(e);var r,o=[],i="GET";if(e.conflicts&&o.push("conflicts=true"),e.descending&&o.push("descending=true"),e.include_docs&&o.push("include_docs=true"),e.attachments&&o.push("attachments=true"),e.key&&o.push("key="+encodeURIComponent(JSON.stringify(e.key))),e.startkey&&o.push("startkey="+encodeURIComponent(JSON.stringify(e.startkey))),e.endkey&&o.push("endkey="+encodeURIComponent(JSON.stringify(e.endkey))),"undefined"!=typeof e.inclusive_end&&o.push("inclusive_end="+!!e.inclusive_end),"undefined"!=typeof e.limit&&o.push("limit="+e.limit),"undefined"!=typeof e.skip&&o.push("skip="+e.skip),o=o.join("&"),""!==o&&(o="?"+o),"undefined"!=typeof e.keys){var s="keys="+encodeURIComponent(JSON.stringify(e.keys));s.length+o.length+1<=l?o+=(-1!==o.indexOf("?")?"&":"?")+s:(i="POST",r=JSON.stringify({keys:e.keys}))}n({headers:y.headers,method:i,url:a(y,"_all_docs"+o),body:r},t)}),g._changes=function(e){var t="batch_size"in e?e.batch_size:f;e=d.clone(e),e.timeout=e.timeout||3e4;var r={timeout:e.timeout-5e3},o="undefined"!=typeof e.limit?e.limit:!1;0===o&&(o=1);var i;i="returnDocs"in e?e.returnDocs:!0;var s=o;if(e.style&&(r.style=e.style),(e.include_docs||e.filter&&"function"==typeof e.filter)&&(r.include_docs=!0),e.attachments&&(r.attachments=!0),e.continuous&&(r.feed="longpoll"),e.conflicts&&(r.conflicts=!0),e.descending&&(r.descending=!0),e.filter&&"string"==typeof e.filter&&(r.filter=e.filter,"_view"===e.filter&&e.view&&"string"==typeof e.view&&(r.view=e.view)),e.query_params&&"object"==typeof e.query_params)for(var u in e.query_params)e.query_params.hasOwnProperty(u)&&(r[u]=e.query_params[u]);var c,p="GET";if(e.doc_ids){r.filter="_doc_ids";var v=JSON.stringify(e.doc_ids);v.length<l?r.doc_ids=v:(p="POST",c={doc_ids:e.doc_ids})}if(e.continuous&&g._useSSE)return g.sse(e,r,i);var m,_,b=function(i,u){if(!e.aborted){r.since=i,e.descending?o&&(r.limit=s):r.limit=!o||s>t?t:s;var f="?"+Object.keys(r).map(function(e){return e+"="+r[e]}).join("&"),l={headers:y.headers,method:p,url:a(y,"_changes"+f),timeout:e.timeout,body:c};_=i,e.aborted||(m=n(l,u))}},w=10,E=0,S={results:[]},A=function(n,r){if(!e.aborted){var a=0;if(r&&r.results){a=r.results.length,S.last_seq=r.last_seq;var u={};u.query=e.query_params,r.results=r.results.filter(function(t){s--;var n=d.filterChange(e)(t);return n&&(i&&S.results.push(t),d.call(e.onChange,t)),n})}else if(n)return e.aborted=!0,void d.call(e.complete,n);r&&r.last_seq&&(_=r.last_seq);var c=o&&0>=s||r&&t>a||e.descending;if((!e.continuous||o&&0>=s)&&c)d.call(e.complete,null,S);else{n?E+=1:E=0;var f=1<<E,l=w*f,p=e.maximumWait||3e4;if(l>p)return void d.call(e.complete,n||h.UNKNOWN_ERROR);setTimeout(function(){b(_,A)},l)}}};return b(e.since||0,A),{cancel:function(){e.aborted=!0,m&&m.abort()}}},g.sse=function(e,t,n){function r(t){var r=JSON.parse(t.data);n&&c.results.push(r),c.last_seq=r.seq,d.call(e.onChange,r)}function o(t){return u.removeEventListener("message",r,!1),l===!1?(g._useSSE=!1,void(f=g._changes(e))):(u.close(),void d.call(e.complete,t))}t.feed="eventsource",t.since=e.since||0,t.limit=e.limit,delete t.timeout;var i="?"+Object.keys(t).map(function(e){return e+"="+t[e]}).join("&"),s=a(y,"_changes"+i),u=new EventSource(s),c={results:[],last_seq:!1},f=!1,l=!1;return u.addEventListener("message",r,!1),u.onopen=function(){l=!0},u.onerror=o,{cancel:function(){return f?f.cancel():(u.removeEventListener("message",r,!1),void u.close())}}},g._useSSE=!1,g.revsDiff=d.adapterFun("revsDiff",function(e,t,r){"function"==typeof t&&(r=t,t={}),n({headers:y.headers,method:"POST",url:a(y,"_revs_diff"),body:JSON.stringify(e)},r)}),g._close=function(e){e()},g.destroy=d.adapterFun("destroy",function(e){n({url:a(y,""),method:"DELETE",headers:y.headers},function(t,n){t?(g.emit("error",t),e(t)):(g.emit("destroyed"),e(null,n))})})}var f=25,l=1800,d=e("../utils"),h=e("../deps/errors"),p=e("debug")("pouchdb:http"),v="undefined"==typeof n||n.browser;c.destroy=d.toPromise(function(e,t,n){var r=s(e,t);t=t||{},"function"==typeof t&&(n=t,t={}),t=d.clone(t),t.headers=r.headers,t.method="DELETE",t.url=a(r,"");var o=t.ajax||{};t=d.extend({},t,o),d.ajax(t,n)}),c.valid=function(){return!0},t.exports=c}).call(this,e("_process"),e("buffer").Buffer)},{"../deps/errors":12,"../utils":25,_process:34,buffer:29,debug:35}],3:[function(e,t){(function(n,r){"use strict";function o(e,t,n){try{e.apply(t,n)}catch(r){window.PouchDBVersion320&&window.PouchDBVersion320.emit("error",r)}}function i(){if(!q.running&&q.queue.length){q.running=!0;var e=q.queue.shift();e.action(function(t,r){o(e.callback,this,[t,r]),q.running=!1,n.nextTick(i)})}}function s(e){return function(t){var n=t.target&&t.target.error&&t.target.error.name||t.target;e(m.error(m.IDB_ERROR,n,t.type))}}function a(e,t,n){var r={data:_.stringify(e)};return r.winningRev=t,r.deletedOrLocal=n?"1":"0",r.id=e.id,r}function u(e){if(!e)return null;if(!e.data)return e;var t=_.parse(e.data);return t.winningRev=e.winningRev,t.deletedOrLocal="1"===e.deletedOrLocal,t}function c(e,t,n,r){n?e?"string"!=typeof e?g.readAsBinaryString(e,function(e){r(g.btoa(e))}):r(e):r(""):e?"string"!=typeof e?r(e):(e=g.fixBinary(atob(e)),r(g.createBlob([e],{type:t}))):r(g.createBlob([""],{type:t}))}function f(e,t,n,r){function o(){++a===s.length&&r&&r()}function i(e,t){var r=e._attachments[t],i=r.digest;n.objectStore(S).get(i).onsuccess=function(e){r.body=e.target.result.body,o()}}var s=Object.keys(e._attachments||{});if(!s.length)return r&&r();var a=0;s.forEach(function(n){t.attachments&&t.include_docs?i(e,n):(e._attachments[n].stub=!0,o())})}function l(e){return g.Promise.all(e.map(function(e){if(e.doc&&e.doc._attachments){var t=Object.keys(e.doc._attachments);return g.Promise.all(t.map(function(t){var n=e.doc._attachments[t];if("body"in n){var r=n.body,o=n.content_type;return new g.Promise(function(i){c(r,o,!0,function(r){e.doc._attachments[t]=g.extend(g.pick(n,["digest","content_type"]),{data:r}),i()})})}}))}}))}function d(e,t){var n=this;q.queue.push({action:function(t){h(n,e,t)},callback:t}),i()}function h(e,t,o){function i(e){var t=e.createObjectStore(w,{keyPath:"id"});t.createIndex("seq","seq",{unique:!0}),e.createObjectStore(E,{autoIncrement:!0}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0}),e.createObjectStore(S,{keyPath:"digest"}),e.createObjectStore(k,{keyPath:"id",autoIncrement:!1}),e.createObjectStore(x),t.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),e.createObjectStore(T,{keyPath:"_id"});var n=e.createObjectStore(A,{autoIncrement:!0});n.createIndex("seq","seq"),n.createIndex("digestSeq","digestSeq",{unique:!0})}function h(e,t){var n=e.objectStore(w);n.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),n.openCursor().onsuccess=function(e){var r=e.target.result;if(r){var o=r.value,i=g.isDeleted(o);o.deletedOrLocal=i?"1":"0",n.put(o),r["continue"]()}else t()}}function p(e){e.createObjectStore(T,{keyPath:"_id"}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0})}function _(e,t){var n=e.objectStore(T),o=e.objectStore(w),i=e.objectStore(E),s=o.openCursor();s.onsuccess=function(e){var s=e.target.result;if(s){var a=s.value,u=a.id,c=g.isLocalId(u),f=y.winningRev(a);if(c){var l=u+"::"+f,d=u+"::",h=u+"::~",p=i.index("_doc_id_rev"),v=r.IDBKeyRange.bound(d,h,!1,!1),m=p.openCursor(v);m.onsuccess=function(e){if(m=e.target.result){var t=m.value;t._doc_id_rev===l&&n.put(t),i["delete"](m.primaryKey),m["continue"]()}else o["delete"](s.primaryKey),s["continue"]()}}else s["continue"]()}else t&&t()}}function q(e){var t=e.createObjectStore(A,{autoIncrement:!0});t.createIndex("seq","seq"),t.createIndex("digestSeq","digestSeq",{unique:!0})}function R(e){var t=e.objectStore(E),n=e.objectStore(S),r=e.objectStore(A),o=n.count();o.onsuccess=function(e){var n=e.target.result;n&&(t.openCursor().onsuccess=function(e){var t=e.target.result;if(t){for(var n=t.value,o=t.primaryKey,i=Object.keys(n._attachments||{}),s={},a=0;a<i.length;a++){var u=n._attachments[i[a]];s[u.digest]=!0}var c=Object.keys(s);for(a=0;a<c.length;a++){var f=c[a];r.put({seq:o,digestSeq:f+"::"+o})}t["continue"]()}})}}function O(e,t,n){function o(){n(null,{total_rows:e,offset:t.skip,rows:I})}var i="startkey"in t?t.startkey:!1,s="endkey"in t?t.endkey:!1,a="key"in t?t.key:!1,c=t.skip||0,d="number"==typeof t.limit?t.limit:-1,h=t.inclusive_end!==!1,p="descending"in t&&t.descending?"prev":null,v=!1;p&&i&&s&&(v=s,s=!1);var _=null;try{i&&s?_=r.IDBKeyRange.bound(i,s,!1,!h):i?_=p?r.IDBKeyRange.upperBound(i):r.IDBKeyRange.lowerBound(i):s?_=p?r.IDBKeyRange.lowerBound(s,!h):r.IDBKeyRange.upperBound(s,!h):a&&(_=r.IDBKeyRange.only(a))}catch(b){return"DataError"===b.name&&0===b.code?n(null,{total_rows:e,offset:t.skip,rows:[]}):n(m.error(m.IDB_ERROR,b.name,b.message))}var A=[w,E];t.attachments&&A.push(S);var k=B.transaction(A,"readonly");k.oncomplete=function(){t.attachments?l(I).then(o):o()};var T=k.objectStore(w),x=p?T.openCursor(_,p):T.openCursor(_),I=[];x.onsuccess=function(e){function n(e,n){var o={id:e.id,key:e.id,value:{rev:i}};t.include_docs&&(o.doc=n,o.doc._rev=i,o.doc._doc_id_rev&&delete o.doc._doc_id_rev,t.conflicts&&(o.doc._conflicts=y.collectConflicts(e)),f(o.doc,t,k));var s=g.isDeleted(e,i);if("ok"===t.deleted)s&&(o.value.deleted=!0,o.doc=null),I.push(o);else if(!s&&c--<=0){if(v){if(h&&o.key<v)return;if(!h&&o.key<=v)return}if(I.push(o),0===--d)return}r["continue"]()}if(e.target.result){var r=e.target.result,o=u(r.value),i=o.winningRev||y.winningRev(o);if(t.include_docs){var s=k.objectStore(E).index("_doc_id_rev"),a=o.id+"::"+i;s.get(a).onsuccess=function(e){n(u(r.value),e.target.result)}}else n(o)}}}function D(e){if(-1!==P)return e(null,P);var t,n=B.transaction([w],"readonly"),o=n.objectStore(w).index("deletedOrLocal");o.count(r.IDBKeyRange.only("0")).onsuccess=function(e){t=e.target.result},n.onerror=s(e),n.oncomplete=function(){P=t,e(null,P)}}var C=t.name,N=null,j=!1,B=null,P=-1;e.type=function(){return"idb"},e._id=g.toPromise(function(e){e(null,N)}),e._bulkDocs=function(t,n,r){function o(){g.processDocs(_,e,q,x,I,h,n)}function i(e){function t(){++n===_.length&&e()}if(!_.length)return e();var n=0;_.forEach(function(e){if(e._id&&g.isLocalId(e._id))return t();var n=e.metadata.id,r=x.objectStore(w).get(n);r.onsuccess=function(e){var r=u(e.target.result);r&&q.set(n,r),t()}})}function c(){if(!R){var e=I.map(function(e){if(!Object.keys(e).length)return{ok:!0};if(e.error)return e;var t=e.metadata,n=y.winningRev(t);return{ok:!0,id:t.id,rev:n}});d.Changes.notify(C),P=-1,r(null,e)}}function f(e,t){var n=x.objectStore([S]).get(e);n.onsuccess=function(n){if(n.target.result)t();else{var r=new Error("unknown stub attachment with digest "+e);r.status=412,t(r)}}}function l(e){function t(){++o===n.length&&e(r)}var n=[];if(_.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){f(e,function(e){e&&!r&&(r=e),t()})})}function h(e,t,n,r,o,i){function s(e){l||(e?(l=e,r(l)):d===m.length&&f())}function u(e){d++,s(e)}function c(t,n){function r(){++i===s.length&&n()}function o(n){var o=e.data._attachments[n].digest,i=x.objectStore(A).put({seq:t,digestSeq:o+"::"+t});i.onsuccess=r,i.onerror=function(e){e.preventDefault(),e.stopPropagation(),r()}}var i=0,s=Object.keys(e.data._attachments||{});if(!s.length)return n();for(var a=0;a<s.length;a++)o(s[a])}function f(){function o(o){var s=e.metadata,u=o.target.result;s.seq=u,delete s.rev;var f=a(s,t,n),l=x.objectStore(w).put(f);l.onsuccess=function(){delete s.deletedOrLocal,delete s.winningRev,I[i]=e,q.set(e.metadata.id,e.metadata),c(u,function(){g.call(r)})}}e.data._doc_id_rev=y;var s=x.objectStore(E),u=s.index("_doc_id_rev"),f=s.put(e.data);f.onsuccess=o,f.onerror=function(t){t.preventDefault(),t.stopPropagation();var n=u.getKey(e.data._doc_id_rev);n.onsuccess=function(t){var n=s.put(e.data,t.target.result);n.onsuccess=o}}}var l=null,d=0,h=e.data._id=e.metadata.id,v=e.data._rev=e.metadata.rev,y=h+"::"+v;n&&(e.data._deleted=!0);var m=e.data._attachments?Object.keys(e.data._attachments):[];for(var _ in e.data._attachments)if(e.data._attachments[_].stub)d++,s();else{var b=e.data._attachments[_].data;delete e.data._attachments[_].data;var S=e.data._attachments[_].digest;p(S,b,u)}m.length||f()}function p(e,t,n){var r=x.objectStore(S);r.get(e).onsuccess=function(o){var i=o.target.result;if(i)return g.call(n);var s={digest:e,body:t};r.put(s).onsuccess=function(){g.call(n)}}}var v=n.new_edits,m=t.docs,_=m.map(function(e){if(e._id&&g.isLocalId(e._id))return e;var t=g.parseDoc(e,v);return t}),b=_.filter(function(e){return e.error});if(b.length)return r(b[0]);var x,I=new Array(_.length),q=new g.Map,R=!1,O=L?"blob":"base64";g.preprocessAttachments(_,O,function(e){if(e)return r(e);var t=[w,E,S,k,T,A];x=B.transaction(t,"readwrite"),x.onerror=s(r),x.ontimeout=s(r),x.oncomplete=c,l(function(e){return e?(R=!0,r(e)):void i(o)})})},e._get=function(e,t,n){function r(){n(s,{doc:o,metadata:i,ctx:a})}var o,i,s,a;t=g.clone(t),a=t.ctx?t.ctx:B.transaction([w,E,S],"readonly"),a.objectStore(w).get(e).onsuccess=function(e){if(i=u(e.target.result),!i)return s=m.MISSING_DOC,r();if(g.isDeleted(i)&&!t.rev)return s=m.error(m.MISSING_DOC,"deleted"),r();var n=a.objectStore(E),c=t.rev||i.winningRev||y.winningRev(i),f=i.id+"::"+c;n.index("_doc_id_rev").get(f).onsuccess=function(e){return o=e.target.result,o&&o._doc_id_rev&&delete o._doc_id_rev,o?void r():(s=m.MISSING_DOC,r())}}},e._getAttachment=function(e,t,n){var r;t=g.clone(t),r=t.ctx?t.ctx:B.transaction([w,E,S],"readonly");var o=e.digest,i=e.content_type;r.objectStore(S).get(o).onsuccess=function(e){var r=e.target.result.body;c(r,i,t.encode,function(e){n(null,e)})}},e._allDocs=function(e,t){D(function(n,r){return n?t(n):0===e.limit?t(null,{total_rows:r,offset:e.skip,rows:[]}):void O(r,e,t)})},e._info=function(e){D(function(t,n){if(t)return e(t);if(null===B){var r=new Error("db isn't open");return r.id="idbNull",e(r)}var o=0,i=B.transaction([E],"readonly");i.objectStore(E).openCursor(null,"prev").onsuccess=function(e){var t=e.target.result;o=t?t.key:0},i.oncomplete=function(){e(null,{doc_count:n,update_seq:o})}})},e._changes=function(t){function n(){var e=[w,E];t.attachments&&e.push(S),_=B.transaction(e,"readonly"),_.onerror=s(t.complete),_.oncomplete=i;var n;n=h?_.objectStore(E).openCursor(r.IDBKeyRange.lowerBound(t.since,!0),h):_.objectStore(E).openCursor(r.IDBKeyRange.lowerBound(t.since,!0)),n.onsuccess=o,n.onerror=onerror}function o(e){var n=e.target.result;if(n){var r=n.value;if(c&&!c.has(r._id))return n["continue"]();var o=_.objectStore(w);o.get(r._id).onsuccess=function(e){var o=u(e.target.result);p<o.seq&&(p=o.seq);var i=o.winningRev||y.winningRev(o);if(r._rev!==i)return n["continue"]();delete r._doc_id_rev;var s=t.processChange(r,o,t);s.seq=n.key,k(s)&&(A++,m&&b.push(s),t.attachments&&t.include_docs?f(r,t,_,function(){l([s]).then(function(){t.onChange(s)})}):t.onChange(s)),A!==v&&n["continue"]()}}}function i(){function e(){t.complete(null,{results:b,last_seq:p})}t.continuous||(t.attachments?l(b).then(e):e())}if(t=g.clone(t),t.continuous){var a=C+":"+g.uuid();return d.Changes.addListener(C,a,e,t),d.Changes.notify(C),{cancel:function(){d.Changes.removeListener(C,a)}}}var c=t.doc_ids&&new g.Set(t.doc_ids),h=t.descending?"prev":null,p=0;t.since=t.since&&!h?t.since:0;var v="limit"in t?t.limit:-1;0===v&&(v=1);var m;m="returnDocs"in t?t.returnDocs:!0;var _,b=[],A=0,k=g.filterChange(t);n()},e._close=function(e){return null===B?e(m.NOT_OPEN):(B.close(),delete I[C],B=null,void e())
-},e._getRevisionTree=function(e,t){var n=B.transaction([w],"readonly"),r=n.objectStore(w).get(e);r.onsuccess=function(e){var n=u(e.target.result);n?t(null,n.rev_tree):t(m.MISSING_DOC)}},e._doCompaction=function(e,t,n){function o(){h.length&&h.forEach(function(e){var t=d.index("digestSeq").count(r.IDBKeyRange.bound(e+"::",e+"::ï¿¿",!1,!1));t.onsuccess=function(t){var n=t.target.result;n||l["delete"](e)}})}var i=B.transaction([w,E,S,A],"readwrite"),c=i.objectStore(w),f=i.objectStore(E),l=i.objectStore(S),d=i.objectStore(A),h=[];c.get(e).onsuccess=function(n){var s=u(n.target.result);y.traverseRevTree(s.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;-1!==t.indexOf(s)&&(i.status="missing")});var c=t.length;t.forEach(function(t){var n=f.index("_doc_id_rev"),u=e+"::"+t;n.getKey(u).onsuccess=function(e){var t=e.target.result;if("number"==typeof t){f["delete"](t);var n=d.index("seq").openCursor(r.IDBKeyRange.only(t));n.onsuccess=function(e){var t=e.target.result;if(t){var n=t.value.digestSeq.split("::")[0];h.push(n),d["delete"](t.primaryKey),t["continue"]()}else if(c--,!c){var r=s.winningRev||y.winningRev(s),u=s.deletedOrLocal;i.objectStore(w).put(a(s,r,u)),o()}}}}})},i.onerror=s(n),i.oncomplete=function(){g.call(n)}},e._getLocal=function(e,t){var n=B.transaction([T],"readonly"),r=n.objectStore(T).get(e);r.onerror=s(t),r.onsuccess=function(e){var n=e.target.result;n?(delete n._doc_id_rev,t(null,n)):t(m.MISSING_DOC)}},e._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),delete e._revisions;var r=e._rev,o=e._id;e._rev=r?"0-"+(parseInt(r.split("-")[1],10)+1):"0-1";var i,a=t.ctx;a||(a=B.transaction([T],"readwrite"),a.onerror=s(n),a.oncomplete=function(){i&&n(null,i)});var u,c=a.objectStore(T);r?(u=c.get(o),u.onsuccess=function(o){var s=o.target.result;if(s&&s._rev===r){var a=c.put(e);a.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)}}else n(m.REV_CONFLICT)}):(u=c.add(e),u.onerror=function(e){n(m.REV_CONFLICT),e.preventDefault(),e.stopPropagation()},u.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)})},e._removeLocal=function(e,t){var n,r=B.transaction([T],"readwrite");r.oncomplete=function(){n&&t(null,n)};var o=e._id,i=r.objectStore(T),a=i.get(o);a.onerror=s(t),a.onsuccess=function(r){var s=r.target.result;s&&s._rev===e._rev?(i["delete"](o),n={ok:!0,id:o,rev:"0-0"}):t(m.MISSING_DOC)}};var U=I[C];if(U)return B=U.idb,N=U.instanceId,j=U.idStored,void n.nextTick(function(){o(null,e)});var F=r.indexedDB.open(C,b);"openReqList"in d||(d.openReqList={}),d.openReqList[C]=F,F.onupgradeneeded=function(e){var t=e.target.result;if(e.oldVersion<1)return void i(t);var n=e.currentTarget.transaction;e.oldVersion<4&&(q(t),e.oldVersion<3?(p(t),e.oldVersion<2?h(n,function(){_(n,function(){R(n)})}):_(n,function(){R(n)})):R(n))},F.onsuccess=function(t){B=t.target.result,B.onversionchange=function(){B.close(),delete I[C]},B.onabort=function(){B.close(),delete I[C]};var n=B.transaction([k,x],"readwrite"),r=n.objectStore(k).get(k);r.onsuccess=function(t){var r=function(){null!==L&&j&&(I[C]={idb:B,instanceId:N,idStored:j,loaded:!0},o(null,e))},i=t.target.result||{id:k};C+"_id"in i?(N=i[C+"_id"],j=!0,r()):(N=g.uuid(),i[C+"_id"]=N,n.objectStore(k).put(i).onsuccess=function(){j=!0,r()}),v||(v=new g.Promise(function(e){var t=g.createBlob([""],{type:"image/png"});n.objectStore(x).put(t,"key"),n.oncomplete=function(){n=B.transaction([k,x],"readwrite");var t=n.objectStore(x).get("key");t.onsuccess=function(t){var n=t.target.result,r=URL.createObjectURL(n);g.ajax({url:r,cache:!0,binary:!0},function(t,n){t&&405===t.status?e(!0):(e(!(!n||"image/png"!==n.type)),t&&404===t.status&&g.explain404("PouchDBVersion320 is just detecting blob URL support.")),URL.revokeObjectURL(r)})}}})["catch"](function(){L=!1,r()})),v.then(function(e){L=e,r()})}},F.onerror=s(o)}function p(e,t,n){"openReqList"in d||(d.openReqList={}),d.Changes.removeAllListeners(e),d.openReqList[e]&&d.openReqList[e].result&&d.openReqList[e].result.close();var o=r.indexedDB.deleteDatabase(e);o.onsuccess=function(){d.openReqList[e]&&(d.openReqList[e]=null),g.hasLocalStorage()&&e in r.localStorage&&delete r.localStorage[e],delete I[e],n(null,{ok:!0})},o.onerror=s(n)}var v,g=e("../utils"),y=e("../merge"),m=e("../deps/errors"),_=e("vuvuzela"),b=4,w="document-store",E="by-sequence",S="attach-store",A="attach-seq-store",k="meta-store",T="local-store",x="detect-blob-support",I={},q={running:!1,queue:[]},L=null;d.valid=function(){var e="undefined"!=typeof openDatabase&&/Safari/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent);return!e&&r.indexedDB&&r.IDBKeyRange},d.destroy=g.toPromise(function(e,t,n){q.queue.push({action:function(n){p(e,t,n)},callback:n}),i()}),d.Changes=new g.Changes,t.exports=d}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../deps/errors":12,"../merge":20,"../utils":25,_process:34,vuvuzela:67}],4:[function(e,t){t.exports=["idb","websql"]},{}],5:[function(e,t){(function(n){"use strict";function r(e){return"'"+e+"'"}function o(e){return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"")}function i(e){return e.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,"")}function s(e,t,n,r,o){function i(){++u===a.length&&o&&o()}function s(e,t){var o=e._attachments[t],s={encode:!0,ctx:r};n._getAttachment(o,s,function(n,r){e._attachments[t]=h.extend(h.pick(o,["digest","content_type"]),{data:r}),i()})}var a=Object.keys(e._attachments||{});if(!a.length)return o&&o();var u=0;a.forEach(function(n){t.attachments&&t.include_docs?s(e,n):(e._attachments[n].stub=!0,i())})}function a(e,t,n,r,o){return"SELECT "+e+" FROM "+("string"==typeof t?t:t.join(" JOIN "))+(n?" ON "+n:"")+(r?" WHERE "+("string"==typeof r?r:r.join(" AND ")):"")+(o?" ORDER BY "+o:"")}function u(e){return function(t){var n=t&&t.constructor.toString().match(/function ([^\(]+)/),r=n&&n[1]||t.type,o=t.target||t.message;e(v.error(v.WSQ_ERROR,o,r))}}function c(e){return delete e._id,delete e._rev,JSON.stringify(e)}function f(e,t,n){return e=JSON.parse(e),e._id=t,e._rev=n,e}function l(e){if("size"in e)return 1e6*e.size;var t=/Android/.test(window.navigator.userAgent);return t?5e6:1}function d(e,t){function r(){h.hasLocalStorage()&&(n.localStorage["_pouch__websqldb_"+K]=!0),t(null,H)}function m(e,t){e.executeSql(L),e.executeSql("ALTER TABLE "+S+" ADD COLUMN deleted TINYINT(1) DEFAULT 0",[],function(){e.executeSql(I),e.executeSql("ALTER TABLE "+E+" ADD COLUMN local TINYINT(1) DEFAULT 0",[],function(){e.executeSql("CREATE INDEX IF NOT EXISTS 'doc-store-local-idx' ON "+E+" (local, id)");var n="SELECT "+E+".winningseq AS seq, "+E+".json AS metadata FROM "+S+" JOIN "+E+" ON "+S+".seq = "+E+".winningseq";e.executeSql(n,[],function(e,n){for(var r=[],o=[],i=0;i<n.rows.length;i++){var s=n.rows.item(i),a=s.seq,u=JSON.parse(s.metadata);h.isDeleted(u)&&r.push(a),h.isLocalId(u.id)&&o.push(u.id)}e.executeSql("UPDATE "+E+"SET local = 1 WHERE id IN ("+o.map(function(){return"?"}).join(",")+")",o,function(){e.executeSql("UPDATE "+S+" SET deleted = 1 WHERE seq IN ("+r.map(function(){return"?"}).join(",")+")",r,t)})})})})}function N(e,t){var n="CREATE TABLE IF NOT EXISTS "+k+" (id UNIQUE, rev, json)";e.executeSql(n,[],function(){var n="SELECT "+E+".id AS id, "+S+".json AS data FROM "+S+" JOIN "+E+" ON "+S+".seq = "+E+".winningseq WHERE local = 1";e.executeSql(n,[],function(e,n){function r(){if(!o.length)return t(e);var n=o.shift(),i=JSON.parse(n.data)._rev;e.executeSql("INSERT INTO "+k+" (id, rev, json) VALUES (?,?,?)",[n.id,i,n.data],function(e){e.executeSql("DELETE FROM "+E+" WHERE id=?",[n.id],function(e){e.executeSql("DELETE FROM "+S+" WHERE seq=?",[n.seq],function(){r()})})})}for(var o=[],i=0;i<n.rows.length;i++)o.push(n.rows.item(i));r()})})}function j(e,t){function n(n){function r(){if(!n.length)return t(e);var o=n.shift(),i=y(o.hex,V),s=i.lastIndexOf("::"),a=i.substring(0,s),u=i.substring(s+2),c="UPDATE "+S+" SET doc_id=?, rev=? WHERE doc_id_rev=?";e.executeSql(c,[a,u,i],function(){r()})}r()}var r="ALTER TABLE "+S+" ADD COLUMN doc_id";e.executeSql(r,[],function(e){var t="ALTER TABLE "+S+" ADD COLUMN rev";e.executeSql(t,[],function(e){e.executeSql(q,[],function(e){var t="SELECT hex(doc_id_rev) as hex FROM "+S;e.executeSql(t,[],function(e,t){for(var r=[],o=0;o<t.rows.length;o++)r.push(t.rows.item(o));n(r)})})})})}function B(e,t){function n(e){var n="SELECT COUNT(*) AS cnt FROM "+A;e.executeSql(n,[],function(e,n){function r(){var n=a(C+", "+E+".id AS id",[E,S],D,null,E+".id ");n+=" LIMIT "+s+" OFFSET "+i,i+=s,e.executeSql(n,[],function(e,n){function o(e,t){var n=i[e]=i[e]||[];-1===n.indexOf(t)&&n.push(t)}if(!n.rows.length)return t(e);for(var i={},s=0;s<n.rows.length;s++)for(var a=n.rows.item(s),u=f(a.data,a.id,a.rev),c=Object.keys(u._attachments||{}),l=0;l<c.length;l++){var d=u._attachments[c[l]];o(d.digest,a.seq)}var h=[];if(Object.keys(i).forEach(function(e){var t=i[e];t.forEach(function(t){h.push([e,t])})}),!h.length)return r();var p=0;h.forEach(function(t){var n="INSERT INTO "+x+" (digest, seq) VALUES (?,?)";e.executeSql(n,t,function(){++p===h.length&&r()})})})}var o=n.rows.item(0).cnt;if(!o)return t(e);var i=0,s=10;r()})}var r="CREATE TABLE IF NOT EXISTS "+x+" (digest, seq INTEGER)";e.executeSql(r,[],function(e){e.executeSql(O,[],function(e){e.executeSql(R,[],n)})})}function P(e,t){var n="ALTER TABLE "+A+" ADD COLUMN escaped TINYINT(1) DEFAULT 0";e.executeSql(n,[],t)}function U(e,t){e.executeSql('SELECT HEX("a") AS hex',[],function(e,n){var r=n.rows.item(0).hex;V=2===r.length?"UTF-8":"UTF-16",t()})}function F(){for(;X.length>0;){var e=X.pop();e(null,W)}}function M(e,t){if(0===t){var n="CREATE TABLE IF NOT EXISTS "+T+" (dbid, db_version INTEGER)",r="CREATE TABLE IF NOT EXISTS "+A+" (digest UNIQUE, escaped TINYINT(1), body BLOB)",o="CREATE TABLE IF NOT EXISTS "+x+" (digest, seq INTEGER)",i="CREATE TABLE IF NOT EXISTS "+E+" (id unique, json, winningseq)",s="CREATE TABLE IF NOT EXISTS "+S+" (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, json, deleted TINYINT(1), doc_id, rev)",a="CREATE TABLE IF NOT EXISTS "+k+" (id UNIQUE, rev, json)";e.executeSql(r),e.executeSql(a),e.executeSql(o,[],function(){e.executeSql(R),e.executeSql(O)}),e.executeSql(i,[],function(){e.executeSql(L),e.executeSql(s,[],function(){e.executeSql(I),e.executeSql(q),e.executeSql(n,[],function(){var t="INSERT INTO "+T+" (db_version, dbid) VALUES (?,?)";W=h.uuid();var n=[w,W];e.executeSql(t,n,function(){F()})})})})}else{var u=function(){var n=w>t;n&&e.executeSql("UPDATE "+T+" SET db_version = "+w);var r="SELECT dbid FROM "+T;e.executeSql(r,[],function(e,t){W=t.rows.item(0).dbid,F()})},c=[m,N,j,B,P,u],f=t,l=function(e){c[f-1](e,l),f++};l(e)}}function G(){Q.transaction(function(e){U(e,function(){J(e)})},u(t),r)}function J(e){var t="SELECT sql FROM sqlite_master WHERE tbl_name = "+T;e.executeSql(t,[],function(e,t){t.rows.length?/db_version/.test(t.rows.item(0).sql)?e.executeSql("SELECT db_version FROM "+T,[],function(e,t){var n=t.rows.item(0).db_version;M(e,n)}):e.executeSql("ALTER TABLE "+T+" ADD COLUMN db_version INTEGER",[],function(){M(e,1)}):M(e,0)})}function Y(e,t){if(-1!==$)return t($);var n=a("COUNT("+E+".id) AS 'num'",[E,S],D,S+".deleted=0");e.executeSql(n,[],function(e,n){$=n.rows.item(0).num,t($)})}var V,H=this,W=null,K=e.name,z=l(e),X=[],$=-1,Q=_(K,b,K,z);return Q?("function"!=typeof Q.readTransaction&&(Q.readTransaction=Q.transaction),h.isCordova()&&"undefined"!=typeof n?n.addEventListener(K+"_pouch",function Z(){n.removeEventListener(K+"_pouch",Z,!1),G()},!1):G(),H.type=function(){return"websql"},H._id=h.toPromise(function(e){e(null,W)}),H._info=function(e){Q.readTransaction(function(t){Y(t,function(n){var r="SELECT MAX(seq) AS seq FROM "+S;t.executeSql(r,[],function(t,r){var o=r.rows.item(0).seq||0;e(null,{doc_count:n,update_seq:o})})})},u(e))},H._bulkDocs=function(e,t,n){function r(){if(T)return n(T);var e=I.map(function(e){if(!Object.keys(e).length)return{ok:!0};if(e.error)return e;var t=e.metadata,n=p.winningRev(t);return{ok:!0,id:t.id,rev:n}});d.Changes.notify(K),$=-1,n(null,e)}function i(e,t){var n="SELECT count(*) as cnt FROM "+A+" WHERE digest=?";k.executeSql(n,[e],function(n,r){if(0===r.rows.item(0).cnt){var o=new Error("unknown stub attachment with digest "+e);o.status=412,t(o)}else t()})}function s(e){function t(){++o===n.length&&e(r)}var n=[];if(b.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){i(e,function(e){e&&!r&&(r=e),t()})})}function f(e,t,n,r,o,i){function s(){function t(e,t){function n(){return++i===s.length&&t(),!1}function o(t){var o="INSERT INTO "+x+" (digest, seq) VALUES (?,?)",i=[r._attachments[t].digest,e];k.executeSql(o,i,n,n)}var i=0,s=Object.keys(r._attachments||{});if(!s.length)return t();for(var a=0;a<s.length;a++)o(s[a])}var r=e.data,o=n?1:0,i=r._id,s=r._rev,u=c(r),f="INSERT INTO "+S+" (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);",d=[i,s,u,o];k.executeSql(f,d,function(e,n){var r=n.insertId;t(r,function(){l(e,r)})},function(){var e=a("seq",S,null,"doc_id=? AND rev=?");return k.executeSql(e,[i,s],function(e,n){var r=n.rows.item(0).seq,a="UPDATE "+S+" SET json=?, deleted=? WHERE doc_id=? AND rev=?;",c=[u,o,i,s];e.executeSql(a,c,function(e){t(r,function(){l(e,r)})})}),!1})}function u(e){d||(e?(d=e,r(d)):h===p.length&&s())}function f(e){h++,u(e)}function l(n,s){e.metadata.seq=s,delete e.metadata.rev;var a=o?"UPDATE "+E+" SET json=?, winningseq=(SELECT seq FROM "+S+" WHERE doc_id="+E+".id AND rev=?) WHERE id=?":"INSERT INTO "+E+" (id, winningseq, json) VALUES (?, ?, ?);",u=g.stringify(e.metadata),c=e.metadata.id,f=o?[u,t,c]:[c,s,u];n.executeSql(a,f,function(){I[i]=e,q.set(c,e.metadata),r()})}var d=null,h=0;e.data._id=e.metadata.id,e.data._rev=e.metadata.rev,n&&(e.data._deleted=!0);var p=e.data._attachments?Object.keys(e.data._attachments):[];for(var v in e.data._attachments)if(e.data._attachments[v].stub)h++,u();else{var m=e.data._attachments[v].data;delete e.data._attachments[v].data;var _=e.data._attachments[v].digest;y(_,m,f)}p.length||s()}function l(){h.processDocs(b,H,q,k,I,f,t)}function v(e){function t(){++n===b.length&&e()}if(!b.length)return e();var n=0;b.forEach(function(e){if(e._id&&h.isLocalId(e._id))return t();var n=e.metadata.id;k.executeSql("SELECT json FROM "+E+" WHERE id = ?",[n],function(e,r){if(r.rows.length){var o=g.parse(r.rows.item(0).json);q.set(n,o)}t()})})}function y(e,t,n){var r="SELECT digest FROM "+A+" WHERE digest=?";k.executeSql(r,[e],function(i,s){return s.rows.length?n():(r="INSERT INTO "+A+" (digest, body, escaped) VALUES (?,?,1)",void i.executeSql(r,[e,o(t)],function(){n()},function(){return n(),!1}))})}var m=t.new_edits,_=e.docs,b=_.map(function(e){if(e._id&&h.isLocalId(e._id))return e;var t=h.parseDoc(e,m);return t}),w=b.filter(function(e){return e.error});if(w.length)return n(w[0]);var k,T,I=new Array(b.length),q=new h.Map;h.preprocessAttachments(b,"binary",function(e){return e?n(e):void Q.transaction(function(e){k=e,s(function(e){e?T=e:v(l)})},u(n),r)})},H._get=function(e,t,n){function r(){n(s,{doc:o,metadata:i,ctx:l})}t=h.clone(t);var o,i,s;if(!t.ctx)return void Q.readTransaction(function(r){t.ctx=r,H._get(e,t,n)});var u,c,l=t.ctx;t.rev?(u=a(C,[E,S],E+".id="+S+".doc_id",[S+".doc_id=?",S+".rev=?"]),c=[e,t.rev]):(u=a(C,[E,S],D,E+".id=?"),c=[e]),l.executeSql(u,c,function(e,n){if(!n.rows.length)return s=v.MISSING_DOC,r();var a=n.rows.item(0);return i=g.parse(a.metadata),a.deleted&&!t.rev?(s=v.error(v.MISSING_DOC,"deleted"),r()):(o=f(a.data,i.id,a.rev),void r())})},H._allDocs=function(e,t){var n,r=[],o="startkey"in e?e.startkey:!1,i="endkey"in e?e.endkey:!1,c="key"in e?e.key:!1,l="descending"in e?e.descending:!1,d="limit"in e?e.limit:-1,h="skip"in e?e.skip:0,v=e.inclusive_end!==!1,y=[],m=[];if(c!==!1)m.push(E+".id = ?"),y.push(c);else if(o!==!1||i!==!1){if(o!==!1&&(m.push(E+".id "+(l?"<=":">=")+" ?"),y.push(o)),i!==!1){var _=l?">":"<";v&&(_+="="),m.push(E+".id "+_+" ?"),y.push(i)}c!==!1&&(m.push(E+".id = ?"),y.push(c))}"ok"!==e.deleted&&m.push(S+".deleted = 0"),Q.readTransaction(function(t){Y(t,function(o){if(n=o,0!==d){var i=a(C,[E,S],D,m,E+".id "+(l?"DESC":"ASC"));i+=" LIMIT "+d+" OFFSET "+h,t.executeSql(i,y,function(t,n){for(var o=0,i=n.rows.length;i>o;o++){var a=n.rows.item(o),u=g.parse(a.metadata),c=f(a.data,u.id,a.rev),l=c._rev,d={id:u.id,key:u.id,value:{rev:l}};if(e.include_docs&&(d.doc=c,d.doc._rev=l,e.conflicts&&(d.doc._conflicts=p.collectConflicts(u)),s(d.doc,e,H,t)),a.deleted){if("ok"!==e.deleted)continue;d.value.deleted=!0,d.doc=null}r.push(d)}})}})},u(t),function(){t(null,{total_rows:n,offset:e.skip,rows:r})})},H._changes=function(e){function t(){var t=[E+".winningseq > "+e.since],n=[];e.doc_ids&&(t.push(E+".id IN ("+e.doc_ids.map(function(){return"?"}).join(",")+")"),n=e.doc_ids);var d=a(C,[E,S],D,t,E+".winningseq "+(r?"DESC":"ASC")),p=h.filterChange(e);e.view||e.filter||(d+=" LIMIT "+o);var v=0;Q.readTransaction(function(t){t.executeSql(d,n,function(t,n){function r(t){return function(){e.onChange(t)}}for(var a=0,u=n.rows.length;u>a;a++){var d=n.rows.item(a),h=g.parse(d.metadata);v<d.seq&&(v=d.seq);var y=f(d.data,h.id,d.rev),m=e.processChange(y,h,e);if(m.seq=d.seq,p(m)&&(l++,i&&c.push(m),e.attachments&&e.include_docs?s(y,e,H,t,r(m)):r(m)()),l===o)break}})},u(e.complete),function(){e.continuous||e.complete(null,{results:c,last_seq:v})})}if(e=h.clone(e),e.continuous){var n=K+":"+h.uuid();return d.Changes.addListener(K,n,H,e),d.Changes.notify(K),{cancel:function(){d.Changes.removeListener(K,n)}}}var r=e.descending;e.since=e.since&&!r?e.since:0;var o="limit"in e?e.limit:-1;0===o&&(o=1);var i;i="returnDocs"in e?e.returnDocs:!0;var c=[],l=0;t()},H._close=function(e){e()},H._getAttachment=function(e,t,n){var r,o=t.ctx,s=e.digest,a=e.content_type,u="SELECT escaped, CASE WHEN escaped = 1 THEN body ELSE HEX(body) END AS body FROM "+A+" WHERE digest=?";o.executeSql(u,[s],function(e,o){var s=o.rows.item(0),u=s.escaped?i(s.body):y(s.body,V);t.encode?r=btoa(u):(u=h.fixBinary(u),r=h.createBlob([u],{type:a})),n(null,r)})},H._getRevisionTree=function(e,t){Q.readTransaction(function(n){var r="SELECT json AS metadata FROM "+E+" WHERE id = ?";n.executeSql(r,[e],function(e,n){if(n.rows.length){var r=g.parse(n.rows.item(0).metadata);t(null,r.rev_tree)}else t(v.MISSING_DOC)})})},H._doCompaction=function(e,t,n){return t.length?void Q.transaction(function(n){var r="SELECT json AS metadata FROM "+E+" WHERE id = ?";n.executeSql(r,[e],function(n,r){var o=g.parse(r.rows.item(0).metadata);p.traverseRevTree(o.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;-1!==t.indexOf(s)&&(i.status="missing")});var i="UPDATE "+E+" SET json = ? WHERE id = ?";n.executeSql(i,[g.stringify(o),e])}),t.forEach(function(t){var r="SELECT seq FROM "+S+" WHERE doc_id=? AND rev=?";n.executeSql(r,[e,t],function(e,t){if(t.rows.length){var n=t.rows.item(0).seq,r="SELECT a1.digest AS digest FROM "+x+" a1 JOIN "+x+" a2 ON a1.digest=a2.digest WHERE a1.seq=? GROUP BY a1.digest HAVING COUNT(*) = 1";e.executeSql(r,[n],function(e,t){for(var r=[],o=0;o<t.rows.length;o++)r.push(t.rows.item(o).digest);e.executeSql("DELETE FROM "+S+" WHERE seq=?",[n]),e.executeSql("DELETE FROM "+x+" WHERE seq=?",[n]),r.forEach(function(t){e.executeSql("DELETE FROM "+x+" WHERE digest=?",[t]),e.executeSql("DELETE FROM "+A+" WHERE digest=?",[t])})})}})})},u(n),function(){n()}):n()},H._getLocal=function(e,t){Q.readTransaction(function(n){var r="SELECT json, rev FROM "+k+" WHERE id=?";n.executeSql(r,[e],function(n,r){if(r.rows.length){var o=r.rows.item(0),i=f(o.json,e,o.rev);t(null,i)}else t(v.MISSING_DOC)})})},H._putLocal=function(e,t,n){function r(e){var r,u;i?(r="UPDATE "+k+" SET rev=?, json=? WHERE id=? AND rev=?",u=[o,f,s,i]):(r="INSERT INTO "+k+" (id, rev, json) VALUES (?,?,?)",u=[s,o,f]),e.executeSql(r,u,function(e,r){r.rowsAffected?(a={ok:!0,id:s,rev:o},t.ctx&&n(null,a)):n(v.REV_CONFLICT)},function(){return n(v.REV_CONFLICT),!1})}"function"==typeof t&&(n=t,t={}),delete e._revisions;var o,i=e._rev,s=e._id;o=e._rev=i?"0-"+(parseInt(i.split("-")[1],10)+1):"0-1";var a,f=c(e);t.ctx?r(t.ctx):Q.transaction(function(e){r(e)},u(n),function(){a&&n(null,a)})},void(H._removeLocal=function(e,t){var n;Q.transaction(function(r){var o="DELETE FROM "+k+" WHERE id=? AND rev=?",i=[e._id,e._rev];r.executeSql(o,i,function(r,o){return o.rowsAffected?void(n={ok:!0,id:e._id,rev:"0-0"}):t(v.MISSING_DOC)})},u(t),function(){n&&t(null,n)})})):t(v.UNKNOWN_ERROR)}var h=e("../utils"),p=e("../merge"),v=e("../deps/errors"),g=e("vuvuzela"),y=e("../deps/parse-hex"),m={},_=h.getArguments(function(e){if("undefined"!=typeof n){if(n.navigator&&n.navigator.sqlitePlugin&&n.navigator.sqlitePlugin.openDatabase)return navigator.sqlitePlugin.openDatabase.apply(navigator.sqlitePlugin,e);if(n.sqlitePlugin&&n.sqlitePlugin.openDatabase)return n.sqlitePlugin.openDatabase.apply(n.sqlitePlugin,e);var t=m[e[0]];return t||(t=m[e[0]]=n.openDatabase.apply(n,e)),t}}),b=1,w=6,E=r("document-store"),S=r("by-sequence"),A=r("attach-store"),k=r("local-store"),T=r("metadata-store"),x=r("attach-seq-store"),I="CREATE INDEX IF NOT EXISTS 'by-seq-deleted-idx' ON "+S+" (seq, deleted)",q="CREATE UNIQUE INDEX IF NOT EXISTS 'by-seq-doc-id-rev' ON "+S+" (doc_id, rev)",L="CREATE INDEX IF NOT EXISTS 'doc-winningseq-idx' ON "+E+" (winningseq)",R="CREATE INDEX IF NOT EXISTS 'attach-seq-seq-idx' ON "+x+" (seq)",O="CREATE UNIQUE INDEX IF NOT EXISTS 'attach-seq-digest-idx' ON "+x+" (digest, seq)",D=S+".seq = "+E+".winningseq",C=S+".seq AS seq, "+S+".deleted AS deleted, "+S+".json AS data, "+S+".rev AS rev, "+E+".json AS metadata";d.valid=function(){if("undefined"!=typeof n){if(n.navigator&&n.navigator.sqlitePlugin&&n.navigator.sqlitePlugin.openDatabase)return!0;if(n.sqlitePlugin&&n.sqlitePlugin.openDatabase)return!0;if(n.openDatabase)return!0}return!1},d.destroy=h.toPromise(function(e,t,r){d.Changes.removeAllListeners(e);var o=l(t),i=_(e,b,e,o);i.transaction(function(e){var t=[E,S,A,T,k,x];t.forEach(function(t){e.executeSql("DROP TABLE IF EXISTS "+t,[])})},u(r),function(){h.hasLocalStorage()&&(delete n.localStorage["_pouch__websqldb_"+e],delete n.localStorage[e]),r(null,{ok:!0})})}),d.Changes=new h.Changes,t.exports=d}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../deps/errors":12,"../deps/parse-hex":14,"../merge":20,"../utils":25,vuvuzela:67}],6:[function(e,t){"use strict";function n(e,t,n){function r(){i.cancel()}a.call(this);var i=this;this.db=e,t=t?o.clone(t):{};var s=n||t.complete||function(){},u=t.complete=o.once(function(t,n){t?i.emit("error",t):i.emit("complete",n),i.removeAllListeners(),e.removeListener("destroyed",r)});s&&(i.on("complete",function(e){s(null,e)}),i.on("error",function(e){s(e)}));var c=t.onChange;c&&i.on("change",c),e.once("destroyed",r),t.onChange=function(e){t.isCancelled||(i.emit("change",e),i.startSeq&&i.startSeq<=e.seq&&(i.emit("uptodate"),i.startSeq=!1),e.deleted?i.emit("delete",e):1===e.changes.length&&"1-"===e.changes[0].rev.slice(0,2)?i.emit("create",e):i.emit("update",e))};var f=new o.Promise(function(e,n){t.complete=function(t,r){t?n(t):e(r)}});i.once("cancel",function(){c&&i.removeListener("change",c),t.complete(null,{status:"cancelled"})}),this.then=f.then.bind(f),this["catch"]=f["catch"].bind(f),this.then(function(e){u(null,e)},u),e.taskqueue.isReady?i.doChanges(t):e.taskqueue.addTask(function(){i.isCancelled?i.emit("cancel"):i.doChanges(t)})}function r(e,t,n){var r=[{rev:e._rev}];"all_docs"===n.style&&(r=i.collectLeaves(t.rev_tree).map(function(e){return{rev:e.rev}}));var s={id:t.id,changes:r,doc:e};return o.isDeleted(t,e._rev)&&(s.deleted=!0),n.conflicts&&(s.doc._conflicts=i.collectConflicts(t),s.doc._conflicts.length||delete s.doc._conflicts),s}var o=e("./utils"),i=e("./merge"),s=e("./deps/errors"),a=e("events").EventEmitter,u=e("./evalFilter"),c=e("./evalView");t.exports=n,o.inherits(n,a),n.prototype.cancel=function(){this.isCancelled=!0,this.db.taskqueue.isReady&&this.emit("cancel")},n.prototype.doChanges=function(e){var t=this,n=e.complete;if(e=o.clone(e),"live"in e&&!("continuous"in e)&&(e.continuous=e.live),e.processChange=r,"latest"===e.since&&(e.since="now"),e.since||(e.since=0),"now"===e.since)return void this.db.info().then(function(r){return t.isCancelled?void n(null,{status:"cancelled"}):(e.since=r.update_seq-1,void t.doChanges(e))},n);if(e.continuous&&"now"!==e.since&&this.db.info().then(function(e){t.startSeq=e.update_seq-1},function(e){if("idbNull"!==e.id)throw e}),"http"!==this.db.type()&&e.filter&&"string"==typeof e.filter&&!e.doc_ids)return this.filterChanges(e);"descending"in e||(e.descending=!1),e.limit=0===e.limit?1:e.limit,e.complete=n;var i=this.db._changes(e);if(i&&"function"==typeof i.cancel){var s=t.cancel;t.cancel=o.getArguments(function(e){i.cancel(),s.apply(this,e)})}},n.prototype.filterChanges=function(e){var t=this,n=e.complete;if("_view"===e.filter){if(!e.view||"string"!=typeof e.view){var r=new Error("`view` filter parameter is not provided.");return r.status=s.BAD_REQUEST.status,r.name=s.BAD_REQUEST.name,r.error=!0,void n(r)}var o=e.view.split("/");this.db.get("_design/"+o[0],function(r,i){if(t.isCancelled)return void n(null,{status:"cancelled"});if(r)return void n(r);if(i&&i.views&&i.views[o[1]]){var a=c(i.views[o[1]].map);return e.filter=a,void t.doChanges(e)}var u=i.views?"missing json key: "+o[1]:"missing json key: views";r||(r=new Error(u),r.status=s.MISSING_DOC.status,r.name=s.MISSING_DOC.name,r.error=!0),n(r)})}else{var i=e.filter.split("/");this.db.get("_design/"+i[0],function(r,o){if(t.isCancelled)return void n(null,{status:"cancelled"});if(r)return void n(r);if(o&&o.filters&&o.filters[i[1]]){var a=u(o.filters[i[1]]);return e.filter=a,void t.doChanges(e)}var c=o&&o.filters?"missing json key: "+i[1]:"missing json key: filters";return r||(r=new Error(c),r.status=s.MISSING_DOC.status,r.name=s.MISSING_DOC.name,r.error=!0),void n(r)})}}},{"./deps/errors":12,"./evalFilter":18,"./evalView":19,"./merge":20,"./utils":25,events:33}],7:[function(e,t){"use strict";function n(e,t,n,r){return e.get(t)["catch"](function(n){if(404===n.status)return"http"===e.type()&&o.explain404("PouchDBVersion320 is just checking if a remote checkpoint exists."),{_id:t};throw n}).then(function(t){return r.cancelled?void 0:(t.last_seq=n,e.put(t))})}function r(e,t,n,r){this.src=e,this.target=t,this.id=n,this.returnValue=r}var o=e("./utils");r.prototype.writeCheckpoint=function(e){var t=this;return this.updateTarget(e).then(function(){return t.updateSource(e)})},r.prototype.updateTarget=function(e){return n(this.target,this.id,e,this.returnValue)},r.prototype.updateSource=function(e){var t=this;return this.readOnlySource?o.Promise.resolve(!0):n(this.src,this.id,e,this.returnValue)["catch"](function(e){var n="number"==typeof e.status&&4===Math.floor(e.status/100);if(n)return t.readOnlySource=!0,!0;throw e})},r.prototype.getCheckpoint=function(){var e=this;return e.target.get(e.id).then(function(t){return e.src.get(e.id).then(function(e){return t.last_seq===e.last_seq?e.last_seq:0},function(n){if(404===n.status&&t.last_seq)return e.src.put({_id:e.id,last_seq:0}).then(function(){return 0},function(n){return 401===n.status?(e.readOnlySource=!0,t.last_seq):0});throw n})})["catch"](function(e){if(404!==e.status)throw e;return 0})},t.exports=r},{"./utils":25}],8:[function(e,t){(function(n){"use strict";function r(e){e&&n.debug&&console.error(e)}function o(e,t,n){if(!(this instanceof o))return new o(e,t,n);var c=this;("function"==typeof t||"undefined"==typeof t)&&(n=t,t={}),e&&"object"==typeof e&&(t=e,e=void 0),"undefined"==typeof n&&(n=r),t=t||{},this.__opts=t;var f=n;c.auto_compaction=t.auto_compaction,c.prefix=o.prefix,i.call(c),c.taskqueue=new a;var l=new u(function(r,i){n=function(e,t){return e?i(e):(delete t.then,void r(t))},t=s.clone(t);var a,u,f=t.name||e;return function(){try{if("string"!=typeof f)throw u=new Error("Missing/invalid DB name"),u.code=400,u;if(a=o.parseAdapter(f,t),t.originalName=f,t.name=a.name,t.prefix&&"http"!==a.adapter&&"https"!==a.adapter&&(t.name=t.prefix+t.name),t.adapter=t.adapter||a.adapter,c._adapter=t.adapter,c._db_name=f,!o.adapters[t.adapter])throw u=new Error("Adapter is missing"),u.code=404,u;if(!o.adapters[t.adapter].valid())throw u=new Error("Invalid Adapter"),u.code=404,u}catch(e){c.taskqueue.fail(e),c.changes=s.toPromise(function(t){t.complete&&t.complete(e)})}}(),u?i(u):(c.adapter=t.adapter,c.replicate={},c.replicate.from=function(e,t,n){return c.constructor.replicate(e,c,t,n)},c.replicate.to=function(e,t,n){return c.constructor.replicate(c,e,t,n)},c.sync=function(e,t,n){return c.constructor.sync(c,e,t,n)},c.replicate.sync=c.sync,c.destroy=s.adapterFun("destroy",function(e){var t=this;t.info(function(n,r){return n?e(n):void t.constructor.destroy(r.db_name,e)})}),o.adapters[t.adapter].call(c,t,function(e){function r(e){"destroyed"===e&&(c.emit("destroyed"),o.removeListener(f,r))}return e?void(n&&(c.taskqueue.fail(e),n(e))):(o.on(f,r),c.emit("created",c),o.emit("created",t.originalName),c.taskqueue.ready(c),void n(null,c))}),t.skipSetup&&c.taskqueue.ready(c),void(s.isCordova()&&cordova.fireWindowEvent(t.name+"_pouch",{})))});l.then(function(e){f(null,e)},f),c.then=l.then.bind(l),c["catch"]=l["catch"].bind(l)}var i=e("./adapter"),s=e("./utils"),a=e("./taskqueue"),u=s.Promise;s.inherits(o,i),o.debug=e("debug"),t.exports=o}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./adapter":1,"./taskqueue":24,"./utils":25,debug:35}],9:[function(e,t){"use strict";function n(e,t){function n(t,n,r){if(e.binary||e.json||!e.processData||"string"==typeof t){if(!e.binary&&e.json&&"string"==typeof t)try{t=JSON.parse(t)}catch(o){return r(o)}}else t=JSON.stringify(t);Array.isArray(t)&&(t=t.map(function(e){var t;return e.ok?e:e.error&&"conflict"===e.error?(t=i.REV_CONFLICT,t.id=e.id,t):e.error&&"forbidden"===e.error?(t=i.FORBIDDEN,t.id=e.id,t.reason=e.reason,t):e.missing?(t=i.MISSING_DOC,t.missing=e.missing,t):e})),r(null,t,n)}function a(e,t){var n,r,o,s;try{n=JSON.parse(e.responseText);for(s in i)if(i.hasOwnProperty(s)&&i[s].name===n.error){o=i[s];break}o||(o=i.UNKNOWN_ERROR,e.status&&(o.status=e.status),e.statusText&&(e.name=e.statusText)),r=i.error(o,n.reason)}catch(a){for(var s in i)if(i.hasOwnProperty(s)&&i[s].status===e.status){o=i[s];break}o||(o=i.UNKNOWN_ERROR,e.status&&(o.status=e.status),e.statusText&&(e.name=e.statusText)),r=i.error(o)}e.withCredentials&&0===e.status&&(r.status=405,r.statusText="Method Not Allowed"),t(r)}var u=!1,c=s.getArguments(function(e){u||(t.apply(this,e),u=!0)});"function"==typeof e&&(c=e,e={}),e=s.clone(e);var f={method:"GET",headers:{},json:!0,processData:!0,timeout:1e4,cache:!1};if(e=s.extend(!0,f,e),"GET"===e.method&&!e.cache){var l=-1!==e.url.indexOf("?");e.url+=(l?"&":"?")+"_nonce="+s.uuid(16)}var d,h;h=e.xhr?new e.xhr:new XMLHttpRequest,h.open(e.method,e.url),h.withCredentials=!0,e.json&&(e.headers.Accept="application/json",e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json",e.body&&e.processData&&"string"!=typeof e.body&&(e.body=JSON.stringify(e.body))),e.binary&&(h.responseType="arraybuffer");var p=function(e,t,n){var r="";if(n){var o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3),r="; expires="+o.toGMTString()}document.cookie=e+"="+t+r+"; path=/"};for(var v in e.headers)if("Cookie"===v){var g=e.headers[v].split("=");p(g[0],g[1],10)}else h.setRequestHeader(v,e.headers[v]);"body"in e||(e.body=null);var y=function(){u||(h.abort(),a(h,c))};return h.onreadystatechange=function(){if(4===h.readyState&&!u)if(clearTimeout(d),h.status>=200&&h.status<300){var t;t=e.binary?o([h.response||""],{type:h.getResponseHeader("Content-Type")}):h.responseText,n(t,h,c)}else a(h,c)},e.timeout>0&&(d=setTimeout(y,e.timeout),h.onprogress=function(){clearTimeout(d),d=setTimeout(y,e.timeout)
-},"undefined"==typeof r&&(r=-1!==Object.keys(h).indexOf("upload")),r&&(h.upload.onprogress=h.onprogress)),e.body&&e.body instanceof Blob?s.readAsBinaryString(e.body,function(e){h.send(s.fixBinary(e))}):h.send(e.body),{abort:y}}var r,o=e("./blob.js"),i=e("./errors"),s=e("../utils");t.exports=n},{"../utils":25,"./blob.js":10,"./errors":12}],10:[function(e,t){(function(e){"use strict";function n(t,n){t=t||[],n=n||{};try{return new Blob(t,n)}catch(r){if("TypeError"!==r.name)throw r;for(var o=e.BlobBuilder||e.MSBlobBuilder||e.MozBlobBuilder||e.WebKitBlobBuilder,i=new o,s=0;s<t.length;s+=1)i.append(t[s]);return i.getBlob(n.type)}}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],11:[function(e,t,n){"use strict";function r(){this.store={}}function o(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=o,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){var t=this,n=Object.keys(t.store);n.forEach(function(n){var r=t.store[n];n=t.unmangle(n),e(r,n)})},o.prototype.add=function(e){return this.store.set(e,!0)},o.prototype.has=function(e){return this.store.has(e)},o.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],12:[function(e,t,n){"use strict";function r(e){this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}r.prototype__proto__=Error.prototype,r.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message})},n.UNAUTHORIZED=new r({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),n.MISSING_BULK_DOCS=new r({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),n.MISSING_DOC=new r({status:404,error:"not_found",reason:"missing"}),n.REV_CONFLICT=new r({status:409,error:"conflict",reason:"Document update conflict"}),n.INVALID_ID=new r({status:400,error:"invalid_id",reason:"_id field must contain a string"}),n.MISSING_ID=new r({status:412,error:"missing_id",reason:"_id is required for puts"}),n.RESERVED_ID=new r({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),n.NOT_OPEN=new r({status:412,error:"precondition_failed",reason:"Database not open"}),n.UNKNOWN_ERROR=new r({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),n.BAD_ARG=new r({status:500,error:"badarg",reason:"Some query argument is invalid"}),n.INVALID_REQUEST=new r({status:400,error:"invalid_request",reason:"Request was invalid"}),n.QUERY_PARSE_ERROR=new r({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),n.DOC_VALIDATION=new r({status:500,error:"doc_validation",reason:"Bad special document member"}),n.BAD_REQUEST=new r({status:400,error:"bad_request",reason:"Something wrong with the request"}),n.NOT_AN_OBJECT=new r({status:400,error:"bad_request",reason:"Document must be a JSON object"}),n.DB_MISSING=new r({status:404,error:"not_found",reason:"Database not found"}),n.IDB_ERROR=new r({status:500,error:"indexed_db_went_bad",reason:"unknown"}),n.WSQ_ERROR=new r({status:500,error:"web_sql_went_bad",reason:"unknown"}),n.LDB_ERROR=new r({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),n.FORBIDDEN=new r({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),n.error=function(e,t,n){function r(){this.message=t,n&&(this.name=n)}return r.prototype=e,new r(t)}},{}],13:[function(e,t){(function(n,r){"use strict";function o(e,t,n){if("function"==typeof e.slice)return t?n?e.slice(t,n):e.slice(t):e.slice();t=Math.floor(t||0),n=Math.floor(n||0);var r=e.byteLength;if(t=0>t?Math.max(t+r,0):Math.min(r,t),n=0>n?Math.max(n+r,0):Math.min(r,n),0>=n-t)return new ArrayBuffer(0);var o=new ArrayBuffer(n-t),i=new Uint8Array(o),s=new Uint8Array(e,t,n-t);return i.set(s),o}function i(e){var t=[255&e,e>>>8&255,e>>>16&255,e>>>24&255];return t.map(function(e){return String.fromCharCode(e)}).join("")}function s(e){for(var t="",n=0;n<e.length;n++)t+=i(e[n]);return r.btoa(t)}var a=e("crypto"),u=e("spark-md5"),c=r.setImmediate||r.setTimeout,f=32768;t.exports=function(e,t){function r(e,t,n,r){d?e.appendBinary(t.substring(n,r)):e.append(o(t,n,r))}function i(){var n=g*p,o=n+p;if(n+p>=e.size&&(o=e.size),g++,v>g)r(y,e,n,o),c(i);else{r(y,e,n,o);var a=y.end(!0),u=s(a);t(null,u),y.destroy()}}if(!n.browser){var l=a.createHash("md5").update(e).digest("base64");return void t(null,l)}var d="string"==typeof e,h=d?e.length:e.byteLength,p=Math.min(f,h),v=Math.ceil(h/p),g=0,y=d?new u:new u.ArrayBuffer;i()}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{_process:34,crypto:28,"spark-md5":66}],14:[function(e,t){"use strict";function n(e){return decodeURIComponent(window.escape(e))}function r(e){return 65>e?e-48:e-55}function o(e,t,n){for(var o="";n>t;)o+=String.fromCharCode(r(e.charCodeAt(t++))<<4|r(e.charCodeAt(t++)));return o}function i(e,t,n){for(var o="";n>t;)o+=String.fromCharCode(r(e.charCodeAt(t+2))<<12|r(e.charCodeAt(t+3))<<8|r(e.charCodeAt(t))<<4|r(e.charCodeAt(t+1))),t+=4;return o}function s(e,t){return"UTF-8"===t?n(o(e,0,e.length)):i(e,0,e.length)}t.exports=s},{}],15:[function(e,t){"use strict";function n(e){for(var t=r,n=t.parser[t.strictMode?"strict":"loose"].exec(e),o={},i=14;i--;){var s=t.key[i],a=n[i]||"",u=-1!==["user","password"].indexOf(s);o[s]=u?decodeURIComponent(a):a}return o[t.q.name]={},o[t.key[12]].replace(t.q.parser,function(e,n,r){n&&(o[t.q.name][n]=r)}),o}var r={strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};t.exports=n},{}],16:[function(e,t){"use strict";function n(e,t,n){return new o(function(o,i){return t&&"object"==typeof t&&(t=t._id),"string"!=typeof t?i(new Error("doc id is required")):void e.get(t,function(s,a){if(s)return 404!==s.status?i(s):o(r(e,n({_id:t}),n));var u=n(a);return u?void o(r(e,u,n)):o(a)})})}function r(e,t,r){return e.put(t)["catch"](function(o){if(409!==o.status)throw o;return n(e,t,r)})}var o=e("../utils").Promise;t.exports=function(e,t,r,o){return"function"!=typeof o?n(e,t,r):void n(e,t,r).then(function(e){o(null,e)},o)}},{"../utils":25}],17:[function(e,t){"use strict";function n(e){return 0|Math.random()*e}function r(e,t){t=t||o.length;var r="",i=-1;if(e){for(;++i<e;)r+=o[n(t)];return r}for(;++i<36;)switch(i){case 8:case 13:case 18:case 23:r+="-";break;case 19:r+=o[3&n(16)|8];break;default:r+=o[n(16)]}return r}var o="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");t.exports=r},{}],18:[function(_dereq_,module,exports){"use strict";function evalFilter(input){return eval(["(function () { return ",input," })()"].join(""))}module.exports=evalFilter},{}],19:[function(_dereq_,module,exports){"use strict";function evalView(input){return eval(["(function () {","  return function (doc) {","    var emitted = false;","    var emit = function (a, b) {","      emitted = true;","    };","    var view = "+input+";","    view(doc);","    if (emitted) {","      return true;","    }","  }","})()"].join("\n"))}module.exports=evalView},{}],20:[function(e,t){"use strict";function n(e){for(var t,n=e.shift(),r=[n.id,n.opts,[]],o=r;e.length;)n=e.shift(),t=[n.id,n.opts,[]],o[2].push(t),o=t;return r}function r(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var o=n.pop(),i=o.tree1,s=o.tree2;(i[1].status||s[1].status)&&(i[1].status="available"===i[1].status||"available"===s[1].status?"available":"missing");for(var a=0;a<s[2].length;a++)if(i[2][0]){for(var u=!1,c=0;c<i[2].length;c++)i[2][c][0]===s[2][a][0]&&(n.push({tree1:i[2][c],tree2:s[2][a]}),u=!0);u||(r="new_branch",i[2].push(s[2][a]),i[2].sort())}else r="new_leaf",i[2][0]=s[2][a]}return{conflicts:r,tree:e}}function o(e,t,n){var o,i=[],s=!1,a=!1;return e.length?(e.forEach(function(e){if(e.pos===t.pos&&e.ids[0]===t.ids[0])o=r(e.ids,t.ids),i.push({pos:e.pos,ids:o.tree}),s=s||o.conflicts,a=!0;else if(n!==!0){var u=e.pos<t.pos?e:t,c=e.pos<t.pos?t:e,f=c.pos-u.pos,l=[],d=[];for(d.push({ids:u.ids,diff:f,parent:null,parentIdx:null});d.length>0;){var h=d.pop();0!==h.diff?h.ids&&h.ids[2].forEach(function(e,t){d.push({ids:e,diff:h.diff-1,parent:h.ids,parentIdx:t})}):h.ids[0]===c.ids[0]&&l.push(h)}var p=l[0];p?(o=r(p.ids,c.ids),p.parent[2][p.parentIdx]=o.tree,i.push({pos:u.pos,ids:u.ids}),s=s||o.conflicts,a=!0):i.push(e)}else i.push(e)}),a||i.push(t),i.sort(function(e,t){return e.pos-t.pos}),{tree:i,conflicts:s||"internal_node"}):{tree:[t],conflicts:"new_leaf"}}function i(e,t){var r=a.rootToLeaf(e).map(function(e){var r=e.ids.slice(-t);return{pos:e.pos+(e.ids.length-r.length),ids:n(r)}});return r.reduce(function(e,t){return o(e,t,!0).tree},[r.shift()])}var s=e("pouchdb-extend"),a={};a.merge=function(e,t,n){e=s(!0,[],e),t=s(!0,{},t);var r=o(e,t);return{tree:i(r.tree,n),conflicts:r.conflicts}},a.winningRev=function(e){var t=[];return a.traverseRevTree(e.rev_tree,function(e,n,r,o,i){e&&t.push({pos:n,id:r,deleted:!!i.deleted})}),t.sort(function(e,t){return e.deleted!==t.deleted?e.deleted>t.deleted?1:-1:e.pos!==t.pos?t.pos-e.pos:e.id<t.id?1:-1}),t[0].pos+"-"+t[0].id},a.traverseRevTree=function(e,t){for(var n,r=e.slice();n=r.pop();)for(var o=n.pos,i=n.ids,s=i[2],a=t(0===s.length,o,i[0],n.ctx,i[1]),u=0,c=s.length;c>u;u++)r.push({pos:o+1,ids:s[u],ctx:a})},a.collectLeaves=function(e){var t=[];return a.traverseRevTree(e,function(e,n,r,o,i){e&&t.unshift({rev:n+"-"+r,pos:n,opts:i})}),t.sort(function(e,t){return t.pos-e.pos}),t.map(function(e){delete e.pos}),t},a.collectConflicts=function(e){var t=a.winningRev(e),n=a.collectLeaves(e.rev_tree),r=[];return n.forEach(function(e){e.rev===t||e.opts.deleted||r.push(e.rev)}),r},a.rootToLeaf=function(e){var t=[];return a.traverseRevTree(e,function(e,n,r,o,i){if(o=o?o.slice(0):[],o.push({id:r,opts:i}),e){var s=n+1-o.length;t.unshift({pos:s,ids:o})}return o}),t},t.exports=a},{"pouchdb-extend":57}],21:[function(e,t,n){"use strict";function r(e,t){e=parseInt(e,10),t=parseInt(t,10),e!==e&&(e=0),t!==t||e>=t?t=(e||1)<<1:t+=1;var n=Math.random(),r=t-e;return~~(r*n+e)}function o(e){var t=0;return e||(t=2e3),r(e,t)}function i(e,t,n,r,i,s,a){return r.retry===!1?(i.emit("error",a),void i.removeAllListeners()):(r.default_back_off=r.default_back_off||0,r.retries=r.retries||0,"function"!=typeof r.back_off_function&&(r.back_off_function=o),r.retries++,r.max_retries&&r.retries>r.max_retries?(i.emit("error",new Error("tried "+r.retries+" times but replication failed")),void i.removeAllListeners()):(i.emit("requestError",a),"active"===i.state&&(i.emit("syncStopped"),i.state="stopped",i.once("syncRestarted",function(){r.current_back_off=r.default_back_off})),r.current_back_off=r.current_back_off||r.default_back_off,r.current_back_off=r.back_off_function(r.current_back_off),void setTimeout(function(){u(e,t,n,r,i)},r.current_back_off)))}function s(){d.call(this),this.cancelled=!1,this.state="pending";var e=this,t=new l.Promise(function(t,n){e.once("complete",t),e.once("error",n)});e.then=function(e,n){return t.then(e,n)},e["catch"]=function(e){return t["catch"](e)},e["catch"](function(){})}function a(e,t,n){var r=n.filter?n.filter.toString():"";return e.id().then(function(e){return t.id().then(function(t){var o=e+t+r+JSON.stringify(n.query_params)+n.doc_ids;return l.MD5(o).then(function(e){return e=e.replace(/\//g,".").replace(/\+/g,"_"),"_local/"+e})})})}function u(e,t,n,r,o,s){function a(){if(0!==T.docs.length){var e=T.docs;return n.bulkDocs({docs:e},{new_edits:!1}).then(function(e){if(P.cancelled)throw b(),new Error("cancelled");var t=[];e.forEach(function(e){if(e.error){s.doc_write_failures++;var n=new Error(e.reason||e.message||"Unknown reason");n.name=e.name||e.error,t.push(n)}}),s.errors=s.errors.concat(t),s.docs_written+=T.docs.length-t.length;var n=t.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(n.length>0){var r=new Error("bulkDocs error");throw r.other_errors=t,_("target.bulkDocs failed to write docs",r),new Error("bulkWrite partial failure")}},function(t){throw s.doc_write_failures+=e.length,t})}}function u(){for(var e=T.diffs,n=Object.keys(e)[0],r=e[n].missing,o=[],i=0;i<r.length;i+=p)o.push(r.slice(i,Math.min(r.length,i+p)));return l.Promise.all(o.map(function(r){return t.get(n,{revs:!0,open_revs:r,attachments:!0}).then(function(t){t.forEach(function(e){return P.cancelled?b():void(e.ok&&(s.docs_read++,T.pendingRevs++,T.docs.push(e.ok)))}),delete e[n]})}))}function c(){return Object.keys(T.diffs).length>0?u().then(c):l.Promise.resolve()}function f(){var e=Object.keys(T.diffs).filter(function(e){var t=T.diffs[e].missing;return 1===t.length&&"1-"===t[0].slice(0,2)});return t.allDocs({keys:e,include_docs:!0}).then(function(e){if(P.cancelled)throw b(),new Error("cancelled");e.rows.forEach(function(e){!e.doc||e.deleted||"1-"!==e.value.rev.slice(0,2)||e.doc._attachments&&0!==Object.keys(e.doc._attachments).length||(s.docs_read++,T.pendingRevs++,T.docs.push(e.doc),delete T.diffs[e.id])})})}function d(){return f().then(c)}function v(){return q=!0,U.writeCheckpoint(T.seq).then(function(){if(q=!1,P.cancelled)throw b(),new Error("cancelled");s.last_seq=O=T.seq,o.emit("change",l.clone(s)),T=void 0,A()})["catch"](function(e){throw q=!1,_("writeCheckpoint completed with error",e),e})}function g(){var e={};return T.changes.forEach(function(t){e[t.id]=t.changes.map(function(e){return e.rev})}),n.revsDiff(e).then(function(e){if(P.cancelled)throw b(),new Error("cancelled");T.diffs=e,T.pendingRevs=0})}function y(){if(!P.cancelled&&!T){if(0===x.length)return void m(!0);T=x.shift(),g().then(d).then(a).then(v).then(y)["catch"](function(e){_("batch processing terminated with error",e)})}}function m(e){return 0===I.changes.length?void(0!==x.length||T||((D&&F.live||L)&&o.emit("uptodate",l.clone(s)),L&&b())):void((e||L||I.changes.length>=C)&&(x.push(I),I={seq:0,changes:[],docs:[]},y()))}function _(e,t){R||(s.ok=!1,s.status="aborting",s.errors.push(t),x=[],I={seq:0,changes:[],docs:[]},b())}function b(){if(!(R||P.cancelled&&(s.status="cancelled",q))){s.status=s.status||"complete",s.end_time=new Date,s.last_seq=O,R=P.cancelled=!0;var a=s.errors.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(a.length>0){var u=s.errors.pop();s.errors.length>0&&(u.other_errors=s.errors),u.result=s,i(e,t,n,r,o,s,u)}else o.emit("complete",s),o.removeAllListeners()}}function w(e){return P.cancelled?b():(0!==I.changes.length||0!==x.length||T||o.emit("outofdate",l.clone(s)),I.seq=e.seq,I.changes.push(e),void m(0===x.length))}function E(e){return j=!1,P.cancelled?b():(F.since<e.last_seq?(F.since=e.last_seq,A()):D?(F.live=!0,A()):L=!0,void m(!0))}function S(e){return j=!1,P.cancelled?b():void _("changes rejected",e)}function A(){function e(){r.cancel()}function n(){o.removeListener("cancel",e)}if(!j&&!L&&x.length<N){j=!0,o.once("cancel",e);var r=t.changes(F).on("change",w);r.then(n,n),r.then(E)["catch"](S)}}function k(){U.getCheckpoint().then(function(e){O=e,F={since:O,limit:C,batch_size:C,style:"all_docs",doc_ids:B,returnDocs:!1},r.filter&&(F.filter=r.filter),r.query_params&&(F.query_params=r.query_params),A()})["catch"](function(e){_("getCheckpoint rejected with ",e)})}var T,x=[],I={seq:0,changes:[],docs:[]},q=!1,L=!1,R=!1,O=0,D=r.continuous||r.live||!1,C=r.batch_size||100,N=r.batches_limit||10,j=!1,B=r.doc_ids,P={cancelled:!1},U=new h(t,n,e,P);s=s||{ok:!0,start_time:new Date,docs_read:0,docs_written:0,doc_write_failures:0,errors:[]};var F={};o.ready(t,n),o.once("cancel",b),"function"==typeof r.onChange&&o.on("change",r.onChange),"function"==typeof r.complete&&(o.once("error",r.complete),o.once("complete",function(e){r.complete(null,e)})),"undefined"==typeof r.since?k():(q=!0,U.writeCheckpoint(r.since).then(function(){return q=!1,P.cancelled?void b():(O=r.since,void k())})["catch"](function(e){throw q=!1,_("writeCheckpoint completed with error",e),e}))}function c(e,t){var n=t.PouchConstructor;return"string"==typeof e?new n(e):e.then?e:l.Promise.resolve(e)}function f(e,t,n,r){"function"==typeof n&&(r=n,n={}),"undefined"==typeof n&&(n={}),n.complete||(n.complete=r||function(){}),n=l.clone(n),n.continuous=n.continuous||n.live,n.retry=n.retry||!1,n.PouchConstructor=n.PouchConstructor||this;var o=new s(n);return c(e,n).then(function(e){return c(t,n).then(function(t){return a(e,t,n).then(function(r){u(r,e,t,n,o)})})})["catch"](function(e){o.emit("error",e),n.complete(e)}),o}var l=e("./utils"),d=e("events").EventEmitter,h=e("./checkpointer"),p=50;l.inherits(s,d),s.prototype.cancel=function(){this.cancelled=!0,this.state="cancelled",this.emit("cancel")},s.prototype.ready=function(e,t){function n(){o.cancel()}function r(){e.removeListener("destroyed",n),t.removeListener("destroyed",n)}var o=this;this.once("change",function(){"pending"===this.state?(o.state="active",o.emit("syncStarted")):"stopped"===o.state&&(o.state="active",o.emit("syncRestarted"))}),e.once("destroyed",n),t.once("destroyed",n),this.then(r,r)},n.toPouch=c,n.replicate=f},{"./checkpointer":7,"./utils":25,events:33}],22:[function(e,t){(function(n){"use strict";var r=e("./constructor"),o=e("./utils"),i=o.Promise,s=e("events").EventEmitter;r.adapters={},r.preferredAdapters=e("./adapters/preferredAdapters.js"),r.prefix="_pouch_";var a=new s,u=["on","addListener","emit","listeners","once","removeAllListeners","removeListener","setMaxListeners"];u.forEach(function(e){r[e]=a[e].bind(a)}),r.setMaxListeners(0),r.parseAdapter=function(e,t){var i,s,a=e.match(/([a-z\-]*):\/\/(.*)/);if(a){if(e=/http(s?)/.test(a[1])?a[1]+"://"+a[2]:a[2],i=a[1],!r.adapters[i].valid())throw"Invalid adapter";return{name:e,adapter:a[1]}}var u="idb"in r.adapters&&"websql"in r.adapters&&o.hasLocalStorage()&&n.localStorage["_pouch__websqldb_"+r.prefix+e];if("undefined"!=typeof t&&t.db)s="leveldb";else for(var c=0;c<r.preferredAdapters.length;++c)if(s=r.preferredAdapters[c],s in r.adapters){if(u&&"idb"===s)continue;break}if(i=r.adapters[s],s&&i){var f="use_prefix"in i?i.use_prefix:!0;return{name:f?r.prefix+e:e,adapter:s}}throw"No valid adapter found"},r.destroy=o.toPromise(function(e,t,n){function s(){c.destroy(d,t,function(t,o){t?n(t):(r.emit("destroyed",e),r.emit(e,"destroyed"),n(null,o||{ok:!0}))})}("function"==typeof t||"undefined"==typeof t)&&(n=t,t={}),e&&"object"==typeof e&&(t=e,e=void 0);var a=r.parseAdapter(t.name||e,t),u=a.name,c=r.adapters[a.adapter],f="use_prefix"in c?c.use_prefix:!0,l=f?u.replace(new RegExp("^"+r.prefix),""):u,d=("http"===a.adapter||"https"===a.adapter?"":t.prefix||"")+u,h=o.extend(!0,{},t,{adapter:a.adapter});new r(l,h,function(e,u){return e?n(e):void u.get("_local/_pouch_dependentDbs",function(e,u){if(e)return 404!==e.status?n(e):s();var c=u.dependentDbs,l=Object.keys(c).map(function(e){var n=f?e.replace(new RegExp("^"+r.prefix),""):e,i=o.extend(!0,t,{adapter:a.adapter});return r.destroy(n,i)});i.all(l).then(s,function(e){n(e)})})})}),r.allDbs=o.toPromise(function(e){var t=new Error("allDbs method removed");t.stats="400",e(t)}),r.adapter=function(e,t){t.valid()&&(r.adapters[e]=t)},r.plugin=function(e){Object.keys(e).forEach(function(t){r.prototype[t]=e[t]})},r.defaults=function(e){function t(t,n,i){("function"==typeof n||"undefined"==typeof n)&&(i=n,n={}),t&&"object"==typeof t&&(n=t,t=void 0),n=o.extend(!0,{},e,n),r.call(this,t,n,i)}return o.inherits(t,r),t.destroy=o.toPromise(function(t,n,i){return("function"==typeof n||"undefined"==typeof n)&&(i=n,n={}),t&&"object"==typeof t&&(n=t,t=void 0),n=o.extend(!0,{},e,n),r.destroy(t,n,i)}),u.forEach(function(e){t[e]=a[e].bind(a)}),t.setMaxListeners(0),t.preferredAdapters=r.preferredAdapters.slice(),Object.keys(r).forEach(function(e){e in t||(t[e]=r[e])}),t},t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./adapters/preferredAdapters.js":4,"./constructor":8,"./utils":25,events:33}],23:[function(e,t){"use strict";function n(e,t,n,s){return"function"==typeof n&&(s=n,n={}),"undefined"==typeof n&&(n={}),n=o.clone(n),n.PouchConstructor=n.PouchConstructor||this,e=i.toPouch(e,n),t=i.toPouch(t,n),new r(e,t,n,s)}function r(e,t,n,r){function i(e){h||(h=!0,f.emit("cancel",e))}function a(e){f.emit("change",{direction:"pull",change:e})}function u(e){f.emit("change",{direction:"push",change:e})}function c(e){return function(t,n){var r="change"===t&&(n===a||n===u),o="cancel"===t&&n===i,s=t in p&&n===p[t];(r||o||s)&&(t in v||(v[t]={}),v[t][e]=!0,2===Object.keys(v[t]).length&&f.removeAllListeners(t))}}var f=this;this.canceled=!1;var l,d;"onChange"in n&&(l=n.onChange,delete n.onChange),"function"!=typeof r||n.complete?"complete"in n&&(d=n.complete,delete n.complete):d=r,this.push=s(e,t,n),this.pull=s(t,e,n);var h=!1,p={},v={};this.on("newListener",function(e){"change"===e?(f.pull.on("change",a),f.push.on("change",u)):"cancel"===e?(f.pull.on("cancel",i),f.push.on("cancel",i)):"error"===e||"removeListener"===e||"complete"===e||e in p||(p[e]=function(t){f.emit(e,t)},f.pull.on(e,p[e]),f.push.on(e,p[e]))}),this.on("removeListener",function(e){"change"===e?(f.pull.removeListener("change",a),f.push.removeListener("change",u)):"cancel"===e?(f.pull.removeListener("cancel",i),f.push.removeListener("cancel",i)):e in p&&"function"==typeof p[e]&&(f.pull.removeListener(e,p[e]),f.push.removeListener(e,p[e]),delete p[e])}),this.pull.on("removeListener",c("pull")),this.push.on("removeListener",c("push"));var g=o.Promise.all([this.push,this.pull]).then(function(e){var t={push:e[0],pull:e[1]};return f.emit("complete",t),d&&d(null,t),f.removeAllListeners(),t},function(e){throw f.cancel(),f.emit("error",e),d&&d(e),f.removeAllListeners(),e});this.then=function(e,t){return g.then(e,t)},this["catch"]=function(e){return g["catch"](e)}}var o=e("./utils"),i=e("./replicate"),s=i.replicate,a=e("events").EventEmitter;o.inherits(r,a),t.exports=n,r.prototype.cancel=function(){this.canceled||(this.canceled=!0,this.push.cancel(),this.pull.cancel())}},{"./replicate":21,"./utils":25,events:33}],24:[function(e,t){"use strict";function n(){this.isReady=!1,this.failed=!1,this.queue=[]}t.exports=n,n.prototype.execute=function(){var e,t;if(this.failed)for(;e=this.queue.shift();)"function"!=typeof e?(t=e.parameters[e.parameters.length-1],"function"==typeof t?t(this.failed):"changes"===e.name&&"function"==typeof t.complete&&t.complete(this.failed)):e(this.failed);else if(this.isReady)for(;e=this.queue.shift();)"function"==typeof e?e():e.task=this.db[e.name].apply(this.db,e.parameters)},n.prototype.fail=function(e){this.failed=e,this.execute()},n.prototype.ready=function(e){return this.failed?!1:0===arguments.length?this.isReady:(this.isReady=e?!0:!1,this.db=e,void this.execute())},n.prototype.addTask=function(e,t){if("function"!=typeof e){var n={name:e,parameters:t};return this.queue.push(n),this.failed&&this.execute(),n}this.queue.push(e),this.failed&&this.execute()}},{}],25:[function(e,t,n){(function(t,r){function o(e){var t={};return e.forEach(function(e){t[e]=!0}),t}function i(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function s(){if(!(this instanceof s))return new s;var e=this;f.call(this),this.isChrome=i(),this.listeners={},this.hasLocal=!1,this.isChrome||(this.hasLocal=n.hasLocalStorage()),this.isChrome?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):this.hasLocal&&(r.addEventListener?r.addEventListener("storage",function(t){e.emit(t.key)}):r.attachEvent("storage",function(t){e.emit(t.key)}))}var a=e("./merge");n.extend=e("pouchdb-extend"),n.ajax=e("./deps/ajax"),n.createBlob=e("./deps/blob"),n.uuid=e("./deps/uuid"),n.getArguments=e("argsarray");var u=e("./deps/buffer"),c=e("./deps/errors"),f=e("events").EventEmitter,l=e("./deps/collections");n.Map=l.Map,n.Set=l.Set,n.Promise="function"==typeof r.Promise?r.Promise:e("bluebird");var d=n.Promise,h=o(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]),p=o(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]);n.lastIndexOf=function(e,t){for(var n=e.length-1;n>=0;n--)if(e.charAt(n)===t)return n;return-1},n.clone=function(e){return n.extend(!0,{},e)},n.pick=function(e,t){for(var n={},r=0,o=t.length;o>r;r++){var i=t[r];n[i]=e[i]}return n},n.inherits=e("inherits"),n.invalidIdError=function(e){var t;if(e?"string"!=typeof e?(t=new TypeError(c.INVALID_ID.message),t.status=400):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=new TypeError(c.RESERVED_ID.message),t.status=400):(t=new TypeError(c.MISSING_ID.message),t.status=412),t)throw t},n.call=n.getArguments(function(e){if(e.length){var t=e.shift();"function"==typeof t&&t.apply(this,e)}}),n.isLocalId=function(e){return/^_local/.test(e)},n.isDeleted=function(e,t){t||(t=a.winningRev(e));var n=t.indexOf("-");-1!==n&&(t=t.substring(n+1));var r=!1;return a.traverseRevTree(e.rev_tree,function(e,n,o,i,s){o===t&&(r=!!s.deleted)}),r},n.revExists=function(e,t){var n=!1;return a.traverseRevTree(e.rev_tree,function(e,r,o){r+"-"+o===t&&(n=!0)}),n},n.filterChange=function(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){if(e.filter&&n&&!e.filter.call(this,r.doc,t))return!1;if(e.include_docs){if(!e.attachments)for(var o in r.doc._attachments)r.doc._attachments.hasOwnProperty(o)&&(r.doc._attachments[o].stub=!0)}else delete r.doc;return!0}},n.parseDoc=function(e,t){var r,o,i,s,a={status:"available"};if(e._deleted&&(a.deleted=!0),t)if(e._id||(e._id=n.uuid()),o=n.uuid(32,16).toLowerCase(),e._rev){if(i=/^(\d+)-(.+)$/.exec(e._rev),!i)return s=new Error("bad_request"),s.message="Invalid rev format",s.error=!0,s;e._rev_tree=[{pos:parseInt(i[1],10),ids:[i[2],{status:"missing"},[[o,a,[]]]]}],r=parseInt(i[1],10)+1}else e._rev_tree=[{pos:1,ids:[o,a,[]]}],r=1;else if(e._revisions&&(e._rev_tree=[{pos:e._revisions.start-e._revisions.ids.length+1,ids:e._revisions.ids.reduce(function(e,t){return null===e?[t,a,[]]:[t,{status:"missing"},[e]]},null)}],r=e._revisions.start,o=e._revisions.ids[0]),!e._rev_tree){if(i=/^(\d+)-(.+)$/.exec(e._rev),!i)return s=new Error("bad_request"),s.message="Invalid rev format",s.error=!0,s;r=parseInt(i[1],10),o=i[2],e._rev_tree=[{pos:parseInt(i[1],10),ids:[i[2],a,[]]}]}n.invalidIdError(e._id),e._rev=[r,o].join("-");var u={metadata:{},data:{}};for(var f in e)if(e.hasOwnProperty(f)){var l="_"===f[0];if(l&&!h[f])throw s=new Error(c.DOC_VALIDATION.message+": "+f),s.status=c.DOC_VALIDATION.status,s;l&&!p[f]?u.metadata[f.slice(1)]=e[f]:u.data[f]=e[f]}return u},n.isCordova=function(){return"undefined"!=typeof cordova||"undefined"!=typeof PhoneGap||"undefined"!=typeof phonegap},n.hasLocalStorage=function(){if(i())return!1;try{return r.localStorage}catch(e){return!1}},n.Changes=s,n.inherits(s,f),s.prototype.addListener=function(e,t,r,o){function i(){r.changes({include_docs:o.include_docs,attachments:o.attachments,conflicts:o.conflicts,continuous:!1,descending:!1,filter:o.filter,doc_ids:o.doc_ids,view:o.view,since:o.since,query_params:o.query_params,onChange:function(e){e.seq>o.since&&!o.cancelled&&(o.since=e.seq,n.call(o.onChange,e))}})}this.listeners[t]||(this.listeners[t]=i,this.on(e,i))},s.prototype.removeListener=function(e,t){t in this.listeners&&f.prototype.removeListener.call(this,e,this.listeners[t])},s.prototype.notifyLocalWindows=function(e){this.isChrome?chrome.storage.local.set({dbName:e}):this.hasLocal&&(localStorage[e]="a"===localStorage[e]?"b":"a")},s.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)},n.atob=t.browser&&"atob"in r?function(e){return atob(e)}:function(e){var t=new u(e,"base64");if(t.toString("base64")!==e)throw"Cannot base64 encode full string";return t.toString("binary")},n.btoa=t.browser&&"btoa"in r?function(e){return btoa(e)}:function(e){return new u(e,"binary").toString("base64")},n.fixBinary=function(e){if(!t.browser)return e;for(var n=e.length,r=new ArrayBuffer(n),o=new Uint8Array(r),i=0;n>i;i++)o[i]=e.charCodeAt(i);return r},n.readAsBinaryString=function(e,t){var r=new FileReader,o="function"==typeof r.readAsBinaryString;r.onloadend=function(e){var r=e.target.result||"";return o?t(r):void t(n.arrayBufferToBinaryString(r))},o?r.readAsBinaryString(e):r.readAsArrayBuffer(e)},n.once=function(e){var t=!1;return n.getArguments(function(n){if(t)throw new Error("once called  more than once");t=!0,e.apply(this,n)})},n.toPromise=function(e){return n.getArguments(function(r){var o,i=this,s="function"==typeof r[r.length-1]?r.pop():!1;s&&(o=function(e,n){t.nextTick(function(){s(e,n)})});var a=new d(function(t,o){var s;try{var a=n.once(function(e,n){e?o(e):t(n)});r.push(a),s=e.apply(i,r),s&&"function"==typeof s.then&&t(s)}catch(u){o(u)}});return o&&a.then(function(e){o(null,e)},o),a.cancel=function(){return this},a})},n.adapterFun=function(t,r){function o(e,t,n){if(i.enabled){for(var r=[e._db_name,t],o=0;o<n.length-1;o++)r.push(n[o]);i.apply(null,r);var s=n[n.length-1];n[n.length-1]=function(n,r){var o=[e._db_name,t];o=o.concat(n?["error",n]:["success",r]),i.apply(null,o),s(n,r)}}}var i=e("debug")("pouchdb:api");return n.toPromise(n.getArguments(function(e){if(this._closed)return d.reject(new Error("database is closed"));var i=this;return o(i,t,e),this.taskqueue.isReady?r.apply(this,e):new n.Promise(function(n,r){i.taskqueue.addTask(function(o){o?r(o):n(i[t].apply(i,e))})})}))},n.arrayBufferToBinaryString=function(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,o=0;r>o;o++)t+=String.fromCharCode(n[o]);return t},n.cancellableFun=function(e,t,r){r=r?n.clone(!0,{},r):{};var o=new f,i=r.complete||function(){},s=r.complete=n.once(function(e,t){e?i(e):(o.emit("end",t),i(null,t)),o.removeAllListeners()}),a=r.onChange||function(){},u=0;t.on("destroyed",function(){o.removeAllListeners()}),r.onChange=function(e){a(e),e.seq<=u||(u=e.seq,o.emit("change",e),e.deleted?o.emit("delete",e):1===e.changes.length&&"1-"===e.changes[0].rev.slice(0,1)?o.emit("create",e):o.emit("update",e))};var c=new d(function(e,t){r.complete=function(n,r){n?t(n):e(r)}});return c.then(function(e){s(null,e)},s),c.cancel=function(){c.isCancelled=!0,t.taskqueue.isReady&&r.complete(null,{status:"cancelled"})},t.taskqueue.isReady?e(t,r,c):t.taskqueue.addTask(function(){c.isCancelled?r.complete(null,{status:"cancelled"}):e(t,r,c)}),c.on=o.on.bind(o),c.once=o.once.bind(o),c.addListener=o.addListener.bind(o),c.removeListener=o.removeListener.bind(o),c.removeAllListeners=o.removeAllListeners.bind(o),c.setMaxListeners=o.setMaxListeners.bind(o),c.listeners=o.listeners.bind(o),c.emit=o.emit.bind(o),c},n.MD5=n.toPromise(e("./deps/md5")),n.explain404=function(e){t.browser&&"console"in r&&"info"in console&&console.info("The above 404 is totally normal. "+e)},n.parseUri=e("./deps/parse-uri"),n.compare=function(e,t){return t>e?-1:e>t?1:0},n.updateDoc=function(e,t,r,o,i,s,u){if(n.revExists(e,t.metadata.rev))return r[o]=t,i();
-var f=n.isDeleted(e),l=n.isDeleted(t.metadata),d=/^1-/.test(t.metadata.rev);if(f&&!l&&u&&d){var h=t.data;h._rev=a.winningRev(e),h._id=t.metadata.id,t=n.parseDoc(h,u)}var p=a.merge(e.rev_tree,t.metadata.rev_tree[0],1e3),v=u&&(f&&l||!f&&"new_leaf"!==p.conflicts||f&&!l&&"new_branch"===p.conflicts);if(v){var g=c.REV_CONFLICT;return r[o]=g,i()}t.metadata.rev_tree=p.tree;var y=a.winningRev(t.metadata);l=n.isDeleted(t.metadata,y),s(t,y,l,i,!0,o)},n.processDocs=function(e,t,r,o,i,s,u){function f(e,t,r){var o=a.winningRev(e.metadata),f=n.isDeleted(e.metadata,o);return"was_delete"in u&&f?(i[t]=c.MISSING_DOC,r()):void s(e,o,f,r,!1,t)}if(e.length){var l=u.new_edits,d=new n.Map;e.forEach(function(e,r){if(e._id&&n.isLocalId(e._id))return void t[e._deleted?"_removeLocal":"_putLocal"](e,{ctx:o},function(e){i[r]=e?e:{}});var s=e.metadata.id;d.has(s)?d.get(s).push([e,r]):d.set(s,[[e,r]])}),d.forEach(function(e,t){function o(){++u<e.length&&a()}function a(){var a=e[u],c=a[0],d=a[1];r.has(t)?n.updateDoc(r.get(t),c,i,d,o,s,l):f(c,d,o)}var u=0;a()})}},n.preprocessAttachments=function(e,t,r){function o(e){try{return n.atob(e)}catch(t){var r=c.error(c.BAD_ARG,"Attachments need to be base64 encoded");return{error:r}}}function i(e,r){if(e.stub)return r();if("string"==typeof e.data){var i=o(e.data);if(i.error)return r(i.error);e.length=i.length,e.data="blob"===t?n.createBlob([n.fixBinary(i)],{type:e.content_type}):"base64"===t?n.btoa(i):i,n.MD5(i).then(function(t){e.digest="md5-"+t,r()})}else n.readAsBinaryString(e.data,function(o){"binary"===t?e.data=o:"base64"===t&&(e.data=n.btoa(o)),n.MD5(o).then(function(t){e.digest="md5-"+t,e.length=o.length,r()})})}function s(){u++,e.length===u&&(a?r(a):r())}if(!e.length)return r();var a,u=0;e.forEach(function(e){function t(e){a=e,r++,r===n.length&&s()}var n=e.data&&e.data._attachments?Object.keys(e.data._attachments):[],r=0;if(!n.length)return s();for(var o in e.data._attachments)e.data._attachments.hasOwnProperty(o)&&i(e.data._attachments[o],t)})}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./deps/ajax":9,"./deps/blob":10,"./deps/buffer":28,"./deps/collections":11,"./deps/errors":12,"./deps/md5":13,"./deps/parse-uri":15,"./deps/uuid":17,"./merge":20,_process:34,argsarray:27,bluebird:42,debug:35,events:33,inherits:38,"pouchdb-extend":57}],26:[function(e,t){t.exports="3.2.0"},{}],27:[function(e,t){"use strict";function n(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=n},{}],28:[function(){},{}],29:[function(e,t,n){function r(e,t,n){if(!(this instanceof r))return new r(e,t,n);var o,i=typeof e;if("number"===i)o=e>0?e>>>0:0;else if("string"===i)"base64"===t&&(e=S(e)),o=r.byteLength(e,t);else{if("object"!==i||null===e)throw new TypeError("must start with number, buffer, array or string");"Buffer"===e.type&&N(e.data)&&(e=e.data),o=+e.length>0?Math.floor(+e.length):0}if(this.length>j)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+j.toString(16)+" bytes");var s;r.TYPED_ARRAY_SUPPORT?s=r._augment(new Uint8Array(o)):(s=this,s.length=o,s._isBuffer=!0);var a;if(r.TYPED_ARRAY_SUPPORT&&"number"==typeof e.byteLength)s._set(e);else if(k(e))if(r.isBuffer(e))for(a=0;o>a;a++)s[a]=e.readUInt8(a);else for(a=0;o>a;a++)s[a]=(e[a]%256+256)%256;else if("string"===i)s.write(e,0,t);else if("number"===i&&!r.TYPED_ARRAY_SUPPORT&&!n)for(a=0;o>a;a++)s[a]=0;return s}function o(e,t,n,r){n=Number(n)||0;var o=e.length-n;r?(r=Number(r),r>o&&(r=o)):r=o;var i=t.length;if(i%2!==0)throw new Error("Invalid hex string");r>i/2&&(r=i/2);for(var s=0;r>s;s++){var a=parseInt(t.substr(2*s,2),16);if(isNaN(a))throw new Error("Invalid hex string");e[n+s]=a}return s}function i(e,t,n,r){var o=R(x(t),e,n,r);return o}function s(e,t,n,r){var o=R(I(t),e,n,r);return o}function a(e,t,n,r){return s(e,t,n,r)}function u(e,t,n,r){var o=R(L(t),e,n,r);return o}function c(e,t,n,r){var o=R(q(t),e,n,r);return o}function f(e,t,n){return D.fromByteArray(0===t&&n===e.length?e:e.slice(t,n))}function l(e,t,n){var r="",o="";n=Math.min(e.length,n);for(var i=t;n>i;i++)e[i]<=127?(r+=O(o)+String.fromCharCode(e[i]),o=""):o+="%"+e[i].toString(16);return r+O(o)}function d(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;n>o;o++)r+=String.fromCharCode(e[o]);return r}function h(e,t,n){return d(e,t,n)}function p(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var o="",i=t;n>i;i++)o+=T(e[i]);return o}function v(e,t,n){for(var r=e.slice(t,n),o="",i=0;i<r.length;i+=2)o+=String.fromCharCode(r[i]+256*r[i+1]);return o}function g(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function y(e,t,n,o,i,s){if(!r.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>i||s>t)throw new TypeError("value is out of bounds");if(n+o>e.length)throw new TypeError("index out of range")}function m(e,t,n,r){0>t&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);i>o;o++)e[n+o]=(t&255<<8*(r?o:1-o))>>>8*(r?o:1-o)}function _(e,t,n,r){0>t&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);i>o;o++)e[n+o]=t>>>8*(r?o:3-o)&255}function b(e,t,n,r,o,i){if(t>o||i>t)throw new TypeError("value is out of bounds");if(n+r>e.length)throw new TypeError("index out of range")}function w(e,t,n,r,o){return o||b(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),C.write(e,t,n,r,23,4),n+4}function E(e,t,n,r,o){return o||b(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),C.write(e,t,n,r,52,8),n+8}function S(e){for(e=A(e).replace(P,"");e.length%4!==0;)e+="=";return e}function A(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function k(e){return N(e)||r.isBuffer(e)||e&&"object"==typeof e&&"number"==typeof e.length}function T(e){return 16>e?"0"+e.toString(16):e.toString(16)}function x(e){for(var t=[],n=0;n<e.length;n++){var r=e.charCodeAt(n);if(127>=r)t.push(r);else{var o=n;r>=55296&&57343>=r&&n++;for(var i=encodeURIComponent(e.slice(o,n+1)).substr(1).split("%"),s=0;s<i.length;s++)t.push(parseInt(i[s],16))}}return t}function I(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function q(e){for(var t,n,r,o=[],i=0;i<e.length;i++)t=e.charCodeAt(i),n=t>>8,r=t%256,o.push(r),o.push(n);return o}function L(e){return D.toByteArray(e)}function R(e,t,n,r){for(var o=0;r>o&&!(o+n>=t.length||o>=e.length);o++)t[o+n]=e[o];return o}function O(e){try{return decodeURIComponent(e)}catch(t){return String.fromCharCode(65533)}}var D=e("base64-js"),C=e("ieee754"),N=e("is-array");n.Buffer=r,n.SlowBuffer=r,n.INSPECT_MAX_BYTES=50,r.poolSize=8192;var j=1073741823;r.TYPED_ARRAY_SUPPORT=function(){try{var e=new ArrayBuffer(0),t=new Uint8Array(e);return t.foo=function(){return 42},42===t.foo()&&"function"==typeof t.subarray&&0===new Uint8Array(1).subarray(1,1).byteLength}catch(n){return!1}}(),r.isBuffer=function(e){return!(null==e||!e._isBuffer)},r.compare=function(e,t){if(!r.isBuffer(e)||!r.isBuffer(t))throw new TypeError("Arguments must be Buffers");for(var n=e.length,o=t.length,i=0,s=Math.min(n,o);s>i&&e[i]===t[i];i++);return i!==s&&(n=e[i],o=t[i]),o>n?-1:n>o?1:0},r.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},r.concat=function(e,t){if(!N(e))throw new TypeError("Usage: Buffer.concat(list[, length])");if(0===e.length)return new r(0);if(1===e.length)return e[0];var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var o=new r(t),i=0;for(n=0;n<e.length;n++){var s=e[n];s.copy(o,i),i+=s.length}return o},r.byteLength=function(e,t){var n;switch(e+="",t||"utf8"){case"ascii":case"binary":case"raw":n=e.length;break;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":n=2*e.length;break;case"hex":n=e.length>>>1;break;case"utf8":case"utf-8":n=x(e).length;break;case"base64":n=L(e).length;break;default:n=e.length}return n},r.prototype.length=void 0,r.prototype.parent=void 0,r.prototype.toString=function(e,t,n){var r=!1;if(t>>>=0,n=void 0===n||1/0===n?this.length:n>>>0,e||(e="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(e){case"hex":return p(this,t,n);case"utf8":case"utf-8":return l(this,t,n);case"ascii":return d(this,t,n);case"binary":return h(this,t,n);case"base64":return f(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return v(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}},r.prototype.equals=function(e){if(!r.isBuffer(e))throw new TypeError("Argument must be a Buffer");return 0===r.compare(this,e)},r.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},r.prototype.compare=function(e){if(!r.isBuffer(e))throw new TypeError("Argument must be a Buffer");return r.compare(this,e)},r.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},r.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},r.prototype.write=function(e,t,n,r){if(isFinite(t))isFinite(n)||(r=n,n=void 0);else{var f=r;r=t,t=n,n=f}t=Number(t)||0;var l=this.length-t;n?(n=Number(n),n>l&&(n=l)):n=l,r=String(r||"utf8").toLowerCase();var d;switch(r){case"hex":d=o(this,e,t,n);break;case"utf8":case"utf-8":d=i(this,e,t,n);break;case"ascii":d=s(this,e,t,n);break;case"binary":d=a(this,e,t,n);break;case"base64":d=u(this,e,t,n);break;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":d=c(this,e,t,n);break;default:throw new TypeError("Unknown encoding: "+r)}return d},r.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}},r.prototype.slice=function(e,t){var n=this.length;if(e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e),r.TYPED_ARRAY_SUPPORT)return r._augment(this.subarray(e,t));for(var o=t-e,i=new r(o,void 0,!0),s=0;o>s;s++)i[s]=this[s+e];return i},r.prototype.readUInt8=function(e,t){return t||g(e,1,this.length),this[e]},r.prototype.readUInt16LE=function(e,t){return t||g(e,2,this.length),this[e]|this[e+1]<<8},r.prototype.readUInt16BE=function(e,t){return t||g(e,2,this.length),this[e]<<8|this[e+1]},r.prototype.readUInt32LE=function(e,t){return t||g(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},r.prototype.readUInt32BE=function(e,t){return t||g(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},r.prototype.readInt8=function(e,t){return t||g(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},r.prototype.readInt16LE=function(e,t){t||g(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},r.prototype.readInt16BE=function(e,t){t||g(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},r.prototype.readInt32LE=function(e,t){return t||g(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},r.prototype.readInt32BE=function(e,t){return t||g(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},r.prototype.readFloatLE=function(e,t){return t||g(e,4,this.length),C.read(this,e,!0,23,4)},r.prototype.readFloatBE=function(e,t){return t||g(e,4,this.length),C.read(this,e,!1,23,4)},r.prototype.readDoubleLE=function(e,t){return t||g(e,8,this.length),C.read(this,e,!0,52,8)},r.prototype.readDoubleBE=function(e,t){return t||g(e,8,this.length),C.read(this,e,!1,52,8)},r.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,1,255,0),r.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=e,t+1},r.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,2,65535,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):m(this,e,t,!0),t+2},r.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,2,65535,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):m(this,e,t,!1),t+2},r.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,4,4294967295,0),r.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=e):_(this,e,t,!0),t+4},r.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,4,4294967295,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):_(this,e,t,!1),t+4},r.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,1,127,-128),r.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=e,t+1},r.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,2,32767,-32768),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):m(this,e,t,!0),t+2},r.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,2,32767,-32768),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):m(this,e,t,!1),t+2},r.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,4,2147483647,-2147483648),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):_(this,e,t,!0),t+4},r.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||y(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):_(this,e,t,!1),t+4},r.prototype.writeFloatLE=function(e,t,n){return w(this,e,t,!0,n)},r.prototype.writeFloatBE=function(e,t,n){return w(this,e,t,!1,n)},r.prototype.writeDoubleLE=function(e,t,n){return E(this,e,t,!0,n)},r.prototype.writeDoubleBE=function(e,t,n){return E(this,e,t,!1,n)},r.prototype.copy=function(e,t,n,o){var i=this;if(n||(n=0),o||0===o||(o=this.length),t||(t=0),o!==n&&0!==e.length&&0!==i.length){if(n>o)throw new TypeError("sourceEnd < sourceStart");if(0>t||t>=e.length)throw new TypeError("targetStart out of bounds");if(0>n||n>=i.length)throw new TypeError("sourceStart out of bounds");if(0>o||o>i.length)throw new TypeError("sourceEnd out of bounds");o>this.length&&(o=this.length),e.length-t<o-n&&(o=e.length-t+n);var s=o-n;if(1e3>s||!r.TYPED_ARRAY_SUPPORT)for(var a=0;s>a;a++)e[a+t]=this[a+n];else e._set(this.subarray(n,n+s),t)}},r.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),t>n)throw new TypeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new TypeError("start out of bounds");if(0>n||n>this.length)throw new TypeError("end out of bounds");var r;if("number"==typeof e)for(r=t;n>r;r++)this[r]=e;else{var o=x(e.toString()),i=o.length;for(r=t;n>r;r++)this[r]=o[r%i]}return this}},r.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(r.TYPED_ARRAY_SUPPORT)return new r(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;n>t;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var B=r.prototype;r._augment=function(e){return e.constructor=r,e._isBuffer=!0,e._get=e.get,e._set=e.set,e.get=B.get,e.set=B.set,e.write=B.write,e.toString=B.toString,e.toLocaleString=B.toString,e.toJSON=B.toJSON,e.equals=B.equals,e.compare=B.compare,e.copy=B.copy,e.slice=B.slice,e.readUInt8=B.readUInt8,e.readUInt16LE=B.readUInt16LE,e.readUInt16BE=B.readUInt16BE,e.readUInt32LE=B.readUInt32LE,e.readUInt32BE=B.readUInt32BE,e.readInt8=B.readInt8,e.readInt16LE=B.readInt16LE,e.readInt16BE=B.readInt16BE,e.readInt32LE=B.readInt32LE,e.readInt32BE=B.readInt32BE,e.readFloatLE=B.readFloatLE,e.readFloatBE=B.readFloatBE,e.readDoubleLE=B.readDoubleLE,e.readDoubleBE=B.readDoubleBE,e.writeUInt8=B.writeUInt8,e.writeUInt16LE=B.writeUInt16LE,e.writeUInt16BE=B.writeUInt16BE,e.writeUInt32LE=B.writeUInt32LE,e.writeUInt32BE=B.writeUInt32BE,e.writeInt8=B.writeInt8,e.writeInt16LE=B.writeInt16LE,e.writeInt16BE=B.writeInt16BE,e.writeInt32LE=B.writeInt32LE,e.writeInt32BE=B.writeInt32BE,e.writeFloatLE=B.writeFloatLE,e.writeFloatBE=B.writeFloatBE,e.writeDoubleLE=B.writeDoubleLE,e.writeDoubleBE=B.writeDoubleBE,e.fill=B.fill,e.inspect=B.inspect,e.toArrayBuffer=B.toArrayBuffer,e};var P=/[^+\/0-9A-z]/g},{"base64-js":30,ieee754:31,"is-array":32}],30:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===s?62:t===a?63:u>t?-1:u+10>t?t-u+26+26:f+26>t?t-f:c+26>t?t-c+26:void 0}function n(e){function n(e){c[l++]=e}var r,o,s,a,u,c;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var f=e.length;u="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0,c=new i(3*e.length/4-u),s=u>0?e.length-4:e.length;var l=0;for(r=0,o=0;s>r;r+=4,o+=3)a=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&a)>>16),n((65280&a)>>8),n(255&a);return 2===u?(a=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&a)):1===u&&(a=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(a>>8&255),n(255&a)),c}function o(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var o,i,s,a=e.length%3,u="";for(o=0,s=e.length-a;s>o;o+=3)i=(e[o]<<16)+(e[o+1]<<8)+e[o+2],u+=n(i);switch(a){case 1:i=e[e.length-1],u+=t(i>>2),u+=t(i<<4&63),u+="==";break;case 2:i=(e[e.length-2]<<8)+e[e.length-1],u+=t(i>>10),u+=t(i>>4&63),u+=t(i<<2&63),u+="="}return u}var i="undefined"!=typeof Uint8Array?Uint8Array:Array,s="+".charCodeAt(0),a="/".charCodeAt(0),u="0".charCodeAt(0),c="a".charCodeAt(0),f="A".charCodeAt(0);e.toByteArray=n,e.fromByteArray=o}("undefined"==typeof n?this.base64js={}:n)},{}],31:[function(e,t,n){n.read=function(e,t,n,r,o){var i,s,a=8*o-r-1,u=(1<<a)-1,c=u>>1,f=-7,l=n?o-1:0,d=n?-1:1,h=e[t+l];for(l+=d,i=h&(1<<-f)-1,h>>=-f,f+=a;f>0;i=256*i+e[t+l],l+=d,f-=8);for(s=i&(1<<-f)-1,i>>=-f,f+=r;f>0;s=256*s+e[t+l],l+=d,f-=8);if(0===i)i=1-c;else{if(i===u)return s?0/0:1/0*(h?-1:1);s+=Math.pow(2,r),i-=c}return(h?-1:1)*s*Math.pow(2,i-r)},n.write=function(e,t,n,r,o,i){var s,a,u,c=8*i-o-1,f=(1<<c)-1,l=f>>1,d=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:i-1,p=r?1:-1,v=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||1/0===t?(a=isNaN(t)?1:0,s=f):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),t+=s+l>=1?d/u:d*Math.pow(2,1-l),t*u>=2&&(s++,u/=2),s+l>=f?(a=0,s=f):s+l>=1?(a=(t*u-1)*Math.pow(2,o),s+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,o),s=0));o>=8;e[n+h]=255&a,h+=p,a/=256,o-=8);for(s=s<<o|a,c+=o;c>0;e[n+h]=255&s,h+=p,s/=256,c-=8);e[n+h-p]|=128*v}},{}],32:[function(e,t){var n=Array.isArray,r=Object.prototype.toString;t.exports=n||function(e){return!!e&&"[object Array]"==r.call(e)}},{}],33:[function(e,t){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function o(e){return"number"==typeof e}function i(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},n.prototype.emit=function(e){var t,n,o,a,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:for(o=arguments.length,a=new Array(o-1),u=1;o>u;u++)a[u-1]=arguments[u];n.apply(this,a)}else if(i(n)){for(o=arguments.length,a=new Array(o-1),u=1;o>u;u++)a[u-1]=arguments[u];for(c=n.slice(),o=c.length,u=0;o>u;u++)c[u].apply(this,a)}return!0},n.prototype.addListener=function(e,t){var o;if(!r(t))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(t.listener)?t.listener:t),this._events[e]?i(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,i(this._events[e])&&!this._events[e].warned){var o;o=s(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,o&&o>0&&this._events[e].length>o&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())}return this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){function n(){this.removeListener(e,n),o||(o=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var o=!1;return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var n,o,s,a;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,o=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(i(n)){for(a=s;a-->0;)if(n[a]===t||n[a].listener&&n[a].listener===t){o=a;break}if(0>o)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.listenerCount=function(e,t){var n;return n=e._events&&e._events[t]?r(e._events[t])?1:e._events[t].length:0}},{}],34:[function(e,t){function n(){}var r=t.exports={};r.nextTick=function(){var e="undefined"!=typeof window&&window.setImmediate,t="undefined"!=typeof window&&window.MutationObserver,n="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};var r=[];if(t){var o=document.createElement("div"),i=new MutationObserver(function(){var e=r.slice();r.length=0,e.forEach(function(e){e()})});return i.observe(o,{attributes:!0}),function(e){r.length||o.setAttribute("yes","no"),r.push(e)}}return n?(window.addEventListener("message",function(e){var t=e.source;if((t===window||null===t)&&"process-tick"===e.data&&(e.stopPropagation(),r.length>0)){var n=r.shift();n()}},!0),function(e){r.push(e),window.postMessage("process-tick","*")}):function(e){setTimeout(e,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=n,r.addListener=n,r.once=n,r.off=n,r.removeListener=n,r.removeAllListeners=n,r.emit=n,r.binding=function(){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(){throw new Error("process.chdir is not supported")}},{}],35:[function(e,t,n){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function o(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var o=0,i=0;return e[0].replace(/%[a-z%]/g,function(e){"%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r),e}function i(){return"object"==typeof console&&"function"==typeof console.log&&Function.prototype.apply.call(console.log,console,arguments)}function s(e){try{null==e?localStorage.removeItem("debug"):localStorage.debug=e}catch(t){}}function a(){var e;try{e=localStorage.debug}catch(t){}return e}n=t.exports=e("./debug"),n.log=i,n.formatArgs=o,n.save=s,n.load=a,n.useColors=r,n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){return JSON.stringify(e)},n.enable(a())},{"./debug":36}],36:[function(e,t,n){function r(){return n.colors[f++%n.colors.length]}function o(e){function t(){}function o(){var e=o,t=+new Date,i=t-(c||t);e.diff=i,e.prev=c,e.curr=t,c=t,null==e.useColors&&(e.useColors=n.useColors()),null==e.color&&e.useColors&&(e.color=r());var s=Array.prototype.slice.call(arguments);s[0]=n.coerce(s[0]),"string"!=typeof s[0]&&(s=["%o"].concat(s));var a=0;s[0]=s[0].replace(/%([a-z%])/g,function(t,r){if("%"===t)return t;a++;var o=n.formatters[r];if("function"==typeof o){var i=s[a];t=o.call(e,i),s.splice(a,1),a--}return t}),"function"==typeof n.formatArgs&&(s=n.formatArgs.apply(e,s));var u=o.log||n.log||console.log.bind(console);u.apply(e,s)}t.enabled=!1,o.enabled=!0;var i=n.enabled(e)?o:t;return i.namespace=e,i}function i(e){n.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;r>o;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function s(){n.enable("")}function a(e){var t,r;for(t=0,r=n.skips.length;r>t;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;r>t;t++)if(n.names[t].test(e))return!0;return!1}function u(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o,n.coerce=u,n.disable=s,n.enable=i,n.enabled=a,n.humanize=e("ms"),n.names=[],n.skips=[],n.formatters={};var c,f=0},{ms:37}],37:[function(e,t){function n(e){var t=/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"y":return n*f;case"days":case"day":case"d":return n*c;case"hours":case"hour":case"h":return n*u;case"minutes":case"minute":case"m":return n*a;case"seconds":case"second":case"s":return n*s;case"ms":return n}}}function r(e){return e>=c?Math.round(e/c)+"d":e>=u?Math.round(e/u)+"h":e>=a?Math.round(e/a)+"m":e>=s?Math.round(e/s)+"s":e+"ms"}function o(e){return i(e,c,"day")||i(e,u,"hour")||i(e,a,"minute")||i(e,s,"second")||e+" ms"}function i(e,t,n){return t>e?void 0:1.5*t>e?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var s=1e3,a=60*s,u=60*a,c=24*u,f=365.25*c;t.exports=function(e,t){return t=t||{},"string"==typeof e?n(e):t.long?o(e):r(e)}},{}],38:[function(e,t){t.exports="function"==typeof Object.create?function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],39:[function(e,t){"use strict";function n(){}t.exports=n},{}],40:[function(e,t){"use strict";function n(e){function t(e,t){function r(e){c[t]=e,++f===n&!u&&(u=!0,a.resolve(d,c))}i(e).then(r,function(e){u||(u=!0,a.reject(d,e))})}if("[object Array]"!==Object.prototype.toString.call(e))return o(new TypeError("must be an array"));var n=e.length,u=!1;if(!n)return i([]);for(var c=new Array(n),f=0,l=-1,d=new r(s);++l<n;)t(e[l],l);return d}var r=e("./promise"),o=e("./reject"),i=e("./resolve"),s=e("./INTERNAL"),a=e("./handlers");t.exports=n},{"./INTERNAL":39,"./handlers":41,"./promise":43,"./reject":46,"./resolve":47}],41:[function(e,t,n){"use strict";function r(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}var o=e("./tryCatch"),i=e("./resolveThenable"),s=e("./states");n.resolve=function(e,t){var a=o(r,t);if("error"===a.status)return n.reject(e,a.value);var u=a.value;if(u)i.safely(e,u);else{e.state=s.FULFILLED,e.outcome=t;for(var c=-1,f=e.queue.length;++c<f;)e.queue[c].callFulfilled(t)}return e},n.reject=function(e,t){e.state=s.REJECTED,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e}},{"./resolveThenable":48,"./states":49,"./tryCatch":50}],42:[function(e,t,n){t.exports=n=e("./promise"),n.resolve=e("./resolve"),n.reject=e("./reject"),n.all=e("./all"),n.race=e("./race")},{"./all":40,"./promise":43,"./race":45,"./reject":46,"./resolve":47}],43:[function(e,t){"use strict";function n(e){if(!(this instanceof n))return new n(e);if("function"!=typeof e)throw new TypeError("reslover must be a function");this.state=s.PENDING,this.queue=[],this.outcome=void 0,e!==o&&i.safely(this,e)}var r=e("./unwrap"),o=e("./INTERNAL"),i=e("./resolveThenable"),s=e("./states"),a=e("./queueItem");t.exports=n,n.prototype["catch"]=function(e){return this.then(null,e)},n.prototype.then=function(e,t){if("function"!=typeof e&&this.state===s.FULFILLED||"function"!=typeof t&&this.state===s.REJECTED)return this;var i=new n(o);if(this.state!==s.PENDING){var u=this.state===s.FULFILLED?e:t;r(i,u,this.outcome)}else this.queue.push(new a(i,e,t));return i}},{"./INTERNAL":39,"./queueItem":44,"./resolveThenable":48,"./states":49,"./unwrap":51}],44:[function(e,t){"use strict";function n(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}var r=e("./handlers"),o=e("./unwrap");t.exports=n,n.prototype.callFulfilled=function(e){r.resolve(this.promise,e)},n.prototype.otherCallFulfilled=function(e){o(this.promise,this.onFulfilled,e)},n.prototype.callRejected=function(e){r.reject(this.promise,e)},n.prototype.otherCallRejected=function(e){o(this.promise,this.onRejected,e)}},{"./handlers":41,"./unwrap":51}],45:[function(e,t){"use strict";function n(e){function t(e){i(e).then(function(e){u||(u=!0,a.resolve(f,e))},function(e){u||(u=!0,a.reject(f,e))})}if("[object Array]"!==Object.prototype.toString.call(e))return o(new TypeError("must be an array"));var n=e.length,u=!1;if(!n)return i([]);for(var c=-1,f=new r(s);++c<n;)t(e[c]);return f}var r=e("./promise"),o=e("./reject"),i=e("./resolve"),s=e("./INTERNAL"),a=e("./handlers");t.exports=n},{"./INTERNAL":39,"./handlers":41,"./promise":43,"./reject":46,"./resolve":47}],46:[function(e,t){"use strict";function n(e){var t=new r(o);return i.reject(t,e)}var r=e("./promise"),o=e("./INTERNAL"),i=e("./handlers");t.exports=n},{"./INTERNAL":39,"./handlers":41,"./promise":43}],47:[function(e,t){"use strict";function n(e){if(e)return e instanceof r?e:i.resolve(new r(o),e);var t=typeof e;switch(t){case"boolean":return s;case"undefined":return u;case"object":return a;case"number":return c;case"string":return f}}var r=e("./promise"),o=e("./INTERNAL"),i=e("./handlers");t.exports=n;var s=i.resolve(new r(o),!1),a=i.resolve(new r(o),null),u=i.resolve(new r(o),void 0),c=i.resolve(new r(o),0),f=i.resolve(new r(o),"")},{"./INTERNAL":39,"./handlers":41,"./promise":43}],48:[function(e,t,n){"use strict";function r(e,t){function n(t){a||(a=!0,o.reject(e,t))}function r(t){a||(a=!0,o.resolve(e,t))}function s(){t(r,n)}var a=!1,u=i(s);"error"===u.status&&n(u.value)}var o=e("./handlers"),i=e("./tryCatch");n.safely=r},{"./handlers":41,"./tryCatch":50}],49:[function(e,t,n){n.REJECTED=["REJECTED"],n.FULFILLED=["FULFILLED"],n.PENDING=["PENDING"]},{}],50:[function(e,t){"use strict";function n(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}t.exports=n},{}],51:[function(e,t){"use strict";function n(e,t,n){r(function(){var r;try{r=t(n)}catch(i){return o.reject(e,i)}r===e?o.reject(e,new TypeError("Cannot resolve promise with itself")):o.resolve(e,r)})}var r=e("immediate"),o=e("./handlers");t.exports=n},{"./handlers":41,immediate:52}],52:[function(e,t){"use strict";function n(){o=!0;for(var e,t,n=a.length;n;){for(t=a,a=[],e=-1;++e<n;)t[e]();n=a.length}o=!1}function r(e){1!==a.push(e)||o||i()}for(var o,i,s=[e("./nextTick"),e("./mutation.js"),e("./messageChannel"),e("./stateChange"),e("./timeout")],a=[],u=-1,c=s.length;++u<c;)if(s[u]&&s[u].test&&s[u].test()){i=s[u].install(n);
-break}t.exports=r},{"./messageChannel":53,"./mutation.js":54,"./nextTick":28,"./stateChange":55,"./timeout":56}],53:[function(e,t,n){(function(e){"use strict";n.test=function(){return e.setImmediate?!1:"undefined"!=typeof e.MessageChannel},n.install=function(t){var n=new e.MessageChannel;return n.port1.onmessage=t,function(){n.port2.postMessage(0)}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],54:[function(e,t,n){(function(e){"use strict";var t=e.MutationObserver||e.WebKitMutationObserver;n.test=function(){return t},n.install=function(n){var r=0,o=new t(n),i=e.document.createTextNode("");return o.observe(i,{characterData:!0}),function(){i.data=r=++r%2}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],55:[function(e,t,n){(function(e){"use strict";n.test=function(){return"document"in e&&"onreadystatechange"in e.document.createElement("script")},n.install=function(t){return function(){var n=e.document.createElement("script");return n.onreadystatechange=function(){t(),n.onreadystatechange=null,n.parentNode.removeChild(n),n=null},e.document.documentElement.appendChild(n),t}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],56:[function(e,t,n){"use strict";n.test=function(){return!0},n.install=function(e){return function(){setTimeout(e,0)}}},{}],57:[function(e,t){"use strict";function n(e){return null===e?String(e):"object"==typeof e||"function"==typeof e?u[d.call(e)]||"object":typeof e}function r(e){return null!==e&&e===e.window}function o(e){if(!e||"object"!==n(e)||e.nodeType||r(e))return!1;try{if(e.constructor&&!h.call(e,"constructor")&&!h.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}var o;for(o in e);return void 0===o||h.call(e,o)}function i(e){return"function"===n(e)}function s(){for(var e=[],t=-1,n=arguments.length,r=new Array(n);++t<n;)r[t]=arguments[t];var o={};e.push({args:r,result:{container:o,key:"key"}});for(var i;i=e.pop();)a(e,i.args,i.result);return o.key}function a(e,t,n){var r,s,a,u,c,f,l,d=t[0]||{},h=1,v=t.length,g=!1,y=/\d+/;for("boolean"==typeof d&&(g=d,d=t[1]||{},h=2),"object"==typeof d||i(d)||(d={}),v===h&&(d=this,--h);v>h;h++)if(null!=(r=t[h])){l=p(r);for(s in r)if(!(s in Object.prototype)){if(l&&!y.test(s))continue;if(a=d[s],u=r[s],d===u)continue;g&&u&&(o(u)||(c=p(u)))?(c?(c=!1,f=a&&p(a)?a:[]):f=a&&o(a)?a:{},e.push({args:[g,f,u],result:{container:d,key:s}})):void 0!==u&&(p(r)&&i(u)||(d[s]=u))}}n.container[n.key]=d}for(var u={},c=["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],f=0;f<c.length;f++){var l=c[f];u["[object "+l+"]"]=l.toLowerCase()}var d=u.toString,h=u.hasOwnProperty,p=Array.isArray||function(e){return"array"===n(e)};t.exports=s},{}],58:[function(e,t){"use strict";var n=e("./upsert"),r=e("./utils"),o=r.Promise;t.exports=function(e){var t=e.db,i=e.viewName,s=e.map,a=e.reduce,u=e.temporary,c=s.toString()+(a&&a.toString())+"undefined";if(!u&&t._cachedViews){var f=t._cachedViews[c];if(f)return o.resolve(f)}return t.info().then(function(e){function o(e){e.views=e.views||{};var t=i;-1===t.indexOf("/")&&(t=i+"/"+i);var n=e.views[t]=e.views[t]||{};if(!n[f])return n[f]=!0,e}var f=e.db_name+"-mrview-"+(u?"temp":r.MD5(c));return n(t,"_local/mrviews",o).then(function(){return t.registerDependentDatabase(f).then(function(e){var n=e.db;n.auto_compaction=!0;var r={name:f,db:n,sourceDB:t,adapter:t.adapter,mapFun:s,reduceFun:a};return r.db.get("_local/lastSeq")["catch"](function(e){if(404!==e.status)throw e}).then(function(e){return r.seq=e?e.seq:0,u||(t._cachedViews=t._cachedViews||{},t._cachedViews[c]=r,r.db.on("destroyed",function(){delete t._cachedViews[c]})),r})})})})}},{"./upsert":64,"./utils":65}],59:[function(_dereq_,module,exports){"use strict";module.exports=function(func,emit,sum,log,isArray,toJSON){return eval("'use strict'; ("+func.replace(/;\s*$/,"")+");")}},{}],60:[function(e,t,n){(function(t){"use strict";function r(e){return-1===e.indexOf("/")?[e,e]:e.split("/")}function o(e,t,n){try{return{output:t.apply(null,n)}}catch(r){return e.emit("error",r),{error:r}}}function i(e,t){var n=A(e.key,t.key);return 0!==n?n:A(e.value,t.value)}function s(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):n>0?e.slice(n):e}function a(e){var t=e.value,n=t&&"object"==typeof t&&t._id||e.id;return n}function u(e){var t=new Error("builtin "+e+" function requires map values to be numbers or number arrays");return t.name="invalid_value",t.status=500,t}function c(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];if("number"!=typeof o){if(!Array.isArray(o))throw u("_sum");t="number"==typeof t?[t]:t;for(var i=0,s=o.length;s>i;i++){var a=o[i];if("number"!=typeof a)throw u("_sum");"undefined"==typeof t[i]?t.push(a):t[i]+=a}}else"number"==typeof t?t+=o:t[0]+=o}return t}function f(e,t,n,r){var o=t[e];"undefined"!=typeof o&&(r&&(o=encodeURIComponent(JSON.stringify(o))),n.push(e+"="+o))}function l(e,t){var n=e.descending?"endkey":"startkey",r=e.descending?"startkey":"endkey";if("undefined"!=typeof e[n]&&"undefined"!=typeof e[r]&&A(e[n],e[r])>0)throw new _("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(t.reduce&&e.reduce!==!1){if(e.include_docs)throw new _("{include_docs:true} is invalid for reduce");if(e.keys&&e.keys.length>1&&!e.group&&!e.group_level)throw new _("Multi-key fetches for reduce views must use {group: true}")}if(e.group_level){if("number"!=typeof e.group_level)throw new _('Invalid value for integer: "'+e.group_level+'"');if(e.group_level<0)throw new _('Invalid value for positive integer: "'+e.group_level+'"')}}function d(e,t,n){var o,i=[],s="GET";if(f("reduce",n,i),f("include_docs",n,i),f("attachments",n,i),f("limit",n,i),f("descending",n,i),f("group",n,i),f("group_level",n,i),f("skip",n,i),f("stale",n,i),f("conflicts",n,i),f("startkey",n,i,!0),f("endkey",n,i,!0),f("inclusive_end",n,i),f("key",n,i,!0),i=i.join("&"),i=""===i?"":"?"+i,"undefined"!=typeof n.keys){var a=2e3,u="keys="+encodeURIComponent(JSON.stringify(n.keys));u.length+i.length+1<=a?i+=("?"===i[0]?"&":"?")+u:(s="POST","string"==typeof t?o=JSON.stringify({keys:n.keys}):t.keys=n.keys)}if("string"==typeof t){var c=r(t);return e.request({method:s,url:"_design/"+c[0]+"/_view/"+c[1]+i,body:o})}return o=o||{},Object.keys(t).forEach(function(e){o[e]=Array.isArray(t[e])?t[e]:t[e].toString()}),e.request({method:"POST",url:"_temp_view"+i,body:o})}function h(e){return function(t){if(404===t.status)return e;throw t}}function p(e,t,n){var r="_local/doc_"+e;return t.db.get(r)["catch"](h({_id:r,keys:[]})).then(function(r){return L.resolve().then(function(){return r.keys.length?t.db.allDocs({keys:r.keys,include_docs:!0}):{rows:[]}}).then(function(t){var o=t.rows.map(function(e){return e.doc}).filter(function(e){return e}),i=n[e],s={};o.forEach(function(e){if(s[e._id]=!0,e._deleted=!i[e._id],!e._deleted){var t=i[e._id];"value"in t&&(e.value=t.value)}});var a=Object.keys(i);return a.forEach(function(e){if(!s[e]){var t={_id:e},n=i[e];"value"in n&&(t.value=n.value),o.push(t)}}),r.keys=q.uniq(a.concat(r.keys)),o.splice(0,0,r),o})})}function v(e,t,n){var r="_local/lastSeq";return e.db.get(r)["catch"](h({_id:r,seq:0})).then(function(r){var o=Object.keys(t);return L.all(o.map(function(n){return p(n,e,t)})).then(function(t){var o=[];return t.forEach(function(e){o=o.concat(e)}),r.seq=n,o.push(r),e.db.bulkDocs({docs:o})})})}function g(e,t,n){0===n.group_level&&delete n.group_level;var r,i=n.group||n.group_level;r=C[e.reduceFun]?C[e.reduceFun]:I(e.reduceFun.toString(),null,c,w,Array.isArray,JSON.parse);var a=[],u=n.group_level;t.forEach(function(e){var t=a[a.length-1],n=i?e.key:null;return i&&Array.isArray(n)&&"number"==typeof u&&(n=n.length>u?n.slice(0,u):n),t&&0===A(t.key[0][0],n)?(t.key.push([n,e.id]),void t.value.push(e.value)):void a.push({key:[[n,e.id]],value:[e.value]})});for(var f=0,l=a.length;l>f;f++){var d=a[f],h=o(e.sourceDB,r,[d.key,d.value,!1]);d.value=h.error?null:h.output,d.key=d.key[0][0]}return{rows:s(a,n.limit,n.skip)}}function y(e){return e.request({method:"POST",url:"_view_cleanup"})}function m(e,n,o){if("http"===e.type())return d(e,n,o);if("string"!=typeof n){l(o,n);var i={db:e,viewName:"temp_view/temp_view",map:n.map,reduce:n.reduce,temporary:!0};return O.add(function(){return x(i).then(function(e){function t(){return e.db.destroy()}return q.fin(N(e).then(function(){return j(e,o)}),t)})}),O.finish()}var s=n,a=r(s),u=a[0],c=a[1];return e.get("_design/"+u).then(function(n){var r=n.views&&n.views[c];if(!r||"string"!=typeof r.map)throw new b("ddoc "+u+" has no view named "+c);l(o,r);var i={db:e,viewName:s,map:r.map,reduce:r.reduce};return x(i).then(function(e){return"ok"===o.stale||"update_after"===o.stale?("update_after"===o.stale&&t.nextTick(function(){N(e)}),j(e,o)):N(e).then(function(){return j(e,o)})})})}function _(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,_)}catch(t){}}function b(e){this.status=404,this.name="not_found",this.message=e,this.error=!0;try{Error.captureStackTrace(this,b)}catch(t){}}var w,E=e("pouchdb-collate"),S=e("./taskqueue"),A=E.collate,k=E.toIndexableString,T=E.normalizeKey,x=e("./create-view"),I=e("./evalfunc");w="undefined"!=typeof console&&"function"==typeof console.log?Function.prototype.bind.call(console.log,console):function(){};var q=e("./utils"),L=q.Promise,R=new S,O=new S,D=50,C={_sum:function(e,t){return c(t)},_count:function(e,t){return t.length},_stats:function(e,t){function n(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];t+=o*o}return t}return{sum:c(t),min:Math.min.apply(null,t),max:Math.max.apply(null,t),count:t.length,sumsqr:n(t)}}},N=q.sequentialize(R,function(e){function t(e,t){var n={id:s._id,key:T(e)};"undefined"!=typeof t&&null!==t&&(n.value=T(t)),r.push(n)}function n(t,n){return function(){return v(e,t,n)}}var r,s,a;if("function"==typeof e.mapFun&&2===e.mapFun.length){var u=e.mapFun;a=function(e){return u(e,t)}}else a=I(e.mapFun.toString(),t,c,w,Array.isArray,JSON.parse);var f=e.seq||0,l=new S;return new L(function(t,u){function c(){l.finish().then(function(){e.seq=f,t()})}function d(){function t(e){u(e)}e.sourceDB.changes({conflicts:!0,include_docs:!0,since:f,limit:D}).on("complete",function(t){var u=t.results;if(!u.length)return c();for(var h={},p=0,v=u.length;v>p;p++){var g=u[p];if("_"!==g.doc._id[0]){r=[],s=g.doc,s._deleted||o(e.sourceDB,a,[s]),r.sort(i);for(var y,m={},_=0,b=r.length;b>_;_++){var w=r[_],E=[w.key,w.id];w.key===y&&E.push(_);var S=k(E);m[S]=w,y=w.key}h[g.doc._id]=m}f=g.seq}return l.add(n(h,f)),u.length<D?c():d()}).on("error",t)}d()})}),j=q.sequentialize(R,function(e,t){function n(t){return t.include_docs=!0,e.db.allDocs(t).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(n>t||t>n))return e.doc.value}var r=E.parseIndexableString(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function r(n){var r;if(r=i?g(e,n,t):{total_rows:o,offset:s,rows:n},t.include_docs){var u=q.uniq(n.map(a));return e.sourceDB.allDocs({keys:u,include_docs:!0,conflicts:t.conflicts,attachments:t.attachments}).then(function(e){var t={};return e.rows.forEach(function(e){e.doc&&(t["$"+e.id]=e.doc)}),n.forEach(function(e){var n=a(e),r=t["$"+n];r&&(e.doc=r)}),r})}return r}var o,i=e.reduceFun&&t.reduce!==!1,s=t.skip||0;"undefined"==typeof t.keys||t.keys.length||(t.limit=0,delete t.keys);var u=function(e){return e.reduce(function(e,t){return e.concat(t)})};if("undefined"!=typeof t.keys){var c=t.keys,f=c.map(function(e){var t={startkey:k([e]),endkey:k([e,{}])};return n(t)});return L.all(f).then(u).then(r)}var l={descending:t.descending};if("undefined"!=typeof t.startkey&&(l.startkey=k(t.descending?[t.startkey,{}]:[t.startkey])),"undefined"!=typeof t.endkey){var d=t.inclusive_end!==!1;t.descending&&(d=!d),l.endkey=k(d?[t.endkey,{}]:[t.endkey])}if("undefined"!=typeof t.key){var h=k([t.key]),p=k([t.key,{}]);l.descending?(l.endkey=h,l.startkey=p):(l.startkey=h,l.endkey=p)}return i||("number"==typeof t.limit&&(l.limit=t.limit),l.skip=s),n(l).then(r)}),B=q.sequentialize(R,function(e){return e.get("_local/mrviews").then(function(t){var n={};Object.keys(t.views).forEach(function(e){var t=r(e),o="_design/"+t[0],i=t[1];n[o]=n[o]||{},n[o][i]=!0});var o={keys:Object.keys(n),include_docs:!0};return e.allDocs(o).then(function(r){var o={};r.rows.forEach(function(e){var r=e.key.substring(8);Object.keys(n[e.key]).forEach(function(n){var i=r+"/"+n;t.views[i]||(i=n);var s=Object.keys(t.views[i]),a=e.doc&&e.doc.views&&e.doc.views[n];s.forEach(function(e){o[e]=o[e]||a})})});var i=Object.keys(o).filter(function(e){return!o[e]}),s=i.map(function(t){return e.constructor.destroy(t,{adapter:e.adapter})});return L.all(s).then(function(){return{ok:!0}})})},h({ok:!0}))});n.viewCleanup=q.callbackify(function(){var e=this;return"http"===e.type()?y(e):B(e)}),n.query=function(e,t,n){"function"==typeof t&&(n=t,t={}),t=q.extend(!0,{},t),"function"==typeof e&&(e={map:e});var r=this,o=L.resolve().then(function(){return m(r,e,t)});return q.promisedCallback(o,n),o},q.inherits(_,Error),q.inherits(b,Error)}).call(this,e("_process"))},{"./create-view":58,"./evalfunc":59,"./taskqueue":63,"./utils":65,_process:34,"pouchdb-collate":61}],61:[function(e,t,n){"use strict";function r(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return f(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),r=t?e:Object.keys(e),o=-1,i=r.length,s="";if(t)for(;++o<i;)s+=n.toIndexableString(r[o]);else for(;++o<i;){var a=r[o];s+=n.toIndexableString(a)+n.toIndexableString(e[a])}return s}return""}function o(e,t){var n,r=t,o="1"===e[t];if(o)n=0,t++;else{var i="0"===e[t];t++;var s="",a=e.substring(t,t+d),u=parseInt(a,10)+l;for(i&&(u=-u),t+=d;;){var c=e[t];if("\x00"===c)break;s+=c,t++}s=s.split("."),n=1===s.length?parseInt(s,10):parseFloat(s[0]+"."+s[1]),i&&(n-=10),0!==u&&(n=parseFloat(n+"e"+u))}return{num:n,length:t-r}}function i(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(n);else if(i===e.length-2){var s=e.pop();o[s]=n}else e.push(n)}}function s(e,t){for(var r=Math.min(e.length,t.length),o=0;r>o;o++){var i=n.collate(e[o],t[o]);if(0!==i)return i}return e.length===t.length?0:e.length>t.length?1:-1}function a(e,t){return e===t?0:e>t?1:-1}function u(e,t){for(var r=Object.keys(e),o=Object.keys(t),i=Math.min(r.length,o.length),s=0;i>s;s++){var a=n.collate(r[s],o[s]);if(0!==a)return a;if(a=n.collate(e[r[s]],t[o[s]]),0!==a)return a}return r.length===o.length?0:r.length>o.length?1:-1}function c(e){var t=["boolean","number","string","object"],n=t.indexOf(typeof e);return~n?null===e?1:Array.isArray(e)?5:3>n?n+2:n+3:Array.isArray(e)?5:void 0}function f(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=0>e,o=r?"0":"2",i=(r?-n:n)-l,s=p.padLeft(i.toString(),"0",d);o+=h+s;var a=Math.abs(parseFloat(t[0]));r&&(a=10-a);var u=a.toFixed(20);return u=u.replace(/\.?0+$/,""),o+=h+u}var l=-324,d=3,h="",p=e("./utils");n.collate=function(e,t){if(e===t)return 0;e=n.normalizeKey(e),t=n.normalizeKey(t);var r=c(e),o=c(t);if(r-o!==0)return r-o;if(null===e)return 0;switch(typeof e){case"number":return e-t;case"boolean":return e===t?0:t>e?-1:1;case"string":return a(e,t)}return Array.isArray(e)?s(e,t):u(e,t)},n.normalizeKey=function(e){switch(typeof e){case"undefined":return null;case"number":return 1/0===e||e===-1/0||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var r=e.length;e=new Array(r);for(var o=0;r>o;o++)e[o]=n.normalizeKey(t[o])}else{if(e instanceof Date)return e.toJSON();if(null!==e){e={};for(var i in t)if(t.hasOwnProperty(i)){var s=t[i];"undefined"!=typeof s&&(e[i]=n.normalizeKey(s))}}}}return e},n.toIndexableString=function(e){var t="\x00";return e=n.normalizeKey(e),c(e)+h+r(e)+t},n.parseIndexableString=function(e){for(var t=[],n=[],r=0;;){var s=e[r++];if("\x00"!==s)switch(s){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var a=o(e,r);t.push(a.num),r+=a.length;break;case"4":for(var u="";;){var c=e[r];if("\x00"===c)break;u+=c,r++}u=u.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(u);break;case"5":var f={element:[],index:t.length};t.push(f.element),n.push(f);break;case"6":var l={element:{},index:t.length};t.push(l.element),n.push(l);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+s)}else{if(1===t.length)return t.pop();i(t,n)}}}},{"./utils":62}],62:[function(e,t,n){"use strict";function r(e,t,n){for(var r="",o=n-e.length;r.length<o;)r+=t;return r}n.padLeft=function(e,t,n){var o=r(e,t,n);return o+e},n.padRight=function(e,t,n){var o=r(e,t,n);return e+o},n.stringLexCompare=function(e,t){var n,r=e.length,o=t.length;for(n=0;r>n;n++){if(n===o)return 1;var i=e.charAt(n),s=t.charAt(n);if(i!==s)return s>i?-1:1}return o>r?-1:0},n.intToDecimalForm=function(e){var t=0>e,n="";do{var r=t?-Math.ceil(e%10):Math.floor(e%10);n=r+n,e=t?Math.ceil(e/10):Math.floor(e/10)}while(e);return t&&"0"!==n&&(n="-"+n),n}},{}],63:[function(e,t){"use strict";function n(){this.promise=new r(function(e){e()})}var r=e("./utils").Promise;n.prototype.add=function(e){return this.promise=this.promise["catch"](function(){}).then(function(){return e()}),this.promise},n.prototype.finish=function(){return this.promise},t.exports=n},{"./utils":65}],64:[function(e,t){"use strict";function n(e,t,n){return new o(function(o,i){return t&&"object"==typeof t&&(t=t._id),"string"!=typeof t?i(new Error("doc id is required")):void e.get(t,function(s,a){if(s)return 404!==s.status?i(s):o(r(e,n({_id:t}),n));var u=n(a);return u?void o(r(e,u,n)):o(a)})})}function r(e,t,r){return e.put(t)["catch"](function(o){if(409!==o.status)throw o;return n(e,t,r)})}var o=e("./utils").Promise;t.exports=n},{"./utils":65}],65:[function(e,t,n){(function(t,r){"use strict";n.Promise="function"==typeof r.Promise?r.Promise:e("lie"),n.inherits=e("inherits"),n.extend=e("pouchdb-extend");var o=e("argsarray");n.promisedCallback=function(e,n){return n&&e.then(function(e){t.nextTick(function(){n(null,e)})},function(e){t.nextTick(function(){n(e)})}),e},n.callbackify=function(e){return o(function(t){var r=t.pop(),o=e.apply(this,t);return"function"==typeof r&&n.promisedCallback(o,r),o})},n.fin=function(e,t){return e.then(function(e){var n=t();return"function"==typeof n.then?n.then(function(){return e}):e},function(e){var n=t();if("function"==typeof n.then)return n.then(function(){throw e});throw e})},n.sequentialize=function(e,t){return function(){var n=arguments,r=this;return e.add(function(){return t.apply(r,n)})}},n.uniq=function(e){for(var t={},n=0,r=e.length;r>n;n++)t["$"+e[n]]=!0;var o=Object.keys(t),i=new Array(o.length);for(n=0,r=o.length;r>n;n++)i[n]=o[n].substring(1);return i};var i=e("crypto"),s=e("spark-md5");n.MD5=function(e){return t.browser?s.hash(e):i.createHash("md5").update(e).digest("hex")}}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{_process:34,argsarray:27,crypto:28,inherits:38,lie:42,"pouchdb-extend":57,"spark-md5":66}],66:[function(e,t,n){!function(e){if("object"==typeof n)t.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;try{r=window}catch(o){r=self}r.SparkMD5=e()}}(function(){"use strict";var e=function(e,t){return e+t&4294967295},t=function(t,n,r,o,i,s){return n=e(e(n,t),e(o,s)),e(n<<i|n>>>32-i,r)},n=function(e,n,r,o,i,s,a){return t(n&r|~n&o,e,n,i,s,a)},r=function(e,n,r,o,i,s,a){return t(n&o|r&~o,e,n,i,s,a)},o=function(e,n,r,o,i,s,a){return t(n^r^o,e,n,i,s,a)},i=function(e,n,r,o,i,s,a){return t(r^(n|~o),e,n,i,s,a)},s=function(t,s){var a=t[0],u=t[1],c=t[2],f=t[3];a=n(a,u,c,f,s[0],7,-680876936),f=n(f,a,u,c,s[1],12,-389564586),c=n(c,f,a,u,s[2],17,606105819),u=n(u,c,f,a,s[3],22,-1044525330),a=n(a,u,c,f,s[4],7,-176418897),f=n(f,a,u,c,s[5],12,1200080426),c=n(c,f,a,u,s[6],17,-1473231341),u=n(u,c,f,a,s[7],22,-45705983),a=n(a,u,c,f,s[8],7,1770035416),f=n(f,a,u,c,s[9],12,-1958414417),c=n(c,f,a,u,s[10],17,-42063),u=n(u,c,f,a,s[11],22,-1990404162),a=n(a,u,c,f,s[12],7,1804603682),f=n(f,a,u,c,s[13],12,-40341101),c=n(c,f,a,u,s[14],17,-1502002290),u=n(u,c,f,a,s[15],22,1236535329),a=r(a,u,c,f,s[1],5,-165796510),f=r(f,a,u,c,s[6],9,-1069501632),c=r(c,f,a,u,s[11],14,643717713),u=r(u,c,f,a,s[0],20,-373897302),a=r(a,u,c,f,s[5],5,-701558691),f=r(f,a,u,c,s[10],9,38016083),c=r(c,f,a,u,s[15],14,-660478335),u=r(u,c,f,a,s[4],20,-405537848),a=r(a,u,c,f,s[9],5,568446438),f=r(f,a,u,c,s[14],9,-1019803690),c=r(c,f,a,u,s[3],14,-187363961),u=r(u,c,f,a,s[8],20,1163531501),a=r(a,u,c,f,s[13],5,-1444681467),f=r(f,a,u,c,s[2],9,-51403784),c=r(c,f,a,u,s[7],14,1735328473),u=r(u,c,f,a,s[12],20,-1926607734),a=o(a,u,c,f,s[5],4,-378558),f=o(f,a,u,c,s[8],11,-2022574463),c=o(c,f,a,u,s[11],16,1839030562),u=o(u,c,f,a,s[14],23,-35309556),a=o(a,u,c,f,s[1],4,-1530992060),f=o(f,a,u,c,s[4],11,1272893353),c=o(c,f,a,u,s[7],16,-155497632),u=o(u,c,f,a,s[10],23,-1094730640),a=o(a,u,c,f,s[13],4,681279174),f=o(f,a,u,c,s[0],11,-358537222),c=o(c,f,a,u,s[3],16,-722521979),u=o(u,c,f,a,s[6],23,76029189),a=o(a,u,c,f,s[9],4,-640364487),f=o(f,a,u,c,s[12],11,-421815835),c=o(c,f,a,u,s[15],16,530742520),u=o(u,c,f,a,s[2],23,-995338651),a=i(a,u,c,f,s[0],6,-198630844),f=i(f,a,u,c,s[7],10,1126891415),c=i(c,f,a,u,s[14],15,-1416354905),u=i(u,c,f,a,s[5],21,-57434055),a=i(a,u,c,f,s[12],6,1700485571),f=i(f,a,u,c,s[3],10,-1894986606),c=i(c,f,a,u,s[10],15,-1051523),u=i(u,c,f,a,s[1],21,-2054922799),a=i(a,u,c,f,s[8],6,1873313359),f=i(f,a,u,c,s[15],10,-30611744),c=i(c,f,a,u,s[6],15,-1560198380),u=i(u,c,f,a,s[13],21,1309151649),a=i(a,u,c,f,s[4],6,-145523070),f=i(f,a,u,c,s[11],10,-1120210379),c=i(c,f,a,u,s[2],15,718787259),u=i(u,c,f,a,s[9],21,-343485551),t[0]=e(a,t[0]),t[1]=e(u,t[1]),t[2]=e(c,t[2]),t[3]=e(f,t[3])},a=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n},u=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n},c=function(e){var t,n,r,o,i,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)s(f,a(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(s(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),u=parseInt(o[1],16)||0,r[14]=i,r[15]=u,s(f,r),f},f=function(e){var t,n,r,o,i,a,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)s(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(s(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),a=parseInt(o[1],16)||0,r[14]=i,r[15]=a,s(f,r),f},l=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"],d=function(e){var t,n="";for(t=0;4>t;t+=1)n+=l[e>>8*t+4&15]+l[e>>8*t&15];return n},h=function(e){var t;for(t=0;t<e.length;t+=1)e[t]=d(e[t]);return e.join("")},p=function(e){return h(c(e))},v=function(){this.reset()};return"5d41402abc4b2a76b9719d911017c592"!==p("hello")&&(e=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),v.prototype.append=function(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),this.appendBinary(e),this},v.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)s(this._state,a(this._buff.substring(t-64,t)));return this._buff=this._buff.substr(t-64),this},v.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(i,o),n=e?this._state:h(this._state),this.reset(),n},v.prototype._finish=function(e,t){var n,r,o,i=t;if(e[i>>2]|=128<<(i%4<<3),i>55)for(s(this._state,e),i=0;16>i;i+=1)e[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),o=parseInt(n[1],16)||0,e[14]=r,e[15]=o,s(this._state,e)},v.prototype.reset=function(){return this._buff="",this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},v.prototype.destroy=function(){delete this._state,delete this._buff,delete this._length},v.hash=function(e,t){/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e)));var n=c(e);return t?n:h(n)},v.hashBinary=function(e,t){var n=c(e);return t?n:h(n)},v.ArrayBuffer=function(){this.reset()},v.ArrayBuffer.prototype.append=function(e){var t,n=this._concatArrayBuffer(this._buff,e),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)s(this._state,u(n.subarray(t-64,t)));return this._buff=r>t-64?n.subarray(t-64):new Uint8Array(0),this},v.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r[t]<<(t%4<<3);return this._finish(i,o),n=e?this._state:h(this._state),this.reset(),n},v.ArrayBuffer.prototype._finish=v.prototype._finish,v.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},v.ArrayBuffer.prototype.destroy=v.prototype.destroy,v.ArrayBuffer.prototype._concatArrayBuffer=function(e,t){var n=e.length,r=new Uint8Array(n+t.byteLength);return r.set(e),r.set(new Uint8Array(t),n),r},v.ArrayBuffer.hash=function(e,t){var n=f(new Uint8Array(e));return t?n:h(n)},v})},{}],67:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(e);else if(i===t.length-2){var s=t.pop();o[s]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,o,i,s,a,u,c,f,l,d,h="";n=t.pop();)if(r=n.obj,o=n.prefix||"",i=n.val||"",h+=o,i)h+=i;else if("object"!=typeof r)h+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)h+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),s=r.length-1;s>=0;s--)a=0===s?"":",",t.push({obj:r[s],prefix:a});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),s=u.length-1;s>=0;s--)f=u[s],l=r[f],d=s>0?",":"",d+=JSON.stringify(f)+":",t.push({obj:l,prefix:d});t.push({val:"{"})}return h},n.parse=function(e){for(var t,n,o,i,s,a,u,c,f,l=[],d=[],h=0;;)if(t=e[h++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":h+=3,r(null,l,d);break;case"t":h+=3,r(!0,l,d);break;case"f":h+=4,r(!1,l,d);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",h--;;){if(o=e[h++],!/[\d\.\-e\+]/.test(o)){h--;break}n+=o}r(parseFloat(n),l,d);break;case'"':for(i="",s=void 0,a=0;;){if(u=e[h++],'"'===u&&("\\"!==s||a%2!==1))break;i+=u,s=u,"\\"===s?a++:a=0}r(JSON.parse('"'+i+'"'),l,d);break;case"[":c={element:[],index:l.length},l.push(c.element),d.push(c);break;case"{":f={element:{},index:l.length},l.push(f.element),d.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,d)}}},{}],68:[function(e,t){(function(n){"use strict";var r=e("./setup");t.exports=r,r.ajax=e("./deps/ajax"),r.extend=e("pouchdb-extend"),r.utils=e("./utils"),r.Errors=e("./deps/errors"),r.replicate=e("./replicate").replicate,r.sync=e("./sync"),r.version=e("./version");var o=e("./adapters/http");if(r.adapter("http",o),r.adapter("https",o),r.adapter("idb",e("./adapters/idb")),r.adapter("websql",e("./adapters/websql")),r.plugin(e("pouchdb-mapreduce")),!n.browser){var i=e("./adapters/leveldb");r.adapter("ldb",i),r.adapter("leveldb",i)}}).call(this,e("_process"))},{"./adapters/http":2,"./adapters/idb":3,"./adapters/leveldb":28,"./adapters/websql":5,"./deps/ajax":9,"./deps/errors":12,"./replicate":21,"./setup":22,"./sync":23,"./utils":25,"./version":26,_process:34,"pouchdb-extend":57,"pouchdb-mapreduce":60}]},{},[68])(68)});
\ No newline at end of file
diff --git a/tests/integration/deps/pouchdb-3.6.0-postfixed.js b/tests/integration/deps/pouchdb-3.6.0-postfixed.js
deleted file mode 100644
index 31848de..0000000
--- a/tests/integration/deps/pouchdb-3.6.0-postfixed.js
+++ /dev/null
@@ -1,11 +0,0 @@
-//    PouchDBVersion360 3.6.0
-//    
-//    (c) 2012-2015 Dale Harvey and the PouchDBVersion360 team
-//    PouchDBVersion360 may be freely distributed under the Apache license, version 2.0.
-//    For all details and documentation:
-//    http://pouchdb.com
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.PouchDBVersion360=e()}}(function(){var define,module,exports;return function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t,n){(function(n){"use strict";function r(e,t){for(var n=0;n<e.length;n++)if(t(e[n],n)===!0)return e[n];return!1}function o(e){return function(t,n){t||n[0]&&n[0].error?e(t||n[0]):e(null,n.length?n[0]:n)}}function i(e){for(var t=0;t<e.length;t++){var n=e[t];if(n._deleted)delete n._attachments;else if(n._attachments)for(var r=Object.keys(n._attachments),o=0;o<r.length;o++){var i=r[o];n._attachments[i]=l.pick(n._attachments[i],["data","digest","content_type","revpos","stub"])}}}function s(e,t){var n=l.compare(e._id,t._id);if(0!==n)return n;var r=e._revisions?e._revisions.start:0,o=t._revisions?t._revisions.start:0;return l.compare(r,o)}function a(e){var t={},n=[];return d.traverseRevTree(e,function(e,r,o,i){var s=r+"-"+o;return e&&(t[s]=0),void 0!==i&&n.push({from:i,to:s}),s}),n.reverse(),n.forEach(function(e){void 0===t[e.from]?t[e.from]=1+t[e.to]:t[e.from]=Math.min(t[e.from],1+t[e.to])}),t}function c(e,t,n){var r="limit"in t?t.keys.slice(t.skip,t.limit+t.skip):t.skip>0?t.keys.slice(t.skip):t.keys;if(t.descending&&r.reverse(),!r.length)return e._allDocs({limit:0},n);var o={offset:t.skip};return _.all(r.map(function(n){var r=l.extend(!0,{key:n,deleted:"ok"},t);return["limit","skip","keys"].forEach(function(e){delete r[e]}),new _(function(t,i){e._allDocs(r,function(e,r){return e?i(e):(o.total_rows=r.total_rows,void t(r.rows[0]||{key:n,error:"not_found"}))})})})).then(function(e){return o.rows=e,o})}function u(e){var t=e._compactionQueue[0],r=t.opts,o=t.callback;e.get("_local/compaction")["catch"](function(){return!1}).then(function(t){t&&t.last_seq&&(r.last_seq=t.last_seq),e._compact(r,function(t,r){t?o(t):o(null,r),n.nextTick(function(){e._compactionQueue.shift(),e._compactionQueue.length&&u(e)})})})}function f(){h.call(this)}var l=e(48),d=e(37),p=e(24),h=e(52).EventEmitter,v=e(33),m=e(13),_=l.Promise;l.inherits(f,h),t.exports=f,f.prototype.post=l.adapterFun("post",function(e,t,n){return"function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e)?n(p.error(p.NOT_AN_OBJECT)):void this.bulkDocs({docs:[e]},t,o(n))}),f.prototype.put=l.adapterFun("put",l.getArguments(function(e){var t,n,r,i,s=e.shift(),a="_id"in s;if("object"!=typeof s||Array.isArray(s))return(i=e.pop())(p.error(p.NOT_AN_OBJECT));for(s=l.clone(s);;)if(t=e.shift(),n=typeof t,"string"!==n||a?"string"!==n||!a||"_rev"in s?"object"===n?r=t:"function"===n&&(i=t):s._rev=t:(s._id=t,a=!0),!e.length)break;r=r||{};var c=l.invalidIdError(s._id);return c?i(c):l.isLocalId(s._id)&&"function"==typeof this._putLocal?s._deleted?this._removeLocal(s,i):this._putLocal(s,i):void this.bulkDocs({docs:[s]},r,o(i))})),f.prototype.putAttachment=l.adapterFun("putAttachment",function(e,t,n,r,o,i){function s(e){return e._attachments=e._attachments||{},e._attachments[t]={content_type:o,data:r},a.put(e)}var a=this;return"function"==typeof o&&(i=o,o=r,r=n,n=null),"undefined"==typeof o&&(o=r,r=n,n=null),a.get(e).then(function(e){if(e._rev!==n)throw p.error(p.REV_CONFLICT);return s(e)},function(t){if(t.reason===p.MISSING_DOC.message)return s({_id:e});throw t})}),f.prototype.removeAttachment=l.adapterFun("removeAttachment",function(e,t,n,r){var o=this;o.get(e,function(e,i){return e?void r(e):i._rev!==n?void r(p.error(p.REV_CONFLICT)):i._attachments?(delete i._attachments[t],0===Object.keys(i._attachments).length&&delete i._attachments,void o.put(i,r)):r()})}),f.prototype.remove=l.adapterFun("remove",function(e,t,n,r){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof n&&(r=n,n={})):(i=e,"function"==typeof t?(r=t,n={}):(r=n,n=t)),n=l.clone(n||{}),n.was_delete=!0;var s={_id:i._id,_rev:i._rev||n.rev};return s._deleted=!0,l.isLocalId(s._id)&&"function"==typeof this._removeLocal?this._removeLocal(i,r):void this.bulkDocs({docs:[s]},n,o(r))}),f.prototype.revsDiff=l.adapterFun("revsDiff",function(e,t,n){function r(e,t){a.has(e)||a.set(e,{missing:[]}),a.get(e).missing.push(t)}function o(t,n){var o=e[t].slice(0);d.traverseRevTree(n,function(e,n,i,s,a){var c=n+"-"+i,u=o.indexOf(c);-1!==u&&(o.splice(u,1),"available"!==a.status&&r(t,c))}),o.forEach(function(e){r(t,e)})}"function"==typeof t&&(n=t,t={}),t=l.clone(t);var i=Object.keys(e);if(!i.length)return n(null,{});var s=0,a=new l.Map;i.map(function(t){this._getRevisionTree(t,function(r,c){if(r&&404===r.status&&"missing"===r.message)a.set(t,{missing:e[t]});else{if(r)return n(r);o(t,c)}if(++s===i.length){var u={};return a.forEach(function(e,t){u[t]=e}),n(null,u)}})},this)}),f.prototype.compactDocument=l.adapterFun("compactDocument",function(e,t,n){var r=this;this._getRevisionTree(e,function(o,i){if(o)return n(o);var s=a(i),c=[],u=[];Object.keys(s).forEach(function(e){s[e]>t&&c.push(e)}),d.traverseRevTree(i,function(e,t,n,r,o){var i=t+"-"+n;"available"===o.status&&-1!==c.indexOf(i)&&u.push(i)}),r._doCompaction(e,u,n)})}),f.prototype.compact=l.adapterFun("compact",function(e,t){"function"==typeof e&&(t=e,e={});var n=this;e=l.clone(e||{}),n._compactionQueue=n._compactionQueue||[],n._compactionQueue.push({opts:e,callback:t}),1===n._compactionQueue.length&&u(n)}),f.prototype._compact=function(e,t){function n(e){s.push(o.compactDocument(e.id,0))}function r(e){var n=e.last_seq;_.all(s).then(function(){return v(o,"_local/compaction",function(e){return!e.last_seq||e.last_seq<n?(e.last_seq=n,e):!1})}).then(function(){t(null,{ok:!0})})["catch"](t)}var o=this,i={returnDocs:!1,last_seq:e.last_seq||0},s=[];o.changes(i).on("change",n).on("complete",r).on("error",t)},f.prototype.get=l.adapterFun("get",function(e,t,n){function o(){var r=[],o=i.length;return o?void i.forEach(function(i){s.get(e,{rev:i,revs:t.revs,attachments:t.attachments},function(e,t){e?r.push({missing:i}):r.push({ok:t}),o--,o||n(null,r)})}):n(null,r)}if("function"==typeof t&&(n=t,t={}),"string"!=typeof e)return n(p.error(p.INVALID_ID));if(l.isLocalId(e)&&"function"==typeof this._getLocal)return this._getLocal(e,n);var i=[],s=this;if(!t.open_revs)return this._get(e,t,function(e,o){if(t=l.clone(t),e)return n(e);var i=o.doc,a=o.metadata,c=o.ctx;if(t.conflicts){var u=d.collectConflicts(a);u.length&&(i._conflicts=u)}if(l.isDeleted(a,i._rev)&&(i._deleted=!0),t.revs||t.revs_info){var f=d.rootToLeaf(a.rev_tree),p=r(f,function(e){return-1!==e.ids.map(function(e){return e.id}).indexOf(i._rev.split("-")[1])}),h=p.ids.map(function(e){return e.id}).indexOf(i._rev.split("-")[1])+1,v=p.ids.length-h;if(p.ids.splice(h,v),p.ids.reverse(),t.revs&&(i._revisions={start:p.pos+p.ids.length-1,ids:p.ids.map(function(e){return e.id})}),t.revs_info){var m=p.pos+p.ids.length;i._revs_info=p.ids.map(function(e){return m--,{rev:m+"-"+e.id,status:e.opts.status}})}}if(t.local_seq&&(l.info('The "local_seq" option is deprecated and will be removed'),i._local_seq=o.metadata.seq),t.attachments&&i._attachments){var _=i._attachments,g=Object.keys(_).length;if(0===g)return n(null,i);Object.keys(_).forEach(function(e){this._getAttachment(_[e],{encode:!0,ctx:c},function(t,r){var o=i._attachments[e];o.data=r,delete o.stub,delete o.length,--g||n(null,i)})},s)}else{if(i._attachments)for(var y in i._attachments)i._attachments.hasOwnProperty(y)&&(i._attachments[y].stub=!0);n(null,i)}});if("all"===t.open_revs)this._getRevisionTree(e,function(e,t){return e?n(e):(i=d.collectLeaves(t).map(function(e){return e.rev}),void o())});else{if(!Array.isArray(t.open_revs))return n(p.error(p.UNKNOWN_ERROR,"function_clause"));i=t.open_revs;for(var a=0;a<i.length;a++){var c=i[a];if("string"!=typeof c||!/^\d+-/.test(c))return n(p.error(p.INVALID_REV))}o()}}),f.prototype.getAttachment=l.adapterFun("getAttachment",function(e,t,n,r){var o=this;n instanceof Function&&(r=n,n={}),n=l.clone(n),this._get(e,n,function(e,i){return e?r(e):i.doc._attachments&&i.doc._attachments[t]?(n.ctx=i.ctx,void o._getAttachment(i.doc._attachments[t],n,r)):r(p.error(p.MISSING_DOC))})}),f.prototype.allDocs=l.adapterFun("allDocs",function(e,t){if("function"==typeof e&&(t=e,e={}),e=l.clone(e),e.skip="undefined"!=typeof e.skip?e.skip:0,"keys"in e){if(!Array.isArray(e.keys))return t(new TypeError("options.keys must be an array"));var n=["startkey","endkey","key"].filter(function(t){return t in e})[0];if(n)return void t(p.error(p.QUERY_PARSE_ERROR,"Query parameter `"+n+"` is not compatible with multi-get"));if("http"!==this.type())return c(this,e,t)}return this._allDocs(e,t)}),f.prototype.changes=function(e,t){return"function"==typeof e&&(t=e,e={}),new m(this,e,t)},f.prototype.close=l.adapterFun("close",function(e){return this._closed=!0,this._close(e)}),f.prototype.info=l.adapterFun("info",function(e){var t=this;this._info(function(n,r){return n?e(n):(r.db_name=r.db_name||t._db_name,r.auto_compaction=!(!t.auto_compaction||"http"===t.type()),void e(null,r))})}),f.prototype.id=l.adapterFun("id",function(e){return this._id(e)}),f.prototype.type=function(){return"function"==typeof this._type?this._type():this.adapter},f.prototype.bulkDocs=l.adapterFun("bulkDocs",function(e,t,n){if("function"==typeof t&&(n=t,t={}),t=l.clone(t),Array.isArray(e)&&(e={docs:e}),!e||!e.docs||!Array.isArray(e.docs))return n(p.error(p.MISSING_BULK_DOCS));for(var r=0;r<e.docs.length;++r)if("object"!=typeof e.docs[r]||Array.isArray(e.docs[r]))return n(p.error(p.NOT_AN_OBJECT));return e=l.clone(e),"new_edits"in t||("new_edits"in e?t.new_edits=e.new_edits:t.new_edits=!0),t.new_edits||"http"===this.type()||e.docs.sort(s),i(e.docs),this._bulkDocs(e,t,function(e,r){return e?n(e):(t.new_edits||(r=r.filter(function(e){return e.error})),void n(null,r))})}),f.prototype.registerDependentDatabase=l.adapterFun("registerDependentDatabase",function(e,t){function n(t){return t.dependentDbs=t.dependentDbs||{},t.dependentDbs[e]?!1:(t.dependentDbs[e]=!0,t)}var r=new this.constructor(e,this.__opts);v(this,"_local/_pouch_dependentDbs",n,function(e){return e?t(e):t(null,{db:r})})}),f.prototype.destroy=l.adapterFun("destroy",function(e){function t(){n._destroy(function(t,r){return t?e(t):(n.emit("destroyed"),void e(null,r||{ok:!0}))})}var n=this,r="use_prefix"in n?n.use_prefix:!0;n.get("_local/_pouch_dependentDbs",function(o,i){if(o)return 404!==o.status?e(o):t();var s=i.dependentDbs,a=n.constructor,c=Object.keys(s).map(function(e){var t=r?e.replace(new RegExp("^"+a.prefix),""):e;return new a(t,n.__opts).destroy()});_.all(c).then(t,function(t){e(t)})})})}).call(this,e(53))},{13:13,24:24,33:33,37:37,48:48,52:52,53:53}],2:[function(e,t,n){(function(n){"use strict";function r(e){return w?new v(function(t){d(e,function(e){t(g(e))})}):v.resolve(e.toString("base64"))}function o(e){return/^_design/.test(e)?"_design/"+encodeURIComponent(e.slice(8)):/^_local/.test(e)?"_local/"+encodeURIComponent(e.slice(7)):encodeURIComponent(e)}function i(e){return e._attachments&&Object.keys(e._attachments)?v.all(Object.keys(e._attachments).map(function(t){var n=e._attachments[t];return n.data&&"string"!=typeof n.data?r(n.data).then(function(e){n.data=e}):void 0})):v.resolve()}function s(e,t){if(/http(s?):/.test(e)){var n=h.parseUri(e);n.remote=!0,(n.user||n.password)&&(n.auth={username:n.user,password:n.password});var r=n.path.replace(/(^\/|\/$)/g,"").split("/");if(n.db=r.pop(),n.path=r.join("/"),t=t||{},t=m(t),n.headers=t.headers||t.ajax&&t.ajax.headers||{},t.auth||n.auth){var o=t.auth||n.auth,i=g(o.username+":"+o.password);n.headers.Authorization="Basic "+i}return t.headers&&(n.headers=t.headers),n}return{host:"",path:"/",db:e,auth:!1}}function a(e,t){return c(e,e.db+"/"+t)}function c(e,t){if(e.remote){var n=e.path?"/":"";return e.protocol+"://"+e.host+":"+e.port+"/"+e.path+n+t}return"/"+t}function u(e,t){function n(e,t){var n=h.extend(!0,m(O),e);return E(n.method+" "+n.url),h.ajax(n,t)}function u(e){return new v(function(t,r){n(e,function(e,n){return e?r(e):void t(n)})})}function d(e){return e.split("/").map(encodeURIComponent).join("/")}var _=this;_.getHost=e.getHost?e.getHost:s;var g=_.getHost(e.name,e),x=a(g,"");_.getUrl=function(){return x},_.getHeaders=function(){return m(g.headers)};var O=e.ajax||{};e=m(e);var A=function(){n({headers:m(g.headers),method:"PUT",url:x},function(e){e&&401===e.status?n({headers:m(g.headers),method:"HEAD",url:x},function(e){e?t(e):t(null,_)}):e&&412!==e.status?t(e):t(null,_)})};e.skipSetup||n({headers:m(g.headers),method:"GET",url:x},function(e){e?404===e.status?(h.explain404("PouchDBVersion360 is just detecting if the remote DB exists."),A()):t(e):t(null,_)}),_.type=function(){return"http"},_.id=h.adapterFun("id",function(e){n({headers:m(g.headers),method:"GET",url:c(g,"")},function(t,n){if(t)return e(t);var r=n&&n.uuid?n.uuid+g.db:a(g,"");e(null,r)})}),_.request=h.adapterFun("request",function(e,t){e.headers=g.headers,e.url=a(g,e.url),n(e,t)}),_.compact=h.adapterFun("compact",function(e,t){"function"==typeof e&&(t=e,e={}),e=m(e),n({headers:m(g.headers),url:a(g,"_compact"),method:"POST"},function(){function n(){_.info(function(r,o){o.compact_running?setTimeout(n,e.interval||200):t(null,{ok:!0})})}"function"==typeof t&&n()})}),_._info=function(e){n({headers:m(g.headers),method:"GET",url:a(g,"")},function(t,n){t?e(t):(n.host=a(g,""),e(null,n))})},_.get=h.adapterFun("get",function(e,t,n){function i(e){var t=e._attachments,n=t&&Object.keys(t);return t&&n.length?v.all(n.map(function(n){var i=t[n],s=o(e._id)+"/"+d(n)+"?rev="+e._rev;return u({headers:m(g.headers),method:"GET",url:a(g,s),binary:!0}).then(r).then(function(e){delete i.stub,delete i.length,i.data=e})})):void 0}function s(e){return Array.isArray(e)?v.all(e.map(function(e){return e.ok?i(e.ok):void 0})):i(e)}"function"==typeof t&&(n=t,t={}),t=m(t);var c=[];t.revs&&c.push("revs=true"),t.revs_info&&c.push("revs_info=true"),t.local_seq&&c.push("local_seq=true"),t.open_revs&&("all"!==t.open_revs&&(t.open_revs=JSON.stringify(t.open_revs)),c.push("open_revs="+t.open_revs)),t.rev&&c.push("rev="+t.rev),t.conflicts&&c.push("conflicts="+t.conflicts),c=c.join("&"),c=""===c?"":"?"+c,e=o(e);var f={headers:m(g.headers),method:"GET",url:a(g,e+c)},l=t.ajax||{};h.extend(!0,f,l),u(f).then(function(e){return v.resolve().then(function(){return t.attachments?s(e):void 0}).then(function(){n(null,e)})})["catch"](n)}),_.remove=h.adapterFun("remove",function(e,t,r,i){var s;"string"==typeof t?(s={_id:e,_rev:t},"function"==typeof r&&(i=r,r={})):(s=e,"function"==typeof t?(i=t,r={}):(i=r,r=t));var c=s._rev||r.rev;n({headers:m(g.headers),method:"DELETE",url:a(g,o(s._id))+"?rev="+c},i)}),_.getAttachment=h.adapterFun("getAttachment",function(e,t,r,i){"function"==typeof r&&(i=r,r={});var s=r.rev?"?rev="+r.rev:"",c=a(g,o(e))+"/"+d(t)+s;n({headers:m(g.headers),method:"GET",url:c,binary:!0},i)}),_.removeAttachment=h.adapterFun("removeAttachment",function(e,t,r,i){var s=a(g,o(e)+"/"+d(t))+"?rev="+r;n({headers:m(g.headers),method:"DELETE",url:s},i)}),_.putAttachment=h.adapterFun("putAttachment",function(e,t,r,i,s,c){"function"==typeof s&&(c=s,s=i,i=r,r=null),"undefined"==typeof s&&(s=i,i=r,r=null);var u=o(e)+"/"+d(t),f=a(g,u);if(r&&(f+="?rev="+r),"string"==typeof i){var l;try{l=y(i)}catch(h){return c(b.error(b.BAD_ARG,"Attachments need to be base64 encoded"))}i=w?p(l,s):l?new S(l,"binary"):""}var v={headers:m(g.headers),method:"PUT",url:f,processData:!1,body:i,timeout:6e4};v.headers["Content-Type"]=s,n(v,c)}),_.put=h.adapterFun("put",h.getArguments(function(e){var t,n,r,s=e.shift(),c="_id"in s,f=e.pop();return"object"!=typeof s||Array.isArray(s)?f(b.error(b.NOT_AN_OBJECT)):(s=m(s),void i(s).then(function(){for(;;)if(t=e.shift(),n=typeof t,"string"!==n||c?"string"!==n||!c||"_rev"in s?"object"===n&&(r=m(t)):s._rev=t:(s._id=t,c=!0),!e.length)break;r=r||{};var i=h.invalidIdError(s._id);if(i)throw i;var l=[];r&&"undefined"!=typeof r.new_edits&&l.push("new_edits="+r.new_edits),l=l.join("&"),""!==l&&(l="?"+l);var d={headers:m(g.headers),method:"PUT",url:a(g,o(s._id))+l,body:s};return v.resolve().then(function(){var e=s._attachments&&Object.keys(s._attachments).filter(function(e){return!s._attachments[e].stub}).length;if(e){var t=T(s);d.body=t.body,d.processData=!1,d.headers=h.extend(d.headers,t.headers)}})["catch"](function(){throw new Error("Did you forget to base64-encode an attachment?")}).then(function(){return u(d)}).then(function(e){e.ok=!0,f(null,e)})})["catch"](f))})),_.post=h.adapterFun("post",function(e,t,n){return"function"==typeof t&&(n=t,t={}),t=m(t),"object"!=typeof e?n(b.error(b.NOT_AN_OBJECT)):("_id"in e||(e._id=h.uuid()),void _.put(e,t,function(e,t){return e?n(e):(t.ok=!0,void n(null,t))}))}),_._bulkDocs=function(e,t,r){"undefined"!=typeof t.new_edits&&(e.new_edits=t.new_edits),v.all(e.docs.map(i)).then(function(){n({headers:m(g.headers),method:"POST",url:a(g,"_bulk_docs"),body:e},function(e,t){return e?r(e):(t.forEach(function(e){e.ok=!0}),void r(null,t))})})["catch"](r)},_.allDocs=h.adapterFun("allDocs",function(e,t){"function"==typeof e&&(t=e,e={}),e=m(e);var r,o=[],i="GET";if(e.conflicts&&o.push("conflicts=true"),e.descending&&o.push("descending=true"),e.include_docs&&o.push("include_docs=true"),e.attachments&&o.push("attachments=true"),e.key&&o.push("key="+encodeURIComponent(JSON.stringify(e.key))),e.startkey&&o.push("startkey="+encodeURIComponent(JSON.stringify(e.startkey))),e.endkey&&o.push("endkey="+encodeURIComponent(JSON.stringify(e.endkey))),"undefined"!=typeof e.inclusive_end&&o.push("inclusive_end="+!!e.inclusive_end),"undefined"!=typeof e.limit&&o.push("limit="+e.limit),"undefined"!=typeof e.skip&&o.push("skip="+e.skip),o=o.join("&"),""!==o&&(o="?"+o),"undefined"!=typeof e.keys){var s="keys="+encodeURIComponent(JSON.stringify(e.keys));s.length+o.length+1<=l?o+=(-1!==o.indexOf("?")?"&":"?")+s:(i="POST",r=JSON.stringify({keys:e.keys}))}n({headers:m(g.headers),method:i,url:a(g,"_all_docs"+o),body:r},t)}),_._changes=function(e){var t="batch_size"in e?e.batch_size:f;e=m(e),e.timeout=e.timeout||3e4;var r={timeout:e.timeout-5e3},o="undefined"!=typeof e.limit?e.limit:!1;0===o&&(o=1);var i;i="returnDocs"in e?e.returnDocs:!0;var s=o;if(e.style&&(r.style=e.style),(e.include_docs||e.filter&&"function"==typeof e.filter)&&(r.include_docs=!0),e.attachments&&(r.attachments=!0),e.continuous&&(r.feed="longpoll"),e.conflicts&&(r.conflicts=!0),e.descending&&(r.descending=!0),e.filter&&"string"==typeof e.filter&&(r.filter=e.filter,"_view"===e.filter&&e.view&&"string"==typeof e.view&&(r.view=e.view)),e.query_params&&"object"==typeof e.query_params)for(var c in e.query_params)e.query_params.hasOwnProperty(c)&&(r[c]=e.query_params[c]);var u,d="GET";if(e.doc_ids){r.filter="_doc_ids";var p=JSON.stringify(e.doc_ids);p.length<l?r.doc_ids=p:(d="POST",u={doc_ids:e.doc_ids})}if(e.continuous&&_._useSSE)return _.sse(e,r,i);var v,y,E=function(i,c){if(!e.aborted){r.since=i,"object"==typeof r.since&&(r.since=JSON.stringify(r.since)),e.descending?o&&(r.limit=s):r.limit=!o||s>t?t:s;var f="?"+Object.keys(r).map(function(e){return e+"="+r[e]}).join("&"),l={headers:m(g.headers),method:d,url:a(g,"_changes"+f),timeout:e.timeout,body:u};y=i,e.aborted||(v=n(l,c))}},w=10,S=0,T={results:[]},x=function(n,r){if(!e.aborted){var a=0;if(r&&r.results){a=r.results.length,T.last_seq=r.last_seq;var c={};c.query=e.query_params,r.results=r.results.filter(function(t){s--;var n=h.filterChange(e)(t);return n&&(i&&T.results.push(t),h.call(e.onChange,t)),n})}else if(n)return e.aborted=!0,void h.call(e.complete,n);r&&r.last_seq&&(y=r.last_seq);var u=o&&0>=s||r&&t>a||e.descending;if((!e.continuous||o&&0>=s)&&u)h.call(e.complete,null,T);else{n?S+=1:S=0;var f=1<<S,l=w*f,d=e.maximumWait||3e4;if(l>d)return void h.call(e.complete,n||b.error(b.UNKNOWN_ERROR));setTimeout(function(){E(y,x)},l)}}};return E(e.since||0,x),{cancel:function(){e.aborted=!0,v&&v.abort()}}},_.sse=function(e,t,n){function r(t){var r=JSON.parse(t.data);n&&u.results.push(r),u.last_seq=r.seq,h.call(e.onChange,r)}function o(t){return c.removeEventListener("message",r,!1),l===!1?(_._useSSE=!1,void(f=_._changes(e))):(c.close(),void h.call(e.complete,t))}t.feed="eventsource",t.since=e.since||0,t.limit=e.limit,delete t.timeout;var i="?"+Object.keys(t).map(function(e){return e+"="+t[e]}).join("&"),s=a(g,"_changes"+i),c=new EventSource(s),u={results:[],last_seq:!1},f=!1,l=!1;return c.addEventListener("message",r,!1),c.onopen=function(){l=!0},c.onerror=o,{cancel:function(){return f?f.cancel():(c.removeEventListener("message",r,!1),void c.close())}}},_._useSSE=!1,_.revsDiff=h.adapterFun("revsDiff",function(e,t,r){"function"==typeof t&&(r=t,t={}),n({headers:m(g.headers),method:"POST",url:a(g,"_revs_diff"),body:JSON.stringify(e)},r)}),_._close=function(e){e()},_._destroy=function(t){n({url:a(g,""),method:"DELETE",headers:m(g.headers)},function(n,r){n?(_.emit("error",n),t(n)):(_.emit("destroyed"),_.constructor.emit("destroyed",e.name),t(null,r))})}}var f=25,l=1800,d=e(22),p=e(19),h=e(48),v=h.Promise,m=h.clone,_=e(17),g=_.btoa,y=_.atob,b=e(24),E=e(54)("pouchdb:http"),w="undefined"==typeof n||n.browser,S=e(23),T=e(27);u.valid=function(){return!0},t.exports=u}).call(this,e(53))},{17:17,19:19,22:22,23:23,24:24,27:27,48:48,53:53,54:54}],3:[function(e,t,n){"use strict";function r(e,t,n,r,o){try{if(e&&t)return o?IDBKeyRange.bound(t,e,!n,!1):IDBKeyRange.bound(e,t,!1,!n);if(e)return o?IDBKeyRange.upperBound(e):IDBKeyRange.lowerBound(e);if(t)return o?IDBKeyRange.lowerBound(t,!n):IDBKeyRange.upperBound(t,!n);if(r)return IDBKeyRange.only(r)}catch(i){return{error:i}}return null}function o(e,t,n,r){return"DataError"===n.name&&0===n.code?r(null,{total_rows:e._meta.docCount,offset:t.skip,rows:[]}):void r(a.error(a.IDB_ERROR,n.name,n.message))}function i(e,t,n,i){function a(e,i){function a(t,n,r){var o=t.id+"::"+r;L.get(o).onsuccess=function(r){n.doc=p(r.target.result),e.conflicts&&(n.doc._conflicts=s.collectConflicts(t)),v(n.doc,e,R)}}function c(t,n,r){var o={id:r.id,key:r.id,value:{rev:n}},i=r.deleted;if("ok"===e.deleted)N.push(o),i?(o.value.deleted=!0,o.doc=null):e.include_docs&&a(r,o,n);else if(!i&&S--<=0&&(N.push(o),e.include_docs&&a(r,o,n),0===--T))return;t["continue"]()}function u(e){j=t._meta.docCount;var n=e.target.result;if(n){var r=h(n.value),o=r.winningRev;c(n,o,r)}}function g(){i(null,{total_rows:j,offset:e.skip,rows:N})}function y(){e.attachments?m(N).then(g):g()}var b="startkey"in e?e.startkey:!1,E="endkey"in e?e.endkey:!1,w="key"in e?e.key:!1,S=e.skip||0,T="number"==typeof e.limit?e.limit:-1,x=e.inclusive_end!==!1,O="descending"in e&&e.descending?"prev":null,A=r(b,E,x,w,O);if(A&&A.error)return o(t,e,A.error,i);var k=[d,l];e.attachments&&k.push(f);var q=_(n,k,"readonly");if(q.error)return i(q.error);var R=q.txn,C=R.objectStore(d),D=R.objectStore(l),I=O?C.openCursor(A,O):C.openCursor(A),L=D.index("_doc_id_rev"),N=[],j=0;R.oncomplete=y,I.onsuccess=u}function c(e,n){return 0===e.limit?n(null,{total_rows:t._meta.docCount,offset:e.skip,rows:[]}):void a(e,n)}c(e,i)}var s=e(37),a=e(24),c=e(7),u=e(6),f=u.ATTACH_STORE,l=u.BY_SEQ_STORE,d=u.DOC_STORE,p=c.decodeDoc,h=c.decodeMetadata,v=c.fetchAttachmentsIfNecessary,m=c.postProcessAttachments,_=c.openTransactionSafely;t.exports=i},{24:24,37:37,6:6,7:7}],4:[function(e,t,n){"use strict";function r(e,t){return new o.Promise(function(n,r){var i=o.createBlob([""],{type:"image/png"});e.objectStore(s).put(i,"key"),e.oncomplete=function(){var e=t.transaction([s],"readwrite"),i=e.objectStore(s).get("key");i.onerror=r,i.onsuccess=function(e){var t=e.target.result,r=URL.createObjectURL(t);o.ajax({url:r,cache:!0,binary:!0},function(e,t){e&&405===e.status?n(!0):(n(!(!t||"image/png"!==t.type)),e&&404===e.status&&o.explain404("PouchDBVersion360 is just detecting blob URL support.")),URL.revokeObjectURL(r)})}}})["catch"](function(){return!1})}var o=e(48),i=e(6),s=i.DETECT_BLOB_SUPPORT_STORE;t.exports=r},{48:48,6:6}],5:[function(e,t,n){"use strict";function r(e,t,n,r,s,a){function y(){var e=[l,f,u,p,d,c],t=g(r,e,"readwrite");return t.error?a(t.error):(C=t.txn,C.onerror=_(a),C.ontimeout=_(a),C.oncomplete=w,D=C.objectStore(l),I=C.objectStore(f),L=C.objectStore(u),N=C.objectStore(c),void T(function(e){return e?(G=!0,a(e)):void E()}))}function b(){o.processDocs(B,n,H,C,J,x,t)}function E(){function e(){++n===B.length&&b()}function t(t){var n=v(t.target.result);n&&H.set(n.id,n),e()}if(B.length)for(var n=0,r=0,i=B.length;i>r;r++){var s=B[r];if(s._id&&o.isLocalId(s._id))e();else{var a=D.get(s.metadata.id);a.onsuccess=t}}}function w(){G||(s.notify(n._meta.name),n._meta.docCount+=F,a(null,J))}function S(e,t){var n=L.get(e);n.onsuccess=function(n){if(n.target.result)t();else{var r=i.error(i.MISSING_STUB,"unknown stub attachment with digest "+e);r.status=412,t(r)}}}function T(e){function t(){++o===n.length&&e(r)}var n=[];if(B.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){S(e,function(e){e&&!r&&(r=e),t()})})}function x(e,t,n,r,o,i,s,a){F+=i;var c=e.data;c._id=e.metadata.id,c._rev=e.metadata.rev,r&&(c._deleted=!0);var u=c._attachments&&Object.keys(c._attachments).length;return u?k(e,t,n,o,s,a):void A(e,t,n,o,s,a)}function O(e){var t=o.compactTree(e.metadata);h(t,e.metadata.id,C)}function A(e,t,r,o,i,s){function a(i){o&&n.auto_compaction&&O(e),l.seq=i.target.result,delete l.rev;var s=m(l,t,r),a=D.put(s);a.onsuccess=u}function c(e){e.preventDefault(),e.stopPropagation();var t=I.index("_doc_id_rev"),n=t.getKey(f._doc_id_rev);n.onsuccess=function(e){var t=I.put(f,e.target.result);t.onsuccess=a}}function u(){J[i]={ok:!0,id:l.id,rev:t},H.set(e.metadata.id,e.metadata),q(e,l.seq,s)}var f=e.data,l=e.metadata;f._doc_id_rev=l.id+"::"+l.rev,delete f._id,delete f._rev;var d=I.put(f);d.onsuccess=a,d.onerror=c}function k(e,t,n,r,o,i){function s(){u===f.length&&A(e,t,n,r,o,i)}function a(){u++,s()}var c=e.data,u=0,f=Object.keys(c._attachments);f.forEach(function(t){var n=e.data._attachments[t];if(n.stub)u++,s();else{var r=n.data;delete n.data;var o=n.digest;R(o,r,a)}})}function q(e,t,n){function r(){++i===s.length&&n()}function o(n){var o=e.data._attachments[n].digest,i=N.put({seq:t,digestSeq:o+"::"+t});i.onsuccess=r,i.onerror=function(e){e.preventDefault(),e.stopPropagation(),r()}}var i=0,s=Object.keys(e.data._attachments||{});if(!s.length)return n();for(var a=0;a<s.length;a++)o(s[a])}function R(e,t,n){var r=L.count(e);r.onsuccess=function(r){var o=r.target.result;if(o)return n();var i={digest:e,body:t},s=L.put(i);s.onsuccess=n}}for(var C,D,I,L,N,j,B=e.docs,F=0,M=0,P=B.length;P>M;M++){var U=B[M];U._id&&o.isLocalId(U._id)||(U=B[M]=o.parseDoc(U,t.new_edits),U.error&&!j&&(j=U))}if(j)return a(j);var J=new Array(B.length),H=new o.Map,G=!1,V=n._meta.blobSupport?"blob":"base64";o.preprocessAttachments(B,V,function(e){return e?a(e):void y()})}var o=e(48),i=e(24),s=e(7),a=e(6),c=a.ATTACH_AND_SEQ_STORE,u=a.ATTACH_STORE,f=a.BY_SEQ_STORE,l=a.DOC_STORE,d=a.LOCAL_STORE,p=a.META_STORE,h=s.compactRevs,v=s.decodeMetadata,m=s.encodeMetadata,_=s.idbError,g=s.openTransactionSafely;t.exports=r},{24:24,48:48,6:6,7:7}],6:[function(e,t,n){"use strict";n.ADAPTER_VERSION=5,n.DOC_STORE="document-store",n.BY_SEQ_STORE="by-sequence",n.ATTACH_STORE="attach-store",n.ATTACH_AND_SEQ_STORE="attach-seq-store",n.META_STORE="meta-store",n.LOCAL_STORE="local-store",n.DETECT_BLOB_SUPPORT_STORE="detect-blob-support"},{}],7:[function(e,t,n){(function(t){"use strict";function r(e,t,n){try{e.apply(t,n)}catch(r){"undefined"!=typeof PouchDBVersion360&&PouchDBVersion360.emit("error",r)}}var o=e(24),i=e(48),s=e(17),a=s.atob,c=s.btoa,u=e(6),f=e(22),l=e(18);n.taskQueue={running:!1,queue:[]},n.applyNext=function(){if(!n.taskQueue.running&&n.taskQueue.queue.length){n.taskQueue.running=!0;var e=n.taskQueue.queue.shift();e.action(function(o,i){r(e.callback,this,[o,i]),n.taskQueue.running=!1,t.nextTick(n.applyNext)})}},n.idbError=function(e){return function(t){var n=t.target&&t.target.error&&t.target.error.name||t.target;e(o.error(o.IDB_ERROR,n,t.type))}},n.encodeMetadata=function(e,t,n){return{data:i.safeJsonStringify(e),winningRev:t,deletedOrLocal:n?"1":"0",seq:e.seq,id:e.id}},n.decodeMetadata=function(e){if(!e)return null;var t=i.safeJsonParse(e.data);return t.winningRev=e.winningRev,t.deleted="1"===e.deletedOrLocal,t.seq=e.seq,t},n.decodeDoc=function(e){if(!e)return e;var t=i.lastIndexOf(e._doc_id_rev,":");return e._id=e._doc_id_rev.substring(0,t-1),e._rev=e._doc_id_rev.substring(t+1),delete e._doc_id_rev,e},n.readBlobData=function(e,t,n,r){n?e?"string"!=typeof e?f(e,function(e){r(c(e))}):r(e):r(""):e?"string"!=typeof e?r(e):(e=l(a(e)),r(i.createBlob([e],{type:t}))):r(i.createBlob([""],{type:t}))},n.fetchAttachmentsIfNecessary=function(e,t,n,r){function o(){++a===s.length&&r&&r()}function i(e,t){var r=e._attachments[t],i=r.digest,s=n.objectStore(u.ATTACH_STORE).get(i);s.onsuccess=function(e){r.body=e.target.result.body,o()}}var s=Object.keys(e._attachments||{});if(!s.length)return r&&r();var a=0;s.forEach(function(n){t.attachments&&t.include_docs?i(e,n):(e._attachments[n].stub=!0,o())})},n.postProcessAttachments=function(e){return i.Promise.all(e.map(function(e){if(e.doc&&e.doc._attachments){var t=Object.keys(e.doc._attachments);return i.Promise.all(t.map(function(t){var r=e.doc._attachments[t];if("body"in r){var o=r.body,s=r.content_type;return new i.Promise(function(a){n.readBlobData(o,s,!0,function(n){e.doc._attachments[t]=i.extend(i.pick(r,["digest","content_type"]),{data:n}),a()})})}}))}}))},n.compactRevs=function(e,t,n){function r(){f--,f||o()}function o(){i.length&&i.forEach(function(e){var t=c.index("digestSeq").count(IDBKeyRange.bound(e+"::",e+"::ï¿¿",!1,!1));t.onsuccess=function(t){var n=t.target.result;n||a["delete"](e)}})}var i=[],s=n.objectStore(u.BY_SEQ_STORE),a=n.objectStore(u.ATTACH_STORE),c=n.objectStore(u.ATTACH_AND_SEQ_STORE),f=e.length;e.forEach(function(e){var n=s.index("_doc_id_rev"),o=t+"::"+e;n.getKey(o).onsuccess=function(e){var t=e.target.result;if("number"!=typeof t)return r();s["delete"](t);var n=c.index("seq").openCursor(IDBKeyRange.only(t));n.onsuccess=function(e){var t=e.target.result;if(t){var n=t.value.digestSeq.split("::")[0];i.push(n),c["delete"](t.primaryKey),t["continue"]()}else r()}}})},n.openTransactionSafely=function(e,t,n){try{return{txn:e.transaction(t,n)}}catch(r){return{error:r}}}}).call(this,e(53))},{17:17,18:18,22:22,24:24,48:48,53:53,6:6}],8:[function(e,t,n){(function(n){"use strict";function r(e,t){var n=this;C.queue.push({action:function(t){o(n,e,t)},callback:t}),w()}function o(e,t,o){function u(e){var t=e.createObjectStore(y,{keyPath:"id"});e.createObjectStore(_,{autoIncrement:!0}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0}),e.createObjectStore(m,{keyPath:"digest"}),e.createObjectStore(E,{keyPath:"id",autoIncrement:!1}),e.createObjectStore(g),t.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),e.createObjectStore(b,{keyPath:"_id"});var n=e.createObjectStore(v,{autoIncrement:!0});n.createIndex("seq","seq"),n.createIndex("digestSeq","digestSeq",{unique:!0})}function f(e,t){var n=e.objectStore(y);n.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),n.openCursor().onsuccess=function(e){var r=e.target.result;if(r){var o=r.value,i=s.isDeleted(o);o.deletedOrLocal=i?"1":"0",n.put(o),r["continue"]()}else t()}}function w(e){e.createObjectStore(b,{keyPath:"_id"}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0})}function C(e,t){var n=e.objectStore(b),r=e.objectStore(y),o=e.objectStore(_),i=r.openCursor();i.onsuccess=function(e){var i=e.target.result;if(i){var c=i.value,u=c.id,f=s.isLocalId(u),l=a.winningRev(c);
-if(f){var d=u+"::"+l,p=u+"::",h=u+"::~",v=o.index("_doc_id_rev"),m=IDBKeyRange.bound(p,h,!1,!1),_=v.openCursor(m);_.onsuccess=function(e){if(_=e.target.result){var t=_.value;t._doc_id_rev===d&&n.put(t),o["delete"](_.primaryKey),_["continue"]()}else r["delete"](i.primaryKey),i["continue"]()}}else i["continue"]()}else t&&t()}}function L(e){var t=e.createObjectStore(v,{autoIncrement:!0});t.createIndex("seq","seq"),t.createIndex("digestSeq","digestSeq",{unique:!0})}function N(e,t){var n=e.objectStore(_),r=e.objectStore(m),o=e.objectStore(v),i=r.count();i.onsuccess=function(e){var r=e.target.result;return r?void(n.openCursor().onsuccess=function(e){var n=e.target.result;if(!n)return t();for(var r=n.value,i=n.primaryKey,s=Object.keys(r._attachments||{}),a={},c=0;c<s.length;c++){var u=r._attachments[s[c]];a[u.digest]=!0}var f=Object.keys(a);for(c=0;c<f.length;c++){var l=f[c];o.put({seq:i,digestSeq:l+"::"+i})}n["continue"]()}):t()}}function j(e){function t(e){return e.data?x(e):(e.deleted="1"===e.deletedOrLocal,e)}var n=e.objectStore(_),r=e.objectStore(y),o=r.openCursor();o.onsuccess=function(e){function o(){var e=c.id+"::",t=c.id+"::ï¿¿",r=n.index("_doc_id_rev").openCursor(IDBKeyRange.bound(e,t)),o=0;r.onsuccess=function(e){var t=e.target.result;if(!t)return c.seq=o,i();var n=t.primaryKey;n>o&&(o=n),t["continue"]()}}function i(){var e=O(c,c.winningRev,c.deleted),t=r.put(e);t.onsuccess=function(){s["continue"]()}}var s=e.target.result;if(s){var c=t(s.value);return c.winningRev=c.winningRev||a.winningRev(c),c.seq?i():void o()}}}var B=t.name,F=null;e._meta=null,e.type=function(){return"idb"},e._id=s.toPromise(function(t){t(null,e._meta.instanceId)}),e._bulkDocs=function(t,n,o){l(t,n,e,F,r.Changes,o)},e._get=function(e,t,n){function r(){n(a,{doc:o,metadata:i,ctx:u})}var o,i,a,u;if(t=s.clone(t),t.ctx)u=t.ctx;else{var f=D(F,[y,_,m],"readonly");if(f.error)return n(f.error);u=f.txn}u.objectStore(y).get(e).onsuccess=function(e){if(i=x(e.target.result),!i)return a=c.error(c.MISSING_DOC,"missing"),r();if(s.isDeleted(i)&&!t.rev)return a=c.error(c.MISSING_DOC,"deleted"),r();var n=u.objectStore(_),f=t.rev||i.winningRev,l=i.id+"::"+f;n.index("_doc_id_rev").get(l).onsuccess=function(e){return o=e.target.result,o&&(o=T(o)),o?void r():(a=c.error(c.MISSING_DOC,"missing"),r())}}},e._getAttachment=function(e,t,n){var r;if(t=s.clone(t),t.ctx)r=t.ctx;else{var o=D(F,[y,_,m],"readonly");if(o.error)return n(o.error);r=o.txn}var i=e.digest,a=e.content_type;r.objectStore(m).get(i).onsuccess=function(e){var r=e.target.result.body;R(r,a,t.encode,function(e){n(null,e)})}},e._info=function(t){if(null===F||!I[B]){var n=new Error("db isn't open");return n.id="idbNull",t(n)}var r,o,i=D(F,[_],"readonly");if(i.error)return t(i.error);var s=i.txn,a=s.objectStore(_).openCursor(null,"prev");a.onsuccess=function(t){var n=t.target.result;r=n?n.key:0,o=e._meta.docCount},s.oncomplete=function(){t(null,{doc_count:o,update_seq:r,idb_attachment_format:e._meta.blobSupport?"binary":"base64"})}},e._allDocs=function(t,n){d(t,e,F,n)},e._changes=function(t){function n(e){function n(){return a.seq!==s?e["continue"]():(l=s,a.winningRev===i._rev?o(i):void r())}function r(){var e=i._id+"::"+a.winningRev,t=v.index("_doc_id_rev").openCursor(IDBKeyRange.bound(e,e+"ï¿¿"));t.onsuccess=function(e){o(T(e.target.result.value))}}function o(n){var r=t.processChange(n,a,t);r.seq=a.seq,w(r)&&(E++,p&&b.push(r),t.attachments&&t.include_docs?A(n,t,h,function(){q([r]).then(function(){t.onChange(r)})}):t.onChange(r)),E!==d&&e["continue"]()}var i=T(e.value),s=e.key;if(u&&!u.has(i._id))return e["continue"]();var a;return(a=S.get(i._id))?n():void(g.get(i._id).onsuccess=function(e){a=x(e.target.result),S.set(i._id,a),n()})}function o(e){var t=e.target.result;t&&n(t)}function i(){var e=[y,_];t.attachments&&e.push(m);var n=D(F,e,"readonly");if(n.error)return t.complete(n.error);h=n.txn,h.onerror=k(t.complete),h.oncomplete=a,v=h.objectStore(_),g=h.objectStore(y);var r;r=f?v.openCursor(null,f):v.openCursor(IDBKeyRange.lowerBound(t.since,!0)),r.onsuccess=o}function a(){function e(){t.complete(null,{results:b,last_seq:l})}!t.continuous&&t.attachments?q(b).then(e):e()}if(t=s.clone(t),t.continuous){var c=B+":"+s.uuid();return r.Changes.addListener(B,c,e,t),r.Changes.notify(B),{cancel:function(){r.Changes.removeListener(B,c)}}}var u=t.doc_ids&&new s.Set(t.doc_ids),f=t.descending?"prev":null;t.since=t.since||0;var l=t.since,d="limit"in t?t.limit:-1;0===d&&(d=1);var p;p="returnDocs"in t?t.returnDocs:!0;var h,v,g,b=[],E=0,w=s.filterChange(t),S=new s.Map;i()},e._close=function(e){return null===F?e(c.error(c.NOT_OPEN)):(F.close(),delete I[B],F=null,void e())},e._getRevisionTree=function(e,t){var n=D(F,[y],"readonly");if(n.error)return t(n.error);var r=n.txn,o=r.objectStore(y).get(e);o.onsuccess=function(e){var n=x(e.target.result);n?t(null,n.rev_tree):t(c.error(c.MISSING_DOC))}},e._doCompaction=function(e,t,n){var r=[y,_,m,v],o=D(F,r,"readwrite");if(o.error)return n(o.error);var i=o.txn,c=i.objectStore(y);c.get(e).onsuccess=function(n){var r=x(n.target.result);a.traverseRevTree(r.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;-1!==t.indexOf(s)&&(i.status="missing")}),S(t,e,i);var o=r.winningRev,s=r.deleted;i.objectStore(y).put(O(r,o,s))},i.onerror=k(n),i.oncomplete=function(){s.call(n)}},e._getLocal=function(e,t){var n=D(F,[b],"readonly");if(n.error)return t(n.error);var r=n.txn,o=r.objectStore(b).get(e);o.onerror=k(t),o.onsuccess=function(e){var n=e.target.result;n?(delete n._doc_id_rev,t(null,n)):t(c.error(c.MISSING_DOC))}},e._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),delete e._revisions;var r=e._rev,o=e._id;r?e._rev="0-"+(parseInt(r.split("-")[1],10)+1):e._rev="0-1";var i,s=t.ctx;if(!s){var a=D(F,[b],"readwrite");if(a.error)return n(a.error);s=a.txn,s.onerror=k(n),s.oncomplete=function(){i&&n(null,i)}}var u,f=s.objectStore(b);r?(u=f.get(o),u.onsuccess=function(o){var s=o.target.result;if(s&&s._rev===r){var a=f.put(e);a.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)}}else n(c.error(c.REV_CONFLICT))}):(u=f.add(e),u.onerror=function(e){n(c.error(c.REV_CONFLICT)),e.preventDefault(),e.stopPropagation()},u.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)})},e._removeLocal=function(e,t){var n=D(F,[b],"readwrite");if(n.error)return t(n.error);var r,o=n.txn;o.oncomplete=function(){r&&t(null,r)};var i=e._id,s=o.objectStore(b),a=s.get(i);a.onerror=k(t),a.onsuccess=function(n){var o=n.target.result;o&&o._rev===e._rev?(s["delete"](i),r={ok:!0,id:i,rev:"0-0"}):t(c.error(c.MISSING_DOC))}},e._destroy=function(e){r.Changes.removeAllListeners(B),r.openReqList[B]&&r.openReqList[B].result&&(r.openReqList[B].result.close(),delete I[B]);var t=indexedDB.deleteDatabase(B);t.onsuccess=function(){r.openReqList[B]&&(r.openReqList[B]=null),s.hasLocalStorage()&&B in localStorage&&delete localStorage[B],e(null,{ok:!0})},t.onerror=k(e)};var M=I[B];if(M)return F=M.idb,e._meta=M.global,void n.nextTick(function(){o(null,e)});var P=indexedDB.open(B,h);"openReqList"in r||(r.openReqList={}),r.openReqList[B]=P,P.onupgradeneeded=function(e){function t(){var e=o[i-1];i++,e&&e(r,t)}var n=e.target.result;if(e.oldVersion<1)return u(n);var r=e.currentTarget.transaction;e.oldVersion<3&&w(n),e.oldVersion<4&&L(n);var o=[f,C,N,j],i=e.oldVersion;t()},P.onsuccess=function(t){F=t.target.result,F.onversionchange=function(){F.close(),delete I[B]},F.onabort=function(){F.close(),delete I[B]};var n=F.transaction([E,g,y],"readwrite"),r=n.objectStore(E).get(E),a=null,c=null,u=null;r.onsuccess=function(t){var r=function(){null!==a&&null!==c&&null!==u&&(e._meta={name:B,instanceId:u,blobSupport:a,docCount:c},I[B]={idb:F,global:e._meta},o(null,e))},f=t.target.result||{id:E};B+"_id"in f?(u=f[B+"_id"],r()):(u=s.uuid(),f[B+"_id"]=u,n.objectStore(E).put(f).onsuccess=function(){r()}),i||(i=p(n,F)),i.then(function(e){a=e,r()});var l=n.objectStore(y).index("deletedOrLocal");l.count(IDBKeyRange.only("0")).onsuccess=function(e){c=e.target.result,r()}}},P.onerror=k(o)}var i,s=e(48),a=e(37),c=e(24),u=e(7),f=e(6),l=e(5),d=e(3),p=e(4),h=f.ADAPTER_VERSION,v=f.ATTACH_AND_SEQ_STORE,m=f.ATTACH_STORE,_=f.BY_SEQ_STORE,g=f.DETECT_BLOB_SUPPORT_STORE,y=f.DOC_STORE,b=f.LOCAL_STORE,E=f.META_STORE,w=u.applyNext,S=u.compactRevs,T=u.decodeDoc,x=u.decodeMetadata,O=u.encodeMetadata,A=u.fetchAttachmentsIfNecessary,k=u.idbError,q=u.postProcessAttachments,R=u.readBlobData,C=u.taskQueue,D=u.openTransactionSafely,I={};r.valid=function(){var e="undefined"!=typeof openDatabase&&/(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent)&&!/BlackBerry/.test(navigator.platform);return!e&&"undefined"!=typeof indexedDB&&"undefined"!=typeof IDBKeyRange},r.Changes=new s.Changes,t.exports=r}).call(this,e(53))},{24:24,3:3,37:37,4:4,48:48,5:5,53:53,6:6,7:7}],9:[function(e,t,n){"use strict";function r(e,t,n,r,a,m){function _(){return q?m(q):(a.notify(n._name),n._docCount=-1,void m(null,R))}function g(e,t){var n="SELECT count(*) as cnt FROM "+f+" WHERE digest=?";k.executeSql(n,[e],function(n,r){if(0===r.rows.item(0).cnt){var o=i.error(i.MISSING_STUB,"unknown stub attachment with digest "+e);t(o)}else t()})}function y(e){function t(){++o===n.length&&e(r)}var n=[];if(O.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){g(e,function(e){e&&!r&&(r=e),t()})})}function b(e,t,r,i,s,a,f,v){function m(){function t(e,t){function r(){return++i===s.length&&t(),!1}function o(t){var o="INSERT INTO "+l+" (digest, seq) VALUES (?,?)",i=[n._attachments[t].digest,e];k.executeSql(o,i,r,r)}var i=0,s=Object.keys(n._attachments||{});if(!s.length)return t();for(var a=0;a<s.length;a++)o(s[a])}var n=e.data,r=i?1:0,o=n._id,s=n._rev,a=p(n),c="INSERT INTO "+u+" (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);",f=[o,s,a,r];k.executeSql(c,f,function(e,n){var r=n.insertId;t(r,function(){b(e,r)})},function(){var e=d("seq",u,null,"doc_id=? AND rev=?");return k.executeSql(e,[o,s],function(e,n){var i=n.rows.item(0).seq,c="UPDATE "+u+" SET json=?, deleted=? WHERE doc_id=? AND rev=?;",f=[a,r,o,s];e.executeSql(c,f,function(e){t(i,function(){b(e,i)})})}),!1})}function _(e){E||(e?(E=e,v(E)):w===T.length&&m())}function g(e){w++,_(e)}function y(){if(s&&n.auto_compaction){var t=e.metadata.id,r=o.compactTree(e.metadata);h(r,t,k)}}function b(n,r){y(),e.metadata.seq=r,delete e.metadata.rev;var i=s?"UPDATE "+c+" SET json=?, max_seq=?, winningseq=(SELECT seq FROM "+u+" WHERE doc_id="+c+".id AND rev=?) WHERE id=?":"INSERT INTO "+c+" (id, winningseq, max_seq, json) VALUES (?,?,?,?);",a=o.safeJsonStringify(e.metadata),l=e.metadata.id,d=s?[a,r,t,l]:[l,r,r,a];n.executeSql(i,d,function(){R[f]={ok:!0,id:e.metadata.id,rev:t},C.set(l,e.metadata),v()})}var E=null,w=0;e.data._id=e.metadata.id,e.data._rev=e.metadata.rev;var T=Object.keys(e.data._attachments||{});i&&(e.data._deleted=!0),T.forEach(function(t){var n=e.data._attachments[t];if(n.stub)w++,_();else{var r=n.data;delete n.data;var o=n.digest;S(o,r,g)}}),T.length||m()}function E(){o.processDocs(O,n,C,k,R,b,t)}function w(e){function t(){++n===O.length&&e()}if(!O.length)return e();var n=0;O.forEach(function(e){if(e._id&&o.isLocalId(e._id))return t();var n=e.metadata.id;k.executeSql("SELECT json FROM "+c+" WHERE id = ?",[n],function(e,r){if(r.rows.length){var i=o.safeJsonParse(r.rows.item(0).json);C.set(n,i)}t()})})}function S(e,t,n){var r="SELECT digest FROM "+f+" WHERE digest=?";k.executeSql(r,[e],function(o,i){return i.rows.length?n():(r="INSERT INTO "+f+" (digest, body, escaped) VALUES (?,?,1)",void o.executeSql(r,[e,s.escapeBlob(t)],function(){n()},function(){return n(),!1}))})}var T=t.new_edits,x=e.docs,O=x.map(function(e){if(e._id&&o.isLocalId(e._id))return e;var t=o.parseDoc(e,T);return t}),A=O.filter(function(e){return e.error});if(A.length)return m(A[0]);var k,q,R=new Array(O.length),C=new o.Map;o.preprocessAttachments(O,"binary",function(e){return e?m(e):void r.transaction(function(e){k=e,y(function(e){e?q=e:w(E)})},v(m),_)})}var o=e(48),i=e(24),s=e(11),a=e(10),c=a.DOC_STORE,u=a.BY_SEQ_STORE,f=a.ATTACH_STORE,l=a.ATTACH_AND_SEQ_STORE,d=s.select,p=s.stringifyDoc,h=s.compactRevs,v=s.unknownError;t.exports=r},{10:10,11:11,24:24,48:48}],10:[function(e,t,n){"use strict";function r(e){return"'"+e+"'"}n.ADAPTER_VERSION=7,n.DOC_STORE=r("document-store"),n.BY_SEQ_STORE=r("by-sequence"),n.ATTACH_STORE=r("attach-store"),n.LOCAL_STORE=r("local-store"),n.META_STORE=r("metadata-store"),n.ATTACH_AND_SEQ_STORE=r("attach-seq-store")},{}],11:[function(e,t,n){"use strict";function r(e){return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"")}function o(e){return e.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,"")}function i(e){return delete e._id,delete e._rev,JSON.stringify(e)}function s(e,t,n){return e=JSON.parse(e),e._id=t,e._rev=n,e}function a(e){for(var t="(";e--;)t+="?",e&&(t+=",");return t+")"}function c(e,t,n,r,o){return"SELECT "+e+" FROM "+("string"==typeof t?t:t.join(" JOIN "))+(n?" ON "+n:"")+(r?" WHERE "+("string"==typeof r?r:r.join(" AND ")):"")+(o?" ORDER BY "+o:"")}function u(e,t,n){function r(){++i===e.length&&o()}function o(){if(s.length){var e="SELECT DISTINCT digest AS digest FROM "+b+" WHERE seq IN "+a(s.length);n.executeSql(e,s,function(e,t){for(var n=[],r=0;r<t.rows.length;r++)n.push(t.rows.item(r).digest);if(n.length){var o="DELETE FROM "+b+" WHERE seq IN ("+s.map(function(){return"?"}).join(",")+")";e.executeSql(o,s,function(e){var t="SELECT digest FROM "+b+" WHERE digest IN ("+n.map(function(){return"?"}).join(",")+")";e.executeSql(t,n,function(e,t){for(var r=new v.Set,o=0;o<t.rows.length;o++)r.add(t.rows.item(o).digest);n.forEach(function(t){r.has(t)||(e.executeSql("DELETE FROM "+b+" WHERE digest=?",[t]),e.executeSql("DELETE FROM "+y+" WHERE digest=?",[t]))})})})}})}}if(e.length){var i=0,s=[];e.forEach(function(e){var o="SELECT seq FROM "+g+" WHERE doc_id=? AND rev=?";n.executeSql(o,[t,e],function(e,t){if(!t.rows.length)return r();var n=t.rows.item(0).seq;s.push(n),e.executeSql("DELETE FROM "+g+" WHERE seq=?",[n],r)})})}}function f(e){return function(t){var n=t&&t.constructor.toString().match(/function ([^\(]+)/),r=n&&n[1]||t.type,o=t.target||t.message;e(m.error(m.WSQ_ERROR,o,r))}}function l(e){if("size"in e)return 1e6*e.size;var t=/Android/.test(window.navigator.userAgent);return t?5e6:1}function d(){return"undefined"!=typeof sqlitePlugin?sqlitePlugin.openDatabase.bind(sqlitePlugin):"undefined"!=typeof openDatabase?function(e){return openDatabase(e.name,e.version,e.description,e.size)}:void 0}function p(e){var t=d(),n=E[e.name];return n||(n=E[e.name]=t(e),n._sqlitePlugin="undefined"!=typeof sqlitePlugin),n}function h(){return"undefined"!=typeof openDatabase||"undefined"!=typeof SQLitePlugin}var v=e(48),m=e(24),_=e(10),g=_.BY_SEQ_STORE,y=_.ATTACH_STORE,b=_.ATTACH_AND_SEQ_STORE,E={};t.exports={escapeBlob:r,unescapeBlob:o,stringifyDoc:i,unstringifyDoc:s,qMarks:a,select:c,compactRevs:u,unknownError:f,getSize:l,openDB:p,valid:h}},{10:10,24:24,48:48}],12:[function(e,t,n){"use strict";function r(e,t,n,r,o){function s(){++u===c.length&&o&&o()}function a(e,t){var o=e._attachments[t],a={encode:!0,ctx:r};n._getAttachment(o,a,function(n,r){e._attachments[t]=i.extend(i.pick(o,["digest","content_type"]),{data:r}),s()})}var c=Object.keys(e._attachments||{});if(!c.length)return o&&o();var u=0;c.forEach(function(n){t.attachments&&t.include_docs?a(e,n):(e._attachments[n].stub=!0,s())})}function o(e,t){function n(){i.hasLocalStorage()&&(window.localStorage["_pouch__websqldb_"+K._name]=!0),t(null,K)}function f(e,t){e.executeSql(C),e.executeSql("ALTER TABLE "+v+" ADD COLUMN deleted TINYINT(1) DEFAULT 0",[],function(){e.executeSql(q),e.executeSql("ALTER TABLE "+h+" ADD COLUMN local TINYINT(1) DEFAULT 0",[],function(){e.executeSql("CREATE INDEX IF NOT EXISTS 'doc-store-local-idx' ON "+h+" (local, id)");var n="SELECT "+h+".winningseq AS seq, "+h+".json AS metadata FROM "+v+" JOIN "+h+" ON "+v+".seq = "+h+".winningseq";e.executeSql(n,[],function(e,n){for(var r=[],o=[],s=0;s<n.rows.length;s++){var a=n.rows.item(s),c=a.seq,u=JSON.parse(a.metadata);i.isDeleted(u)&&r.push(c),i.isLocalId(u.id)&&o.push(u.id)}e.executeSql("UPDATE "+h+"SET local = 1 WHERE id IN "+b(o.length),o,function(){e.executeSql("UPDATE "+v+" SET deleted = 1 WHERE seq IN "+b(r.length),r,t)})})})})}function j(e,t){var n="CREATE TABLE IF NOT EXISTS "+_+" (id UNIQUE, rev, json)";e.executeSql(n,[],function(){var n="SELECT "+h+".id AS id, "+v+".json AS data FROM "+v+" JOIN "+h+" ON "+v+".seq = "+h+".winningseq WHERE local = 1";e.executeSql(n,[],function(e,n){function r(){if(!o.length)return t(e);var n=o.shift(),i=JSON.parse(n.data)._rev;e.executeSql("INSERT INTO "+_+" (id, rev, json) VALUES (?,?,?)",[n.id,i,n.data],function(e){e.executeSql("DELETE FROM "+h+" WHERE id=?",[n.id],function(e){e.executeSql("DELETE FROM "+v+" WHERE seq=?",[n.seq],function(){r()})})})}for(var o=[],i=0;i<n.rows.length;i++)o.push(n.rows.item(i));r()})})}function B(e,t){function n(n){function r(){if(!n.length)return t(e);var o=n.shift(),i=c(o.hex,W),s=i.lastIndexOf("::"),a=i.substring(0,s),u=i.substring(s+2),f="UPDATE "+v+" SET doc_id=?, rev=? WHERE doc_id_rev=?";e.executeSql(f,[a,u,i],function(){r()})}r()}var r="ALTER TABLE "+v+" ADD COLUMN doc_id";e.executeSql(r,[],function(e){var t="ALTER TABLE "+v+" ADD COLUMN rev";e.executeSql(t,[],function(e){e.executeSql(R,[],function(e){var t="SELECT hex(doc_id_rev) as hex FROM "+v;e.executeSql(t,[],function(e,t){for(var r=[],o=0;o<t.rows.length;o++)r.push(t.rows.item(o));n(r)})})})})}function F(e,t){function n(e){var n="SELECT COUNT(*) AS cnt FROM "+m;e.executeSql(n,[],function(e,n){function r(){var n=S(N+", "+h+".id AS id",[h,v],L,null,h+".id ");n+=" LIMIT "+s+" OFFSET "+i,i+=s,e.executeSql(n,[],function(e,n){function o(e,t){var n=i[e]=i[e]||[];-1===n.indexOf(t)&&n.push(t)}if(!n.rows.length)return t(e);for(var i={},s=0;s<n.rows.length;s++)for(var a=n.rows.item(s),c=w(a.data,a.id,a.rev),u=Object.keys(c._attachments||{}),f=0;f<u.length;f++){var l=c._attachments[u[f]];o(l.digest,a.seq)}var d=[];if(Object.keys(i).forEach(function(e){var t=i[e];t.forEach(function(t){d.push([e,t])})}),!d.length)return r();var p=0;d.forEach(function(t){var n="INSERT INTO "+y+" (digest, seq) VALUES (?,?)";e.executeSql(n,t,function(){++p===d.length&&r()})})})}var o=n.rows.item(0).cnt;if(!o)return t(e);var i=0,s=10;r()})}var r="CREATE TABLE IF NOT EXISTS "+y+" (digest, seq INTEGER)";e.executeSql(r,[],function(e){e.executeSql(I,[],function(e){e.executeSql(D,[],n)})})}function M(e,t){var n="ALTER TABLE "+m+" ADD COLUMN escaped TINYINT(1) DEFAULT 0";e.executeSql(n,[],t)}function P(e,t){var n="ALTER TABLE "+h+" ADD COLUMN max_seq INTEGER";e.executeSql(n,[],function(e){var n="UPDATE "+h+" SET max_seq=(SELECT MAX(seq) FROM "+v+" WHERE doc_id=id)";e.executeSql(n,[],function(e){var n="CREATE UNIQUE INDEX IF NOT EXISTS 'doc-max-seq-idx' ON "+h+" (max_seq)";e.executeSql(n,[],t)})})}function U(e,t){e.executeSql('SELECT HEX("a") AS hex',[],function(e,n){var r=n.rows.item(0).hex;W=2===r.length?"UTF-8":"UTF-16",t()})}function J(){for(;Y.length>0;){var e=Y.pop();e(null,z)}}function H(e,t){if(0===t){var n="CREATE TABLE IF NOT EXISTS "+g+" (dbid, db_version INTEGER)",r="CREATE TABLE IF NOT EXISTS "+m+" (digest UNIQUE, escaped TINYINT(1), body BLOB)",o="CREATE TABLE IF NOT EXISTS "+y+" (digest, seq INTEGER)",s="CREATE TABLE IF NOT EXISTS "+h+" (id unique, json, winningseq, max_seq INTEGER UNIQUE)",a="CREATE TABLE IF NOT EXISTS "+v+" (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, json, deleted TINYINT(1), doc_id, rev)",c="CREATE TABLE IF NOT EXISTS "+_+" (id UNIQUE, rev, json)";e.executeSql(r),e.executeSql(c),e.executeSql(o,[],function(){e.executeSql(D),e.executeSql(I)}),e.executeSql(s,[],function(){e.executeSql(C),e.executeSql(a,[],function(){e.executeSql(q),e.executeSql(R),e.executeSql(n,[],function(){var t="INSERT INTO "+g+" (db_version, dbid) VALUES (?,?)";z=i.uuid();var n=[p,z];e.executeSql(t,n,function(){J()})})})})}else{var u=function(){var n=p>t;n&&e.executeSql("UPDATE "+g+" SET db_version = "+p);var r="SELECT dbid FROM "+g;e.executeSql(r,[],function(e,t){z=t.rows.item(0).dbid,J()})},l=[f,j,B,F,M,P,u],d=t,b=function(e){l[d-1](e,b),d++};b(e)}}function G(){$.transaction(function(e){U(e,function(){V(e)})},x(t),n)}function V(e){var t="SELECT sql FROM sqlite_master WHERE tbl_name = "+g;e.executeSql(t,[],function(e,t){t.rows.length?/db_version/.test(t.rows.item(0).sql)?e.executeSql("SELECT db_version FROM "+g,[],function(e,t){var n=t.rows.item(0).db_version;H(e,n)}):e.executeSql("ALTER TABLE "+g+" ADD COLUMN db_version INTEGER",[],function(){H(e,1)}):H(e,0)})}function Q(e,t){if(-1!==K._docCount)return t(K._docCount);var n=S("COUNT("+h+".id) AS 'num'",[h,v],L,v+".deleted=0");e.executeSql(n,[],function(e,n){K._docCount=n.rows.item(0).num,t(K._docCount)})}var W,K=this,z=null,X=O(e),Y=[];K._docCount=-1,K._name=e.name;var $=A({name:K._name,version:k,description:K._name,size:X,location:e.location,createFromLocation:e.createFromLocation,androidDatabaseImplementation:e.androidDatabaseImplementation});return $?("function"!=typeof $.readTransaction&&($.readTransaction=$.transaction),i.isCordova()?window.addEventListener(K._name+"_pouch",function Z(){window.removeEventListener(K._name+"_pouch",Z,!1),G()},!1):G(),K.type=function(){return"websql"},K._id=i.toPromise(function(e){e(null,z)}),K._info=function(e){$.readTransaction(function(t){Q(t,function(n){var r="SELECT MAX(seq) AS seq FROM "+v;t.executeSql(r,[],function(t,r){var o=r.rows.item(0).seq||0;e(null,{doc_count:n,update_seq:o,sqlite_plugin:$._sqlitePlugin,websql_encoding:W})})})},x(e))},K._bulkDocs=function(e,t,n){d(e,t,K,$,o.Changes,n)},K._get=function(e,t,n){function r(){n(c,{doc:o,metadata:s,ctx:l})}t=i.clone(t);var o,s,c;if(!t.ctx)return void $.readTransaction(function(r){t.ctx=r,K._get(e,t,n)});var u,f,l=t.ctx;t.rev?(u=S(N,[h,v],h+".id="+v+".doc_id",[v+".doc_id=?",v+".rev=?"]),f=[e,t.rev]):(u=S(N,[h,v],L,h+".id=?"),f=[e]),l.executeSql(u,f,function(e,n){if(!n.rows.length)return c=a.error(a.MISSING_DOC,"missing"),r();var u=n.rows.item(0);return s=i.safeJsonParse(u.metadata),u.deleted&&!t.rev?(c=a.error(a.MISSING_DOC,"deleted"),r()):(o=w(u.data,s.id,u.rev),void r())})},K._allDocs=function(e,t){var n,o=[],a="startkey"in e?e.startkey:!1,c="endkey"in e?e.endkey:!1,u="key"in e?e.key:!1,f="descending"in e?e.descending:!1,l="limit"in e?e.limit:-1,d="skip"in e?e.skip:0,p=e.inclusive_end!==!1,m=[],_=[];if(u!==!1)_.push(h+".id = ?"),m.push(u);else if(a!==!1||c!==!1){if(a!==!1&&(_.push(h+".id "+(f?"<=":">=")+" ?"),m.push(a)),c!==!1){var g=f?">":"<";p&&(g+="="),_.push(h+".id "+g+" ?"),m.push(c)}u!==!1&&(_.push(h+".id = ?"),m.push(u))}"ok"!==e.deleted&&_.push(v+".deleted = 0"),$.readTransaction(function(t){Q(t,function(a){if(n=a,0!==l){var c=S(N,[h,v],L,_,h+".id "+(f?"DESC":"ASC"));c+=" LIMIT "+l+" OFFSET "+d,t.executeSql(c,m,function(t,n){for(var a=0,c=n.rows.length;c>a;a++){var u=n.rows.item(a),f=i.safeJsonParse(u.metadata),l=f.id,d=w(u.data,l,u.rev),p=d._rev,h={id:l,key:l,value:{rev:p}};if(e.include_docs&&(h.doc=d,h.doc._rev=p,e.conflicts&&(h.doc._conflicts=s.collectConflicts(f)),r(h.doc,e,K,t)),u.deleted){if("ok"!==e.deleted)continue;h.value.deleted=!0,h.doc=null}o.push(h)}})}})},x(t),function(){t(null,{total_rows:n,offset:e.skip,rows:o})})},K._changes=function(e){function t(){var t=h+".json AS metadata, "+h+".max_seq AS maxSeq, "+v+".json AS winningDoc, "+v+".rev AS winningRev ",n=h+" JOIN "+v,o=h+".id="+v+".doc_id AND "+h+".winningseq="+v+".seq",l=["maxSeq > ?"],d=[e.since];e.doc_ids&&(l.push(h+".id IN "+b(e.doc_ids.length)),d=d.concat(e.doc_ids));var p="maxSeq "+(s?"DESC":"ASC"),m=S(t,n,o,l,p),_=i.filterChange(e);e.view||e.filter||(m+=" LIMIT "+a);var g=e.since||0;$.readTransaction(function(t){t.executeSql(m,d,function(t,n){function o(t){return function(){e.onChange(t)}}for(var s=0,l=n.rows.length;l>s;s++){var d=n.rows.item(s),p=i.safeJsonParse(d.metadata);g=d.maxSeq;var h=w(d.winningDoc,p.id,d.winningRev),v=e.processChange(h,p,e);if(v.seq=d.maxSeq,_(v)&&(f++,c&&u.push(v),e.attachments&&e.include_docs?r(h,e,K,t,o(v)):o(v)()),f===a)break}})},x(e.complete),function(){e.continuous||e.complete(null,{results:u,last_seq:g})})}if(e=i.clone(e),e.continuous){var n=K._name+":"+i.uuid();return o.Changes.addListener(K._name,n,K,e),o.Changes.notify(K._name),{cancel:function(){o.Changes.removeListener(K._name,n)}}}var s=e.descending;e.since=e.since&&!s?e.since:0;var a="limit"in e?e.limit:-1;0===a&&(a=1);var c;c="returnDocs"in e?e.returnDocs:!0;var u=[],f=0;t()},K._close=function(e){e()},K._getAttachment=function(e,t,n){var r,o=t.ctx,s=e.digest,a=e.content_type,f="SELECT escaped, CASE WHEN escaped = 1 THEN body ELSE HEX(body) END AS body FROM "+m+" WHERE digest=?";o.executeSql(f,[s],function(e,o){var s=o.rows.item(0),f=s.escaped?l.unescapeBlob(s.body):c(s.body,W);r=t.encode?i.btoa(f):u(f,a),n(null,r)})},K._getRevisionTree=function(e,t){$.readTransaction(function(n){var r="SELECT json AS metadata FROM "+h+" WHERE id = ?";n.executeSql(r,[e],function(e,n){if(n.rows.length){var r=i.safeJsonParse(n.rows.item(0).metadata);t(null,r.rev_tree)}else t(a.error(a.MISSING_DOC))})})},K._doCompaction=function(e,t,n){return t.length?void $.transaction(function(n){var r="SELECT json AS metadata FROM "+h+" WHERE id = ?";n.executeSql(r,[e],function(n,r){var o=i.safeJsonParse(r.rows.item(0).metadata);s.traverseRevTree(o.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;-1!==t.indexOf(s)&&(i.status="missing")});var a="UPDATE "+h+" SET json = ? WHERE id = ?";n.executeSql(a,[i.safeJsonStringify(o),e])}),T(t,e,n)},x(n),function(){n()}):n()},K._getLocal=function(e,t){$.readTransaction(function(n){var r="SELECT json, rev FROM "+_+" WHERE id=?";n.executeSql(r,[e],function(n,r){if(r.rows.length){var o=r.rows.item(0),i=w(o.json,e,o.rev);t(null,i)}else t(a.error(a.MISSING_DOC))})})},K._putLocal=function(e,t,n){function r(e){var r,f;i?(r="UPDATE "+_+" SET rev=?, json=? WHERE id=? AND rev=?",f=[o,u,s,i]):(r="INSERT INTO "+_+" (id, rev, json) VALUES (?,?,?)",f=[s,o,u]),e.executeSql(r,f,function(e,r){r.rowsAffected?(c={ok:!0,id:s,rev:o},t.ctx&&n(null,c)):n(a.error(a.REV_CONFLICT))},function(){return n(a.error(a.REV_CONFLICT)),!1})}"function"==typeof t&&(n=t,t={}),delete e._revisions;var o,i=e._rev,s=e._id;o=i?e._rev="0-"+(parseInt(i.split("-")[1],10)+1):e._rev="0-1";var c,u=E(e);t.ctx?r(t.ctx):$.transaction(function(e){r(e)},x(n),function(){c&&n(null,c)})},K._removeLocal=function(e,t){var n;$.transaction(function(r){var o="DELETE FROM "+_+" WHERE id=? AND rev=?",i=[e._id,e._rev];r.executeSql(o,i,function(r,o){return o.rowsAffected?void(n={ok:!0,id:e._id,rev:"0-0"}):t(a.error(a.MISSING_DOC))})},x(t),function(){n&&t(null,n)})},void(K._destroy=function(e){o.Changes.removeAllListeners(K._name),$.transaction(function(e){var t=[h,v,m,g,_,y];t.forEach(function(t){e.executeSql("DROP TABLE IF EXISTS "+t,[])})},x(e),function(){i.hasLocalStorage()&&(delete window.localStorage["_pouch__websqldb_"+K._name],delete window.localStorage[K._name]),e(null,{ok:!0})})})):t(a.error(a.UNKNOWN_ERROR))}var i=e(48),s=e(37),a=e(24),c=e(29),u=e(19),f=e(10),l=e(11),d=e(9),p=f.ADAPTER_VERSION,h=f.DOC_STORE,v=f.BY_SEQ_STORE,m=f.ATTACH_STORE,_=f.LOCAL_STORE,g=f.META_STORE,y=f.ATTACH_AND_SEQ_STORE,b=l.qMarks,E=l.stringifyDoc,w=l.unstringifyDoc,S=l.select,T=l.compactRevs,x=l.unknownError,O=l.getSize,A=l.openDB,k=1,q="CREATE INDEX IF NOT EXISTS 'by-seq-deleted-idx' ON "+v+" (seq, deleted)",R="CREATE UNIQUE INDEX IF NOT EXISTS 'by-seq-doc-id-rev' ON "+v+" (doc_id, rev)",C="CREATE INDEX IF NOT EXISTS 'doc-winningseq-idx' ON "+h+" (winningseq)",D="CREATE INDEX IF NOT EXISTS 'attach-seq-seq-idx' ON "+y+" (seq)",I="CREATE UNIQUE INDEX IF NOT EXISTS 'attach-seq-digest-idx' ON "+y+" (digest, seq)",L=v+".seq = "+h+".winningseq",N=v+".seq AS seq, "+v+".deleted AS deleted, "+v+".json AS data, "+v+".rev AS rev, "+h+".json AS metadata";o.valid=l.valid,o.Changes=new i.Changes,t.exports=o},{10:10,11:11,19:19,24:24,29:29,37:37,48:48,9:9}],13:[function(e,t,n){"use strict";function r(e,t,n){function r(){o.cancel()}c.call(this);var o=this;this.db=e,t=t?i.clone(t):{};var s=n||t.complete||function(){},a=t.complete=i.once(function(t,n){t?o.emit("error",t):o.emit("complete",n),o.removeAllListeners(),e.removeListener("destroyed",r)});s&&(o.on("complete",function(e){s(null,e)}),o.on("error",function(e){s(e)}));var u=t.onChange;u&&o.on("change",u),e.once("destroyed",r),t.onChange=function(e){t.isCancelled||(o.emit("change",e),o.startSeq&&o.startSeq<=e.seq&&(o.emit("uptodate"),o.startSeq=!1),e.deleted?o.emit("delete",e):1===e.changes.length&&"1-"===e.changes[0].rev.slice(0,2)?o.emit("create",e):o.emit("update",e))};var f=new i.Promise(function(e,n){t.complete=function(t,r){t?n(t):e(r)}});o.once("cancel",function(){u&&o.removeListener("change",u),e.removeListener("destroyed",r),t.complete(null,{status:"cancelled"})}),this.then=f.then.bind(f),this["catch"]=f["catch"].bind(f),this.then(function(e){a(null,e)},a),e.taskqueue.isReady?o.doChanges(t):e.taskqueue.addTask(function(){o.isCancelled?o.emit("cancel"):o.doChanges(t)})}function o(e,t,n){var r=[{rev:e._rev}];"all_docs"===n.style&&(r=s.collectLeaves(t.rev_tree).map(function(e){return{rev:e.rev}}));var o={id:t.id,changes:r,doc:e};return i.isDeleted(t,e._rev)&&(o.deleted=!0),n.conflicts&&(o.doc._conflicts=s.collectConflicts(t),o.doc._conflicts.length||delete o.doc._conflicts),o}var i=e(48),s=e(37),a=e(24),c=e(52).EventEmitter,u=e(35),f=e(36);t.exports=r,i.inherits(r,c),r.prototype.cancel=function(){this.isCancelled=!0,this.db.taskqueue.isReady&&this.emit("cancel")},r.prototype.doChanges=function(e){var t=this,n=e.complete;if(e=i.clone(e),"live"in e&&!("continuous"in e)&&(e.continuous=e.live),e.processChange=o,"latest"===e.since&&(e.since="now"),e.since||(e.since=0),"now"===e.since)return void this.db.info().then(function(r){return t.isCancelled?void n(null,{status:"cancelled"}):(e.since=r.update_seq,void t.doChanges(e))},n);if(e.continuous&&"now"!==e.since&&this.db.info().then(function(e){t.startSeq=e.update_seq},function(e){if("idbNull"!==e.id)throw e}),"http"!==this.db.type()&&e.filter&&"string"==typeof e.filter&&!e.doc_ids)return this.filterChanges(e);"descending"in e||(e.descending=!1),e.limit=0===e.limit?1:e.limit,e.complete=n;var r=this.db._changes(e);if(r&&"function"==typeof r.cancel){var s=t.cancel;t.cancel=i.getArguments(function(e){r.cancel(),s.apply(this,e)})}},r.prototype.filterChanges=function(e){var t=this,n=e.complete;if("_view"===e.filter){if(!e.view||"string"!=typeof e.view){var r=a.error(a.BAD_REQUEST,"`view` filter parameter is not provided.");return void n(r)}var o=e.view.split("/");this.db.get("_design/"+o[0],function(r,i){if(t.isCancelled)return void n(null,{status:"cancelled"});if(r)return void n(a.generateErrorFromResponse(r));if(i&&i.views&&i.views[o[1]]){var s=f(i.views[o[1]].map);return e.filter=s,void t.doChanges(e)}var c=i.views?"missing json key: "+o[1]:"missing json key: views";r||(r=a.error(a.MISSING_DOC,c)),n(r)})}else{var i=e.filter.split("/");this.db.get("_design/"+i[0],function(r,o){if(t.isCancelled)return void n(null,{status:"cancelled"});if(r)return void n(a.generateErrorFromResponse(r));if(o&&o.filters&&o.filters[i[1]]){var s=u(o.filters[i[1]]);return e.filter=s,void t.doChanges(e)}var c=o&&o.filters?"missing json key: "+i[1]:"missing json key: filters";return r||(r=a.error(a.MISSING_DOC,c)),void n(r)})}}},{24:24,35:35,36:36,37:37,48:48,52:52}],14:[function(e,t,n){(function(n,r){"use strict";function o(e){e&&r.debug&&console.error(e)}function i(e,t,r){if(!(this instanceof i))return new i(e,t,r);var f=this;("function"==typeof t||"undefined"==typeof t)&&(r=t,t={}),e&&"object"==typeof e&&(t=e,e=void 0),"undefined"==typeof r&&(r=o),e=e||t.name,t=t?a.clone(t):{},delete t.name,this.__opts=t;var l=r;f.auto_compaction=t.auto_compaction,f.prefix=i.prefix,s.call(f),
-f.taskqueue=new c;var d=new u(function(o,s){r=function(e,t){return e?s(e):(delete t.then,void o(t))},t=a.clone(t);var c,u,l=t.name||e;return function(){try{if("string"!=typeof l)throw u=new Error("Missing/invalid DB name"),u.code=400,u;if(c=i.parseAdapter(l,t),t.originalName=l,t.name=c.name,t.prefix&&"http"!==c.adapter&&"https"!==c.adapter&&(t.name=t.prefix+t.name),t.adapter=t.adapter||c.adapter,f._adapter=t.adapter,f._db_name=l,!i.adapters[t.adapter])throw u=new Error("Adapter is missing"),u.code=404,u;if(!i.adapters[t.adapter].valid())throw u=new Error("Invalid Adapter"),u.code=404,u}catch(e){f.taskqueue.fail(e),f.changes=a.toPromise(function(t){t.complete&&t.complete(e)})}}(),u?s(u):(f.adapter=t.adapter,f.replicate={},f.replicate.from=function(e,t,n){return f.constructor.replicate(e,f,t,n)},f.replicate.to=function(e,t,n){return f.constructor.replicate(f,e,t,n)},f.sync=function(e,t,n){return f.constructor.sync(f,e,t,n)},f.replicate.sync=f.sync,i.adapters[t.adapter].call(f,t,function(e){function n(){i.emit("destroyed",t.originalName),i.emit(t.originalName,"destroyed"),f.removeListener("destroyed",n)}return e?void(r&&(f.taskqueue.fail(e),r(e))):(f.on("destroyed",n),f.emit("created",f),i.emit("created",t.originalName),f.taskqueue.ready(f),void r(null,f))}),t.skipSetup&&(f.taskqueue.ready(f),n.nextTick(function(){r(null,f)})),void(a.isCordova()&&cordova.fireWindowEvent(t.name+"_pouch",{})))});d.then(function(e){l(null,e)},l),f.then=d.then.bind(d),f["catch"]=d["catch"].bind(d)}var s=e(1),a=e(48),c=e(47),u=a.Promise;a.inherits(i,s),i.debug=e(54),t.exports=i}).call(this,e(53),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1,47:47,48:48,53:53,54:54}],15:[function(e,t,n){(function(n){"use strict";function r(e,t){function r(t,n,r){if(e.binary||e.json||!e.processData||"string"==typeof t){if(!e.binary&&e.json&&"string"==typeof t)try{t=JSON.parse(t)}catch(o){return r(o)}}else t=JSON.stringify(t);Array.isArray(t)&&(t=t.map(function(e){return e.error||e.missing?s.generateErrorFromResponse(e):e})),r(null,t,n)}function c(e,t){var n,r;if(e.code&&e.status){var o=new Error(e.message||e.code);return o.status=e.status,t(o)}try{n=JSON.parse(e.responseText),r=s.generateErrorFromResponse(n)}catch(i){r=s.generateErrorFromResponse(e)}t(r)}function u(e){return n.browser?"":new i("","binary")}var f=!1,l=a.getArguments(function(e){f||(t.apply(this,e),f=!0)});"function"==typeof e&&(l=e,e={}),e=a.clone(e);var d={method:"GET",headers:{},json:!0,processData:!0,timeout:1e4,cache:!1};return e=a.extend(!0,d,e),e.json&&(e.binary||(e.headers.Accept="application/json"),e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json"),e.binary&&(e.encoding=null,e.json=!1),e.processData||(e.json=!1),o(e,function(t,n,o){if(t)return t.status=n?n.statusCode:400,c(t,l);var i,a=n.headers&&n.headers["content-type"],f=o||u();e.binary||!e.json&&e.processData||"object"==typeof f||!(/json/.test(a)||/^[\s]*\{/.test(f)&&/\}[\s]*$/.test(f))||(f=JSON.parse(f)),n.statusCode>=200&&n.statusCode<300?r(f,n,l):(e.binary&&(f=JSON.parse(f.toString())),i=s.generateErrorFromResponse(f),i.status=n.statusCode,l(i))})}var o=e(32),i=e(23),s=e(24),a=e(48);t.exports=r}).call(this,e(53))},{23:23,24:24,32:32,48:48,53:53}],16:[function(e,t,n){"use strict";t.exports=function(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,o=0;r>o;o++)t+=String.fromCharCode(n[o]);return t}},{}],17:[function(e,t,n){"use strict";var r=e(23);"function"==typeof atob?n.atob=function(e){return atob(e)}:n.atob=function(e){var t=new r(e,"base64");if(t.toString("base64")!==e)throw"Cannot base64 encode full string";return t.toString("binary")},"function"==typeof btoa?n.btoa=function(e){return btoa(e)}:n.btoa=function(e){return new r(e,"binary").toString("base64")}},{23:23}],18:[function(e,t,n){"use strict";t.exports=function(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),o=0;t>o;o++)r[o]=e.charCodeAt(o);return n}},{}],19:[function(e,t,n){"use strict";var r=e(20),o=e(18);t.exports=function(e,t){return r([o(e)],{type:t})}},{18:18,20:20}],20:[function(e,t,n){(function(e){"use strict";function n(t,n){t=t||[],n=n||{};try{return new Blob(t,n)}catch(r){if("TypeError"!==r.name)throw r;for(var o=e.BlobBuilder||e.MSBlobBuilder||e.MozBlobBuilder||e.WebKitBlobBuilder,i=new o,s=0;s<t.length;s+=1)i.append(t[s]);return i.getBlob(n.type)}}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],21:[function(e,t,n){"use strict";t.exports=function(e,t){var n=new FileReader;n.onloadend=function(e){var n=e.target.result||new ArrayBuffer(0);t(n)},n.readAsArrayBuffer(e)}},{}],22:[function(e,t,n){"use strict";var r=e(16);t.exports=function(e,t){var n=new FileReader,o="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";return o?t(n):void t(r(n))},o?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}},{16:16}],23:[function(e,t,n){t.exports={}},{}],24:[function(e,t,n){"use strict";function r(e){Error.call(e.reason),this.status=e.status,this.name=e.error,this.message=e.reason,this.error=!0}var o=e(57);o(r,Error),r.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message})},n.UNAUTHORIZED=new r({status:401,error:"unauthorized",reason:"Name or password is incorrect."}),n.MISSING_BULK_DOCS=new r({status:400,error:"bad_request",reason:"Missing JSON list of 'docs'"}),n.MISSING_DOC=new r({status:404,error:"not_found",reason:"missing"}),n.REV_CONFLICT=new r({status:409,error:"conflict",reason:"Document update conflict"}),n.INVALID_ID=new r({status:400,error:"invalid_id",reason:"_id field must contain a string"}),n.MISSING_ID=new r({status:412,error:"missing_id",reason:"_id is required for puts"}),n.RESERVED_ID=new r({status:400,error:"bad_request",reason:"Only reserved document ids may start with underscore."}),n.NOT_OPEN=new r({status:412,error:"precondition_failed",reason:"Database not open"}),n.UNKNOWN_ERROR=new r({status:500,error:"unknown_error",reason:"Database encountered an unknown error"}),n.BAD_ARG=new r({status:500,error:"badarg",reason:"Some query argument is invalid"}),n.INVALID_REQUEST=new r({status:400,error:"invalid_request",reason:"Request was invalid"}),n.QUERY_PARSE_ERROR=new r({status:400,error:"query_parse_error",reason:"Some query parameter is invalid"}),n.DOC_VALIDATION=new r({status:500,error:"doc_validation",reason:"Bad special document member"}),n.BAD_REQUEST=new r({status:400,error:"bad_request",reason:"Something wrong with the request"}),n.NOT_AN_OBJECT=new r({status:400,error:"bad_request",reason:"Document must be a JSON object"}),n.DB_MISSING=new r({status:404,error:"not_found",reason:"Database not found"}),n.IDB_ERROR=new r({status:500,error:"indexed_db_went_bad",reason:"unknown"}),n.WSQ_ERROR=new r({status:500,error:"web_sql_went_bad",reason:"unknown"}),n.LDB_ERROR=new r({status:500,error:"levelDB_went_went_bad",reason:"unknown"}),n.FORBIDDEN=new r({status:403,error:"forbidden",reason:"Forbidden by design doc validate_doc_update function"}),n.INVALID_REV=new r({status:400,error:"bad_request",reason:"Invalid rev format"}),n.FILE_EXISTS=new r({status:412,error:"file_exists",reason:"The database could not be created, the file already exists."}),n.MISSING_STUB=new r({status:412,error:"missing_stub"}),n.error=function(e,t,n){function o(t){for(var r in e)"function"!=typeof e[r]&&(this[r]=e[r]);void 0!==n&&(this.name=n),void 0!==t&&(this.reason=t)}return o.prototype=r.prototype,new o(t)},n.getErrorTypeByProp=function(e,t,r){var o=n,i=Object.keys(o).filter(function(n){var r=o[n];return"function"!=typeof r&&r[e]===t}),s=r&&i.filter(function(e){var t=o[e];return t.message===r})[0]||i[0];return s?o[s]:null},n.generateErrorFromResponse=function(e){var t,r,o,i,s,a=n;return r=e.error===!0&&"string"==typeof e.name?e.name:e.error,s=e.reason,o=a.getErrorTypeByProp("name",r,s),e.missing||"missing"===s||"deleted"===s||"not_found"===r?o=a.MISSING_DOC:"doc_validation"===r?(o=a.DOC_VALIDATION,i=s):"bad_request"===r&&o.message!==s&&(0===s.indexOf("unknown stub attachment")?(o=a.MISSING_STUB,i=s):o=a.BAD_REQUEST),o||(o=a.getErrorTypeByProp("status",e.status,s)||a.UNKNOWN_ERROR),t=a.error(o,s,r),i&&(t.message=i),e.id&&(t.id=e.id),e.status&&(t.status=e.status),e.statusText&&(t.name=e.statusText),e.missing&&(t.missing=e.missing),t}},{57:57}],25:[function(e,t,n){(function(e,n){"use strict";function r(t){e.browser&&"console"in n&&"info"in console&&console.info("The above 404 is totally normal. "+t)}t.exports=r}).call(this,e(53),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{53:53}],26:[function(e,t,n){(function(n,r){"use strict";function o(e){return String.fromCharCode(255&e)+String.fromCharCode(e>>>8&255)+String.fromCharCode(e>>>16&255)+String.fromCharCode(e>>>24&255)}function i(e){for(var t="",n=0,r=e.length;r>n;n++)t+=o(e[n]);return c.btoa(t)}function s(e,t,n,r){(n>0||r<t.byteLength)&&(t=new Uint8Array(t,n,Math.min(r,t.byteLength)-n)),e.append(t)}function a(e,t,n,r){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t)}var c=e(17),u=e(51),f=e(87),l=r.setImmediate||r.setTimeout,d=32768;t.exports=function(e,t){function r(){var n=m*h,o=n+h;if(m++,v>m)g(_,e,n,o),l(r);else{g(_,e,n,o);var s=_.end(!0),a=i(s);t(null,a),_.destroy()}}if(!n.browser){var o=u.createHash("md5").update(e).digest("base64");return void t(null,o)}var c="string"==typeof e,p=c?e.length:e.byteLength,h=Math.min(d,p),v=Math.ceil(p/h),m=0,_=c?new f:new f.ArrayBuffer,g=c?a:s;r()}}).call(this,e(53),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{17:17,51:51,53:53,87:87}],27:[function(e,t,n){(function(n){"use strict";function r(e,t){return d?c(e,{type:t}):p.concat(e.map(function(e){return new p(e,"binary")}))}function o(e){e=l(e);var t=a(),n={};Object.keys(e._attachments).forEach(function(t){var r=e._attachments[t];if(!r.stub){var o=s(r.data);n[t]={type:r.content_type,data:o},r.length=o.length,r.follows=!0,delete r.digest,delete r.data}});var o="--"+t+"\r\nContent-Type: application/json\r\n\r\n",i=[o,JSON.stringify(e)];Object.keys(n).forEach(function(e){var r=n[e],o="\r\n--"+t+"\r\nContent-Disposition: attachment; filename="+JSON.stringify(e)+"\r\nContent-Type: "+r.type+"\r\nContent-Length: "+r.data.length+"\r\n\r\n";i.push(o),i.push(d?u(r.data):r.data)}),i.push("\r\n--"+t+"--");var c="multipart/related; boundary="+t,f=r(i,c);return{headers:{"Content-Type":c},body:f}}var i=e(17),s=i.atob,a=e(34),c=e(20),u=e(18),f=e(48),l=f.clone,d="undefined"==typeof n||n.browser,p=e(23);t.exports=o}).call(this,e(53))},{17:17,18:18,20:20,23:23,34:34,48:48,53:53}],28:[function(e,t,n){"use strict";function r(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function o(e){if(!/^\d+\-./.test(e))return s.error(s.INVALID_REV);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function i(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,o=[r[0],t,[]],i=1,s=r.length;s>i;i++)o=[r[i],{status:"missing"},[o]];return[{pos:n,ids:o}]}var s=e(24),a=e(34),c=r(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"]),u=r(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]);n.invalidIdError=function(e){var t;if(e?"string"!=typeof e?t=s.error(s.INVALID_ID):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=s.error(s.RESERVED_ID)):t=s.error(s.MISSING_ID),t)throw t},n.parseDoc=function(e,t){var r,f,l,d={status:"available"};if(e._deleted&&(d.deleted=!0),t)if(e._id||(e._id=a()),f=a(32,16).toLowerCase(),e._rev){if(l=o(e._rev),l.error)return l;e._rev_tree=[{pos:l.prefix,ids:[l.id,{status:"missing"},[[f,d,[]]]]}],r=l.prefix+1}else e._rev_tree=[{pos:1,ids:[f,d,[]]}],r=1;else if(e._revisions&&(e._rev_tree=i(e._revisions,d),r=e._revisions.start,f=e._revisions.ids[0]),!e._rev_tree){if(l=o(e._rev),l.error)return l;r=l.prefix,f=l.id,e._rev_tree=[{pos:r,ids:[f,d,[]]}]}n.invalidIdError(e._id),e._rev=r+"-"+f;var p={metadata:{},data:{}};for(var h in e)if(e.hasOwnProperty(h)){var v="_"===h[0];if(v&&!c[h]){var m=s.error(s.DOC_VALIDATION,h);throw m.message=s.DOC_VALIDATION.message+": "+h,m}v&&!u[h]?p.metadata[h.slice(1)]=e[h]:p.data[h]=e[h]}return p}},{24:24,34:34}],29:[function(e,t,n){"use strict";function r(e){return decodeURIComponent(window.escape(e))}function o(e){return 65>e?e-48:e-55}function i(e,t,n){for(var r="";n>t;)r+=String.fromCharCode(o(e.charCodeAt(t++))<<4|o(e.charCodeAt(t++)));return r}function s(e,t,n){for(var r="";n>t;)r+=String.fromCharCode(o(e.charCodeAt(t+2))<<12|o(e.charCodeAt(t+3))<<8|o(e.charCodeAt(t))<<4|o(e.charCodeAt(t+1))),t+=4;return r}function a(e,t){return"UTF-8"===t?r(i(e,0,e.length)):s(e,0,e.length)}t.exports=a},{}],30:[function(e,t,n){"use strict";function r(e){for(var t=o,n=t.parser[t.strictMode?"strict":"loose"].exec(e),r={},i=14;i--;){var s=t.key[i],a=n[i]||"",c=-1!==["user","password"].indexOf(s);r[s]=c?decodeURIComponent(a):a}return r[t.q.name]={},r[t.key[12]].replace(t.q.parser,function(e,n,o){n&&(r[t.q.name][n]=o)}),r}var o={strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};t.exports=r},{}],31:[function(e,t,n){"use strict";"function"==typeof Promise?t.exports=Promise:t.exports=e(61)},{61:61}],32:[function(e,t,n){"use strict";function r(){for(var e={},t=new c.Promise(function(t,n){e.resolve=t,e.reject=n}),n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.promise=t,c.Promise.resolve().then(function(){return fetch.apply(null,n)}).then(function(t){e.resolve(t)})["catch"](function(t){e.reject(t)}),e}function o(e,t){var n,o,i,s=new Headers,a={method:e.method,credentials:"include",headers:s};return e.json&&(s.set("Accept","application/json"),s.set("Content-Type",e.headers["Content-Type"]||"application/json")),e.body&&e.body instanceof Blob?u(e.body,function(e){a.body=e}):e.body&&e.processData&&"string"!=typeof e.body?a.body=JSON.stringify(e.body):"body"in e?a.body=e.body:a.body=null,Object.keys(e.headers).forEach(function(t){e.headers.hasOwnProperty(t)&&s.set(t,e.headers[t])}),n=r(e.url,a),e.timeout>0&&(o=setTimeout(function(){n.reject(new Error("Load timeout for resource: "+e.url))},e.timeout)),n.promise.then(function(t){return i={statusCode:t.status},e.timeout>0&&clearTimeout(o),i.statusCode>=200&&i.statusCode<300?e.binary?t.blob():t.text():t.json()}).then(function(e){i.statusCode>=200&&i.statusCode<300?t(null,i,e):t(e,i)})["catch"](function(e){t(e,i)}),{abort:n.reject}}function i(e,t){var n,r,o,i=function(){n.abort()};if(n=e.xhr?new e.xhr:new XMLHttpRequest,"GET"===e.method&&!e.cache){var s=-1!==e.url.indexOf("?");e.url+=(s?"&":"?")+"_nonce="+Date.now()}n.open(e.method,e.url),n.withCredentials=!0,"GET"===e.method?delete e.headers["Content-Type"]:e.json&&(e.headers.Accept="application/json",e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json",e.body&&e.processData&&"string"!=typeof e.body&&(e.body=JSON.stringify(e.body))),e.binary&&(n.responseType="arraybuffer"),"body"in e||(e.body=null);for(var c in e.headers)e.headers.hasOwnProperty(c)&&n.setRequestHeader(c,e.headers[c]);return e.timeout>0&&(r=setTimeout(i,e.timeout),n.onprogress=function(){clearTimeout(r),r=setTimeout(i,e.timeout)},"undefined"==typeof o&&(o=-1!==Object.keys(n).indexOf("upload")&&"undefined"!=typeof n.upload),o&&(n.upload.onprogress=n.onprogress)),n.onreadystatechange=function(){if(4===n.readyState){var r={statusCode:n.status};if(n.status>=200&&n.status<300){var o;o=e.binary?a([n.response||""],{type:n.getResponseHeader("Content-Type")}):n.responseText,t(null,r,o)}else{var i={};try{i=JSON.parse(n.response)}catch(s){}t(i,r)}}},e.body&&e.body instanceof Blob?u(e.body,function(e){n.send(e)}):n.send(e.body),{abort:i}}function s(){try{return new XMLHttpRequest,!0}catch(e){return!1}}var a=e(20),c=e(48),u=e(21),f=s();t.exports=function(e,t){return f||e.xhr?i(e,t):o(e,t)}},{20:20,21:21,48:48}],33:[function(e,t,n){"use strict";var r=e(86).upsert;t.exports=function(e,t,n,o){return r.call(e,t,n,o)}},{86:86}],34:[function(e,t,n){"use strict";function r(e){return 0|Math.random()*e}function o(e,t){t=t||i.length;var n="",o=-1;if(e){for(;++o<e;)n+=i[r(t)];return n}for(;++o<36;)switch(o){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=i[3&r(16)|8];break;default:n+=i[r(16)]}return n}var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");t.exports=o},{}],35:[function(_dereq_,module,exports){"use strict";function evalFilter(input){return eval(["(function () { return ",input," })()"].join(""))}module.exports=evalFilter},{}],36:[function(_dereq_,module,exports){"use strict";function evalView(input){return eval(["(function () {","  return function (doc) {","    var emitted = false;","    var emit = function (a, b) {","      emitted = true;","    };","    var view = "+input+";","    view(doc);","    if (emitted) {","      return true;","    }","  }","})()"].join("\n"))}module.exports=evalView},{}],37:[function(e,t,n){"use strict";function r(e,t,n){for(var r,o=0,i=e.length;i>o;)r=o+i>>>1,n(e[r],t)<0?o=r+1:i=r;return o}function o(e,t,n){var o=r(e,t,n);e.splice(o,0,t)}function i(e){for(var t,n=e.shift(),r=[n.id,n.opts,[]],o=r;e.length;)n=e.shift(),t=[n.id,n.opts,[]],o[2].push(t),o=t;return r}function s(e,t){return e[0]<t[0]?-1:1}function a(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var i=n.pop(),a=i.tree1,c=i.tree2;(a[1].status||c[1].status)&&(a[1].status="available"===a[1].status||"available"===c[1].status?"available":"missing");for(var u=0;u<c[2].length;u++)if(a[2][0]){for(var f=!1,l=0;l<a[2].length;l++)a[2][l][0]===c[2][u][0]&&(n.push({tree1:a[2][l],tree2:c[2][u]}),f=!0);f||(r="new_branch",o(a[2],c[2][u],s))}else r="new_leaf",a[2][0]=c[2][u]}return{conflicts:r,tree:e}}function c(e,t,n){var r,o=[],i=!1,s=!1;return e.length?(e.forEach(function(e){if(e.pos===t.pos&&e.ids[0]===t.ids[0])r=a(e.ids,t.ids),o.push({pos:e.pos,ids:r.tree}),i=i||r.conflicts,s=!0;else if(n!==!0){var c=e.pos<t.pos?e:t,u=e.pos<t.pos?t:e,f=u.pos-c.pos,l=[],d=[];for(d.push({ids:c.ids,diff:f,parent:null,parentIdx:null});d.length>0;){var p=d.pop();0!==p.diff?p.ids&&p.ids[2].forEach(function(e,t){d.push({ids:e,diff:p.diff-1,parent:p.ids,parentIdx:t})}):p.ids[0]===u.ids[0]&&l.push(p)}var h=l[0];h?(r=a(h.ids,u.ids),h.parent[2][h.parentIdx]=r.tree,o.push({pos:c.pos,ids:c.ids}),i=i||r.conflicts,s=!0):o.push(e)}else o.push(e)}),s||o.push(t),o.sort(function(e,t){return e.pos-t.pos}),{tree:o,conflicts:i||"internal_node"}):{tree:[t],conflicts:"new_leaf"}}function u(e,t){var n=l.rootToLeaf(e).map(function(e){var n=e.ids.slice(-t);return{pos:e.pos+(e.ids.length-n.length),ids:i(n)}});return n.reduce(function(e,t){return c(e,t,!0).tree},[n.shift()])}var f=e(79),l={};l.merge=function(e,t,n){e=f(!0,[],e),t=f(!0,{},t);var r=c(e,t);return{tree:u(r.tree,n),conflicts:r.conflicts}},l.winningRev=function(e){var t=[];return l.traverseRevTree(e.rev_tree,function(e,n,r,o,i){e&&t.push({pos:n,id:r,deleted:!!i.deleted})}),t.sort(function(e,t){return e.deleted!==t.deleted?e.deleted>t.deleted?1:-1:e.pos!==t.pos?t.pos-e.pos:e.id<t.id?1:-1}),t[0].pos+"-"+t[0].id},l.traverseRevTree=function(e,t){for(var n,r=e.slice();n=r.pop();)for(var o=n.pos,i=n.ids,s=i[2],a=t(0===s.length,o,i[0],n.ctx,i[1]),c=0,u=s.length;u>c;c++)r.push({pos:o+1,ids:s[c],ctx:a})},l.collectLeaves=function(e){var t=[];return l.traverseRevTree(e,function(e,n,r,o,i){e&&t.push({rev:n+"-"+r,pos:n,opts:i})}),t.sort(function(e,t){return t.pos-e.pos}),t.forEach(function(e){delete e.pos}),t},l.collectConflicts=function(e){var t=l.winningRev(e),n=l.collectLeaves(e.rev_tree),r=[];return n.forEach(function(e){e.rev===t||e.opts.deleted||r.push(e.rev)}),r},l.rootToLeaf=function(e){var t=[];return l.traverseRevTree(e,function(e,n,r,o,i){if(o=o?o.slice(0):[],o.push({id:r,opts:i}),e){var s=n+1-o.length;t.unshift({pos:s,ids:o})}return o}),t},t.exports=l},{79:79}],38:[function(e,t,n){"use strict";function r(e,t){e=parseInt(e,10),t=parseInt(t,10),e!==e&&(e=0),t!==t||e>=t?t=(e||1)<<1:t+=1;var n=Math.random(),r=t-e;return~~(r*n+e)}function o(e){var t=0;return e||(t=2e3),r(e,t)}function i(e,t,n,r){return e.retry===!1?(t.emit("error",n),void t.removeAllListeners()):("function"!=typeof e.back_off_function&&(e.back_off_function=o),t.emit("requestError",n),"active"===t.state&&(t.emit("paused",n),t.state="stopped",t.once("active",function(){e.current_back_off=s})),e.current_back_off=e.current_back_off||s,e.current_back_off=e.back_off_function(e.current_back_off),void setTimeout(r,e.current_back_off))}var s=0;t.exports=i},{}],39:[function(e,t,n){"use strict";function r(e,t,n,o){return e.get(t)["catch"](function(n){if(404===n.status)return"http"===e.type()&&s("PouchDBVersion360 is just checking if a remote checkpoint exists."),{_id:t};throw n}).then(function(i){return o.cancelled?void 0:(i.last_seq=n,e.put(i)["catch"](function(i){if(409===i.status)return r(e,t,n,o);throw i}))})}function o(e,t,n,r){this.src=e,this.target=t,this.id=n,this.returnValue=r}var i=e(31),s=e(25),a=e(76),c=a.collate;o.prototype.writeCheckpoint=function(e){var t=this;return this.updateTarget(e).then(function(){return t.updateSource(e)})},o.prototype.updateTarget=function(e){return r(this.target,this.id,e,this.returnValue)},o.prototype.updateSource=function(e){var t=this;return this.readOnlySource?i.resolve(!0):r(this.src,this.id,e,this.returnValue)["catch"](function(e){var n="number"==typeof e.status&&4===Math.floor(e.status/100);if(n)return t.readOnlySource=!0,!0;throw e})},o.prototype.getCheckpoint=function(){var e=this;return e.target.get(e.id).then(function(t){return e.src.get(e.id).then(function(e){return 0===c(t.last_seq,e.last_seq)?e.last_seq:0},function(n){if(404===n.status&&t.last_seq)return e.src.put({_id:e.id,last_seq:0}).then(function(){return 0},function(n){return 401===n.status?(e.readOnlySource=!0,t.last_seq):0});throw n})})["catch"](function(e){if(404!==e.status)throw e;return 0})},t.exports=o},{25:25,31:31,76:76}],40:[function(e,t,n){"use strict";function r(e,t,n){var r=n.filter?n.filter.toString():"";return e.id().then(function(e){return t.id().then(function(t){var i=e+t+r+JSON.stringify(n.query_params)+n.doc_ids;return o.MD5(i).then(function(e){return e=e.replace(/\//g,".").replace(/\+/g,"_"),"_local/"+e})})})}var o=e(48);t.exports=r},{48:48}],41:[function(e,t,n){"use strict";function r(e){return/^1-/.test(e)}function o(e,t,n){function o(t,r){var o={revs:!0,open_revs:r,attachments:!0};return e.get(t,o).then(function(e){if(n.cancelled)throw new Error("cancelled");e.forEach(function(e){e.ok&&h.push(e.ok)})})}function i(e){for(var n=t[e].missing,r=[],i=0;i<n.length;i+=c){var s=n.slice(i,Math.min(n.length,i+c));r.push(s)}return a.all(r.map(function(t){return o(e,t)}))}function u(){var e=Object.keys(t);return a.all(e.map(i))}function f(e){return e._attachments&&Object.keys(e._attachments).length>0}function l(o){return e.allDocs({keys:o,include_docs:!0}).then(function(e){if(n.cancelled)throw new Error("cancelled");e.rows.forEach(function(e){!e.deleted&&e.doc&&r(e.value.rev)&&!f(e.doc)&&(h.push(e.doc),delete t[e.id])})})}function d(){var e=Object.keys(t).filter(function(e){var n=t[e].missing;return 1===n.length&&r(n[0])});return e.length>0?l(e):void 0}function p(){return h}t=s(t);var h=[];return a.resolve().then(d).then(u).then(p)}var i=e(48),s=i.clone,a=i.Promise,c=50;t.exports=o},{48:48}],42:[function(e,t,n){"use strict";function r(e,t){var n=t.PouchConstructor;return"string"==typeof e?new n(e,t):e}function o(e,t,n,o){"function"==typeof n&&(o=n,n={}),"undefined"==typeof n&&(n={}),n.complete||(n.complete=o||function(){}),n=i.clone(n),n.continuous=n.continuous||n.live,n.retry="retry"in n?n.retry:!1,n.PouchConstructor=n.PouchConstructor||this;var c=new a(n),u=r(e,n),f=r(t,n);return s(u,f,n,c),c}var i=e(48),s=e(43),a=e(44);t.exports={replicate:o,toPouch:r}},{43:43,44:44,48:48}],43:[function(e,t,n){"use strict";function r(e,t,n,u,f){function l(){return A?o.Promise.resolve():a(e,t,n).then(function(n){O=n,A=new i(e,t,O,M)})}function d(){if(0!==x.docs.length){var e=x.docs;return t.bulkDocs({docs:e,new_edits:!1}).then(function(t){if(M.cancelled)throw y(),new Error("cancelled");var n=[],r={};t.forEach(function(e){e.error&&(f.doc_write_failures++,n.push(e),r[e.id]=e)}),P=P.concat(n),f.docs_written+=x.docs.length-n.length;var i=n.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(U=[],e.forEach(function(e){var t=r[e._id];t?u.emit("denied",o.clone(t)):U.push(e)}),i.length>0){var s=new Error("bulkDocs error");throw s.other_errors=n,g("target.bulkDocs failed to write docs",s),new Error("bulkWrite partial failure")}},function(t){throw f.doc_write_failures+=e.length,t})}}function p(){return R=!0,A.writeCheckpoint(x.seq).then(function(){if(R=!1,M.cancelled)throw y(),new Error("cancelled");f.last_seq=I=x.seq;var e=o.clone(f);e.docs=U,u.emit("change",e),x=void 0,S()})["catch"](function(e){throw R=!1,g("writeCheckpoint completed with error",e),e})}function h(){var e={};return x.changes.forEach(function(t){"_user/"!==t.id&&(e[t.id]=t.changes.map(function(e){return e.rev}))}),t.revsDiff(e).then(function(e){if(M.cancelled)throw y(),new Error("cancelled");x.diffs=e})}function v(){return c(e,x.diffs,M).then(function(e){e.forEach(function(e){delete x.diffs[e._id],f.docs_read++,x.docs.push(e)})})}function m(){if(!M.cancelled&&!x){if(0===k.length)return void _(!0);x=k.shift(),h().then(v).then(d).then(p).then(m)["catch"](function(e){g("batch processing terminated with error",e)})}}function _(e){return 0===q.changes.length?void(0!==k.length||x||((L&&J.live||C)&&(u.state="pending",u.emit("paused"),u.emit("uptodate",f)),C&&y())):void((e||C||q.changes.length>=N)&&(k.push(q),q={seq:0,changes:[],docs:[]},("pending"===u.state||"stopped"===u.state)&&(u.state="active",u.emit("active")),m()))}function g(e,t){D||(t.message||(t.message=e),f.ok=!1,f.status="aborting",f.errors.push(t),P=P.concat(t),k=[],q={seq:0,changes:[],docs:[]},y())}function y(){if(!(D||M.cancelled&&(f.status="cancelled",R))){f.status=f.status||"complete",f.end_time=new Date,f.last_seq=I,D=M.cancelled=!0;var o=P.filter(function(e){return"unauthorized"!==e.name&&"forbidden"!==e.name});if(o.length>0){var i=P.pop();P.length>0&&(i.other_errors=P),i.result=f,s(n,u,i,function(){r(e,t,n,u)})}else f.errors=P,u.emit("complete",f),u.removeAllListeners()}}function b(e){if(M.cancelled)return y();var t=o.filterChange(n)(e);t&&(q.seq=e.seq,q.changes.push(e),_(0===k.length))}function E(e){return B=!1,M.cancelled?y():(e.results.length>0?(J.since=e.last_seq,S()):L?(J.live=!0,S()):C=!0,void _(!0))}function w(e){return B=!1,M.cancelled?y():void g("changes rejected",e)}function S(){function t(){o.cancel()}function r(){u.removeListener("cancel",t)}if(!B&&!C&&k.length<j){B=!0,u._changes&&(u.removeListener("cancel",u._abortChanges),u._changes.cancel()),u.once("cancel",t);var o=e.changes(J).on("change",b);o.then(r,r),o.then(E)["catch"](w),n.retry&&(u._changes=o,u._abortChanges=t)}}function T(){l().then(function(){return M.cancelled?void y():A.getCheckpoint().then(function(e){I=e,J={since:I,limit:N,batch_size:N,style:"all_docs",doc_ids:F,returnDocs:!0},n.filter&&("string"!=typeof n.filter?J.include_docs=!0:J.filter=n.filter),n.query_params&&(J.query_params=n.query_params),n.view&&(J.view=n.view),S()})})["catch"](function(e){g("getCheckpoint rejected with ",e)})}var x,O,A,k=[],q={seq:0,changes:[],docs:[]},R=!1,C=!1,D=!1,I=0,L=n.continuous||n.live||!1,N=n.batch_size||100,j=n.batches_limit||10,B=!1,F=n.doc_ids,M={cancelled:!1},P=[],U=[];f=f||{ok:!0,start_time:new Date,docs_read:0,docs_written:0,doc_write_failures:0,errors:[]};var J={};return u.ready(e,t),u.cancelled?void y():(u._addedListeners||(u.once("cancel",y),"function"==typeof n.onChange&&u.on("change",n.onChange),"function"==typeof n.complete&&(u.once("error",n.complete),u.once("complete",function(e){n.complete(null,e)})),u._addedListeners=!0),void("undefined"==typeof n.since?T():l().then(function(){return R=!0,A.writeCheckpoint(n.since)}).then(function(){return R=!1,M.cancelled?void y():(I=n.since,void T())})["catch"](function(e){throw R=!1,g("writeCheckpoint completed with error",e),e})))}var o=e(48),i=e(39),s=e(38),a=e(40),c=e(41);t.exports=r},{38:38,39:39,40:40,41:41,48:48}],44:[function(e,t,n){"use strict";function r(){i.call(this),this.cancelled=!1,this.state="pending";var e=this,t=new s(function(t,n){e.once("complete",t),e.once("error",n)});e.then=function(e,n){return t.then(e,n)},e["catch"]=function(e){return t["catch"](e)},e["catch"](function(){})}var o=e(48),i=e(52).EventEmitter,s=o.Promise;o.inherits(r,i),r.prototype.cancel=function(){this.cancelled=!0,this.state="cancelled",this.emit("cancel")},r.prototype.ready=function(e,t){function n(){o.cancel()}function r(){e.removeListener("destroyed",n),t.removeListener("destroyed",n)}var o=this;o._readyCalled||(o._readyCalled=!0,e.once("destroyed",n),t.once("destroyed",n),o.once("complete",r))},t.exports=r},{48:48,52:52}],45:[function(e,t,n){"use strict";var r=e(14),o=e(48),i=e(52).EventEmitter;r.adapters={},r.preferredAdapters=[],r.prefix="_pouch_";var s=new i,a=["on","addListener","emit","listeners","once","removeAllListeners","removeListener","setMaxListeners"];a.forEach(function(e){r[e]=s[e].bind(s)}),r.setMaxListeners(0),r.parseAdapter=function(e,t){var n,i,s=e.match(/([a-z\-]*):\/\/(.*)/);if(s){if(e=/http(s?)/.test(s[1])?s[1]+"://"+s[2]:s[2],n=s[1],!r.adapters[n].valid())throw"Invalid adapter";return{name:e,adapter:s[1]}}var a="idb"in r.adapters&&"websql"in r.adapters&&o.hasLocalStorage()&&localStorage["_pouch__websqldb_"+r.prefix+e];if(t.adapter)i=t.adapter;else if("undefined"!=typeof t&&t.db)i="leveldb";else for(var c=0;c<r.preferredAdapters.length;++c)if(i=r.preferredAdapters[c],i in r.adapters){if(a&&"idb"===i){console.log('PouchDBVersion360 is downgrading "'+e+'" to WebSQL to avoid data loss, because it was already opened with WebSQL.');continue}break}n=r.adapters[i];var u=n&&"use_prefix"in n?n.use_prefix:!0;return{name:u?r.prefix+e:e,adapter:i}},r.destroy=o.toPromise(function(e,t,n){console.log("PouchDBVersion360.destroy() is deprecated and will be removed. Please use db.destroy() instead."),("function"==typeof t||"undefined"==typeof t)&&(n=t,t={}),e&&"object"==typeof e&&(t=e,e=void 0),new r(e,t,function(e,t){return e?n(e):void t.destroy(n)})}),r.adapter=function(e,t,n){t.valid()&&(r.adapters[e]=t,n&&r.preferredAdapters.push(e))},r.plugin=function(e){Object.keys(e).forEach(function(t){r.prototype[t]=e[t]})},r.defaults=function(e){function t(t,n,i){("function"==typeof n||"undefined"==typeof n)&&(i=n,n={}),t&&"object"==typeof t&&(n=t,t=void 0),n=o.extend(!0,{},e,n),r.call(this,t,n,i)}return o.inherits(t,r),t.destroy=o.toPromise(function(t,n,i){return("function"==typeof n||"undefined"==typeof n)&&(i=n,n={}),t&&"object"==typeof t&&(n=t,t=void 0),n=o.extend(!0,{},e,n),r.destroy(t,n,i)}),a.forEach(function(e){t[e]=s[e].bind(s)}),t.setMaxListeners(10),t.preferredAdapters=r.preferredAdapters.slice(),Object.keys(r).forEach(function(e){e in t||(t[e]=r[e])}),t},t.exports=r},{14:14,48:48,52:52}],46:[function(e,t,n){"use strict";function r(e,t,n,r){return"function"==typeof n&&(r=n,n={}),"undefined"==typeof n&&(n={}),n=i.clone(n),n.PouchConstructor=n.PouchConstructor||this,e=s.toPouch(e,n),t=s.toPouch(t,n),new o(e,t,n,r);
-}function o(e,t,n,r){function o(e){v||(v=!0,d.emit("cancel",e))}function s(e){d.emit("change",{direction:"pull",change:e})}function c(e){d.emit("change",{direction:"push",change:e})}function u(e){d.emit("denied",{direction:"push",doc:e})}function f(e){d.emit("denied",{direction:"pull",doc:e})}function l(e){return function(t,n){var r="change"===t&&(n===s||n===c),i="cancel"===t&&n===o,a=t in m&&n===m[t];(r||i||a)&&(t in _||(_[t]={}),_[t][e]=!0,2===Object.keys(_[t]).length&&d.removeAllListeners(t))}}var d=this;this.canceled=!1;var p,h;"onChange"in n&&(p=n.onChange,delete n.onChange),"function"!=typeof r||n.complete?"complete"in n&&(h=n.complete,delete n.complete):h=r,this.push=a(e,t,n),this.pull=a(t,e,n);var v=!1,m={},_={};n.live&&(this.push.on("complete",d.pull.cancel.bind(d.pull)),this.pull.on("complete",d.push.cancel.bind(d.push))),this.on("newListener",function(e){"change"===e?(d.pull.on("change",s),d.push.on("change",c)):"denied"===e?(d.pull.on("denied",f),d.push.on("denied",u)):"cancel"===e?(d.pull.on("cancel",o),d.push.on("cancel",o)):"error"===e||"removeListener"===e||"complete"===e||e in m||(m[e]=function(t){d.emit(e,t)},d.pull.on(e,m[e]),d.push.on(e,m[e]))}),this.on("removeListener",function(e){"change"===e?(d.pull.removeListener("change",s),d.push.removeListener("change",c)):"cancel"===e?(d.pull.removeListener("cancel",o),d.push.removeListener("cancel",o)):e in m&&"function"==typeof m[e]&&(d.pull.removeListener(e,m[e]),d.push.removeListener(e,m[e]),delete m[e])}),this.pull.on("removeListener",l("pull")),this.push.on("removeListener",l("push"));var g=i.Promise.all([this.push,this.pull]).then(function(e){var t={push:e[0],pull:e[1]};return d.emit("complete",t),h&&h(null,t),d.removeAllListeners(),t},function(e){throw d.cancel(),d.emit("error",e),h&&h(e),d.removeAllListeners(),e});this.then=function(e,t){return g.then(e,t)},this["catch"]=function(e){return g["catch"](e)}}var i=e(48),s=e(42),a=s.replicate,c=e(52).EventEmitter;i.inherits(o,c),t.exports=r,o.prototype.cancel=function(){this.canceled||(this.canceled=!0,this.push.cancel(),this.pull.cancel())}},{42:42,48:48,52:52}],47:[function(e,t,n){"use strict";function r(){this.isReady=!1,this.failed=!1,this.queue=[]}t.exports=r,r.prototype.execute=function(){var e,t;if(this.failed)for(;e=this.queue.shift();)"function"!=typeof e?(t=e.parameters[e.parameters.length-1],"function"==typeof t?t(this.failed):"changes"===e.name&&"function"==typeof t.complete&&t.complete(this.failed)):e(this.failed);else if(this.isReady)for(;e=this.queue.shift();)"function"==typeof e?e():e.task=this.db[e.name].apply(this.db,e.parameters)},r.prototype.fail=function(e){this.failed=e,this.execute()},r.prototype.ready=function(e){return this.failed?!1:0===arguments.length?this.isReady:(this.isReady=e?!0:!1,this.db=e,void this.execute())},r.prototype.addTask=function(e,t){if("function"!=typeof e){var n={name:e,parameters:t};return this.queue.push(n),this.failed&&this.execute(),n}this.queue.push(e),this.failed&&this.execute()}},{}],48:[function(e,t,n){(function(t){function r(){return"undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage&&"undefined"!=typeof chrome.storage.local}function o(){if(!(this instanceof o))return new o;var e=this;a.call(this),this.isChrome=r(),this._listeners={},this.hasLocal=!1,this.isChrome||(this.hasLocal=n.hasLocalStorage()),this.isChrome?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):this.hasLocal&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}var i=e(37);n.extend=e(79),n.ajax=e(15),n.createBlob=e(20),n.uuid=e(34),n.getArguments=e(50);var s=e(24),a=e(52).EventEmitter,c=e(78);n.Map=c.Map,n.Set=c.Set;var u=e(28),f=e(31);n.Promise=f;var l=e(17);n.atob=l.atob,n.btoa=l.btoa;var d=e(19),p=e(16),h=e(21);n.binaryStringToBlob=d,n.lastIndexOf=function(e,t){for(var n=e.length-1;n>=0;n--)if(e.charAt(n)===t)return n;return-1},n.clone=function(e){return n.extend(!0,{},e)},n.pick=function(e,t){for(var n={},r=0,o=t.length;o>r;r++){var i=t[r];n[i]=e[i]}return n},n.inherits=e(57),n.call=n.getArguments(function(e){if(e.length){var t=e.shift();"function"==typeof t&&t.apply(this,e)}}),n.isLocalId=function(e){return/^_local/.test(e)},n.isDeleted=function(e,t){t||(t=i.winningRev(e));var n=t.indexOf("-");-1!==n&&(t=t.substring(n+1));var r=!1;return i.traverseRevTree(e.rev_tree,function(e,n,o,i,s){o===t&&(r=!!s.deleted)}),r},n.revExists=function(e,t){var n=!1;return i.traverseRevTree(e.rev_tree,function(e,r,o){r+"-"+o===t&&(n=!0)}),n},n.filterChange=function(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){if(r.doc||(r.doc={}),e.filter&&n&&!e.filter.call(this,r.doc,t))return!1;if(e.include_docs){if(!e.attachments)for(var o in r.doc._attachments)r.doc._attachments.hasOwnProperty(o)&&(r.doc._attachments[o].stub=!0)}else delete r.doc;return!0}},n.parseDoc=u.parseDoc,n.invalidIdError=u.invalidIdError,n.isCordova=function(){return"undefined"!=typeof cordova||"undefined"!=typeof PhoneGap||"undefined"!=typeof phonegap},n.hasLocalStorage=function(){if(r())return!1;try{return localStorage}catch(e){return!1}},n.Changes=o,n.inherits(o,a),o.prototype.addListener=function(e,r,o,i){function s(){if(a._listeners[r]){if(c)return void(c="waiting");c=!0,o.changes({style:i.style,include_docs:i.include_docs,attachments:i.attachments,conflicts:i.conflicts,continuous:!1,descending:!1,filter:i.filter,doc_ids:i.doc_ids,view:i.view,since:i.since,query_params:i.query_params}).on("change",function(e){e.seq>i.since&&!i.cancelled&&(i.since=e.seq,n.call(i.onChange,e))}).on("complete",function(){"waiting"===c&&t.nextTick(function(){a.notify(e)}),c=!1}).on("error",function(){c=!1})}}if(!this._listeners[r]){var a=this,c=!1;this._listeners[r]=s,this.on(e,s)}},o.prototype.removeListener=function(e,t){t in this._listeners&&a.prototype.removeListener.call(this,e,this._listeners[t])},o.prototype.notifyLocalWindows=function(e){this.isChrome?chrome.storage.local.set({dbName:e}):this.hasLocal&&(localStorage[e]="a"===localStorage[e]?"b":"a")},o.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)},n.once=function(e){var t=!1;return n.getArguments(function(n){if(t)throw new Error("once called  more than once");t=!0,e.apply(this,n)})},n.toPromise=function(e){return n.getArguments(function(r){var o,i=this,s="function"==typeof r[r.length-1]?r.pop():!1;s&&(o=function(e,n){t.nextTick(function(){s(e,n)})});var a=new f(function(t,o){var s;try{var a=n.once(function(e,n){e?o(e):t(n)});r.push(a),s=e.apply(i,r),s&&"function"==typeof s.then&&t(s)}catch(c){o(c)}});return o&&a.then(function(e){o(null,e)},o),a.cancel=function(){return this},a})},n.adapterFun=function(t,r){function o(e,t,n){if(i.enabled){for(var r=[e._db_name,t],o=0;o<n.length-1;o++)r.push(n[o]);i.apply(null,r);var s=n[n.length-1];n[n.length-1]=function(n,r){var o=[e._db_name,t];o=o.concat(n?["error",n]:["success",r]),i.apply(null,o),s(n,r)}}}var i=e(54)("pouchdb:api");return n.toPromise(n.getArguments(function(e){if(this._closed)return f.reject(new Error("database is closed"));var n=this;return o(n,t,e),this.taskqueue.isReady?r.apply(this,e):new f(function(r,o){n.taskqueue.addTask(function(i){i?o(i):r(n[t].apply(n,e))})})}))},n.cancellableFun=function(e,t,r){r=r?n.clone(!0,{},r):{};var o=new a,i=r.complete||function(){},s=r.complete=n.once(function(e,t){e?i(e):(o.emit("end",t),i(null,t)),o.removeAllListeners()}),c=r.onChange||function(){},u=0;t.on("destroyed",function(){o.removeAllListeners()}),r.onChange=function(e){c(e),e.seq<=u||(u=e.seq,o.emit("change",e),e.deleted?o.emit("delete",e):1===e.changes.length&&"1-"===e.changes[0].rev.slice(0,1)?o.emit("create",e):o.emit("update",e))};var l=new f(function(e,t){r.complete=function(n,r){n?t(n):e(r)}});return l.then(function(e){s(null,e)},s),l.cancel=function(){l.isCancelled=!0,t.taskqueue.isReady&&r.complete(null,{status:"cancelled"})},t.taskqueue.isReady?e(t,r,l):t.taskqueue.addTask(function(){l.isCancelled?r.complete(null,{status:"cancelled"}):e(t,r,l)}),l.on=o.on.bind(o),l.once=o.once.bind(o),l.addListener=o.addListener.bind(o),l.removeListener=o.removeListener.bind(o),l.removeAllListeners=o.removeAllListeners.bind(o),l.setMaxListeners=o.setMaxListeners.bind(o),l.listeners=o.listeners.bind(o),l.emit=o.emit.bind(o),l},n.MD5=n.toPromise(e(26)),n.explain404=e(25),n.info=function(e){"undefined"!=typeof console&&"info"in console&&console.info(e)},n.parseUri=e(30),n.compare=function(e,t){return t>e?-1:e>t?1:0},n.updateDoc=function(e,t,r,o,a,c,u){if(n.revExists(e,t.metadata.rev))return r[o]=t,a();var f=i.winningRev(e),l=n.isDeleted(e,f),d=n.isDeleted(t.metadata),p=/^1-/.test(t.metadata.rev);if(l&&!d&&u&&p){var h=t.data;h._rev=f,h._id=t.metadata.id,t=n.parseDoc(h,u)}var v=i.merge(e.rev_tree,t.metadata.rev_tree[0],1e3),m=u&&(l&&d||!l&&"new_leaf"!==v.conflicts||l&&!d&&"new_branch"===v.conflicts);if(m){var _=s.error(s.REV_CONFLICT);return r[o]=_,a()}var g=t.metadata.rev;t.metadata.rev_tree=v.tree,e.rev_map&&(t.metadata.rev_map=e.rev_map);var y=i.winningRev(t.metadata),b=n.isDeleted(t.metadata,y),E=l===b?0:b>l?-1:1,w=n.isDeleted(t.metadata,g);c(t,y,b,w,!0,E,o,a)},n.processDocs=function(e,t,r,o,a,c,u,f){function l(e,t,r){var o=i.winningRev(e.metadata),f=n.isDeleted(e.metadata,o);if("was_delete"in u&&f)return a[t]=s.error(s.MISSING_DOC,"deleted"),r();var l=f?0:1;c(e,o,f,f,!1,l,t,r)}function d(){++v===m&&f&&f()}if(e.length){var p=u.new_edits,h=new n.Map,v=0,m=e.length;e.forEach(function(e,r){if(e._id&&n.isLocalId(e._id))return void t[e._deleted?"_removeLocal":"_putLocal"](e,{ctx:o},function(e){e?a[r]=e:a[r]={ok:!0},d()});var i=e.metadata.id;h.has(i)?(m--,h.get(i).push([e,r])):h.set(i,[[e,r]])}),h.forEach(function(e,t){function o(){++s<e.length?i():d()}function i(){var i=e[s],u=i[0],f=i[1];r.has(t)?n.updateDoc(r.get(t),u,a,f,o,c,p):l(u,f,o)}var s=0;i()})}},n.preprocessAttachments=function(e,t,r){function o(e){try{return l.atob(e)}catch(t){var n=s.error(s.BAD_ARG,"Attachments need to be base64 encoded");return{error:n}}}function i(e,r){if(e.stub)return r();if("string"==typeof e.data){var i=o(e.data);if(i.error)return r(i.error);e.length=i.length,"blob"===t?e.data=d(i,e.content_type):"base64"===t?e.data=l.btoa(i):e.data=i,n.MD5(i).then(function(t){e.digest="md5-"+t,r()})}else h(e.data,function(o){"binary"===t?e.data=p(o):"base64"===t&&(e.data=l.btoa(p(o))),n.MD5(o).then(function(t){e.digest="md5-"+t,e.length=o.byteLength,r()})})}function a(){u++,e.length===u&&(c?r(c):r())}if(!e.length)return r();var c,u=0;e.forEach(function(e){function t(e){c=e,r++,r===n.length&&a()}var n=e.data&&e.data._attachments?Object.keys(e.data._attachments):[],r=0;if(!n.length)return a();for(var o in e.data._attachments)e.data._attachments.hasOwnProperty(o)&&i(e.data._attachments[o],t)})},n.compactTree=function(e){var t=[];return i.traverseRevTree(e.rev_tree,function(e,n,r,o,i){"available"!==i.status||e||(t.push(n+"-"+r),i.status="missing")}),t};var v=e(88);n.safeJsonParse=function(e){try{return JSON.parse(e)}catch(t){return v.parse(e)}},n.safeJsonStringify=function(e){try{return JSON.stringify(e)}catch(t){return v.stringify(e)}}}).call(this,e(53))},{15:15,16:16,17:17,19:19,20:20,21:21,24:24,25:25,26:26,28:28,30:30,31:31,34:34,37:37,50:50,52:52,53:53,54:54,57:57,78:78,79:79,88:88}],49:[function(e,t,n){t.exports="3.6.0"},{}],50:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],51:[function(e,t,n){},{}],52:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function o(e){return"function"==typeof e}function i(e){return"number"==typeof e}function s(e){return"object"==typeof e&&null!==e}function a(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!i(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,i,c,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||s(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],a(n))return!1;if(o(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:for(r=arguments.length,i=new Array(r-1),c=1;r>c;c++)i[c-1]=arguments[c];n.apply(this,i)}else if(s(n)){for(r=arguments.length,i=new Array(r-1),c=1;r>c;c++)i[c-1]=arguments[c];for(u=n.slice(),r=u.length,c=0;r>c;c++)u[c].apply(this,i)}return!0},r.prototype.addListener=function(e,t){var n;if(!o(t))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,o(t.listener)?t.listener:t),this._events[e]?s(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,s(this._events[e])&&!this._events[e].warned){var n;n=a(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!o(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,i,a;if(!o(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],i=n.length,r=-1,n===t||o(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(n)){for(a=i;a-->0;)if(n[a]===t||n[a].listener&&n[a].listener===t){r=a;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],o(n))this.removeListener(e,n);else for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?o(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.listenerCount=function(e,t){var n;return n=e._events&&e._events[t]?o(e._events[t])?1:e._events[t].length:0}},{}],53:[function(e,t,n){function r(){if(!a){a=!0;for(var e,t=s.length;t;){e=s,s=[];for(var n=-1;++n<t;)e[n]();t=s.length}a=!1}}function o(){}var i=t.exports={},s=[],a=!1;i.nextTick=function(e){s.push(e),a||setTimeout(r,0)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=o,i.addListener=o,i.once=o,i.off=o,i.removeListener=o,i.removeAllListeners=o,i.emit=o,i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},{}],54:[function(e,t,n){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function o(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var o=0,i=0;return e[0].replace(/%[a-z%]/g,function(e){"%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r),e}function i(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function s(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(t){}}function a(){var e;try{e=n.storage.debug}catch(t){}return e}function c(){try{return window.localStorage}catch(e){}}n=t.exports=e(55),n.log=i,n.formatArgs=o,n.save=s,n.load=a,n.useColors=r,n.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:c(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){return JSON.stringify(e)},n.enable(a())},{55:55}],55:[function(e,t,n){function r(){return n.colors[f++%n.colors.length]}function o(e){function t(){}function o(){var e=o,t=+new Date,i=t-(u||t);e.diff=i,e.prev=u,e.curr=t,u=t,null==e.useColors&&(e.useColors=n.useColors()),null==e.color&&e.useColors&&(e.color=r());var s=Array.prototype.slice.call(arguments);s[0]=n.coerce(s[0]),"string"!=typeof s[0]&&(s=["%o"].concat(s));var a=0;s[0]=s[0].replace(/%([a-z%])/g,function(t,r){if("%"===t)return t;a++;var o=n.formatters[r];if("function"==typeof o){var i=s[a];t=o.call(e,i),s.splice(a,1),a--}return t}),"function"==typeof n.formatArgs&&(s=n.formatArgs.apply(e,s));var c=o.log||n.log||console.log.bind(console);c.apply(e,s)}t.enabled=!1,o.enabled=!0;var i=n.enabled(e)?o:t;return i.namespace=e,i}function i(e){n.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;r>o;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function s(){n.enable("")}function a(e){var t,r;for(t=0,r=n.skips.length;r>t;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;r>t;t++)if(n.names[t].test(e))return!0;return!1}function c(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o,n.coerce=c,n.disable=s,n.enable=i,n.enabled=a,n.humanize=e(56),n.names=[],n.skips=[],n.formatters={};var u,f=0},{56:56}],56:[function(e,t,n){function r(e){if(e=""+e,!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*l;case"days":case"day":case"d":return n*f;case"hours":case"hour":case"hrs":case"hr":case"h":return n*u;case"minutes":case"minute":case"mins":case"min":case"m":return n*c;case"seconds":case"second":case"secs":case"sec":case"s":return n*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}}}function o(e){return e>=f?Math.round(e/f)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return s(e,f,"day")||s(e,u,"hour")||s(e,c,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,n){return t>e?void 0:1.5*t>e?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var a=1e3,c=60*a,u=60*c,f=24*u,l=365.25*f;t.exports=function(e,t){return t=t||{},"string"==typeof e?r(e):t["long"]?i(e):o(e)}},{}],57:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],58:[function(e,t,n){"use strict";function r(){}t.exports=r},{}],59:[function(e,t,n){"use strict";function r(e){function t(e,t){function o(e){u[t]=e,++f===n&!r&&(r=!0,c.resolve(d,u))}s(e).then(o,function(e){r||(r=!0,c.reject(d,e))})}if("[object Array]"!==Object.prototype.toString.call(e))return i(new TypeError("must be an array"));var n=e.length,r=!1;if(!n)return s([]);for(var u=new Array(n),f=0,l=-1,d=new o(a);++l<n;)t(e[l],l);return d}var o=e(62),i=e(65),s=e(66),a=e(58),c=e(60);t.exports=r},{58:58,60:60,62:62,65:65,66:66}],60:[function(e,t,n){"use strict";function r(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}var o=e(69),i=e(67),s=e(68);n.resolve=function(e,t){var a=o(r,t);if("error"===a.status)return n.reject(e,a.value);var c=a.value;if(c)i.safely(e,c);else{e.state=s.FULFILLED,e.outcome=t;for(var u=-1,f=e.queue.length;++u<f;)e.queue[u].callFulfilled(t)}return e},n.reject=function(e,t){e.state=s.REJECTED,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e}},{67:67,68:68,69:69}],61:[function(e,t,n){t.exports=n=e(62),n.resolve=e(66),n.reject=e(65),n.all=e(59),n.race=e(64)},{59:59,62:62,64:64,65:65,66:66}],62:[function(e,t,n){"use strict";function r(e){if(!(this instanceof r))return new r(e);if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=a.PENDING,this.queue=[],this.outcome=void 0,e!==i&&s.safely(this,e)}var o=e(70),i=e(58),s=e(67),a=e(68),c=e(63);t.exports=r,r.prototype["catch"]=function(e){return this.then(null,e)},r.prototype.then=function(e,t){if("function"!=typeof e&&this.state===a.FULFILLED||"function"!=typeof t&&this.state===a.REJECTED)return this;var n=new r(i);if(this.state!==a.PENDING){var s=this.state===a.FULFILLED?e:t;o(n,s,this.outcome)}else this.queue.push(new c(n,e,t));return n}},{58:58,63:63,67:67,68:68,70:70}],63:[function(e,t,n){"use strict";function r(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}var o=e(60),i=e(70);t.exports=r,r.prototype.callFulfilled=function(e){o.resolve(this.promise,e)},r.prototype.otherCallFulfilled=function(e){i(this.promise,this.onFulfilled,e)},r.prototype.callRejected=function(e){o.reject(this.promise,e)},r.prototype.otherCallRejected=function(e){i(this.promise,this.onRejected,e)}},{60:60,70:70}],64:[function(e,t,n){"use strict";function r(e){function t(e){s(e).then(function(e){r||(r=!0,c.resolve(f,e))},function(e){r||(r=!0,c.reject(f,e))})}if("[object Array]"!==Object.prototype.toString.call(e))return i(new TypeError("must be an array"));var n=e.length,r=!1;if(!n)return s([]);for(var u=-1,f=new o(a);++u<n;)t(e[u]);return f}var o=e(62),i=e(65),s=e(66),a=e(58),c=e(60);t.exports=r},{58:58,60:60,62:62,65:65,66:66}],65:[function(e,t,n){"use strict";function r(e){var t=new o(i);return s.reject(t,e)}var o=e(62),i=e(58),s=e(60);t.exports=r},{58:58,60:60,62:62}],66:[function(e,t,n){"use strict";function r(e){if(e)return e instanceof o?e:s.resolve(new o(i),e);var t=typeof e;switch(t){case"boolean":return a;case"undefined":return u;case"object":return c;case"number":return f;case"string":return l}}var o=e(62),i=e(58),s=e(60);t.exports=r;var a=s.resolve(new o(i),!1),c=s.resolve(new o(i),null),u=s.resolve(new o(i),void 0),f=s.resolve(new o(i),0),l=s.resolve(new o(i),"")},{58:58,60:60,62:62}],67:[function(e,t,n){"use strict";function r(e,t){function n(t){a||(a=!0,o.reject(e,t))}function r(t){a||(a=!0,o.resolve(e,t))}function s(){t(r,n)}var a=!1,c=i(s);"error"===c.status&&n(c.value)}var o=e(60),i=e(69);n.safely=r},{60:60,69:69}],68:[function(e,t,n){n.REJECTED=["REJECTED"],n.FULFILLED=["FULFILLED"],n.PENDING=["PENDING"]},{}],69:[function(e,t,n){"use strict";function r(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}t.exports=r},{}],70:[function(e,t,n){"use strict";function r(e,t,n){o(function(){var r;try{r=t(n)}catch(o){return i.reject(e,o)}r===e?i.reject(e,new TypeError("Cannot resolve promise with itself")):i.resolve(e,r)})}var o=e(71),i=e(60);t.exports=r},{60:60,71:71}],71:[function(e,t,n){"use strict";function r(){i=!0;for(var e,t,n=c.length;n;){for(t=c,c=[],e=-1;++e<n;)t[e]();n=c.length}i=!1}function o(e){1!==c.push(e)||i||s()}for(var i,s,a=[e(51),e(73),e(72),e(74),e(75)],c=[],u=-1,f=a.length;++u<f;)if(a[u]&&a[u].test&&a[u].test()){s=a[u].install(r);break}t.exports=o},{51:51,72:72,73:73,74:74,75:75}],72:[function(e,t,n){(function(e){"use strict";n.test=function(){return e.setImmediate?!1:"undefined"!=typeof e.MessageChannel},n.install=function(t){var n=new e.MessageChannel;return n.port1.onmessage=t,function(){n.port2.postMessage(0)}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],73:[function(e,t,n){(function(e){"use strict";var t=e.MutationObserver||e.WebKitMutationObserver;n.test=function(){return t},n.install=function(n){var r=0,o=new t(n),i=e.document.createTextNode("");return o.observe(i,{characterData:!0}),function(){i.data=r=++r%2}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],74:[function(e,t,n){(function(e){"use strict";n.test=function(){return"document"in e&&"onreadystatechange"in e.document.createElement("script")},n.install=function(t){return function(){var n=e.document.createElement("script");return n.onreadystatechange=function(){t(),n.onreadystatechange=null,n.parentNode.removeChild(n),n=null},e.document.documentElement.appendChild(n),t}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],75:[function(e,t,n){"use strict";n.test=function(){return!0},n.install=function(e){return function(){setTimeout(e,0)}}},{}],76:[function(e,t,n){"use strict";function r(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return f(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),r=t?e:Object.keys(e),o=-1,i=r.length,s="";if(t)for(;++o<i;)s+=n.toIndexableString(r[o]);else for(;++o<i;){var a=r[o];s+=n.toIndexableString(a)+n.toIndexableString(e[a])}return s}return""}function o(e,t){var n,r=t,o="1"===e[t];if(o)n=0,t++;else{var i="0"===e[t];t++;var s="",a=e.substring(t,t+d),c=parseInt(a,10)+l;for(i&&(c=-c),t+=d;;){var u=e[t];if("\x00"===u)break;s+=u,t++}s=s.split("."),n=1===s.length?parseInt(s,10):parseFloat(s[0]+"."+s[1]),i&&(n-=10),0!==c&&(n=parseFloat(n+"e"+c))}return{num:n,length:t-r}}function i(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(n);else if(i===e.length-2){var s=e.pop();o[s]=n}else e.push(n)}}function s(e,t){for(var r=Math.min(e.length,t.length),o=0;r>o;o++){var i=n.collate(e[o],t[o]);if(0!==i)return i}return e.length===t.length?0:e.length>t.length?1:-1}function a(e,t){return e===t?0:e>t?1:-1}function c(e,t){for(var r=Object.keys(e),o=Object.keys(t),i=Math.min(r.length,o.length),s=0;i>s;s++){var a=n.collate(r[s],o[s]);if(0!==a)return a;if(a=n.collate(e[r[s]],t[o[s]]),0!==a)return a}return r.length===o.length?0:r.length>o.length?1:-1}function u(e){var t=["boolean","number","string","object"],n=t.indexOf(typeof e);return~n?null===e?1:Array.isArray(e)?5:3>n?n+2:n+3:Array.isArray(e)?5:void 0}function f(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=0>e,o=r?"0":"2",i=(r?-n:n)-l,s=h.padLeft(i.toString(),"0",d);o+=p+s;var a=Math.abs(parseFloat(t[0]));r&&(a=10-a);var c=a.toFixed(20);return c=c.replace(/\.?0+$/,""),o+=p+c}var l=-324,d=3,p="",h=e(77);n.collate=function(e,t){if(e===t)return 0;e=n.normalizeKey(e),t=n.normalizeKey(t);var r=u(e),o=u(t);if(r-o!==0)return r-o;if(null===e)return 0;switch(typeof e){case"number":return e-t;case"boolean":return e===t?0:t>e?-1:1;case"string":return a(e,t)}return Array.isArray(e)?s(e,t):c(e,t)},n.normalizeKey=function(e){switch(typeof e){case"undefined":return null;case"number":return e===1/0||e===-(1/0)||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var r=e.length;e=new Array(r);for(var o=0;r>o;o++)e[o]=n.normalizeKey(t[o])}else{if(e instanceof Date)return e.toJSON();if(null!==e){e={};for(var i in t)if(t.hasOwnProperty(i)){var s=t[i];"undefined"!=typeof s&&(e[i]=n.normalizeKey(s))}}}}return e},n.toIndexableString=function(e){var t="\x00";return e=n.normalizeKey(e),u(e)+p+r(e)+t},n.parseIndexableString=function(e){for(var t=[],n=[],r=0;;){var s=e[r++];if("\x00"!==s)switch(s){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var a=o(e,r);t.push(a.num),r+=a.length;break;case"4":for(var c="";;){var u=e[r];if("\x00"===u)break;c+=u,r++}c=c.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(c);break;case"5":var f={element:[],index:t.length};t.push(f.element),n.push(f);break;case"6":var l={element:{},index:t.length};t.push(l.element),n.push(l);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+s)}else{if(1===t.length)return t.pop();i(t,n)}}}},{77:77}],77:[function(e,t,n){"use strict";function r(e,t,n){for(var r="",o=n-e.length;r.length<o;)r+=t;return r}n.padLeft=function(e,t,n){var o=r(e,t,n);return o+e},n.padRight=function(e,t,n){var o=r(e,t,n);return e+o},n.stringLexCompare=function(e,t){var n,r=e.length,o=t.length;for(n=0;r>n;n++){if(n===o)return 1;var i=e.charAt(n),s=t.charAt(n);if(i!==s)return s>i?-1:1}return o>r?-1:0},n.intToDecimalForm=function(e){var t=0>e,n="";do{var r=t?-Math.ceil(e%10):Math.floor(e%10);n=r+n,e=t?Math.ceil(e/10):Math.floor(e/10)}while(e);return t&&"0"!==n&&(n="-"+n),n}},{}],78:[function(e,t,n){"use strict";function r(){this.store={}}function o(e){if(this.store=new r,e&&Array.isArray(e))for(var t=0,n=e.length;n>t;t++)this.add(e[t])}n.Map=r,n.Set=o,r.prototype.mangle=function(e){if("string"!=typeof e)throw new TypeError("key must be a string but Got "+e);return"$"+e},r.prototype.unmangle=function(e){return e.substring(1)},r.prototype.get=function(e){var t=this.mangle(e);return t in this.store?this.store[t]:void 0},r.prototype.set=function(e,t){var n=this.mangle(e);return this.store[n]=t,!0},r.prototype.has=function(e){var t=this.mangle(e);return t in this.store},r.prototype["delete"]=function(e){var t=this.mangle(e);return t in this.store?(delete this.store[t],!0):!1},r.prototype.forEach=function(e){var t=this,n=Object.keys(t.store);n.forEach(function(n){var r=t.store[n];n=t.unmangle(n),e(r,n)})},o.prototype.add=function(e){return this.store.set(e,!0)},o.prototype.has=function(e){return this.store.has(e)},o.prototype["delete"]=function(e){return this.store["delete"](e)}},{}],79:[function(e,t,n){"use strict";function r(e){return null===e?String(e):"object"==typeof e||"function"==typeof e?u[p.call(e)]||"object":typeof e}function o(e){return null!==e&&e===e.window}function i(e){if(!e||"object"!==r(e)||e.nodeType||o(e))return!1;try{if(e.constructor&&!h.call(e,"constructor")&&!h.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}var n;for(n in e);return void 0===n||h.call(e,n)}function s(e){return"function"===r(e)}function a(){for(var e=[],t=-1,n=arguments.length,r=new Array(n);++t<n;)r[t]=arguments[t];var o={};e.push({args:r,result:{container:o,key:"key"}});for(var i;i=e.pop();)c(e,i.args,i.result);return o.key}function c(e,t,n){var r,o,a,c,u,f,l,d=t[0]||{},p=1,h=t.length,m=!1,_=/\d+/;for("boolean"==typeof d&&(m=d,d=t[1]||{},p=2),"object"==typeof d||s(d)||(d={}),h===p&&(d=this,--p);h>p;p++)if(null!=(r=t[p])){l=v(r);for(o in r)if(!(o in Object.prototype)){if(l&&!_.test(o))continue;if(a=d[o],c=r[o],d===c)continue;m&&c&&(i(c)||(u=v(c)))?(u?(u=!1,f=a&&v(a)?a:[]):f=a&&i(a)?a:{},e.push({args:[m,f,c],result:{container:d,key:o}})):void 0!==c&&(v(r)&&s(c)||(d[o]=c))}}n.container[n.key]=d}for(var u={},f=["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],l=0;l<f.length;l++){var d=f[l];u["[object "+d+"]"]=d.toLowerCase()}var p=u.toString,h=u.hasOwnProperty,v=Array.isArray||function(e){return"array"===r(e)};t.exports=a;
-},{}],80:[function(e,t,n){"use strict";var r=e(84),o=e(85),i=o.Promise;t.exports=function(e){var t=e.db,n=e.viewName,s=e.map,a=e.reduce,c=e.temporary,u=s.toString()+(a&&a.toString())+"undefined";if(!c&&t._cachedViews){var f=t._cachedViews[u];if(f)return i.resolve(f)}return t.info().then(function(e){function i(e){e.views=e.views||{};var t=n;-1===t.indexOf("/")&&(t=n+"/"+n);var r=e.views[t]=e.views[t]||{};if(!r[f])return r[f]=!0,e}var f=e.db_name+"-mrview-"+(c?"temp":o.MD5(u));return r(t,"_local/mrviews",i).then(function(){return t.registerDependentDatabase(f).then(function(e){var n=e.db;n.auto_compaction=!0;var r={name:f,db:n,sourceDB:t,adapter:t.adapter,mapFun:s,reduceFun:a};return r.db.get("_local/lastSeq")["catch"](function(e){if(404!==e.status)throw e}).then(function(e){return r.seq=e?e.seq:0,c||(t._cachedViews=t._cachedViews||{},t._cachedViews[u]=r,r.db.on("destroyed",function(){delete t._cachedViews[u]})),r})})})})}},{84:84,85:85}],81:[function(_dereq_,module,exports){"use strict";module.exports=function(func,emit,sum,log,isArray,toJSON){return eval("'use strict'; ("+func.replace(/;\s*$/,"")+");")}},{}],82:[function(e,t,n){(function(t){"use strict";function r(e){return-1===e.indexOf("/")?[e,e]:e.split("/")}function o(e){return 1===e.length&&/^1-/.test(e[0].rev)}function i(e,t){try{e.emit("error",t)}catch(n){console.error("The user's map/reduce function threw an uncaught error.\nYou can debug this error by doing:\nmyDatabase.on('error', function (err) { debugger; });\nPlease double-check your map/reduce function."),console.error(t)}}function s(e,t,n){try{return{output:t.apply(null,n)}}catch(r){return i(e,r),{error:r}}}function a(e,t){var n=I(e.key,t.key);return 0!==n?n:I(e.value,t.value)}function c(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):n>0?e.slice(n):e}function u(e){var t=e.value,n=t&&"object"==typeof t&&t._id||e.id;return n}function f(e){var t="builtin "+e+" function requires map values to be numbers or number arrays";return new q(t)}function l(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];if("number"!=typeof o){if(!Array.isArray(o))throw f("_sum");t="number"==typeof t?[t]:t;for(var i=0,s=o.length;s>i;i++){var a=o[i];if("number"!=typeof a)throw f("_sum");"undefined"==typeof t[i]?t.push(a):t[i]+=a}}else"number"==typeof t?t+=o:t[0]+=o}return t}function d(e,t,n,r){var o=t[e];"undefined"!=typeof o&&(r&&(o=encodeURIComponent(JSON.stringify(o))),n.push(e+"="+o))}function p(e,t){var n=e.descending?"endkey":"startkey",r=e.descending?"startkey":"endkey";if("undefined"!=typeof e[n]&&"undefined"!=typeof e[r]&&I(e[n],e[r])>0)throw new A("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(t.reduce&&e.reduce!==!1){if(e.include_docs)throw new A("{include_docs:true} is invalid for reduce");if(e.keys&&e.keys.length>1&&!e.group&&!e.group_level)throw new A("Multi-key fetches for reduce views must use {group: true}")}if(e.group_level){if("number"!=typeof e.group_level)throw new A('Invalid value for integer: "'+e.group_level+'"');if(e.group_level<0)throw new A('Invalid value for positive integer: "'+e.group_level+'"')}}function h(e,t,n){var o,i=[],s="GET";if(d("reduce",n,i),d("include_docs",n,i),d("attachments",n,i),d("limit",n,i),d("descending",n,i),d("group",n,i),d("group_level",n,i),d("skip",n,i),d("stale",n,i),d("conflicts",n,i),d("startkey",n,i,!0),d("endkey",n,i,!0),d("inclusive_end",n,i),d("key",n,i,!0),i=i.join("&"),i=""===i?"":"?"+i,"undefined"!=typeof n.keys){var a=2e3,c="keys="+encodeURIComponent(JSON.stringify(n.keys));c.length+i.length+1<=a?i+=("?"===i[0]?"&":"?")+c:(s="POST","string"==typeof t?o=JSON.stringify({keys:n.keys}):t.keys=n.keys)}if("string"==typeof t){var u=r(t);return e.request({method:s,url:"_design/"+u[0]+"/_view/"+u[1]+i,body:o})}return o=o||{},Object.keys(t).forEach(function(e){Array.isArray(t[e])?o[e]=t[e]:o[e]=t[e].toString()}),e.request({method:"POST",url:"_temp_view"+i,body:o})}function v(e){return function(t){if(404===t.status)return e;throw t}}function m(e,t,n){function r(){return o(l)?M.resolve(c):t.db.get(a)["catch"](v(c))}function i(e){return e.keys.length?t.db.allDocs({keys:e.keys,include_docs:!0}):M.resolve({rows:[]})}function s(e,t){for(var n=[],r={},o=0,i=t.rows.length;i>o;o++){var s=t.rows[o],a=s.doc;if(a&&(n.push(a),r[a._id]=!0,a._deleted=!f[a._id],!a._deleted)){var c=f[a._id];"value"in c&&(a.value=c.value)}}var u=Object.keys(f);return u.forEach(function(e){if(!r[e]){var t={_id:e},o=f[e];"value"in o&&(t.value=o.value),n.push(t)}}),e.keys=F.uniq(u.concat(e.keys)),n.push(e),n}var a="_local/doc_"+e,c={_id:a,keys:[]},u=n[e],f=u.indexableKeysToKeyValues,l=u.changes;return r().then(function(e){return i(e).then(function(t){return s(e,t)})})}function _(e,t,n){var r="_local/lastSeq";return e.db.get(r)["catch"](v({_id:r,seq:0})).then(function(r){var o=Object.keys(t);return M.all(o.map(function(n){return m(n,e,t)})).then(function(t){var o=F.flatten(t);return r.seq=n,o.push(r),e.db.bulkDocs({docs:o})})})}function g(e){var t="string"==typeof e?e:e.name,n=P[t];return n||(n=P[t]=new D),n}function y(e){return F.sequentialize(g(e),function(){return b(e)})()}function b(e){function t(e,t){var n={id:o._id,key:N(e)};"undefined"!=typeof t&&null!==t&&(n.value=N(t)),r.push(n)}function n(t,n){return function(){return _(e,t,n)}}var r,o,i;if("function"==typeof e.mapFun&&2===e.mapFun.length){var c=e.mapFun;i=function(e){return c(e,t)}}else i=B(e.mapFun.toString(),t,l,R,Array.isArray,JSON.parse);var u=e.seq||0,f=new D;return new M(function(t,c){function l(){f.finish().then(function(){e.seq=u,t()})}function d(){function t(e){c(e)}e.sourceDB.changes({conflicts:!0,include_docs:!0,style:"all_docs",since:u,limit:J}).on("complete",function(t){var c=t.results;if(!c.length)return l();for(var p={},h=0,v=c.length;v>h;h++){var m=c[h];if("_"!==m.doc._id[0]){r=[],o=m.doc,o._deleted||s(e.sourceDB,i,[o]),r.sort(a);for(var _,g={},y=0,b=r.length;b>y;y++){var E=r[y],w=[E.key,E.id];0===I(E.key,_)&&w.push(y);var S=L(w);g[S]=E,_=E.key}p[m.doc._id]={indexableKeysToKeyValues:g,changes:m.changes}}u=m.seq}return f.add(n(p,u)),c.length<J?l():d()}).on("error",t)}d()})}function E(e,t,n){0===n.group_level&&delete n.group_level;var r,o=n.group||n.group_level;r=H[e.reduceFun]?H[e.reduceFun]:B(e.reduceFun.toString(),null,l,R,Array.isArray,JSON.parse);var i=[],a=n.group_level;t.forEach(function(e){var t=i[i.length-1],n=o?e.key:null;return o&&Array.isArray(n)&&"number"==typeof a&&(n=n.length>a?n.slice(0,a):n),t&&0===I(t.key[0][0],n)?(t.key.push([n,e.id]),void t.value.push(e.value)):void i.push({key:[[n,e.id]],value:[e.value]})});for(var u=0,f=i.length;f>u;u++){var d=i[u],p=s(e.sourceDB,r,[d.key,d.value,!1]);if(p.error&&p.error instanceof q)throw p.error;d.value=p.error?null:p.output,d.key=d.key[0][0]}return{rows:c(i,n.limit,n.skip)}}function w(e,t){return F.sequentialize(g(e),function(){return S(e,t)})()}function S(e,t){function n(t){return t.include_docs=!0,e.db.allDocs(t).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(n>t||t>n))return e.doc.value}var r=C.parseIndexableString(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function r(n){var r;if(r=i?E(e,n,t):{total_rows:o,offset:s,rows:n},t.include_docs){var a=F.uniq(n.map(u));return e.sourceDB.allDocs({keys:a,include_docs:!0,conflicts:t.conflicts,attachments:t.attachments}).then(function(e){var t={};return e.rows.forEach(function(e){e.doc&&(t["$"+e.id]=e.doc)}),n.forEach(function(e){var n=u(e),r=t["$"+n];r&&(e.doc=r)}),r})}return r}var o,i=e.reduceFun&&t.reduce!==!1,s=t.skip||0;"undefined"==typeof t.keys||t.keys.length||(t.limit=0,delete t.keys);var a=function(e){return e.reduce(function(e,t){return e.concat(t)})};if("undefined"!=typeof t.keys){var c=t.keys,f=c.map(function(e){var t={startkey:L([e]),endkey:L([e,{}])};return n(t)});return M.all(f).then(a).then(r)}var l={descending:t.descending};if("undefined"!=typeof t.startkey&&(l.startkey=L(t.descending?[t.startkey,{}]:[t.startkey])),"undefined"!=typeof t.endkey){var d=t.inclusive_end!==!1;t.descending&&(d=!d),l.endkey=L(d?[t.endkey,{}]:[t.endkey])}if("undefined"!=typeof t.key){var p=L([t.key]),h=L([t.key,{}]);l.descending?(l.endkey=p,l.startkey=h):(l.startkey=p,l.endkey=h)}return i||("number"==typeof t.limit&&(l.limit=t.limit),l.skip=s),n(l).then(r)}function T(e){return e.request({method:"POST",url:"_view_cleanup"})}function x(e){return e.get("_local/mrviews").then(function(t){var n={};Object.keys(t.views).forEach(function(e){var t=r(e),o="_design/"+t[0],i=t[1];n[o]=n[o]||{},n[o][i]=!0});var o={keys:Object.keys(n),include_docs:!0};return e.allDocs(o).then(function(r){var o={};r.rows.forEach(function(e){var r=e.key.substring(8);Object.keys(n[e.key]).forEach(function(n){var i=r+"/"+n;t.views[i]||(i=n);var s=Object.keys(t.views[i]),a=e.doc&&e.doc.views&&e.doc.views[n];s.forEach(function(e){o[e]=o[e]||a})})});var i=Object.keys(o).filter(function(e){return!o[e]}),s=i.map(function(t){return F.sequentialize(g(t),function(){return new e.constructor(t,e.__opts).destroy()})()});return M.all(s).then(function(){return{ok:!0}})})},v({ok:!0}))}function O(e,n,o){if("http"===e.type())return h(e,n,o);if("string"!=typeof n){p(o,n);var i={db:e,viewName:"temp_view/temp_view",map:n.map,reduce:n.reduce,temporary:!0};return U.add(function(){return j(i).then(function(e){function t(){return e.db.destroy()}return F.fin(y(e).then(function(){return w(e,o)}),t)})}),U.finish()}var s=n,a=r(s),c=a[0],u=a[1];return e.get("_design/"+c).then(function(n){var r=n.views&&n.views[u];if(!r||"string"!=typeof r.map)throw new k("ddoc "+c+" has no view named "+u);p(o,r);var i={db:e,viewName:s,map:r.map,reduce:r.reduce};return j(i).then(function(e){return"ok"===o.stale||"update_after"===o.stale?("update_after"===o.stale&&t.nextTick(function(){y(e)}),w(e,o)):y(e).then(function(){return w(e,o)})})})}function A(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,A)}catch(t){}}function k(e){this.status=404,this.name="not_found",this.message=e,this.error=!0;try{Error.captureStackTrace(this,k)}catch(t){}}function q(e){this.status=500,this.name="invalid_value",this.message=e,this.error=!0;try{Error.captureStackTrace(this,q)}catch(t){}}var R,C=e(76),D=e(83),I=C.collate,L=C.toIndexableString,N=C.normalizeKey,j=e(80),B=e(81);R="undefined"!=typeof console&&"function"==typeof console.log?Function.prototype.bind.call(console.log,console):function(){};var F=e(85),M=F.Promise,P={},U=new D,J=50,H={_sum:function(e,t){return l(t)},_count:function(e,t){return t.length},_stats:function(e,t){function n(e){for(var t=0,n=0,r=e.length;r>n;n++){var o=e[n];t+=o*o}return t}return{sum:l(t),min:Math.min.apply(null,t),max:Math.max.apply(null,t),count:t.length,sumsqr:n(t)}}};n.viewCleanup=F.callbackify(function(){var e=this;return"http"===e.type()?T(e):x(e)}),n.query=function(e,t,n){"function"==typeof t&&(n=t,t={}),t=F.extend(!0,{},t),"function"==typeof e&&(e={map:e});var r=this,o=M.resolve().then(function(){return O(r,e,t)});return F.promisedCallback(o,n),o},F.inherits(A,Error),F.inherits(k,Error),F.inherits(q,Error)}).call(this,e(53))},{53:53,76:76,80:80,81:81,83:83,85:85}],83:[function(e,t,n){"use strict";function r(){this.promise=new o(function(e){e()})}var o=e(85).Promise;r.prototype.add=function(e){return this.promise=this.promise["catch"](function(){}).then(function(){return e()}),this.promise},r.prototype.finish=function(){return this.promise},t.exports=r},{85:85}],84:[function(e,t,n){"use strict";var r=e(86).upsert;t.exports=function(e,t,n){return r.apply(e,[t,n])}},{86:86}],85:[function(e,t,n){(function(t,r){"use strict";"function"==typeof r.Promise?n.Promise=r.Promise:n.Promise=e(61),n.inherits=e(57),n.extend=e(79);var o=e(50);n.promisedCallback=function(e,n){return n&&e.then(function(e){t.nextTick(function(){n(null,e)})},function(e){t.nextTick(function(){n(e)})}),e},n.callbackify=function(e){return o(function(t){var r=t.pop(),o=e.apply(this,t);return"function"==typeof r&&n.promisedCallback(o,r),o})},n.fin=function(e,t){return e.then(function(e){var n=t();return"function"==typeof n.then?n.then(function(){return e}):e},function(e){var n=t();if("function"==typeof n.then)return n.then(function(){throw e});throw e})},n.sequentialize=function(e,t){return function(){var n=arguments,r=this;return e.add(function(){return t.apply(r,n)})}},n.flatten=function(e){for(var t=[],n=0,r=e.length;r>n;n++)t=t.concat(e[n]);return t},n.uniq=function(e){for(var t={},n=0,r=e.length;r>n;n++)t["$"+e[n]]=!0;var o=Object.keys(t),i=new Array(o.length);for(n=0,r=o.length;r>n;n++)i[n]=o[n].substring(1);return i};var i=e(51),s=e(87);n.MD5=function(e){return t.browser?s.hash(e):i.createHash("md5").update(e).digest("hex")}}).call(this,e(53),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{50:50,51:51,53:53,57:57,61:61,79:79,87:87}],86:[function(e,t,n){(function(t){"use strict";function r(e,t,n){return new i(function(r,i){return"string"!=typeof t?i(new Error("doc id is required")):void e.get(t,function(s,a){if(s){if(404!==s.status)return i(s);a={}}var c=a._rev,u=n(a);return u?(u._id=t,u._rev=c,void r(o(e,u,n))):r({updated:!1,rev:c})})})}function o(e,t,n){return e.put(t).then(function(e){return{updated:!0,rev:e.rev}},function(o){if(409!==o.status)throw o;return r(e,t._id,n)})}var i;i="undefined"!=typeof window&&window.PouchDBVersion360?window.PouchDBVersion360.utils.Promise:"function"==typeof t.Promise?t.Promise:e(61),n.upsert=function(e,t,n){var o=this,i=r(o,e,t);return"function"!=typeof n?i:void i.then(function(e){n(null,e)},n)},n.putIfNotExists=function(e,t,n){var o=this;"string"!=typeof e&&(n=t,t=e,e=t._id);var i=function(e){return e._rev?!1:t},s=r(o,e,i);return"function"!=typeof n?s:void s.then(function(e){n(null,e)},n)},"undefined"!=typeof window&&window.PouchDBVersion360&&window.PouchDBVersion360.plugin(n)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{61:61}],87:[function(e,t,n){!function(e){if("object"==typeof n)t.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var r;try{r=window}catch(o){r=self}r.SparkMD5=e()}}(function(e){"use strict";var t=function(e,t){return e+t&4294967295},n=function(e,n,r,o,i,s){return n=t(t(n,e),t(o,s)),t(n<<i|n>>>32-i,r)},r=function(e,t,r,o,i,s,a){return n(t&r|~t&o,e,t,i,s,a)},o=function(e,t,r,o,i,s,a){return n(t&o|r&~o,e,t,i,s,a)},i=function(e,t,r,o,i,s,a){return n(t^r^o,e,t,i,s,a)},s=function(e,t,r,o,i,s,a){return n(r^(t|~o),e,t,i,s,a)},a=function(e,n){var a=e[0],c=e[1],u=e[2],f=e[3];a=r(a,c,u,f,n[0],7,-680876936),f=r(f,a,c,u,n[1],12,-389564586),u=r(u,f,a,c,n[2],17,606105819),c=r(c,u,f,a,n[3],22,-1044525330),a=r(a,c,u,f,n[4],7,-176418897),f=r(f,a,c,u,n[5],12,1200080426),u=r(u,f,a,c,n[6],17,-1473231341),c=r(c,u,f,a,n[7],22,-45705983),a=r(a,c,u,f,n[8],7,1770035416),f=r(f,a,c,u,n[9],12,-1958414417),u=r(u,f,a,c,n[10],17,-42063),c=r(c,u,f,a,n[11],22,-1990404162),a=r(a,c,u,f,n[12],7,1804603682),f=r(f,a,c,u,n[13],12,-40341101),u=r(u,f,a,c,n[14],17,-1502002290),c=r(c,u,f,a,n[15],22,1236535329),a=o(a,c,u,f,n[1],5,-165796510),f=o(f,a,c,u,n[6],9,-1069501632),u=o(u,f,a,c,n[11],14,643717713),c=o(c,u,f,a,n[0],20,-373897302),a=o(a,c,u,f,n[5],5,-701558691),f=o(f,a,c,u,n[10],9,38016083),u=o(u,f,a,c,n[15],14,-660478335),c=o(c,u,f,a,n[4],20,-405537848),a=o(a,c,u,f,n[9],5,568446438),f=o(f,a,c,u,n[14],9,-1019803690),u=o(u,f,a,c,n[3],14,-187363961),c=o(c,u,f,a,n[8],20,1163531501),a=o(a,c,u,f,n[13],5,-1444681467),f=o(f,a,c,u,n[2],9,-51403784),u=o(u,f,a,c,n[7],14,1735328473),c=o(c,u,f,a,n[12],20,-1926607734),a=i(a,c,u,f,n[5],4,-378558),f=i(f,a,c,u,n[8],11,-2022574463),u=i(u,f,a,c,n[11],16,1839030562),c=i(c,u,f,a,n[14],23,-35309556),a=i(a,c,u,f,n[1],4,-1530992060),f=i(f,a,c,u,n[4],11,1272893353),u=i(u,f,a,c,n[7],16,-155497632),c=i(c,u,f,a,n[10],23,-1094730640),a=i(a,c,u,f,n[13],4,681279174),f=i(f,a,c,u,n[0],11,-358537222),u=i(u,f,a,c,n[3],16,-722521979),c=i(c,u,f,a,n[6],23,76029189),a=i(a,c,u,f,n[9],4,-640364487),f=i(f,a,c,u,n[12],11,-421815835),u=i(u,f,a,c,n[15],16,530742520),c=i(c,u,f,a,n[2],23,-995338651),a=s(a,c,u,f,n[0],6,-198630844),f=s(f,a,c,u,n[7],10,1126891415),u=s(u,f,a,c,n[14],15,-1416354905),c=s(c,u,f,a,n[5],21,-57434055),a=s(a,c,u,f,n[12],6,1700485571),f=s(f,a,c,u,n[3],10,-1894986606),u=s(u,f,a,c,n[10],15,-1051523),c=s(c,u,f,a,n[1],21,-2054922799),a=s(a,c,u,f,n[8],6,1873313359),f=s(f,a,c,u,n[15],10,-30611744),u=s(u,f,a,c,n[6],15,-1560198380),c=s(c,u,f,a,n[13],21,1309151649),a=s(a,c,u,f,n[4],6,-145523070),f=s(f,a,c,u,n[11],10,-1120210379),u=s(u,f,a,c,n[2],15,718787259),c=s(c,u,f,a,n[9],21,-343485551),e[0]=t(a,e[0]),e[1]=t(c,e[1]),e[2]=t(u,e[2]),e[3]=t(f,e[3])},c=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n},u=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n},f=function(e){var t,n,r,o,i,s,u=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;u>=t;t+=64)a(f,c(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*u,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),s=parseInt(o[1],16)||0,r[14]=i,r[15]=s,a(f,r),f},l=function(e){var t,n,r,o,i,s,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,u(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),s=parseInt(o[1],16)||0,r[14]=i,r[15]=s,a(f,r),f},d=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"],p=function(e){var t,n="";for(t=0;4>t;t+=1)n+=d[e>>8*t+4&15]+d[e>>8*t&15];return n},h=function(e){var t;for(t=0;t<e.length;t+=1)e[t]=p(e[t]);return e.join("")},v=function(e){return h(f(e))},m=function(){this.reset()};return"5d41402abc4b2a76b9719d911017c592"!==v("hello")&&(t=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),m.prototype.append=function(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),this.appendBinary(e),this},m.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._state,c(this._buff.substring(t-64,t)));return this._buff=this._buff.substr(t-64),this},m.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(i,o),n=e?this._state:h(this._state),this.reset(),n},m.prototype._finish=function(e,t){var n,r,o,i=t;if(e[i>>2]|=128<<(i%4<<3),i>55)for(a(this._state,e),i=0;16>i;i+=1)e[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),o=parseInt(n[1],16)||0,e[14]=r,e[15]=o,a(this._state,e)},m.prototype.reset=function(){return this._buff="",this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},m.prototype.destroy=function(){delete this._state,delete this._buff,delete this._length},m.hash=function(e,t){/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e)));var n=f(e);return t?n:h(n)},m.hashBinary=function(e,t){var n=f(e);return t?n:h(n)},m.ArrayBuffer=function(){this.reset()},m.ArrayBuffer.prototype.append=function(e){var t,n=this._concatArrayBuffer(this._buff,e),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._state,u(n.subarray(t-64,t)));return this._buff=r>t-64?n.subarray(t-64):new Uint8Array(0),this},m.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r[t]<<(t%4<<3);return this._finish(i,o),n=e?this._state:h(this._state),this.reset(),n},m.ArrayBuffer.prototype._finish=m.prototype._finish,m.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},m.ArrayBuffer.prototype.destroy=m.prototype.destroy,m.ArrayBuffer.prototype._concatArrayBuffer=function(e,t){var n=e.length,r=new Uint8Array(n+t.byteLength);return r.set(e),r.set(new Uint8Array(t),n),r},m.ArrayBuffer.hash=function(e,t){var n=l(new Uint8Array(e));return t?n:h(n)},m})},{}],88:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(e);else if(i===t.length-2){var s=t.pop();o[s]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,o,i,s,a,c,u,f,l,d,p="";n=t.pop();)if(r=n.obj,o=n.prefix||"",i=n.val||"",p+=o,i)p+=i;else if("object"!=typeof r)p+="undefined"==typeof r?null:JSON.stringify(r);else if(null===r)p+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),s=r.length-1;s>=0;s--)a=0===s?"":",",t.push({obj:r[s],prefix:a});t.push({val:"["})}else{c=[];for(u in r)r.hasOwnProperty(u)&&c.push(u);for(t.push({val:"}"}),s=c.length-1;s>=0;s--)f=c[s],l=r[f],d=s>0?",":"",d+=JSON.stringify(f)+":",t.push({obj:l,prefix:d});t.push({val:"{"})}return p},n.parse=function(e){for(var t,n,o,i,s,a,c,u,f,l=[],d=[],p=0;;)if(t=e[p++],"}"!==t&&"]"!==t&&"undefined"!=typeof t)switch(t){case" ":case"	":case"\n":case":":case",":break;case"n":p+=3,r(null,l,d);break;case"t":p+=3,r(!0,l,d);break;case"f":p+=4,r(!1,l,d);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",p--;;){if(o=e[p++],!/[\d\.\-e\+]/.test(o)){p--;break}n+=o}r(parseFloat(n),l,d);break;case'"':for(i="",s=void 0,a=0;;){if(c=e[p++],'"'===c&&("\\"!==s||a%2!==1))break;i+=c,s=c,"\\"===s?a++:a=0}r(JSON.parse('"'+i+'"'),l,d);break;case"[":u={element:[],index:l.length},l.push(u.element),d.push(u);break;case"{":f={element:{},index:l.length},l.push(f.element),d.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,d)}}},{}],89:[function(e,t,n){(function(n){"use strict";var r=e(45);t.exports=r,r.ajax=e(15),r.utils=e(48),r.Errors=e(24),r.replicate=e(42).replicate,r.sync=e(46),r.version=e(49);var o=e(2);if(r.adapter("http",o),r.adapter("https",o),r.adapter("idb",e(8),!0),r.adapter("websql",e(12),!0),r.plugin(e(82)),!n.browser){var i=e(51);r.adapter("leveldb",i,!0)}}).call(this,e(53))},{12:12,15:15,2:2,24:24,42:42,45:45,46:46,48:48,49:49,51:51,53:53,8:8,82:82}]},{},[89])(89)});
diff --git a/tests/integration/index.html b/tests/integration/index.html
deleted file mode 100644
index 5aace80..0000000
--- a/tests/integration/index.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Mocha</title>
-    <link rel="stylesheet" type="text/css" href="../../node_modules/mocha/mocha.css">
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script src="../../node_modules/mocha/mocha.js"></script>
-    <script src="../../node_modules/chai/chai.js"></script>
-    <script src="../../node_modules/chai-as-promised/lib/chai-as-promised.js"></script>
-    <script>
-      mocha.setup({
-        timeout:100000,
-        ui: 'bdd'
-      });
-      var should = chai.should();
-    </script>
-    <script src='deps/pouchdb-1.1.0-postfixed.js'></script>
-    <script src='deps/pouchdb-2.0.0-postfixed.js'></script>
-    <script src='deps/pouchdb-2.2.0-postfixed.js'></script>
-    <script src='deps/pouchdb-3.0.6-postfixed.js'></script>
-    <script src='deps/pouchdb-3.2.0-postfixed.js'></script>
-    <script src='deps/pouchdb-3.6.0-postfixed.js'></script>
-    <script src='utils.js'></script>
-    <script src='test.ajax.js'></script>
-    <script src='test.aa.setup.js'></script>
-    <script src='test.basics.js'></script>
-    <script src='test.constructor.js'></script>
-    <script src='test.changes.js'></script>
-    <script src='test.bulk_docs.js'></script>
-    <script src='test.bulk_get.js'></script>
-    <script src='test.all_docs.js'></script>
-    <script src='test.events.js'></script>
-    <script src='test.conflicts.js'></script>
-    <script src='test.revs_diff.js'></script>
-    <script src='test.replication.js'></script>
-    <script src='test.replication_events.js'></script>
-    <script src='test.sync.js'></script>
-    <script src='test.sync_events.js'></script>
-    <script src='test.retry.js'></script>
-    <script src='test.taskqueue.js'></script>
-    <script src='test.design_docs.js'></script>
-    <script src='browser.info.js'></script>
-    <script src='test.issue221.js'></script>
-    <script src='test.issue3179.js'></script>
-    <script src='test.issue3646.js'></script>
-    <script src='test.http.js'></script>
-    <script src='test.compaction.js'></script>
-    <script src='test.get.js'></script>
-    <script src='test.local_docs.js'></script>
-    <script src='test.attachments.js'></script>
-    <script src='browser.migration.js'></script>
-    <script src='test.uuids.js'></script>
-    <script src='test.slash_id.js'></script>
-    <script src='test.reserved.js'></script>
-    <script src='browser.worker.js'></script>
-    <script type="text/javascript" src="./webrunner.js"></script>
-  </body>
-</html>
diff --git a/tests/integration/leveldb/lateStyle/000003.log b/tests/integration/leveldb/lateStyle/000003.log
deleted file mode 100644
index 33de8cc..0000000
--- a/tests/integration/leveldb/lateStyle/000003.log
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/lateStyle/CURRENT b/tests/integration/leveldb/lateStyle/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/lateStyle/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/lateStyle/LOCK b/tests/integration/leveldb/lateStyle/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/lateStyle/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/lateStyle/LOG b/tests/integration/leveldb/lateStyle/LOG
deleted file mode 100644
index b83544f..0000000
--- a/tests/integration/leveldb/lateStyle/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/10/18-13:54:18.233480 103b7a000 Delete type=3 #1
diff --git a/tests/integration/leveldb/lateStyle/MANIFEST-000002 b/tests/integration/leveldb/lateStyle/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/lateStyle/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/laterStyle/000003.log b/tests/integration/leveldb/laterStyle/000003.log
deleted file mode 100644
index 08a82f0..0000000
--- a/tests/integration/leveldb/laterStyle/000003.log
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/laterStyle/CURRENT b/tests/integration/leveldb/laterStyle/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/laterStyle/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/laterStyle/LOCK b/tests/integration/leveldb/laterStyle/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/laterStyle/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/laterStyle/LOG b/tests/integration/leveldb/laterStyle/LOG
deleted file mode 100644
index 80ca43e..0000000
--- a/tests/integration/leveldb/laterStyle/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/12/13-15:08:05.242031 103b97000 Delete type=3 #1
diff --git a/tests/integration/leveldb/laterStyle/MANIFEST-000002 b/tests/integration/leveldb/laterStyle/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/laterStyle/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/middleStyle/000003.log b/tests/integration/leveldb/middleStyle/000003.log
deleted file mode 100644
index 05cc845..0000000
--- a/tests/integration/leveldb/middleStyle/000003.log
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/middleStyle/CURRENT b/tests/integration/leveldb/middleStyle/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/middleStyle/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/middleStyle/LOCK b/tests/integration/leveldb/middleStyle/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/middleStyle/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/middleStyle/LOG b/tests/integration/leveldb/middleStyle/LOG
deleted file mode 100644
index bc24db1..0000000
--- a/tests/integration/leveldb/middleStyle/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/04/30-13:26:08.586711 106881000 Delete type=3 #1
diff --git a/tests/integration/leveldb/middleStyle/MANIFEST-000002 b/tests/integration/leveldb/middleStyle/MANIFEST-000002
deleted file mode 100644
index dbf594e..0000000
--- a/tests/integration/leveldb/middleStyle/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle.uuid b/tests/integration/leveldb/oldStyle.uuid
deleted file mode 100644
index 751fa94..0000000
--- a/tests/integration/leveldb/oldStyle.uuid
+++ /dev/null
@@ -1 +0,0 @@
-F25693E5-4052-4F30-BEAF-9D1E48DD05CF
\ No newline at end of file
diff --git a/tests/integration/leveldb/oldStyle/attach-binary-store/000003.log b/tests/integration/leveldb/oldStyle/attach-binary-store/000003.log
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/attach-binary-store/000003.log
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/attach-binary-store/CURRENT b/tests/integration/leveldb/oldStyle/attach-binary-store/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/oldStyle/attach-binary-store/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/oldStyle/attach-binary-store/LOCK b/tests/integration/leveldb/oldStyle/attach-binary-store/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/attach-binary-store/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/attach-binary-store/LOG b/tests/integration/leveldb/oldStyle/attach-binary-store/LOG
deleted file mode 100644
index 5b9c46e..0000000
--- a/tests/integration/leveldb/oldStyle/attach-binary-store/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/02/21-19:45:02.682927 103b87000 Delete type=3 #1
diff --git a/tests/integration/leveldb/oldStyle/attach-binary-store/MANIFEST-000002 b/tests/integration/leveldb/oldStyle/attach-binary-store/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/oldStyle/attach-binary-store/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle/attach-store/000003.log b/tests/integration/leveldb/oldStyle/attach-store/000003.log
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/attach-store/000003.log
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/attach-store/CURRENT b/tests/integration/leveldb/oldStyle/attach-store/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/oldStyle/attach-store/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/oldStyle/attach-store/LOCK b/tests/integration/leveldb/oldStyle/attach-store/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/attach-store/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/attach-store/LOG b/tests/integration/leveldb/oldStyle/attach-store/LOG
deleted file mode 100644
index 2c68122..0000000
--- a/tests/integration/leveldb/oldStyle/attach-store/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/02/21-19:45:02.682637 103a81000 Delete type=3 #1
diff --git a/tests/integration/leveldb/oldStyle/attach-store/MANIFEST-000002 b/tests/integration/leveldb/oldStyle/attach-store/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/oldStyle/attach-store/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle/by-sequence/000003.log b/tests/integration/leveldb/oldStyle/by-sequence/000003.log
deleted file mode 100644
index 953ab4b..0000000
--- a/tests/integration/leveldb/oldStyle/by-sequence/000003.log
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle/by-sequence/CURRENT b/tests/integration/leveldb/oldStyle/by-sequence/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/oldStyle/by-sequence/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/oldStyle/by-sequence/LOCK b/tests/integration/leveldb/oldStyle/by-sequence/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/by-sequence/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/by-sequence/LOG b/tests/integration/leveldb/oldStyle/by-sequence/LOG
deleted file mode 100644
index 52362b6..0000000
--- a/tests/integration/leveldb/oldStyle/by-sequence/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/02/21-19:45:02.682960 103b04000 Delete type=3 #1
diff --git a/tests/integration/leveldb/oldStyle/by-sequence/MANIFEST-000002 b/tests/integration/leveldb/oldStyle/by-sequence/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/oldStyle/by-sequence/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle/document-store/000003.log b/tests/integration/leveldb/oldStyle/document-store/000003.log
deleted file mode 100644
index c011370..0000000
--- a/tests/integration/leveldb/oldStyle/document-store/000003.log
+++ /dev/null
Binary files differ
diff --git a/tests/integration/leveldb/oldStyle/document-store/CURRENT b/tests/integration/leveldb/oldStyle/document-store/CURRENT
deleted file mode 100644
index 1a84852..0000000
--- a/tests/integration/leveldb/oldStyle/document-store/CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-MANIFEST-000002
diff --git a/tests/integration/leveldb/oldStyle/document-store/LOCK b/tests/integration/leveldb/oldStyle/document-store/LOCK
deleted file mode 100644
index e69de29..0000000
--- a/tests/integration/leveldb/oldStyle/document-store/LOCK
+++ /dev/null
diff --git a/tests/integration/leveldb/oldStyle/document-store/LOG b/tests/integration/leveldb/oldStyle/document-store/LOG
deleted file mode 100644
index 4833ff5..0000000
--- a/tests/integration/leveldb/oldStyle/document-store/LOG
+++ /dev/null
@@ -1 +0,0 @@
-2014/02/21-19:45:02.682986 102781000 Delete type=3 #1
diff --git a/tests/integration/leveldb/oldStyle/document-store/MANIFEST-000002 b/tests/integration/leveldb/oldStyle/document-store/MANIFEST-000002
deleted file mode 100644
index bbbc585..0000000
--- a/tests/integration/leveldb/oldStyle/document-store/MANIFEST-000002
+++ /dev/null
Binary files differ
diff --git a/tests/integration/node.setup.js b/tests/integration/node.setup.js
deleted file mode 100644
index 8ed4ead..0000000
--- a/tests/integration/node.setup.js
+++ /dev/null
@@ -1,25 +0,0 @@
-"use strict";
-
-// throw an error if any EventEmitter adds too many listeners
-require('throw-max-listeners-error');
-
-var seedrandom = require('seedrandom');
-var seed = process.env.SEED || Date.now();
-console.log('Seeded with: ' + seed);
-seedrandom(seed, { global: true });
-
-var testsDir = process.env.TESTS_DIR || './tmp';
-var exec = require('child_process').exec;
-function cleanup() {
-  // Remove test databases
-  exec('rm -r ' + testsDir);
-}
-exec('mkdir -p ' + testsDir, function () {
-  process.on('SIGINT', cleanup);
-  process.on('exit', cleanup);
-});
-global.testUtils = require('./utils.js');
-var chai = require('chai');
-chai.use(require('chai-as-promised'));
-global.should = chai.should();
-
diff --git a/tests/integration/test.aa.setup.js b/tests/integration/test.aa.setup.js
deleted file mode 100644
index 6103b84..0000000
--- a/tests/integration/test.aa.setup.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-describe('DB Setup', function () {
-  it('we can find CouchDB with admin credentials', function (done) {
-    PouchDB.ajax({ url: testUtils.couchHost() + '/_session' },
-      function (err, res) {
-        if (err) { return done(err); }
-        should.exist(res.ok, 'Found CouchDB');
-        res.userCtx.roles.should.include('_admin', 'Found admin permissions');
-        done();
-      }
-    );
-  });
-
-  it('PouchDB has a version', function () {
-    PouchDB.version.should.be.a('string');
-    PouchDB.version.should.match(/\d+\.\d+\.\d+/);
-  });
-});
diff --git a/tests/integration/test.ajax.js b/tests/integration/test.ajax.js
deleted file mode 100644
index 0f0f7c9..0000000
--- a/tests/integration/test.ajax.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-
-adapters.forEach(function (adapter) {
-
-  describe('test.ajax.js-' + adapter, function () {
-
-    it('#5061 ajax returns ETIMEDOUT error on timeout', function (done) {
-      this.timeout(240000);
-      PouchDB.ajax({
-        method: 'GET',
-        url: 'http://192.0.2.1/',
-        timeout: 10
-      }, function (err, res) {
-        // here's the test, we should get an 'err' response
-        should.exist(err);
-        err.status.should.equal(400);
-        err.message.should.equal('ETIMEDOUT');
-        should.not.exist(res);
-        done();
-      });
-    });
-  });
-});
-
diff --git a/tests/integration/test.all_docs.js b/tests/integration/test.all_docs.js
deleted file mode 100644
index c4db3ad..0000000
--- a/tests/integration/test.all_docs.js
+++ /dev/null
@@ -1,703 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.all_docs.js-' + adapter, function () {
-
-    var dbs = {};
-    beforeEach(function (done) {
-      dbs = {name: testUtils.adapterUrl(adapter, 'testdb')};
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    var origDocs = [
-      {_id: '0', a: 1, b: 1},
-      {_id: '3', a: 4, b: 16},
-      {_id: '1', a: 2, b: 4},
-      {_id: '2', a: 3, b: 9}
-    ];
-
-    it('Testing all docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-        function () {
-        db.allDocs(function (err, result) {
-          should.not.exist(err);
-          var rows = result.rows;
-          result.total_rows.should.equal(4, 'correct number of results');
-          for (var i = 0; i < rows.length; i++) {
-            rows[i].id.should.be.at.least('0');
-            rows[i].id.should.be.at.most('4');
-          }
-          db.allDocs({
-            startkey: '2',
-            include_docs: true
-          }, function (err, all) {
-            all.rows.should.have
-              .length(2, 'correct number when opts.startkey set');
-            all.rows[0].id.should
-              .equal('2', 'correct docs when opts.startkey set');
-            var opts = {
-              startkey: 'org.couchdb.user:',
-              endkey: 'org.couchdb.user;'
-            };
-            db.allDocs(opts, function (err, raw) {
-              raw.rows.should.have.length(0, 'raw collation');
-              var ids = ['0', '3', '1', '2'];
-              db.changes().on('complete', function (changes) {
-                // order of changes is not guaranteed in a
-                // clustered changes feed
-                changes.results.forEach(function (row) {
-                  ids.should.include(row.id, 'seq order');
-                });
-                db.changes({
-                  descending: true
-                }).on('complete', function (changes) {
-                  // again, order is not guaranteed so
-                  // unsure if this is a useful test
-                  ids = ['2', '1', '3', '0'];
-                  changes.results.forEach(function (row) {
-                    ids.should.include(row.id, 'descending=true');
-                  });
-                  done();
-                }).on('error', done);
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing allDocs opts.keys', function () {
-      var db = new PouchDB(dbs.name);
-      function keyFunc(doc) {
-        return doc.key;
-      }
-      var keys;
-      return db.bulkDocs(origDocs).then(function () {
-        keys = ['3', '1'];
-        return db.allDocs({keys: keys});
-      }).then(function (result) {
-        result.rows.map(keyFunc).should.deep.equal(keys);
-        keys = ['2', '0', '1000'];
-        return db.allDocs({ keys: keys });
-      }).then(function (result) {
-        result.rows.map(keyFunc).should.deep.equal(keys);
-        result.rows[2].error.should.equal('not_found');
-        return db.allDocs({
-          keys: keys,
-          descending: true
-        });
-      }).then(function (result) {
-        result.rows.map(keyFunc).should.deep.equal(['1000', '0', '2']);
-        result.rows[0].error.should.equal('not_found');
-        return db.allDocs({
-          keys: keys,
-          startkey: 'a'
-        });
-      }).then(function () {
-        throw new Error('expected an error');
-      }, function (err) {
-        should.exist(err);
-        return db.allDocs({
-          keys: keys,
-          endkey: 'a'
-        });
-      }).then(function () {
-          throw new Error('expected an error');
-        }, function (err) {
-        should.exist(err);
-        return db.allDocs({keys: []});
-      }).then(function (result) {
-        result.rows.should.have.length(0);
-        return db.get('2');
-      }).then(function (doc) {
-        return db.remove(doc);
-      }).then(function () {
-        return db.allDocs({
-          keys: keys,
-          include_docs: true
-        });
-      }).then(function (result) {
-        result.rows.map(keyFunc).should.deep.equal(keys);
-      });
-    });
-
-    it('Testing allDocs opts.keys with skip', function () {
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(origDocs).then(function () {
-        return db.allDocs({
-          keys: ['3', '1'],
-          skip: 1
-        });
-      }).then(function (res) {
-        res.total_rows.should.equal(4);
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('1');
-      });
-    });
-
-    it('Testing allDocs invalid opts.keys', function () {
-      var db = new PouchDB(dbs.name);
-      return db.allDocs({keys: 1234}).then(function () {
-        throw 'should not be here';
-      }).catch(function (err) {
-        should.exist(err);
-      });
-    });
-
-    it('Testing deleting in changes', function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.info(function (err, info) {
-        var update_seq = info.update_seq;
-        
-        testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-          function () {
-          db.get('1', function (err, doc) {
-            db.remove(doc, function (err, deleted) {
-              should.exist(deleted.ok);
-
-              db.changes({
-                since: update_seq
-              }).on('complete', function (changes) {
-                var deleted_ids = changes.results.map(function (c) {
-                  if (c.deleted) { return c.id; }
-                });
-                deleted_ids.should.include('1');
-
-                done();
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing updating in changes', function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.info(function (err, info) {
-        var update_seq = info.update_seq;
-        
-        testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)), 
-          function () {
-          db.get('3', function (err, doc) {
-            doc.updated = 'totally';
-            db.put(doc, function () {
-              db.changes({
-                since: update_seq
-              }).on('complete', function (changes) {
-                var ids = changes.results.map(function (c) { return c.id; });
-                ids.should.include('3');
-
-                done();
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing include docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-        function () {
-        db.changes({
-          include_docs: true
-        }).on('complete', function (changes) {
-          changes.results.forEach(function (row) {
-            if (row.id === '0') {
-              row.doc.a.should.equal(1);
-            }
-          });
-          done();
-        }).on('error', done);
-      });
-    });
-
-    it('Testing conflicts', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-        function () {
-        // add conflicts
-        var conflictDoc1 = {
-          _id: '3',
-          _rev: '2-aa01552213fafa022e6167113ed01087',
-          value: 'X'
-        };
-        var conflictDoc2 = {
-          _id: '3',
-          _rev: '2-ff01552213fafa022e6167113ed01087',
-          value: 'Z'
-        };
-        db.put(conflictDoc1, { new_edits: false }, function () {
-          db.put(conflictDoc2, { new_edits: false }, function () {
-            db.get('3', function (err, winRev) {
-              winRev._rev.should.equal(conflictDoc2._rev);
-              db.changes({
-                include_docs: true,
-                conflicts: true,
-                style: 'all_docs'
-              }).on('complete', function (changes) {
-                changes.results.map(function (x) { return x.id; }).sort()
-                  .should.deep.equal(['0', '1', '2', '3'],
-                    'all ids are in _changes');
-
-                var result = changes.results.filter(function (row) {
-                  return row.id === '3';
-                })[0];
-
-                result.changes.should.have
-                  .length(3, 'correct number of changes');
-                result.doc._rev.should.equal(conflictDoc2._rev);
-                result.doc._id.should.equal('3', 'correct doc id');
-                winRev._rev.should.equal(result.doc._rev);
-                result.doc._conflicts.should.be.instanceof(Array);
-                result.doc._conflicts.should.have.length(2);
-                conflictDoc1._rev.should.equal(result.doc._conflicts[0]);
-
-                db.allDocs({
-                  include_docs: true,
-                  conflicts: true
-                }, function (err, res) {
-                  var row = res.rows[3];
-                  res.rows.should.have.length(4, 'correct number of changes');
-                  row.key.should.equal('3', 'correct key');
-                  row.id.should.equal('3', 'correct id');
-                  row.value.rev.should.equal(winRev._rev, 'correct rev');
-                  row.doc._rev.should.equal(winRev._rev, 'correct rev');
-                  row.doc._id.should.equal('3', 'correct order');
-                  row.doc._conflicts.should.be.instanceof(Array);
-                  row.doc._conflicts.should.have.length(2);
-                  conflictDoc1._rev.should
-                    .equal(res.rows[3].doc._conflicts[0]);
-                  done();
-                });
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('test basic collation', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = {
-        docs: [
-          {_id: 'z', foo: 'z'},
-          {_id: 'a', foo: 'a'}
-        ]
-      };
-      db.bulkDocs(docs, function () {
-        db.allDocs({
-          startkey: 'z',
-          endkey: 'z'
-        }, function (err, result) {
-          result.rows.should.have.length(1, 'Exclude a result');
-          done();
-        });
-      });
-    });
-
-    it('3883 start_key end_key aliases', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [{_id: 'a', foo: 'a'}, {_id: 'z', foo: 'z'}];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({start_key: 'z', end_key: 'z'});
-      }).then(function (result) {
-        result.rows.should.have.length(1, 'Exclude a result');
-      });
-    });
-
-    it('test total_rows with a variety of criteria', function (done) {
-      this.timeout(20000);
-      var db = new PouchDB(dbs.name);
-
-      var docs = [
-        {_id : '0'},
-        {_id : '1'},
-        {_id : '2'},
-        {_id : '3'},
-        {_id : '4'},
-        {_id : '5'},
-        {_id : '6'},
-        {_id : '7'},
-        {_id : '8'},
-        {_id : '9'}
-      ];
-      db.bulkDocs({docs : docs}).then(function (res) {
-        docs[3]._deleted = true;
-        docs[7]._deleted = true;
-        docs[3]._rev = res[3].rev;
-        docs[7]._rev = res[7].rev;
-        return db.remove(docs[3]);
-      }).then(function () {
-          return db.remove(docs[7]);
-        }).then(function () {
-          return db.allDocs();
-        }).then(function (res) {
-          res.rows.should.have.length(8,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5'});
-        }).then(function (res) {
-          res.rows.should.have.length(4,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', skip : 2, limit : 10});
-        }).then(function (res) {
-          res.rows.should.have.length(2,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', limit : 0});
-        }).then(function (res) {
-          res.rows.should.have
-            .length(0,  'correctly return rows, startkey w/ limit=0');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({keys : ['5'], limit : 0});
-        }).then(function (res) {
-          res.rows.should.have
-            .length(0,  'correctly return rows, keys w/ limit=0');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({limit : 0});
-        }).then(function (res) {
-          res.rows.should.have.length(0,  'correctly return rows, limit=0');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', descending : true, skip : 1});
-        }).then(function (res) {
-          res.rows.should.have.length(4,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', endkey : 'z'});
-        }).then(function (res) {
-          res.rows.should.have.length(4,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', endkey : '5'});
-        }).then(function (res) {
-          res.rows.should.have.length(1,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', endkey : '4'});
-        }).then(function (res) {
-          res.rows.should.have.length(0,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '5', endkey : '4', descending : true});
-        }).then(function (res) {
-          res.rows.should.have.length(2,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '3', endkey : '7', descending : false});
-        }).then(function (res) {
-          res.rows.should.have.length(3,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '7', endkey : '3', descending : true});
-        }).then(function (res) {
-          res.rows.should.have.length(3,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({startkey : '', endkey : '0'});
-        }).then(function (res) {
-          res.rows.should.have.length(1,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({keys : ['0', '1', '3']});
-        }).then(function (res) {
-          res.rows.should.have.length(3,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({keys : ['0', '1', '0', '2', '1', '1']});
-        }).then(function (res) {
-          res.rows.should.have.length(6,  'correctly return rows');
-          res.rows.map(function (row) { return row.key; }).should.deep.equal(
-            ['0', '1', '0', '2', '1', '1']);
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({keys : []});
-        }).then(function (res) {
-          res.rows.should.have.length(0,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({keys : ['7']});
-        }).then(function (res) {
-          res.rows.should.have.length(1,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({key : '3'});
-        }).then(function (res) {
-          res.rows.should.have.length(0,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({key : '2'});
-        }).then(function (res) {
-          res.rows.should.have.length(1,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          return db.allDocs({key : 'z'});
-        }).then(function (res) {
-          res.rows.should.have.length(0,  'correctly return rows');
-          res.total_rows.should.equal(8,  'correctly return total_rows');
-          done();
-        }, done);
-
-    });
-
-    it('test total_rows with both skip and limit', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = {
-        docs: [
-          {_id: "w", foo: "w"},
-          {_id: "x", foo: "x"},
-          {_id: "y", foo: "y"},
-          {_id: "z", foo: "z"}
-        ]
-      };
-      db.bulkDocs(docs, function () {
-        db.allDocs({ startkey: 'x', limit: 1, skip : 1}, function (err, res) {
-          res.total_rows.should.equal(4,  'Accurately return total_rows count');
-          res.rows.should.have.length(1,  'Correctly limit the returned rows');
-          res.rows[0].id.should.equal('y', 'Correctly skip 1 doc');
-
-          db.get('x', function (err, xDoc) {
-            db.remove(xDoc, function () {
-              db.allDocs({ startkey: 'w', limit: 2, skip : 1},
-                function (err, res) {
-                res.total_rows.should
-                  .equal(3,  'Accurately return total_rows count after delete');
-                res.rows.should.have
-                  .length(2,  'Correctly limit the returned rows after delete');
-                res.rows[0].id.should
-                  .equal('y', 'Correctly skip 1 doc after delete');
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('test limit option and total_rows', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = {
-        docs: [
-          {_id: 'z', foo: 'z'},
-          {_id: 'a', foo: 'a'}
-        ]
-      };
-      db.bulkDocs(docs, function () {
-        db.allDocs({
-          startkey: 'a',
-          limit: 1
-        }, function (err, res) {
-          res.total_rows.should.equal(2, 'Accurately return total_rows count');
-          res.rows.should.have.length(1, 'Correctly limit the returned rows.');
-          done();
-        });
-      });
-    });
-
-    it('test escaped startkey/endkey', function (done) {
-      var db = new PouchDB(dbs.name);
-      var id1 = '"weird id!" a';
-      var id2 = '"weird id!" z';
-      var docs = {
-        docs: [
-          {
-            _id: id1,
-            foo: 'a'
-          },
-          {
-            _id: id2,
-            foo: 'z'
-          }
-        ]
-      };
-      db.bulkDocs(docs, function () {
-        db.allDocs({
-          startkey: id1,
-          endkey: id2
-        }, function (err, res) {
-          res.total_rows.should.equal(2, 'Accurately return total_rows count');
-          done();
-        });
-      });
-    });
-
-    it('test "key" option', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { _id: '0' },
-          { _id: '1' },
-          { _id: '2' }
-        ]
-      }, function (err) {
-        should.not.exist(err);
-        db.allDocs({ key: '1' }, function (err, res) {
-          res.rows.should.have.length(1, 'key option returned 1 doc');
-          db.allDocs({
-            key: '1',
-            keys: [
-              '1',
-              '2'
-            ]
-          }, function (err) {
-            should.exist(err);
-            db.allDocs({
-              key: '1',
-              startkey: '1'
-            }, function (err) {
-              should.not.exist(err);
-              db.allDocs({
-                key: '1',
-                endkey: '1'
-              }, function (err) {
-                should.not.exist(err);
-                // when mixing key/startkey or key/endkey, the results
-                // are very weird and probably undefined, so don't go beyond
-                // verifying that there's no error
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('test inclusive_end=false', function (done) {
-      new PouchDB(dbs.name).then(function (db) {
-        var docs = [
-          { _id: '1' },
-          { _id: '2' },
-          { _id: '3' },
-          { _id: '4' }
-        ];
-        return db.bulkDocs({docs: docs}).then(function () {
-          return db.allDocs({inclusive_end: false, endkey: '2'});
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          return db.allDocs({inclusive_end: false, endkey: '1'});
-        }).then(function (res) {
-          res.rows.should.have.length(0);
-          return db.allDocs({inclusive_end: false, endkey: '1',
-            startkey: '0'});
-        }).then(function (res) {
-          res.rows.should.have.length(0);
-          return db.allDocs({inclusive_end: false, endkey: '5'});
-        }).then(function (res) {
-          res.rows.should.have.length(4);
-          return db.allDocs({inclusive_end: false, endkey: '4'});
-        }).then(function (res) {
-          res.rows.should.have.length(3);
-          return db.allDocs({inclusive_end: false, endkey: '4',
-            startkey: '3'});
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          return db.allDocs({inclusive_end: false, endkey: '1',
-            descending: true});
-        }).then(function (res) {
-          res.rows.should.have.length(3);
-          return db.allDocs({inclusive_end: true, endkey: '4'});
-        }).then(function (res) {
-          res.rows.should.have.length(4);
-          return db.allDocs({
-            descending: true,
-            startkey: '3',
-            endkey: '2',
-            inclusive_end: false
-          });
-        });
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-      }).then(function () {
-        done();
-      }, function (err) {
-        done(err);
-      });
-    });
-
-    it('#3082 test wrong num results returned', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 1000; i++) {
-        docs.push({});
-      }
-
-      var lastkey;
-      var allkeys = [];
-
-      function paginate() {
-        var opts = {include_doc: true, limit: 100};
-        if (lastkey) {
-          opts.startkey = lastkey;
-          opts.skip = 1;
-        }
-        return db.allDocs(opts).then(function (res) {
-          if (!res.rows.length) {
-            return;
-          }
-          if (lastkey) {
-            res.rows[0].key.should.be.above(lastkey);
-          }
-          res.rows.should.have.length(100);
-          lastkey = res.rows.pop().key;
-          allkeys.push(lastkey);
-          return paginate();
-        });
-      }
-
-      return db.bulkDocs(docs).then(function () {
-        return paginate().then(function () {
-          // try running all queries at once to try to isolate race condition
-          return PouchDB.utils.Promise.all(allkeys.map(function (key) {
-            return db.allDocs({
-              limit: 100,
-              include_docs: true,
-              startkey: key,
-              skip: 1
-            }).then(function (res) {
-              if (!res.rows.length) {
-                return;
-              }
-              res.rows[0].key.should.be.above(key);
-              res.rows.should.have.length(100);
-            });
-          }));
-        });
-      });
-    });
-
-    it('test empty db', function (done) {
-      return new PouchDB(dbs.name).then(function (db) {
-        return db.allDocs().then(function (res) {
-          res.rows.should.have.length(0);
-          res.total_rows.should.equal(0);
-          done();
-        });
-      });
-    });
-
-    it('test after db close', function (done) {
-      return new PouchDB(dbs.name).then(function (db) {
-        return db.close().then(function () {
-          return db.allDocs().catch(function (err) {
-            err.message.should.equal('database is closed');
-            done();
-          });
-        });
-      });
-    });
-
-    if (adapter === 'local') { // chrome doesn't like \u0000 in URLs
-      it('test unicode ids and revs', function (done) {
-        var db = new PouchDB(dbs.name);
-        var id = 'baz\u0000';
-        var rev;
-        return db.put({_id: id}).then(function (res) {
-          rev = res.rev;
-        }).then(function () {
-            return db.get(id);
-          }).then(function (doc) {
-            doc._id.should.equal(id);
-            doc._rev.should.equal(rev);
-            return db.allDocs({keys: [id]});
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows[0].value.rev.should.equal(rev);
-          }).then(done, done);
-      });
-    }
-  });
-});
diff --git a/tests/integration/test.attachments.js b/tests/integration/test.attachments.js
deleted file mode 100644
index 1c704f2..0000000
--- a/tests/integration/test.attachments.js
+++ /dev/null
@@ -1,3880 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-var repl_adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-/* jshint maxlen:false */
-var icons = [
-  "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"
-];
-
-var iconDigests = [
-  "md5-Mf8m9ehZnCXC717bPkqkCA==",
-  "md5-fdEZBYtnvr+nozYVDzzxpA==",
-  "md5-ImDARszfC+GA3Cv9TVW4HA==",
-  "md5-hBsgoz3ujHM4ioa72btwow==",
-  "md5-jDUyV6ySnTVANn2qq3332g=="
-];
-
-var iconLengths = [1047, 789, 967, 527, 1108];
-
-adapters.forEach(function (adapter) {
-  describe('suite2 test.attachments.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    var binAttDoc = {
-      _id: 'bin_doc',
-      _attachments: {
-        'foo.txt': {
-          content_type: 'text/plain',
-          data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-        }
-      }
-    };
-    // empty attachment
-    var binAttDoc2 = {
-      _id: 'bin_doc2',
-      _attachments: {
-        'foo.txt': {
-          content_type: 'text/plain',
-          data: ''
-        }
-      }
-    };
-    // json string doc
-    var jsonDoc = {
-      _id: 'json_doc',
-      _attachments: {
-        'foo.json': {
-          content_type: 'application/json',
-          data: 'eyJIZWxsbyI6IndvcmxkIn0='
-        }
-      }
-    };
-    var pngAttDoc = {
-      _id: 'png_doc',
-      _attachments: {
-        'foo.png': {
-          content_type: 'image/png',
-          data: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAMFBMVEX+9+' +
-                'j+9OD+7tL95rr93qT80YD7x2L6vkn6syz5qRT4ogT4nwD4ngD4nQD4nQD4' +
-                'nQDT2nT/AAAAcElEQVQY002OUQLEQARDw1D14f7X3TCdbfPnhQTqI5UqvG' +
-                'OWIz8gAIXFH9zmC63XRyTsOsCWk2A9Ga7wCXlA9m2S6G4JlVwQkpw/Ymxr' +
-                'UgNoMoyxBwSMH/WnAzy5cnfLFu+dK2l5gMvuPGLGJd1/9AOiBQiEgkzOpg' +
-                'AAAABJRU5ErkJggg=='
-        }
-      }
-    };
-
-    it('3357 Attachment names cant start with _', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'baz', _attachments: {
-        '_text1.txt': {
-          content_type: 'text/plain',
-          data: testUtils.btoa('text1')
-        }
-      }};
-      return db.put(doc).then(function () {
-        done('Should not succeed');
-      }).catch(function (err) {
-        err.name.should.equal('bad_request');
-        done();
-      });
-    });
-
-    it('fetch atts with open_revs and missing', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'frog',
-        _rev: '1-x',
-        _revisions: {
-          start: 1,
-          ids: ['x']
-        },
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: ''
-          }
-        }
-      };
-      return db.bulkDocs({
-        docs: [doc],
-        new_edits: false
-      }).then(function () {
-        return db.get('frog', {
-          revs: true,
-          open_revs: ['1-x', '2-fake'],
-          attachments: true
-        });
-      }).then(function (res) {
-        // there should be exactly one "ok" result
-        // and one result with attachments
-        res.filter(function (x) {
-          return x.ok;
-        }).should.have.length(1);
-        res.filter(function (x) {
-          return x.ok && x.ok._attachments;
-        }).should.have.length(1);
-      });
-    });
-
-    it('issue 2803 should throw 412', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['bar.txt'] = {
-          stub: true,
-          digest: 'md5-sorryIDoNotReallyExist=='
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        should.not.exist(res, 'should throw');
-      }).catch(function (err) {
-        should.exist(err.status, 'got improper error: ' + err);
-        err.status.should.equal(412);
-      });
-    });
-
-    it('issue 2803 should throw 412 part 2', function () {
-      var stubDoc = {
-        _id: 'stubby',
-        "_attachments": {
-          "foo.txt": {
-            "content_type": "text/plain",
-            "digest": "md5-aEI7pOYCRBLTRQvvqYrrJQ==",
-            "stub": true
-          }
-        }
-      };
-      var db = new PouchDB(dbs.name);
-      return db.put(stubDoc).then(function (res) {
-        should.not.exist(res, 'should throw');
-      }).catch(function (err) {
-        should.exist(err.status, 'got improper error: ' + err);
-        err.status.should.equal(412, 'got improper error: ' + err);
-      });
-    });
-
-    it('issue 2803 should throw 412 part 3', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['foo.json'] = jsonDoc._attachments['foo.json'];
-      }).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['bar.txt'] = {
-          stub: true,
-          digest: 'md5-sorryIDoNotReallyExist=='
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        should.not.exist(res, 'should throw');
-      }).catch(function (err) {
-        should.exist(err.status, 'got improper error: ' + err);
-        err.status.should.equal(412);
-      });
-    });
-
-    it('issue 2803 should throw 412 part 4', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['foo.json'] = jsonDoc._attachments['foo.json'];
-      }).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['bar.txt'] = {
-          stub: true,
-          digest: 'md5-sorryIDoNotReallyExist=='
-        };
-        doc._attachments['baz.txt'] = {
-          stub: true,
-          digest: 'md5-yahNoIDoNotExistEither=='
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        should.not.exist(res, 'should throw');
-      }).catch(function (err) {
-        should.exist(err.status, 'got improper error: ' + err);
-        err.status.should.equal(412);
-      });
-    });
-
-    it('#2858 {binary: true} in get()', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc];
-      return db.bulkDocs(docs).then(function () {
-        return PouchDB.utils.Promise.all(docs.map(function (doc) {
-          var attName = Object.keys(doc._attachments)[0];
-          var expected = doc._attachments[attName];
-          return db.get(doc._id, {
-            attachments: true,
-            binary: true
-          }).then(function (savedDoc) {
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data);
-          }).then(function (bin) {
-            testUtils.btoa(bin).should.equal(expected.data);
-          });
-        }));
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs() 1', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc, {_id: 'foo'}];
-      return db.bulkDocs(docs).then(function () {
-        return PouchDB.utils.Promise.all(docs.map(function (doc) {
-          var atts = doc._attachments;
-          var attName = atts && Object.keys(atts)[0];
-          var expected = atts && atts[attName];
-          return db.allDocs({
-            key: doc._id,
-            attachments: true,
-            binary: true,
-            include_docs: true
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            var savedDoc = res.rows[0].doc;
-            if (!atts) {
-              should.not.exist(savedDoc._attachments);
-              return;
-            }
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data).then(function (bin) {
-              testUtils.btoa(bin).should.equal(expected.data);
-            });
-          });
-        }));
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs() 2', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc, {_id: 'foo'}];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          include_docs: true,
-          attachments: true,
-          binary: true
-        }).then(function (res) {
-          var savedDocs = res.rows.map(function (x) {
-            return x.doc;
-          });
-          return PouchDB.utils.Promise.all(docs.map(function (doc) {
-            var atts = doc._attachments;
-            var attName = atts && Object.keys(atts)[0];
-            var expected = atts && atts[attName];
-            var savedDoc = savedDocs.filter(function (x) {
-              return x._id === doc._id;
-            })[0];
-            if (!atts) {
-              should.not.exist(savedDoc._attachments);
-              return;
-            }
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data).then(function (bin) {
-              testUtils.btoa(bin).should.equal(expected.data);
-            });
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs() 3', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', _deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          include_docs: true,
-          attachments: true,
-          binary: true
-        }).then(function (res) {
-          res.rows.should.have.length(4);
-          var savedDocs = res.rows.map(function (x) {
-            return x.doc;
-          });
-          return PouchDB.utils.Promise.all(docs.filter(function (doc) {
-            return !doc._deleted;
-          }).map(function (doc) {
-            var atts = doc._attachments;
-            var attName = atts && Object.keys(atts)[0];
-            var expected = atts && atts[attName];
-            var savedDoc = savedDocs.filter(function (x) {
-              return x._id === doc._id;
-            })[0];
-            if (!atts) {
-              should.not.exist(savedDoc._attachments);
-              return;
-            }
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data).then(function (bin) {
-              testUtils.btoa(bin).should.equal(expected.data);
-            });
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs() 4', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', _deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          attachments: true,
-          binary: true
-        }).then(function (res) {
-          res.rows.should.have.length(4);
-          res.rows.forEach(function (row) {
-            should.not.exist(row.doc);
-          });
-          return db.allDocs({
-            binary: true
-          });
-        }).then(function (res) {
-          res.rows.should.have.length(4);
-          res.rows.forEach(function (row) {
-            should.not.exist(row.doc);
-          });
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs() 5', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          keys: [
-            binAttDoc._id, binAttDoc2._id, pngAttDoc._id, 'foo', 'bar'
-          ],
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.rows.should.have.length(5);
-
-          return PouchDB.utils.Promise.all(res.rows.map(function (row, i) {
-            if (docs[i]._deleted) {
-              should.not.exist(row.doc);
-              return;
-            }
-            var atts = docs[i]._attachments;
-            var attName = atts && Object.keys(atts)[0];
-            var expected = atts && atts[attName];
-            var savedDoc = row.doc;
-            if (!atts) {
-              should.not.exist(savedDoc._attachments);
-              return;
-            }
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data).then(function (bin) {
-              testUtils.btoa(bin).should.equal(expected.data);
-            });
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs(), many atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.rows.should.have.length(5);
-
-          return PouchDB.utils.Promise.all(res.rows.map(function (row) {
-            var doc = docs.filter(function (x) {
-              return x._id === row.id;
-            })[0];
-            var atts = doc._attachments;
-            var attNames = Object.keys(atts);
-            return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-              var expected = atts && atts[attName];
-              var savedDoc = row.doc;
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-              });
-            }));
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in allDocs(), mixed atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'imdeleted', _deleted: true},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'imempty'},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-
-        {_id: 'imempty2'},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'imkindaempty', _attachments: {
-          'text0.txt': {
-            content_type: 'text/plain',
-            data: ''
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.rows.should.have.length(8);
-
-          return PouchDB.utils.Promise.all(res.rows.map(function (row) {
-            var doc = docs.filter(function (x) {
-              return x._id === row.id;
-            })[0];
-            if (doc._deleted) {
-              should.not.exist(row.doc);
-              return;
-            }
-            var atts = doc._attachments;
-            if (!atts) {
-              should.not.exist(row.doc._attachments);
-              return;
-            }
-            var attNames = Object.keys(atts);
-            return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-              var expected = atts && atts[attName];
-              var savedDoc = row.doc;
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-              });
-            }));
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in changes() non-live', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.results.should.have.length(5);
-
-          return PouchDB.utils.Promise.all(res.results.map(function (row) {
-            var doc = docs.filter(function (x) {
-              return x._id === row.id;
-            })[0];
-            if (doc._deleted) {
-              should.not.exist(row.doc);
-              return;
-            }
-            var atts = doc._attachments;
-            var attName = atts && Object.keys(atts)[0];
-            var expected = atts && atts[attName];
-            var savedDoc = row.doc;
-            if (!atts) {
-              should.not.exist(savedDoc._attachments);
-              return;
-            }
-            var att = savedDoc._attachments[attName];
-            should.not.exist(att.stub);
-            should.exist(att.digest);
-            att.content_type.should.equal(expected.content_type);
-            att.data.should.not.be.a('string');
-            att.data.type.should.equal(expected.content_type);
-            return testUtils.readBlobPromise(att.data).then(function (bin) {
-              testUtils.btoa(bin).should.equal(expected.data);
-            });
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in changes() non-live, many atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.results.should.have.length(5);
-
-          return PouchDB.utils.Promise.all(res.results.map(function (row) {
-            var doc = docs.filter(function (x) {
-              return x._id === row.id;
-            })[0];
-            var atts = doc._attachments;
-            var attNames = Object.keys(atts);
-            return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-              var expected = atts && atts[attName];
-              var savedDoc = row.doc;
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-              });
-            }));
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in changes() non-live, mixed atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'imdeleted', _deleted: true},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'imempty'},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-
-        {_id: 'imempty2'},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'imkindaempty', _attachments: {
-          'text0.txt': {
-            content_type: 'text/plain',
-            data: ''
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          attachments: true,
-          binary: true,
-          include_docs: true
-        }).then(function (res) {
-          res.results.should.have.length(9);
-
-          return PouchDB.utils.Promise.all(res.results.map(function (row) {
-            var doc = docs.filter(function (x) {
-              return x._id === row.id;
-            })[0];
-            var atts = doc._attachments;
-            if (!atts) {
-              should.not.exist(row.doc._attachments);
-              return;
-            }
-            var attNames = Object.keys(atts);
-            return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-              var expected = atts && atts[attName];
-              var savedDoc = row.doc;
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-              });
-            }));
-          }));
-        });
-      });
-    });
-
-    it('#2858 {binary: true} non-live changes, complete event', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'imdeleted', _deleted: true},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'imempty'},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-
-        {_id: 'imempty2'},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'imkindaempty', _attachments: {
-          'text0.txt': {
-            content_type: 'text/plain',
-            data: ''
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          db.changes({
-            attachments: true,
-            binary: true,
-            include_docs: true
-          }).on('error', reject).on('complete', resolve);
-        }).then(function (results) {
-            return PouchDB.utils.Promise.all(results.results.map(function (row) {
-              var doc = docs.filter(function (x) {
-                return x._id === row.id;
-              })[0];
-              if (row.deleted) {
-                should.not.exist(row.doc._attachments);
-                return;
-              }
-              var atts = doc._attachments;
-              var savedDoc = row.doc;
-              if (!atts) {
-                should.not.exist(savedDoc._attachments);
-                return;
-              }
-              var attNames = Object.keys(atts);
-              return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-                var expected = atts && atts[attName];
-                var att = savedDoc._attachments[attName];
-                should.not.exist(att.stub);
-                should.exist(att.digest);
-                att.content_type.should.equal(expected.content_type);
-                att.data.should.not.be.a('string');
-                att.data.type.should.equal(expected.content_type);
-                return testUtils.readBlobPromise(att.data).then(function (bin) {
-                  testUtils.btoa(bin).should.equal(expected.data);
-                });
-              }));
-            }));
-          });
-      });
-    });
-
-    it('#2858 {binary: true} in live changes', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var ret = db.changes({
-            attachments: true,
-            binary: true,
-            include_docs: true,
-            live: true
-          }).on('error', reject)
-            .on('change', handleChange)
-            .on('complete', resolve);
-
-          var promise = PouchDB.utils.Promise.resolve();
-          var done = 0;
-
-          function doneWithDoc() {
-            if (++done === 5 && changes === 5) {
-              ret.cancel();
-            }
-          }
-
-          var changes = 0;
-          function handleChange(change) {
-            changes++;
-            promise = promise.then(function () {
-              var doc = docs.filter(function (x) {
-                return x._id === change.id;
-              })[0];
-              if (change.deleted) {
-                should.not.exist(change.doc);
-                return doneWithDoc();
-              }
-              var atts = doc._attachments;
-              var attName = atts && Object.keys(atts)[0];
-              var expected = atts && atts[attName];
-              var savedDoc = change.doc;
-              if (!atts) {
-                should.not.exist(savedDoc._attachments);
-                return doneWithDoc();
-              }
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-                doneWithDoc();
-              });
-            }).catch(reject);
-          }
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in live changes, mixed atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'baz', _attachments: {
-          'text1.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text1')
-          },
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          }
-        }},
-        {_id: 'foo', _attachments: {
-          'text5.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text5')
-          }
-        }},
-        {_id: 'imdeleted', _deleted: true},
-        {_id: 'quux', _attachments: {
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          },
-          'text4.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text4')
-          }
-        }},
-        {_id: 'imempty'},
-        {_id: 'zob', _attachments: {
-          'text6.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-
-        {_id: 'imempty2'},
-        {_id: 'zorb', _attachments: {
-          'text2.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text2')
-          },
-          'text3.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('text3')
-          }
-        }},
-        {_id: 'imkindaempty', _attachments: {
-          'text0.txt': {
-            content_type: 'text/plain',
-            data: ''
-          }
-        }}
-      ];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var ret = db.changes({
-            attachments: true,
-            binary: true,
-            include_docs: true,
-            live: true
-          }).on('error', reject)
-            .on('change', handleChange)
-            .on('complete', resolve);
-
-          var promise = PouchDB.utils.Promise.resolve();
-          var done = 0;
-
-          function doneWithDoc() {
-            if (++done === 9 && changes === 9) {
-              ret.cancel();
-            }
-          }
-
-          var changes = 0;
-          function handleChange(change) {
-            changes++;
-            promise = promise.then(function () {
-              var doc = docs.filter(function (x) {
-                return x._id === change.id;
-              })[0];
-              if (change.deleted) {
-                should.not.exist(change.doc._attachments);
-                return doneWithDoc();
-              }
-              var atts = doc._attachments;
-              var savedDoc = change.doc;
-              if (!atts) {
-                should.not.exist(savedDoc._attachments);
-                return doneWithDoc();
-              }
-              var attNames = Object.keys(atts);
-              return PouchDB.utils.Promise.all(attNames.map(function (attName) {
-                var expected = atts && atts[attName];
-                var att = savedDoc._attachments[attName];
-                should.not.exist(att.stub);
-                should.exist(att.digest);
-                att.content_type.should.equal(expected.content_type);
-                att.data.should.not.be.a('string');
-                att.data.type.should.equal(expected.content_type);
-                return testUtils.readBlobPromise(att.data).then(function (bin) {
-                  testUtils.btoa(bin).should.equal(expected.data);
-                });
-              })).then(doneWithDoc);
-            }).catch(reject);
-          }
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in live+retry changes', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var ret = db.changes({
-            attachments: true,
-            binary: true,
-            include_docs: true,
-            live: true
-          }).on('error', reject)
-            .on('change', handleChange)
-            .on('complete', resolve);
-
-          var promise = PouchDB.utils.Promise.resolve();
-          var done = 0;
-
-          function doneWithDoc() {
-            if (++done === 5 && changes === 5) {
-              ret.cancel();
-            }
-          }
-
-          var changes = 0;
-          function handleChange(change) {
-            changes++;
-            promise = promise.then(function () {
-              var doc = docs.filter(function (x) {
-                return x._id === change.id;
-              })[0];
-              if (change.deleted) {
-                should.not.exist(change.doc);
-                return doneWithDoc();
-              }
-              var atts = doc._attachments;
-              var attName = atts && Object.keys(atts)[0];
-              var expected = atts && atts[attName];
-              var savedDoc = change.doc;
-              if (!atts) {
-                should.not.exist(savedDoc._attachments);
-                return doneWithDoc();
-              }
-              var att = savedDoc._attachments[attName];
-              should.not.exist(att.stub);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              att.data.should.not.be.a('string');
-              att.data.type.should.equal(expected.content_type);
-              return testUtils.readBlobPromise(att.data).then(function (bin) {
-                testUtils.btoa(bin).should.equal(expected.data);
-                doneWithDoc();
-              });
-            }).catch(reject);
-          }
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in live changes, attachments:false', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var ret = db.changes({
-            include_docs: true,
-            binary: true,
-            live: true
-          }).on('error', reject)
-            .on('change', handleChange)
-            .on('complete', resolve);
-
-          var promise = PouchDB.utils.Promise.resolve();
-          var done = 0;
-
-          function doneWithDoc() {
-            if (++done === 5 && changes === 5) {
-              ret.cancel();
-            }
-          }
-
-          var changes = 0;
-          function handleChange(change) {
-            changes++;
-            promise = promise.then(function () {
-              var doc = docs.filter(function (x) {
-                return x._id === change.id;
-              })[0];
-              if (change.deleted) {
-                should.not.exist(change.doc);
-                return doneWithDoc();
-              }
-              var atts = doc._attachments;
-              var attName = atts && Object.keys(atts)[0];
-              var expected = atts && atts[attName];
-              var savedDoc = change.doc;
-              if (!atts) {
-                should.not.exist(savedDoc._attachments);
-                return doneWithDoc();
-              }
-              var att = savedDoc._attachments[attName];
-              att.stub.should.equal(true);
-              should.exist(att.digest);
-              att.content_type.should.equal(expected.content_type);
-              should.not.exist(att.data);
-              doneWithDoc();
-            }).catch(reject);
-          }
-        });
-      });
-    });
-
-    it('#2858 {binary: true} in live changes, include_docs:false', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [binAttDoc, binAttDoc2, pngAttDoc,
-        {_id: 'bar'},
-        {_id: 'foo', deleted: true}];
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var ret = db.changes({
-            attachments: true,
-            binary: true,
-            live: true
-          }).on('error', reject)
-            .on('change', handleChange)
-            .on('complete', resolve);
-
-          var promise = PouchDB.utils.Promise.resolve();
-          var done = 0;
-
-          function doneWithDoc() {
-            if (++done === 5 && changes === 5) {
-              ret.cancel();
-            }
-          }
-
-          var changes = 0;
-          function handleChange(change) {
-            changes++;
-            promise = promise.then(function () {
-              should.not.exist(change.doc);
-              return doneWithDoc();
-            }).catch(reject);
-          }
-        });
-      });
-    });
-
-    it('Measures length correctly after put()', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        delete doc._attachments["foo.txt"].revpos;
-
-        // because of libicu vs. ascii
-        var digest = doc._attachments["foo.txt"].digest;
-        var validDigests = [
-          "md5-qUUYqS41RhwF0TrCsTAxFg==",
-          "md5-aEI7pOYCRBLTRQvvqYrrJQ==",
-          "md5-jeLnIuUvK7d+6gya044lVA=="
-        ];
-        validDigests.indexOf(digest).should.not.equal(-1,
-          'expected ' + digest  + ' to be in: ' +
-            JSON.stringify(validDigests));
-        delete doc._attachments["foo.txt"].digest;
-        doc._attachments.should.deep.equal({
-          "foo.txt": {
-            "content_type": "text/plain",
-            "stub": true,
-            length: 29
-          }
-        });
-      });
-    });
-
-    it('#3074 non-live changes()', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({include_docs: true, attachments: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "foo.png": {
-              "content_type": "image/png",
-              "data": icon,
-              "digest": iconDigests[i]
-            }
-          };
-        }), 'when attachments=true');
-        return db.changes({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments['foo.png'];
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "content_type": "image/png",
-            stub: true,
-            "digest": iconDigests[i],
-            length: iconLengths[i]
-          };
-        }), 'when attachments=false');
-        return db.changes({attachments: true});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=true but include_docs=false');
-        });
-        return db.changes();
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=false and include_docs=false');
-        });
-      });
-    });
-
-    it('#3074 live changes()', function () {
-      var db = new PouchDB(dbs.name);
-
-      function liveChangesPromise(opts) {
-        opts.live = true;
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var retChanges = {results: []};
-          var changes = db.changes(opts)
-            .on('change', function (change) {
-              retChanges.results.push(change);
-              if (retChanges.results.length === 5) {
-                changes.cancel();
-                resolve(retChanges);
-              }
-            }).on('error', reject);
-        });
-      }
-
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return liveChangesPromise({
-          include_docs: true,
-          attachments: true
-        });
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "foo.png": {
-              "content_type": "image/png",
-              "data": icon,
-              "digest": iconDigests[i]
-            }
-          };
-        }), 'when attachments=true');
-        return liveChangesPromise({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments['foo.png'];
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "content_type": "image/png",
-            stub: true,
-            "digest": iconDigests[i],
-            length: iconLengths[i]
-          };
-        }), 'when attachments=false');
-        return liveChangesPromise({attachments: true});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=true but include_docs=false');
-        });
-        return liveChangesPromise({});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=false and include_docs=false');
-        });
-      });
-    });
-
-    it('#3074 non-live changes(), no attachments', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString()
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({include_docs: true, attachments: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          return !!doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function () {
-          return false;
-        }), 'when attachments=true');
-        return db.changes({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          return !!doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function () {
-          return false;
-        }), 'when attachments=false');
-        return db.changes({attachments: true});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=true but include_docs=false');
-        });
-        return db.changes();
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=false and include_docs=false');
-        });
-      });
-    });
-
-    it('#3074 live changes(), no attachments', function () {
-
-      var db = new PouchDB(dbs.name);
-
-      function liveChangesPromise(opts) {
-        opts.live = true;
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var retChanges = {results: []};
-          var changes = db.changes(opts)
-            .on('change', function (change) {
-              retChanges.results.push(change);
-              if (retChanges.results.length === 5) {
-                changes.cancel();
-                resolve(retChanges);
-              }
-            }).on('error', reject);
-        });
-      }
-
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString()
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return liveChangesPromise({
-          include_docs: true,
-          attachments: true
-        });
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          return !!doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function () {
-          return false;
-        }), 'when attachments=true');
-        return liveChangesPromise({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.results.sort(function (left, right) {
-          return left.id < right.id ? -1 : 1;
-        }).map(function (change) {
-          var doc = change.doc;
-          return !!doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function () {
-          return false;
-        }), 'when attachments=false');
-        return liveChangesPromise({attachments: true});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=true but include_docs=false');
-        });
-        return liveChangesPromise({});
-      }).then(function (res) {
-        res.results.should.have.length(5);
-        res.results.forEach(function (row) {
-          should.not.exist(row.doc,
-            'no doc when attachments=false and include_docs=false');
-        });
-      });
-    });
-
-    it('#3881 filter extraneous keys from _attachments', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({
-        _id: 'foo',
-        _attachments: {
-          'foo.txt': {
-            data: '',
-            content_type: 'text/plain',
-            follows: false,
-            foo: 'bar',
-            baz: true,
-            quux: 1
-          }
-        }
-      }).then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        var keys = Object.keys(doc._attachments['foo.txt']).filter(function (x) {
-          return x !== 'revpos'; // not supported by PouchDB right now
-        }).sort();
-        keys.should.deep.equal(['content_type', 'data', 'digest']);
-      });
-    });
-
-    it('#2771 allDocs() 1, single attachment', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.allDocs({key: binAttDoc._id, include_docs: true});
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        delete doc._attachments["foo.txt"].revpos;
-
-        // because of libicu vs. ascii
-        var digest = doc._attachments["foo.txt"].digest;
-        var validDigests = [
-          "md5-qUUYqS41RhwF0TrCsTAxFg==",
-          "md5-aEI7pOYCRBLTRQvvqYrrJQ==",
-          "md5-jeLnIuUvK7d+6gya044lVA=="
-        ];
-        validDigests.indexOf(digest).should.not.equal(-1,
-          'expected ' + digest  + ' to be in: ' +
-          JSON.stringify(validDigests));
-        delete doc._attachments["foo.txt"].digest;
-        doc._attachments.should.deep.equal({
-          "foo.txt": {
-            "content_type": "text/plain",
-            "stub": true,
-            length: 29
-          }
-        });
-        return db.allDocs({
-          key: binAttDoc._id,
-          include_docs: true,
-          attachments: true
-        });
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        doc._attachments['foo.txt'].content_type.should.equal(
-          binAttDoc._attachments['foo.txt'].content_type);
-        doc._attachments['foo.txt'].data.should.equal(
-          binAttDoc._attachments['foo.txt'].data);
-      });
-    });
-
-    it('#2771 allDocs() 2, many docs same att', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.txt': {
-              data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=',
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true, attachments: true});
-      }).then(function (res) {
-        var attachments = res.rows.map(function (row) {
-          var doc = row.doc;
-          delete doc._attachments['foo.txt'].revpos;
-          should.exist(doc._attachments['foo.txt'].digest);
-          delete doc._attachments['foo.txt'].digest;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal([1, 2, 3, 4, 5].map(function () {
-          return {
-            "foo.txt": {
-              "content_type": "text/plain",
-              "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
-            }
-          };
-        }));
-      });
-    });
-
-    it('#2771 allDocs() 3, many docs diff atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true, attachments: true});
-      }).then(function (res) {
-        var attachments = res.rows.map(function (row) {
-          var doc = row.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "foo.png": {
-              "content_type": "image/png",
-              "data": icon,
-              "digest": iconDigests[i]
-            }
-          };
-        }));
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.rows.map(function (row) {
-          var doc = row.doc;
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments['foo.png'];
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "content_type": "image/png",
-            stub: true,
-            "digest": iconDigests[i],
-            length: iconLengths[i]
-          };
-        }));
-      });
-    });
-
-    it('#2771 allDocs() 4, mix of atts and no atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        var doc = {
-          _id: i.toString()
-        };
-        if (i % 2 === 1) {
-          doc._attachments = {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          };
-        }
-        docs.push(doc);
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true, attachments: true});
-      }).then(function (res) {
-        var attachments = res.rows.map(function (row, i) {
-          var doc = row.doc;
-          if (i % 2 === 1) {
-            delete doc._attachments['foo.png'].revpos;
-            return doc._attachments;
-          }
-          return null;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          if (i % 2 === 0) {
-            return null;
-          }
-          return {
-            "foo.png": {
-              "content_type": "image/png",
-              "data": icon,
-              "digest": iconDigests[i]
-            }
-          };
-        }));
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var attachments = res.rows.map(function (row, i) {
-          var doc = row.doc;
-          if (i % 2 === 1) {
-            delete doc._attachments['foo.png'].revpos;
-            return doc._attachments['foo.png'];
-          }
-          return null;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          if (i % 2 === 0) {
-            return null;
-          }
-          return {
-            "content_type": "image/png",
-            stub: true,
-            "digest": iconDigests[i],
-            length: iconLengths[i]
-          };
-        }));
-      });
-    });
-
-    it('#2771 allDocs() 5, no atts', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        var doc = {
-          _id: i.toString()
-        };
-        docs.push(doc);
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true, attachments: true});
-      }).then(function (res) {
-        res.rows.should.have.length(5);
-        res.rows.forEach(function (row) {
-          should.exist(row.doc);
-          should.not.exist(row.doc._attachments);
-        });
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        res.rows.should.have.length(5);
-        res.rows.forEach(function (row) {
-          should.exist(row.doc);
-          should.not.exist(row.doc._attachments);
-        });
-      });
-    });
-
-    it('#2771 allDocs() 6, no docs', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        var doc = {
-          _id: i.toString()
-        };
-        docs.push(doc);
-      }
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({
-          include_docs: true,
-          attachments: true,
-          keys: []
-        });
-      }).then(function (res) {
-        res.rows.should.have.length(0);
-        return db.allDocs({include_docs: true, keys: []});
-      }).then(function (res) {
-        res.rows.should.have.length(0);
-      });
-    });
-
-    it('#2771 allDocs() 7, revisions and deletions', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9vYmFy' // 'foobar'
-          }
-        }
-      };
-      var rev;
-      return db.put(doc).then(function () {
-        return db.allDocs({keys: ['doc'], attachments: true, include_docs: true});
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        doc._attachments['foo.txt'].data.should.equal('Zm9vYmFy');
-        rev = doc._rev;
-        doc._attachments['foo.txt'] = {
-          content_type: 'text/plain',
-          data: 'dG90bw=='
-        }; // 'toto'
-        return db.put(doc);
-      }).then(function () {
-        return db.allDocs({keys: ['doc'], attachments: true, include_docs: true});
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        doc._attachments['foo.txt'].data.should.equal('dG90bw==');
-        return db.remove(doc);
-      }).then(function (res) {
-        rev = res.rev;
-        return db.allDocs({keys: ['doc'], attachments: true, include_docs: true});
-      }).then(function (res) {
-        // technically CouchDB sets this to null, but we won't adhere strictly to that
-        should.not.exist(res.rows[0].doc);
-        delete res.rows[0].doc;
-        res.rows.should.deep.equal([
-          {
-            id: "doc",
-            key: "doc",
-            value: {
-              rev: rev,
-              deleted: true
-            }
-          }
-        ]);
-      });
-    });
-
-    it('#2771 allDocs() 8, empty attachment', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc2).then(function () {
-        return db.allDocs({key: binAttDoc2._id, include_docs: true});
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        delete doc._attachments["foo.txt"].revpos;
-
-        // because of libicu vs. ascii
-        var digest = doc._attachments["foo.txt"].digest;
-        var validDigests = [
-          'md5-1B2M2Y8AsgTpgAmY7PhCfg==',
-          'md5-cCkGbCesb17xjWYNV0GXmg==',
-          'md5-3gIs+o2eJiHrXZqziQZqBA=='
-        ];
-        validDigests.indexOf(digest).should.not.equal(-1,
-          'expected ' + digest  + ' to be in: ' +
-          JSON.stringify(validDigests));
-        delete doc._attachments["foo.txt"].digest;
-        delete doc._attachments["foo.txt"].digest;
-        doc._attachments.should.deep.equal({
-          "foo.txt": {
-            "content_type": "text/plain",
-            "stub": true,
-            length: 0
-          }
-        });
-        return db.allDocs({
-          key: binAttDoc2._id,
-          include_docs: true,
-          attachments: true
-        });
-      }).then(function (res) {
-        var doc = res.rows[0].doc;
-        doc._attachments['foo.txt'].content_type.should.equal(
-          binAttDoc2._attachments['foo.txt'].content_type);
-        doc._attachments['foo.txt'].data.should.equal(
-          binAttDoc2._attachments['foo.txt'].data);
-      });
-    });
-
-    it('No length for non-stubs', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id, {attachments: true});
-      }).then(function (doc) {
-        should.not.exist(doc._attachments['foo.txt'].stub);
-        should.not.exist(doc._attachments['foo.txt'].length);
-      });
-    });
-
-    it('Test some attachments', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(binAttDoc, function (err) {
-        should.not.exist(err, 'saved doc with attachment');
-        db.get('bin_doc', function (err, doc) {
-          should.exist(doc._attachments, 'doc has attachments field');
-          should.exist(doc._attachments['foo.txt'], 'doc has attachment');
-          doc._attachments['foo.txt'].content_type.should.equal('text/plain');
-          db.getAttachment('bin_doc', 'foo.txt', function (err, res) {
-            should.not.exist(err, 'fetched attachment');
-            res.type.should.equal('text/plain');
-            testUtils.readBlob(res, function (data) {
-              data.should.equal('This is a base64 encoded text');
-              db.put(binAttDoc2, function (err, rev) {
-                db.getAttachment('bin_doc2', 'foo.txt',
-                  function (err, res) {
-                  should.not.exist(err);
-                  res.type.should.equal('text/plain');
-                  testUtils.readBlob(res, function (data) {
-                    data.should.equal('', 'Correct data returned');
-                    moreTests(rev.rev);
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-
-      function moreTests(rev) {
-        var blob = testUtils.makeBlob('This is no base64 encoded text');
-        db.putAttachment('bin_doc2', 'foo2.txt', rev, blob, 'text/plain',
-                         function (err, info) {
-          info.ok.should.equal(true);
-          db.getAttachment('bin_doc2', 'foo2.txt', function (err, res) {
-            should.not.exist(err);
-            res.type.should.equal('text/plain');
-            testUtils.readBlob(res, function (data) {
-              should.exist(data);
-              db.get('bin_doc2', { attachments: true },
-                function (err, res) {
-                should.not.exist(err);
-                should.exist(res._attachments, 'Result has attachments field');
-                should.not
-                  .exist(res._attachments['foo2.txt'].stub, 'stub is false');
-                res._attachments['foo2.txt'].data.should
-                  .equal('VGhpcyBpcyBubyBiYXNlNjQgZW5jb2RlZCB0ZXh0');
-                res._attachments['foo2.txt'].content_type.should
-                  .equal('text/plain');
-                res._attachments['foo.txt'].data.should.equal('');
-                done();
-              });
-            });
-          });
-        });
-      }
-    });
-
-    it('Test getAttachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(binAttDoc, function (err) {
-        should.not.exist(err);
-        db.getAttachment('bin_doc', 'foo.txt', function (err, res) {
-          if (err) {
-            return done(err);
-          }
-          res.type.should.equal('text/plain');
-          testUtils.readBlob(res, function (data) {
-            data.should.equal('This is a base64 encoded text', 'correct data');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test getAttachment with stubs', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({
-        _id: 'doc',
-        _attachments: {
-          '1': {
-            content_type: 'application/octet-stream',
-            data: testUtils.btoa('1\u00002\u00013\u0002')
-          }
-        }
-      }).then(function () {
-        return db.get('doc');
-      }).then(function (doc) {
-        doc._attachments['2'] = {
-          content_type: 'application/octet-stream',
-          data: testUtils.btoa('3\u00002\u00011\u0002')
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.getAttachment('doc', '1');
-      }).then(function (att) {
-        att.type.should.equal('application/octet-stream');
-        return testUtils.readBlobPromise(att);
-      }).then(function (bin) {
-        bin.should.equal('1\u00002\u00013\u0002');
-        return db.getAttachment('doc', '2');
-      }).then(function (att) {
-        att.type.should.equal('application/octet-stream');
-        return testUtils.readBlobPromise(att);
-      }).then(function (bin) {
-        bin.should.equal('3\u00002\u00011\u0002');
-      });
-    });
-
-    it('Test get() with binary:true and stubs', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({
-        _id: 'doc',
-        _attachments: {
-          '1': {
-            content_type: 'application/octet-stream',
-            data: testUtils.btoa('1\u00002\u00013\u0002')
-          }
-        }
-      }).then(function () {
-        return db.get('doc');
-      }).then(function (doc) {
-        doc._attachments['2'] = {
-          content_type: 'application/octet-stream',
-          data: testUtils.btoa('3\u00002\u00011\u0002')
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.get('doc', {attachments: true, binary: true});
-      }).then(function (doc) {
-        var att1 = doc._attachments['1'].data;
-        var att2 = doc._attachments['2'].data;
-        att1.type.should.equal('application/octet-stream');
-        att2.type.should.equal('application/octet-stream');
-        return testUtils.readBlobPromise(att1).then(function (bin) {
-          bin.should.equal('1\u00002\u00013\u0002');
-          return testUtils.readBlobPromise(att2);
-        }).then(function (bin) {
-          bin.should.equal('3\u00002\u00011\u0002');
-        });
-      });
-    });
-
-    it('Test attachments in allDocs/changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        { _id: 'doc0' },
-        {
-          _id: 'doc1',
-          _attachments: {
-            'att0': {
-              data: 'YXR0YWNobWVudDA=',
-              content_type: 'text/plain'
-            }
-          }
-        },
-        {
-          _id: 'doc2',
-          _attachments: {
-            'att0': {
-              data: 'YXR0YWNobWVudDA=',
-              content_type: 'text/plain'
-            },
-            'att1': {
-              data: 'YXR0YWNobWVudDE=',
-              content_type: 'text/plain'
-            }
-          }
-        },
-        {
-          _id: 'doc3',
-          _attachments: {
-            'att0': {
-              data: 'YXR0YWNobWVudDA=',
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-      function sort(a, b) {
-        return a.id.localeCompare(b.id);
-      }
-      db.bulkDocs({ docs: docs }, function () {
-        db.allDocs({ include_docs: true }, function (err, res) {
-          for (var i = 0; i < docs.length; i++) {
-            var attachmentsNb = typeof docs[i]._attachments !== 'undefined' ?
-              Object.keys(docs[i]._attachments).length : 0;
-            for (var j = 0; j < attachmentsNb; j++) {
-              res.rows[i].doc._attachments['att' + j].stub.should
-                .equal(true, '(allDocs) doc' + i + ' contains att' + j +
-                       ' stub');
-            }
-          }
-          should.not.exist(res.rows[0].doc._attachments,
-                           '(allDocs) doc0 contains no attachments');
-          db.changes({
-            include_docs: true
-          }).on('change', function (change) {
-            var i = +change.id.substr(3);
-            if (i === 0) {
-              should.not.exist(res.rows[0].doc._attachments,
-                               '(onChange) doc0 contains no attachments');
-            } else {
-              var attachmentsNb =
-                typeof docs[i]._attachments !== 'undefined' ?
-                Object.keys(docs[i]._attachments).length : 0;
-              for (var j = 0; j < attachmentsNb; j++) {
-                res.rows[i].doc._attachments['att' + j].stub.should
-                  .equal(true, '(onChange) doc' + i + ' contains att' + j +
-                         ' stub');
-              }
-            }
-          }).on('complete', function (res) {
-            var attachmentsNb = 0;
-            res.results.sort(sort);
-            for (var i = 0; i < 3; i++) {
-              attachmentsNb = typeof docs[i]._attachments !== 'undefined' ?
-                Object.keys(docs[i]._attachments).length : 0;
-              for (var j = 0; j < attachmentsNb; j++) {
-                res.results[i].doc._attachments['att' + j].stub.should
-                  .equal(true, '(complete) doc' + i + ' contains att' + j +
-                         ' stub');
-              }
-            }
-            should.not.exist(res.results[0].doc._attachments,
-                             '(complete) doc0 contains no attachments');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test putAttachment with base64 plaintext', function () {
-      var db = new PouchDB(dbs.name);
-      return db.putAttachment('doc', 'att', null, 'Zm9v', 'text/plain').then(function () {
-        return db.getAttachment('doc', 'att');
-      }).then(function (blob) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          testUtils.base64Blob(blob, function (data) {
-            data.should.equal('Zm9v', 'should get the correct base64 back');
-            resolve();
-          });
-        });
-      });
-    });
-
-    it('Test putAttachment with invalid base64', function () {
-      var db = new PouchDB(dbs.name);
-      return db.putAttachment('doc', 'att', null, '\u65e5\u672c\u8a9e', 'text/plain')
-        .should.be.rejected.then(function (err) {
-          err.should.have.property("message", "Some query argument is invalid");
-        });
-    });
-
-    it('Test getAttachment with empty text', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(binAttDoc2, function (err) {
-        if (err) { return done(err); }
-        db.getAttachment('bin_doc2', 'foo.txt', function (err, res) {
-          if (err) { return done(err); }
-          (typeof res).should.equal('object', 'res is object, ' +
-            'not a string');
-          testUtils.base64Blob(res, function (data) {
-            data.should.equal('', 'correct data');
-            db.get(binAttDoc2._id, function (err, doc) {
-              var att = doc._attachments['foo.txt'];
-              att.stub.should.equal(true);
-              // both ascii and libicu
-              var validDigests = [
-                'md5-1B2M2Y8AsgTpgAmY7PhCfg==',
-                'md5-cCkGbCesb17xjWYNV0GXmg==',
-                'md5-3gIs+o2eJiHrXZqziQZqBA=='
-              ];
-              validDigests.indexOf(att.digest).should.be.above(-1);
-              att.content_type.should.equal('text/plain');
-              att.length.should.equal(0);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test getAttachment with normal text', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(binAttDoc, function (err) {
-        if (err) { return done(err); }
-        db.getAttachment('bin_doc', 'foo.txt', function (err, res) {
-          if (err) { return done(err); }
-          (typeof res).should.equal('object', 'res is object, ' +
-            'not a string');
-          testUtils.base64Blob(res, function (data) {
-            data.should.equal(
-              binAttDoc._attachments['foo.txt'].data, 'correct data');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test getAttachment with PNG', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(pngAttDoc, function (err) {
-        if (err) { return done(err); }
-        db.getAttachment('png_doc', 'foo.png', function (err, res) {
-          if (err) { return done(err); }
-          (typeof res).should.equal('object', 'res is object, ' +
-            'not a string');
-          testUtils.base64Blob(res, function (data) {
-            data.should
-              .equal(pngAttDoc._attachments['foo.png'].data, 'correct data');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test getAttachment with PNG using bulkDocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs([pngAttDoc], function (err) {
-        if (err) { return done(err); }
-        db.getAttachment('png_doc', 'foo.png', function (err, res) {
-          if (err) { return done(err); }
-          testUtils.base64Blob(res, function (data) {
-            data.should
-              .equal(pngAttDoc._attachments['foo.png'].data, 'correct data');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test getAttachment with PNG using post', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post(pngAttDoc, function (err) {
-        if (err) { return done(err); }
-        db.getAttachment('png_doc', 'foo.png', function (err, res) {
-          if (err) { return done(err); }
-          testUtils.base64Blob(res, function (data) {
-            data.should
-              .equal(pngAttDoc._attachments['foo.png'].data, 'correct data');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test postAttachment with PNG then bulkDocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function () {
-        db.get('foo', function (err, doc) {
-          var data = pngAttDoc._attachments['foo.png'].data;
-          var blob = testUtils.binaryStringToBlob(testUtils.atob(data),
-            'image/png');
-          db.putAttachment('foo', 'foo.png', doc._rev, blob, 'image/png',
-              function (err) {
-            should.not.exist(err, 'attachment inserted');
-            db.bulkDocs([{}], function (err) {
-              should.not.exist(err, 'doc inserted');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('proper stub behavior', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        return db.putAttachment(doc._id, 'foo.json', doc._rev,
-          jsonDoc._attachments['foo.json'].data,
-          jsonDoc._attachments['foo.json'].content_type);
-      }).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        Object.keys(doc._attachments).forEach(function (filename) {
-          var att = doc._attachments[filename];
-          should.not.exist(att.data);
-          att.stub.should.equal(true);
-          should.exist(att.digest);
-          should.exist(att.content_type);
-        });
-        return db.get(binAttDoc._id, {attachments: true});
-      }).then(function (doc) {
-        Object.keys(doc._attachments).forEach(function (filename) {
-          var att = doc._attachments[filename];
-          should.exist(att.data);
-          should.not.exist(att.stub);
-          should.exist(att.digest);
-          should.exist(att.content_type);
-        });
-      });
-    });
-
-    it('Testing with invalid docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      var invalidDoc = {
-        '_id': '_invalid',
-        foo: 'bar'
-      };
-      db.bulkDocs({
-        docs: [
-          invalidDoc,
-          binAttDoc
-        ]
-      }, function (err) {
-        should.exist(err, 'bad request');
-        done();
-      });
-    });
-
-    it('Test create attachment and doc in one go', function (done) {
-      var db = new PouchDB(dbs.name);
-      var blob = testUtils.makeBlob('Mytext');
-      db.putAttachment('anotherdoc', 'mytext', blob, 'text/plain',
-        function (err, res) {
-        should.exist(res.ok);
-        done();
-      });
-    });
-
-    it('Test create attachment and doc in one go without callback',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var changes = db.changes({
-        live: true
-      }).on('complete', function (result) {
-        result.status.should.equal('cancelled');
-        done();
-      }).on('change', function (change) {
-        if (change.id === 'anotherdoc2') {
-          change.id.should.equal('anotherdoc2', 'Doc has been created');
-          db.get(change.id, { attachments: true }, function (err, doc) {
-            doc._attachments.should.be
-              .an('object', 'doc has attachments object');
-            should.exist(doc._attachments.mytext,
-                         'doc has attachments attachment');
-            doc._attachments.mytext.data.should
-              .equal('TXl0ZXh0', 'doc has attachments attachment');
-            changes.cancel();
-          });
-        }
-      });
-        var blob = testUtils.makeBlob('Mytext');
-      db.putAttachment('anotherdoc2', 'mytext', blob, 'text/plain');
-    });
-
-    it('Test create attachment without callback', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'anotherdoc3' }, function (err, resp) {
-        should.not.exist(err, 'doc was saved');
-        db.info(function (err, info) {
-
-          var changes = db.changes({
-            since: info.update_seq,
-            live: true,
-            include_docs: true
-          }).on('complete', function (result) {
-            result.status.should.equal('cancelled');
-            done();
-          }).on('change', function (change) {
-            if (change.id === 'anotherdoc3') {
-              db.get(change.id, { attachments: true }, function (err, doc) {
-                doc._attachments.should.be.an('object',
-                                            'doc has attachments object');
-                should.exist(doc._attachments.mytext);
-                doc._attachments.mytext.data.should.equal('TXl0ZXh0');
-                changes.cancel();
-              });
-            }
-          });
-          var blob = testUtils.makeBlob('Mytext');
-          db.putAttachment('anotherdoc3', 'mytext', resp.rev, blob,
-            'text/plain');
-        });
-      });
-    });
-
-    it('Test put attachment on a doc without attachments', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'mydoc' }, function (err, resp) {
-        var blob = testUtils.makeBlob('Mytext');
-        db.putAttachment('mydoc', 'mytext', resp.rev, blob, 'text/plain',
-                         function (err, res) {
-          should.exist(res.ok);
-          done();
-        });
-      });
-    });
-
-    it('Test put attachment with unencoded name', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'mydoc' }, function (err, resp) {
-        var blob = testUtils.makeBlob('Mytext');
-        db.putAttachment('mydoc', 'my/text?@', resp.rev, blob, 'text/plain',
-                         function (err, res) {
-          should.exist(res.ok);
-
-          db.get('mydoc', { attachments: true }, function (err, res) {
-            should.exist(res._attachments['my/text?@']);
-
-            db.getAttachment('mydoc', 'my/text?@', function (err, attachment) {
-              should.not.exist(err);
-              attachment.type.should.equal('text/plain');
-              testUtils.readBlob(attachment, function (data) {
-                data.should.eql('Mytext');
-
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('3963 length property on stubs', function () {
-      var db = new PouchDB(dbs.name);
-
-      function checkAttachments() {
-        return db.get('bin_doc').then(function (doc) {
-          doc._attachments['foo.txt'].stub.should.equal(true);
-          doc._attachments['foo.txt'].length.should.equal(29);
-          return db.changes({include_docs: true});
-        }).then(function (res) {
-          var doc = res.results[0].doc;
-          doc._attachments['foo.txt'].stub.should.equal(true);
-          doc._attachments['foo.txt'].length.should.equal(29);
-          return db.allDocs({include_docs: true});
-        }).then(function (res) {
-          var doc = res.rows[0].doc;
-          doc._attachments['foo.txt'].stub.should.equal(true);
-          doc._attachments['foo.txt'].length.should.equal(29);
-          return new PouchDB.utils.Promise(function (resolve, reject) {
-            var change;
-            var changes = db.changes({include_docs: true, live: true})
-              .on('change', function (x) {
-                change = x;
-                changes.cancel();
-              })
-              .on('error', reject)
-              .on('complete', function () {
-                resolve(change);
-              });
-          });
-        }).then(function (change) {
-          var doc = change.doc;
-          doc._attachments['foo.txt'].stub.should.equal(true);
-          doc._attachments['foo.txt'].length.should.equal(29);
-        });
-      }
-
-      return db.put(binAttDoc).then(checkAttachments).then(function () {
-        return db.get('bin_doc');
-      }).then(function (doc) {
-        return db.put(doc);
-      }).then(checkAttachments);
-    });
-
-    it('Testing with invalid rev', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = { _id: 'adoc' };
-      db.put(doc, function (err, resp) {
-        should.not.exist(err, 'Doc has been saved');
-        doc._rev = resp.rev;
-        doc.foo = 'bar';
-        db.put(doc, function (err) {
-          should.not.exist(err, 'Doc has been updated');
-          var blob = testUtils.makeBlob('bar');
-          db.putAttachment('adoc', 'foo.txt', doc._rev, blob, 'text/plain',
-                           function (err) {
-            should.exist(err, 'Attachment has not been saved');
-            err.name.should.equal('conflict', 'error is a conflict');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test put another attachment on a doc with attachments',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'mydoc' }, function (err, res1) {
-        var blob = testUtils.makeBlob('Mytext');
-        db.putAttachment('mydoc', 'mytext', res1.rev, blob, 'text/plain',
-                         function (err, res2) {
-          db.putAttachment('mydoc', 'mytext2', res2.rev, blob, 'text/plain',
-                           function (err, res3) {
-            should.exist(res3.ok);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test get with attachments: true if empty attachments', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({
-        _id: 'foo',
-        _attachments: {}
-      }, function () {
-        db.get('foo', { attachments: true }, function (err, res) {
-          res._id.should.equal('foo');
-          done();
-        });
-      });
-    });
-
-    it('Test delete attachment from a doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({
-        _id: 'mydoc',
-        _attachments: {
-          'mytext1': {
-            content_type: 'text/plain',
-            data: 'TXl0ZXh0MQ=='
-          },
-          'mytext2': {
-            content_type: 'text/plain',
-            data: 'TXl0ZXh0Mg=='
-          }
-        }
-      }, function (err, res) {
-        var rev = res.rev;
-        db.get('mydoc', { attachments: true }, function (err, res) {
-          res._attachments.should.include.keys('mytext1', 'mytext2');
-          db.removeAttachment('mydoc', 'mytext1', 0, function (err) {
-            should.exist(err, 'removal should fail due to broken rev');
-            db.removeAttachment('mydoc', 'mytext1', rev, function () {
-              db.get('mydoc', { attachments: true }, function (err, res) {
-                res._attachments.should.not.include.keys('mytext1');
-                res._attachments.should.include.keys('mytext2');
-                db.removeAttachment('mydoc', 'mytext2', res._rev,
-                  function (err, res) {
-                  should.not.exist(res._attachments);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test a document with a json string attachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put(jsonDoc, function (err, results) {
-        should.not.exist(err, 'saved doc with attachment');
-        db.get(results.id, function (err, doc) {
-          should.not.exist(err, 'fetched doc');
-          should.exist(doc._attachments, 'doc has attachments field');
-          doc._attachments.should.include.keys('foo.json');
-          doc._attachments['foo.json'].content_type.should
-            .equal('application/json', 'doc has correct content type');
-          db.getAttachment(results.id, 'foo.json', function (err, attachment) {
-            should.not.exist(err);
-            attachment.type.should.equal('application/json');
-            testUtils.readBlob(attachment, function () {
-              jsonDoc._attachments['foo.json'].data.should
-                .equal('eyJIZWxsbyI6IndvcmxkIn0=', 'correct data');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test remove doc with attachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'mydoc' }, function (err, resp) {
-        var blob = testUtils.makeBlob('Mytext');
-        db.putAttachment('mydoc', 'mytext', resp.rev, blob, 'text/plain',
-                         function (err, res) {
-          db.get('mydoc', { attachments: false }, function (err, doc) {
-            db.remove(doc, function () {
-              should.exist(res.ok);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Try to insert a doc with unencoded attachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'foo',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'this should have been encoded!'
-          }
-        }
-      };
-      db.put(doc, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('Try to get attachment of unexistent doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.getAttachment('unexistent', 'attachment', function (err) {
-        should.exist(err, 'Correctly returned error');
-        done();
-      });
-    });
-
-    it('Test synchronous getAttachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.getAttachment('unexistent', 'attachment', function (err) {
-        should.exist(err, 'Correctly returned error');
-        done();
-      });
-    });
-
-    it('Test synchronous putAttachment with text data', function (done) {
-      var db = new PouchDB(dbs.name);
-      var blob = testUtils.makeBlob('foobaz', 'text/plain');
-      db.putAttachment('a', 'foo2.txt', '', blob, 'text/plain', function (err) {
-        should.not.exist(err, 'Correctly wrote attachment');
-        db.get('a', { attachments: true }, function (err, doc) {
-          should.not.exist(err, 'Correctly got attachment');
-          doc._attachments['foo2.txt'].data.should.equal('Zm9vYmF6');
-          doc._attachments['foo2.txt'].content_type.should.equal('text/plain');
-          done();
-        });
-      });
-    });
-
-    it('Test synchronous putAttachment with no text data', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.putAttachment('a', 'foo2.txt', '', '', 'text/plain', function (err) {
-        should.not.exist(err, 'Correctly wrote attachment');
-        db.get('a', { attachments: true }, function (err, doc) {
-          should.not.exist(err, 'Correctly got attachment');
-          doc._attachments['foo2.txt'].data.should.equal('');
-          // firefox 3 appends charset=utf8
-          // see http://forums.mozillazine.org/viewtopic.php?p=6318215#p6318215
-          doc._attachments['foo2.txt'].content_type.indexOf('text/plain')
-            .should.equal(0, 'expected content-type to start with text/plain');
-          done();
-        });
-      });
-    });
-
-    it('Test put with partial stubs', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          },
-          'bar.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          }
-        }
-      };
-      return db.put(doc).then(function () {
-        return db.get(doc._id);
-      }).then(function (doc) {
-        doc._attachments['baz.txt'] = {
-          content_type: 'text/plain',
-          data: 'Zm9v'
-        };
-        // at this point, foo and bar are stubs, but baz is not
-        return db.put(doc);
-      }).then(function () {
-        return db.get(doc._id, {attachments: true});
-      }).then(function (doc) {
-        doc._rev.should.not.equal('2-x');
-        Object.keys(doc._attachments).should.have.length(3);
-        Object.keys(doc._attachments).forEach(function (key) {
-          var att = doc._attachments[key];
-          att.data.should.equal('Zm9v');
-          att.content_type.should.equal('text/plain');
-        });
-      });
-    });
-
-    it('Test put with attachments and new_edits=false', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'doc',
-        _rev: '2-x',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          },
-          'bar.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          },
-          'baz.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          }
-        },
-        _revisions: {
-          'start': 2,
-          'ids': ['x', 'a']
-        }
-      };
-      return db.bulkDocs([doc], {new_edits: false}).then(function () {
-        return db.get(doc._id);
-      }).then(function () {
-          // at this point, foo and bar are stubs, but baz is not
-          return db.bulkDocs([doc], {new_edits: false});
-        }).then(function () {
-          return db.get(doc._id, {attachments: true});
-        }).then(function (doc) {
-          doc._rev.should.equal('2-x');
-          Object.keys(doc._attachments).should.have.length(3);
-          Object.keys(doc._attachments).forEach(function (key) {
-            var att = doc._attachments[key];
-            att.data.should.equal('Zm9v');
-            att.content_type.should.equal('text/plain');
-          });
-        });
-    });
-
-    it('Test getAttachment with specific rev', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      var doc = {
-        _id: 'a'
-      };
-      var rev1;
-      var rev2;
-      var rev3;
-      return db.put(doc).then(function (res) {
-        doc._rev = rev1 = res.rev;
-        doc._attachments = {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          }
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = rev2 = res.rev;
-
-        delete doc._attachments;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = rev3 = res.rev;
-
-        return db.getAttachment('a', 'foo.txt', {rev: rev2});
-      }).then(function (blob) {
-        should.exist(blob);
-
-        return PouchDB.utils.Promise.all([
-          db.getAttachment('a', 'foo.txt', {rev: rev1}),
-          db.getAttachment('a', 'foo.txt', {rev: '3-fake'}),
-          db.getAttachment('a', 'foo.txt'),
-          db.getAttachment('a', 'foo.txt', {}),
-          db.getAttachment('a', 'foo.txt', {rev: rev3})
-        ].map(function (promise) {
-          return promise.then(function () {
-            throw new Error('expected an error');
-          }, function (err) {
-            should.exist(err);
-            err.status.should.equal(404);
-          });
-        }));
-      });
-    });
-
-    it('Test getAttachment with diff revs and content', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      var doc = {
-        _id: 'a',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9v'
-          }
-        }
-      };
-      var rev1;
-      var rev2;
-      var rev3;
-      return db.put(doc).then(function (res) {
-        doc._rev = rev1 = res.rev;
-        doc._attachments = {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'YmFy'
-          }
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = rev2 = res.rev;
-        doc._attachments = {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'YmF6'
-          }
-        };
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = rev3 = res.rev;
-
-        var testCases = [
-          [db.getAttachment('a', 'foo.txt'), 'baz'],
-          [db.getAttachment('a', 'foo.txt', {rev: rev3}), 'baz'],
-          [db.getAttachment('a', 'foo.txt', {rev: rev2}), 'bar'],
-          [db.getAttachment('a', 'foo.txt', {rev: rev1}), 'foo']
-        ];
-
-        return PouchDB.utils.Promise.all(testCases.map(function (testCase) {
-          var promise = testCase[0];
-          var expected = testCase[1];
-          return promise.then(function (blob) {
-            blob.type.should.equal('text/plain');
-            return testUtils.readBlobPromise(blob);
-          }).then(function (bin) {
-            bin.should.equal(expected, 'didn\'t get blob we expected for rev');
-          });
-        }));
-      });
-    });
-
-    it('Test stubs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.putAttachment('a', 'foo2.txt', '', '', 'text/plain', function () {
-        db.allDocs({ include_docs: true }, function (err, docs) {
-          should.not.exist(docs.rows[0].stub, 'no stub');
-          done();
-        });
-      });
-    });
-
-    it('Try to get unexistent attachment of some doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function (err) {
-        should.not.exist(err, 'doc inserted');
-        db.getAttachment('foo', 'unexistentAttachment', function (err) {
-          should.exist(err, 'Correctly returned error');
-          done();
-        });
-      });
-    });
-
-    it('putAttachment and getAttachment with plaintext', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function () {
-        db.get('foo', function (err, doc) {
-          var data = binAttDoc._attachments['foo.txt'].data;
-          var blob = testUtils.binaryStringToBlob(testUtils.atob(data),
-            'text/plain');
-          db.putAttachment('foo', 'foo.txt', doc._rev, blob, 'text/plain',
-                           function (err) {
-            should.not.exist(err, 'attachment inserted');
-            db.getAttachment('foo', 'foo.txt', function (err, blob) {
-              should.not.exist(err, 'attachment gotten');
-              blob.type.should.equal('text/plain');
-              testUtils.readBlob(blob, function (returnedData) {
-                testUtils.btoa(returnedData).should.equal(data);
-                db.get('foo', function (err, doc) {
-                  should.not.exist(err, 'err on get');
-                  delete doc._attachments["foo.txt"].revpos;
-
-                  // couchdb encodes plaintext strings differently from us
-                  // because of libicu vs. ascii. that's okay
-                  var digest = doc._attachments["foo.txt"].digest;
-                  var validDigests = [
-                    "md5-qUUYqS41RhwF0TrCsTAxFg==",
-                    "md5-aEI7pOYCRBLTRQvvqYrrJQ==",
-                    "md5-jeLnIuUvK7d+6gya044lVA=="
-                  ];
-                  validDigests.indexOf(digest).should.not.equal(-1,
-                    'expected ' + digest  + ' to be in: ' +
-                      JSON.stringify(validDigests));
-                  delete doc._attachments["foo.txt"].digest;
-                  doc._attachments.should.deep.equal({
-                    "foo.txt": {
-                      "content_type": "text/plain",
-                      "stub": true,
-                      length: 29
-                    }
-                  });
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('putAttachment and getAttachment with png data', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function () {
-        db.get('foo', function (err, doc) {
-          var data = pngAttDoc._attachments['foo.png'].data;
-          var blob = testUtils.binaryStringToBlob(testUtils.atob(data),
-            'image/png');
-          db.putAttachment('foo', 'foo.png', doc._rev, blob, 'image/png',
-                           function (err) {
-            should.not.exist(err, 'attachment inserted');
-            db.getAttachment('foo', 'foo.png', function (err, blob) {
-              should.not.exist(err, 'attachment gotten');
-              blob.type.should.equal('image/png');
-              testUtils.readBlob(blob, function (returnedData) {
-                testUtils.btoa(returnedData).should.equal(data);
-                db.get('foo', function (err, doc) {
-                  should.not.exist(err, 'err on get');
-                  delete doc._attachments["foo.png"].revpos;
-                  doc._attachments.should.deep.equal({
-                    "foo.png": {
-                      "content_type": "image/png",
-                      "digest": "md5-c6eA+rofKUsstTNQBKUc8A==",
-                      "stub": true,
-                      length: 229
-                    }
-                  });
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('putAttachment in new doc with base64', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      return db.putAttachment('foo', 'att', 'Zm9v', 'text/plain').then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        doc._attachments['att'].content_type.should.match(/^text\/plain/);
-        doc._attachments['att'].data.should.equal('Zm9v');
-      });
-    });
-
-    it('#2818 - save same attachment in different revs', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      return db.put({_id: 'foo'}).then(function (res) {
-        return db.putAttachment('foo', 'att', res.rev, 'Zm9v', 'text/plain');
-      }).then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        doc._attachments['att'].content_type.should.match(/^text\/plain/);
-        should.exist(doc._attachments['att'].data);
-        return db.get('foo');
-      }).then(function (doc) {
-        return db.put(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        doc._attachments['att'].content_type.should.match(/^text\/plain/);
-        doc._attachments['att'].data.length.should.be.above(0, 'attachment exists');
-      });
-    });
-
-    it('#2818 - save same attachment many times in parallel', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-
-      for (var i  = 0; i < 50; i++) {
-        docs.push({
-          _id: 'doc' + i,
-          _attachments: {
-            'foo.txt': {
-              content_type: 'text/plain',
-              data: 'Zm9vYmFy' // 'foobar'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs);
-    });
-
-    it('#2818 - revisions keep attachments (no compaction)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9vYmFy' // 'foobar'
-          }
-        }
-      };
-      var rev;
-      return db.put(doc).then(function () {
-        return db.get('doc');
-      }).then(function (doc) {
-        rev = doc._rev;
-        //delete doc._attachments['foo.txt'];
-        doc._attachments['foo.txt'] = {
-          content_type: 'text/plain',
-          data: 'dG90bw=='
-        }; // 'toto'
-        return db.put(doc);
-      }).then(function () {
-        return db.get('doc', {attachments: true});
-      }).then(function (doc) {
-        doc._attachments['foo.txt'].data.should.equal('dG90bw==');
-        return db.get('doc', {rev: rev, attachments: true});
-      }).then(function (doc) {
-        doc._attachments['foo.txt'].data.should.equal('Zm9vYmFy');
-      });
-    });
-
-    it('#2818 - doesn\'t throw 409 if same filename', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'Zm9vYmFy' // 'foobar'
-          }
-        }
-      };
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        doc._attachments['foo.txt'].data = 'dG90bw=='; // 'toto'
-        return db.put(doc);
-      });
-    });
-
-    if (typeof process === 'undefined' || process.browser) {
-      it('test stored URL content type of png data', function (done) {
-        var db = new PouchDB(dbs.name);
-        db.put({ _id: 'foo' }, function () {
-          db.get('foo', function (err, doc) {
-            var data = pngAttDoc._attachments['foo.png'].data;
-            var blob = testUtils.binaryStringToBlob(
-              testUtils.atob(data), 'image/png');
-            if (typeof URL === 'undefined') {
-              // phantomjs doesn't have this, give up on this test
-              return done();
-            }
-            var checkedOnce = false;
-            function checkBlobType(blob, cb) {
-              var url = URL.createObjectURL(blob);
-              PouchDB.utils.ajax({
-                url: url,
-                cache: true,
-                binary: true
-              }, function (err, res) {
-                if (err && err.status === 500) {
-                  // firefox won't let us use ajax to get the blob.
-                  // too bad, but firefox wasn't the problem anyway
-                  return done();
-                }
-                should.not.exist(err, 'ajax gotten');
-                if (!checkedOnce) {
-                  checkedOnce = true;
-                  if (res.type !== 'image/png') {
-                    // in Safari/iOS 7, blob URLs are missing
-                    // the content type even without storing them.
-                    // so just give up.
-                    return done();
-                  }
-                } else {
-                  res.type.should.equal('image/png');
-                }
-                cb();
-              });
-            }
-            checkBlobType(blob, function () {
-              db.putAttachment('foo', 'foo.png', doc._rev, blob, 'image/png',
-                function (err) {
-                should.not.exist(err, 'attachment inserted');
-                db.getAttachment('foo', 'foo.png', function (err, blob) {
-                  should.not.exist(err, 'attachment gotten');
-                  checkBlobType(blob, done);
-                });
-              });
-            });
-          });
-        });
-      });
-    }
-
-    it('#3008 test correct encoding/decoding of \\u0000 etc.', function () {
-
-      var base64 =
-        'iVBORw0KGgoAAAANSUhEUgAAAhgAAAJLCAYAAAClnu9J' +
-        'AAAgAElEQVR4Xuy9B7ylZXUu/p62T5nOMAPM0BVJICQi' +
-        'ogjEJN5ohEgQ';
-
-      var db = new PouchDB(dbs.name);
-      return db.putAttachment('foo', 'foo.bin', base64, 'image/png').then(function () {
-        return db.getAttachment('foo', 'foo.bin');
-      }).then(function (blob) {
-        blob.type.should.equal('image/png');
-        return testUtils.readBlobPromise(blob);
-      }).then(function (bin) {
-        testUtils.btoa(bin).should.equal(base64);
-      });
-    });
-
-
-    var isSafari = (typeof process === 'undefined' || process.browser) &&
-      /Safari/.test(window.navigator.userAgent) &&
-      !/Chrome/.test(window.navigator.userAgent);
-    if (!isSafari) {
-      // skip in safari/ios because of size limit popup
-      it('putAttachment and getAttachment with big png data', function (done) {
-
-        function getData(cb) {
-          if (typeof process !== 'undefined' && !process.browser) {
-            var bigimage = require('./deps/bigimage.js');
-            cb(null, bigimage);
-          } else { // browser
-            var script = document.createElement('script');
-            script.src = 'deps/bigimage.js';
-            document.body.appendChild(script);
-            var timeout = setInterval(function () {
-              if (window.bigimage) {
-                clearInterval(timeout);
-                cb(null, window.bigimage);
-              }
-            }, 500);
-          }
-        }
-
-        var db = new PouchDB(dbs.name);
-        db.put({ _id: 'foo' }, function () {
-          db.get('foo', function (err, doc) {
-
-            getData(function (err, data) {
-              var blob = testUtils.binaryStringToBlob(
-                  testUtils.atob(data), 'image/png');
-              db.putAttachment('foo', 'foo.png', doc._rev, blob, 'image/png',
-                  function (err) {
-                should.not.exist(err, 'attachment inserted');
-                db.getAttachment('foo', 'foo.png', function (err, blob) {
-                  should.not.exist(err, 'attachment gotten');
-                  blob.type.should.equal('image/png');
-                  testUtils.readBlob(blob, function (returnedData) {
-                    testUtils.btoa(returnedData).should.equal(data);
-                    db.get('foo', function (err, doc) {
-                      should.not.exist(err, 'err on get');
-                      delete doc._attachments["foo.png"].revpos;
-                      doc._attachments.should.deep.equal({
-                        "foo.png": {
-                          "content_type": "image/png",
-                          "digest": "md5-kqr2YcdElgDs3RkMn1Ygbw==",
-                          "stub": true,
-                          length: 678010
-                        }
-                      });
-                      done();
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    }
-    
-    it('#2709 `revpos` with putAttachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.putAttachment('a', 'one', '', testUtils.btoa('one'), 'text/plain', function () {
-        db.get('a', function (err, doc) {
-          should.exist(doc._attachments.one.revpos);
-          doc._attachments.one.revpos.should.equal(1);
-          db.putAttachment('a', 'two', doc._rev, testUtils.btoa('two'), 'text/plain', function () {
-            db.get('a', function (err, doc) {
-              should.exist(doc._attachments.two.revpos);
-              doc._attachments.two.revpos.should.equal(2);
-              doc._attachments.one.revpos.should.equal(1);
-              db.putAttachment('a', 'one', doc._rev, testUtils.btoa('one-changed'), 'text/plain', function () {
-                db.get('a', function (err, doc) {
-                  doc._attachments.one.revpos.should.equal(3);
-                  doc._attachments.two.revpos.should.equal(2);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-    
-    it('#2709 `revpos` with inline attachment', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'a',
-        _attachments: {
-          one: {
-            content_type: 'text/plain',
-            data: testUtils.btoa('one')
-          }
-        }
-      };
-      db.put(doc, function () {
-        db.get('a', function (err, doc) {
-          should.exist(doc._attachments.one.revpos);
-          doc._attachments.one.revpos.should.equal(1);
-          doc._attachments.two = {
-            content_type: 'text/plain',
-            data: testUtils.btoa('two')
-          };
-          db.put(doc, function () {
-            db.get('a', function (err, doc) {
-              should.exist(doc._attachments.two.revpos);
-              doc._attachments.two.revpos.should.equal(2);
-              doc._attachments.one.revpos.should.equal(1);
-              delete doc._attachments.one.stub;
-              doc._attachments.one.data = testUtils.btoa('one-changed');
-              db.put(doc, function () {
-                db.get('a', function (err, doc) {
-                  doc._attachments.one.revpos.should.equal(3);
-                  doc._attachments.two.revpos.should.equal(2);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('#2709 `revpos` with allDocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.putAttachment('a', 'one', '', testUtils.btoa('one'), 'text/plain', function () {
-        db.allDocs({ keys: ['a'], include_docs: true }, function (err, docs) {
-          var doc = docs.rows[0].doc;
-          should.exist(doc._attachments.one.revpos);
-          doc._attachments.one.revpos.should.equal(1);
-          done();
-        });
-      });
-    });
-    
-  });
-});
-
-repl_adapters.forEach(function (adapters) {
-  describe('suite2 test.attachments.js- ' + adapters[0] + ':' + adapters[1],
-    function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_attach_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('Attachments replicate back and forth', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('foo')
-          }
-        }
-      };
-
-      return db.bulkDocs({ docs: [doc] }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        doc._id = 'doc2';
-        return remote.put(doc);
-      }).then(function () {
-        doc._id = 'doc3';
-        return db.put(doc);
-      }).then(function () {
-        return db.sync(remote);
-      }).then(function () {
-        return PouchDB.utils.Promise.all([db, remote].map(function (pouch) {
-          return pouch.allDocs({
-            include_docs: true,
-            attachments: true
-          }).then(function (res) {
-            res.rows.should.have.length(3);
-            res.rows.forEach(function (row) {
-              Object.keys(row.doc._attachments).should.have.length(1);
-              var att = row.doc._attachments['foo.txt'];
-              att.content_type.should.equal('text/plain');
-              att.data.should.equal(testUtils.btoa('foo'));
-              att.digest.should.be.a('string');
-              should.not.exist(att.length);
-              should.not.exist(att.stub);
-            });
-          });
-        }));
-      });
-    });
-
-    it('Replicate same doc, same atts', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('foo')
-          }
-        }
-      };
-
-      return remote.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.put(doc);
-      }).then(function () {
-        return db.sync(remote);
-      }).then(function () {
-        return PouchDB.utils.Promise.all([db, remote].map(function (pouch) {
-          return pouch.allDocs({
-            include_docs: true,
-            attachments: true
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows.forEach(function (row) {
-              Object.keys(row.doc._attachments).should.have.length(1);
-              var att = row.doc._attachments['foo.txt'];
-              att.content_type.should.equal('text/plain');
-              att.data.should.equal(testUtils.btoa('foo'));
-              att.digest.should.be.a('string');
-              should.not.exist(att.length);
-              should.not.exist(att.stub);
-            });
-          });
-        }));
-      });
-    });
-
-    it('Replicate same doc, same atts 2', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {
-        _id: 'doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: testUtils.btoa('foo')
-          }
-        }
-      };
-
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.put(doc);
-      }).then(function () {
-        return db.sync(remote);
-      }).then(function () {
-        return PouchDB.utils.Promise.all([db, remote].map(function (pouch) {
-          return pouch.allDocs({
-            include_docs: true,
-            attachments: true
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows.forEach(function (row) {
-              Object.keys(row.doc._attachments).should.have.length(1);
-              var att = row.doc._attachments['foo.txt'];
-              att.content_type.should.equal('text/plain');
-              att.data.should.equal(testUtils.btoa('foo'));
-              att.digest.should.be.a('string');
-              should.not.exist(att.length);
-              should.not.exist(att.stub);
-            });
-          });
-        }));
-      });
-    });
-
-    it('Attachments replicate', function (done) {
-      var binAttDoc = {
-        _id: 'bin_doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      };
-      var docs1 = [
-        binAttDoc,
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      remote.bulkDocs({ docs: docs1 }, function () {
-        db.replicate.from(remote, function () {
-          db.get('bin_doc', { attachments: true }, function (err, doc) {
-            binAttDoc._attachments['foo.txt'].data.should
-              .equal(doc._attachments['foo.txt'].data);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Attachment types replicate', function () {
-      var binAttDoc = {
-        _id: 'bin_doc',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      };
-      var docs1 = [
-        binAttDoc,
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs({ docs: docs1 }).then(function () {
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.get('bin_doc', {attachments: true, binary: true});
-      }).then(function (doc) {
-        var blob = doc._attachments['foo.txt'].data;
-        blob.type.should.equal('text/plain');
-        return testUtils.readBlobPromise(blob);
-      }).then(function (bin) {
-        bin.should.equal(testUtils.atob(
-          'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='));
-      });
-    });
-
-    it('Many many attachments replicate', function () {
-      var doc = {_id: 'foo'};
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var data = testUtils.btoa('foobar');
-      var blob = testUtils.binaryStringToBlob(
-        testUtils.atob(data), 'text/plain');
-
-      doc._attachments = {};
-      var expectedKeys = [];
-      for (var i = 0; i < 50; i++) {
-        doc._attachments[i + '.txt'] = {
-          content_type: 'text/plain',
-          data: blob
-        };
-        expectedKeys.push(i + '.txt');
-      }
-      return db.put(doc).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.get('foo', {attachments: true});
-      }).then(function (doc) {
-        var keys = Object.keys(doc._attachments);
-        keys.sort();
-        keys.should.deep.equal(expectedKeys.sort());
-        doc._attachments[keys[0]].data.should.equal(data);
-      });
-    });
-
-    it('Many many png attachments replicate', function () {
-      var doc = {_id: 'foo'};
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var data = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAMFBMVEX+9+' +
-        'j+9OD+7tL95rr93qT80YD7x2L6vkn6syz5qRT4ogT4nwD4ngD4nQD4nQD4' +
-        'nQDT2nT/AAAAcElEQVQY002OUQLEQARDw1D14f7X3TCdbfPnhQTqI5UqvG' +
-        'OWIz8gAIXFH9zmC63XRyTsOsCWk2A9Ga7wCXlA9m2S6G4JlVwQkpw/Ymxr' +
-        'UgNoMoyxBwSMH/WnAzy5cnfLFu+dK2l5gMvuPGLGJd1/9AOiBQiEgkzOpg' +
-        'AAAABJRU5ErkJggg==';
-      var blob = testUtils.binaryStringToBlob(testUtils.atob(data),
-          'image/png');
-
-      doc._attachments = {};
-      var expectedKeys = [];
-      for (var i = 0; i < 50; i++) {
-        doc._attachments[i + '.txt'] = {
-          content_type: 'image/png',
-          data: blob
-        };
-        expectedKeys.push(i + '.txt');
-      }
-      return db.put(doc).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.get('foo', {attachments: true});
-      }).then(function (doc) {
-        var keys = Object.keys(doc._attachments);
-        keys.sort();
-        keys.should.deep.equal(expectedKeys.sort());
-        doc._attachments[keys[0]].data.should.equal(data);
-      });
-    });
-
-    it('Multiple attachments replicate', function () {
-      var doc = {_id: 'foo'};
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var data = 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=';
-      var rev;
-      return db.put(doc).then(function (info) {
-        rev = info.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return db.putAttachment(doc._id, 'foo1.txt', rev, data, 'text/plain');
-      }).then(function (info) {
-        rev = info.rev;
-        return db.putAttachment(doc._id, 'foo2.txt', rev, data, 'text/plain');
-      }).then(function (info) {
-        rev = info.rev;
-        return db.putAttachment(doc._id, 'foo3.txt', rev, data, 'text/plain');
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.get('foo', {attachments: true});
-      }).then(function (doc) {
-        var keys = Object.keys(doc._attachments);
-        keys.sort();
-        keys.should.deep.equal(['foo1.txt', 'foo2.txt', 'foo3.txt']);
-      });
-    });
-
-      it('#3961 Many attachments on same doc', function () {
-        var doc = {_id: 'foo', _attachments: {}};
-
-        var db = new PouchDB(dbs.name);
-        var remote = new PouchDB(dbs.remote);
-
-        for (var i = 0; i < 100; i++) {
-          doc._attachments[i + '.txt'] = {
-            data: testUtils.btoa(i.toString()),
-            content_type: 'text/plain'
-          };
-        }
-
-        return db.put(doc).then(function () {
-          return db.replicate.to(remote);
-        }).then(function () {
-          return PouchDB.utils.Promise.all([
-            db, remote
-          ].map(function (pouch) {
-            return pouch.get('foo', {attachments: true}).then(function (doc) {
-              var atts = doc._attachments;
-              Object.keys(atts).length.should.equal(100);
-              for (var i = 0; i < 100; i++) {
-                var att = atts[i + '.txt'];
-                should.not.exist(att.stub);
-                att.data.should.equal(testUtils.btoa(i.toString()));
-                att.content_type.should.equal('text/plain');
-              }
-            }).then(function () {
-              return pouch.get('foo');
-            }).then(function (doc) {
-              var atts = doc._attachments;
-              Object.keys(atts).length.should.equal(100);
-              for (var i = 0; i < 100; i++) {
-                var att = atts[i + '.txt'];
-                att.stub.should.equal(true);
-                att.content_type.should.equal('text/plain');
-                att.length.should.equal(i.toString().length);
-                should.exist(att.digest);
-              }
-            });
-          }));
-        });
-      });
-
-    it('Multiple attachments replicate, different docs (#2698)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.txt': {
-              data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=',
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }
-      return remote.bulkDocs(docs).then(function () {
-        return remote.replicate.to(db);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        return PouchDB.utils.Promise.all(res.rows.map(function (row) {
-          return db.get(row.id, {attachments: true});
-        }));
-      }).then(function (docs) {
-        var attachments = docs.map(function (doc) {
-          delete doc._attachments['foo.txt'].revpos;
-          delete doc._attachments['foo.txt'].digest;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal([1, 2, 3, 4, 5].map(function () {
-          return {
-            "foo.txt": {
-              "content_type": "text/plain",
-              "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
-            }
-          };
-        }));
-      });
-    });
-
-    it('Multiple attachments replicate, different docs png (#2698)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return remote.bulkDocs(docs).then(function () {
-        return remote.replicate.to(db);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        return PouchDB.utils.Promise.all(res.rows.map(function (row) {
-          return db.get(row.id, {attachments: true});
-        }));
-      }).then(function (docs) {
-        var attachments = docs.map(function (doc) {
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments;
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "foo.png": {
-              "content_type": "image/png",
-              "data": icon,
-              "digest": iconDigests[i]
-            }
-          };
-        }));
-
-        return PouchDB.utils.Promise.all(docs.map(function (doc) {
-          return db.get(doc._id);
-        }));
-      }).then(function (docs) {
-        var attachments = docs.map(function (doc) {
-          delete doc._attachments['foo.png'].revpos;
-          return doc._attachments['foo.png'];
-        });
-        attachments.should.deep.equal(icons.map(function (icon, i) {
-          return {
-            "content_type": "image/png",
-            stub: true,
-            "digest": iconDigests[i],
-            length: iconLengths[i]
-          };
-        }));
-      });
-    });
-
-    it('#3932 attachments with tricky revpos', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var rev;
-
-      return remote.put({
-        _id:"test1",
-        type:"XX",
-        name: "Test1",
-        _attachments:{
-          "1.txt":{ content_type:"text/plain", data: "Wlpa"} }
-      }).then(function () {
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.get('test1');
-      }).then(function (doc) {
-        return db.put(doc);
-      }).then(function (res) {
-        rev = res.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.putAttachment('test1', '2.txt', rev,
-          'Wlpa', 'text/plain');
-      }).then(function () {
-        return remote.replicate.to(db);
-      }).then(function () {
-        return db.get('test1', {attachments: true});
-      }).then(function () {
-        return remote.get('test1', {attachments: true});
-      }).then(function (doc) {
-        doc._attachments = {
-          "1.txt": {content_type: "text/plain", data: "Wlpa"},
-          "2.txt": {content_type: "text/plain", data: "Wlpa"}
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.get("test1", {attachments:true});
-      }).then(function (doc) {
-        return db.put(doc);
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return PouchDB.utils.Promise.all([db, remote].map(function (pouch) {
-          return pouch.get('test1', {attachments: true}).then(function (doc) {
-            var filenames = Object.keys(doc._attachments);
-            filenames.should.have.length(2);
-            filenames.forEach(function (filename) {
-              var data = doc._attachments[filename].data;
-              data.should.equal('Wlpa');
-            });
-          });
-        }));
-      });
-    });
-
-    it('replication with changing attachments', function () {
-      var attachment = {
-        content_type: 'text/plain',
-        data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-      };
-      var attachment2 = {
-        content_type: 'text/plain',
-        data: ''
-      };
-      var binAttDoc = {
-        _id: 'bin_doc',
-        _attachments: {
-          'foo.txt': attachment
-        }
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      return db.put(binAttDoc).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        should.exist(doc);
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        doc._attachments['bar.txt'] = attachment2;
-        return db.put(doc);
-      }).then(function () {
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        should.exist(doc);
-        return db.get(binAttDoc._id, {attachments: true});
-      }).then(function (doc) {
-        should.not.exist(doc._attachments['foo.txt'].stub);
-        should.not.exist(doc._attachments['bar.txt'].stub);
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.get(binAttDoc._id, {attachments: true});
-      }).then(function (doc) {
-        should.not.exist(doc._attachments['foo.txt'].stub);
-        doc._attachments['baz.txt'] = doc._attachments['foo.txt'];
-        return remote.put(doc);
-      }).then(function () {
-        return remote.replicate.to(db);
-      }).then(function () {
-        return db.get(binAttDoc._id, {attachments: true});
-      }).then(function (doc) {
-        should.not.exist(doc._attachments['foo.txt'].stub);
-        should.not.exist(doc._attachments['bar.txt'].stub);
-        should.not.exist(doc._attachments['baz.txt'].stub);
-        return db.get(binAttDoc._id);
-      }).then(function (doc) {
-        should.exist(doc);
-      });
-    });
-
-    it('3955 race condition in put', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var btoa = testUtils.btoa;
-      var srcdata = ['', '', ''];
-
-      for (var i = 0; i < 50; i++) {
-        srcdata[0] += 'AAA';
-        srcdata[1] += 'BBB';
-        srcdata[2] += 'CCC';
-      }
-
-      var doc = {
-        _id: 'x',
-        type: 'testdoc',
-        _attachments:{
-          'a.txt': {
-            content_type: 'text/plain',
-            data:btoa(srcdata[0])
-          },
-          'b.txt': {
-            content_type: 'text/plain',
-            data:btoa(srcdata[1])
-          },
-          'c.txt': {
-            content_type: 'text/plain',
-            data:btoa(srcdata[2])
-          },
-          'zzz.txt': {
-            content_type: 'text/plain',
-            data:btoa('ZZZ')
-          }
-        }
-      };
-
-      db.put(doc).then(function () {
-        return db.get('x');
-      }).then(function (doc){
-        var digests = Object.keys(doc._attachments).map(function (a) {
-          return doc._attachments[a].digest;
-        });
-        if (isUnique(digests)) {
-          done();
-        } else {
-          done('digests are not unique');
-        }
-      });
-
-      doc._attachments['c.txt'].data = btoa('ZZZ');
-      doc._attachments['b.txt'].data = btoa('ZZZ');
-
-      function isUnique(arr) {
-        arr.sort();
-        for (var i = 1; i < arr.length; i++ ) {
-          if (arr[i-1] === arr[i]) {
-            return false;
-          }
-        }
-        return true;
-      }
-    });
-
-  });
-});
diff --git a/tests/integration/test.basics.js b/tests/integration/test.basics.js
deleted file mode 100644
index 502687f..0000000
--- a/tests/integration/test.basics.js
+++ /dev/null
@@ -1,1181 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-
-  describe('test.basics.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('Create a pouch', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        should.not.exist(err);
-        db.should.be.an.instanceof(PouchDB);
-        done();
-      });
-    });
-
-    it('Create a pouch without new keyword', function () {
-      /* jshint newcap:false */
-      var db = PouchDB(dbs.name);
-      db.should.be.an.instanceof(PouchDB);
-    });
-
-    it('Create a pouch with a promise', function () {
-      return new PouchDB(dbs.name);
-    });
-
-    it('4314 Create a pouch with + in name', function () {
-      var db = new PouchDB(dbs.name + '+suffix');
-      return db.info().then(function () {
-        return db.destroy();
-      });
-    });
-
-    it('4314 Create a pouch with urlencoded name', function () {
-      var db = new PouchDB(dbs.name + 'some%2Ftest');
-      return db.info().then(function () {
-        return db.destroy();
-      });
-    });
-
-    it('Catch an error when creating a pouch with a promise', function (done) {
-      new PouchDB().catch(function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('destroy a pouch', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        should.exist(db);
-        db.destroy(function (err, info) {
-          should.not.exist(err);
-          should.exist(info);
-          info.ok.should.equal(true);
-          done();
-        });
-      });
-    });
-
-    it('4219 destroy a pouch', function () {
-      return new PouchDB(dbs.name).destroy({});
-    });
-
-    it('4339 throw useful error if method called on stale instance', function () {
-      var db = new PouchDB(dbs.name);
-
-      return db.put({
-        _id: 'cleanTest'
-      }).then(function () {
-        return db.destroy();
-      }).then(function () {
-        return db.get('cleanTest');
-      }).then(function () {
-        throw new Error('.get should return an error');
-      }, function (err) {
-        should.equal(err instanceof Error, true, 'should be an error');
-      });
-    });
-
-    it('destroy a pouch, with a promise', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        should.exist(db);
-        db.destroy().then(function (info) {
-          should.exist(info);
-          info.ok.should.equal(true);
-          done();
-        }, done);
-      });
-    });
-
-    it('[4595] should reject xhr errors', function (done){
-      var invalidUrl = 'http:///';
-      new PouchDB(dbs.name).replicate.to(invalidUrl, {}).catch(function () {
-        done();
-      });
-
-    });
-    it('[4595] should emit error event on xhr error', function (done){
-      var invalidUrl = 'http:///';
-      new PouchDB(dbs.name).replicate.to(invalidUrl,{})
-        .on('error', function () { done(); });
-    });
-
-    it('Add a doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, function (err) {
-        should.not.exist(err);
-        done();
-      });
-    });
-
-    it('Get invalid id', function () {
-      var db = new PouchDB(dbs.name);
-      return db.get(1234).then(function () {
-        throw 'show not be here';
-      }).catch(function (err) {
-        should.exist(err);
-      });
-    });
-
-    it('Add a doc with a promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}).then(function () {
-        done();
-      }, done);
-    });
-
-    it('Add a doc with opts object', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, {}, function (err) {
-        should.not.exist(err);
-        done();
-      });
-    });
-
-    it('Modify a doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, function (err, info) {
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }, function (err, info2) {
-          should.not.exist(err);
-          info.rev.should.not.equal(info2.rev);
-          done();
-        });
-      });
-    });
-
-    it('Modify a doc with sugar syntax', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, function (err, info) {
-        db.put({another: 'test'}, info.id, info.rev, function (err, info2) {
-          info.rev.should.not.equal(info2.rev);
-          db.put({yet_another: 'test'}, 'yet_another', function (err, info3) {
-            info3.id.should.equal('yet_another');
-            info.rev.should.not.equal(info2.rev);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Modify a doc with sugar syntax and omit the _id', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, function (err, info) {
-        db.put({another: 'test', _id: info.id}, info.rev,
-          function (err, info2) {
-          info.rev.should.not.equal(info2.rev);
-          db.put({yet_another: 'test'}, 'yet_another', function (err, info3) {
-            info3.id.should.equal('yet_another');
-            info.rev.should.not.equal(info2.rev);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Modify a doc with a promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'promisestuff'}).then(function (info) {
-        return db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }).then(function (info2) {
-          info.rev.should.not.equal(info2.rev);
-        });
-      }).catch(done).then(function () {
-        done();
-      });
-    });
-
-    it('Read db id', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.id(function (err, id) {
-        id.should.be.a('string');
-        done(err);
-      });
-    });
-
-    it('Read db id with promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.id().then(function (id) {
-        id.should.be.a('string');
-        done();
-      });
-    });
-
-    it('Close db', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        db.close(done);
-      });
-    });
-
-    it('Close db with a promise', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        db.close().then(done, done);
-      });
-    });
-
-    it('Read db id after closing Close', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        db.close(function () {
-          db = new PouchDB(dbs.name);
-          db.id(function (err, id) {
-            id.should.be.a('string');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Modify a doc with incorrect rev', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        var nDoc = {
-          _id: info.id,
-          _rev: info.rev + 'broken',
-          another: 'test'
-        };
-        db.put(nDoc, function (err) {
-          should.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Remove doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        db.remove({
-          test: 'somestuff',
-          _id: info.id,
-          _rev: info.rev
-        }, function () {
-          db.get(info.id, function (err) {
-            should.exist(err.error);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Remove doc with a promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'someotherstuff'}).then(function (info) {
-        return db.remove({
-          test: 'someotherstuff',
-          _id: info.id,
-          _rev: info.rev
-        }).then(function () {
-          return db.get(info.id).then(function () {
-            done(true);
-          }, function (err) {
-            should.exist(err.error);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Remove doc with new syntax', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        db.remove(info.id, info.rev, function (err) {
-          should.not.exist(err);
-          db.get(info.id, function (err) {
-            should.exist(err);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Remove doc with new syntax and a promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      var id;
-      db.post({test: 'someotherstuff'}).then(function (info) {
-        id = info.id;
-        return db.remove(info.id, info.rev);
-      }).then(function () {
-        return db.get(id);
-      }).then(function () {
-        done(true);
-      }, function (err) {
-        should.exist(err.error);
-        done();
-      });
-    });
-
-    it('Doc removal leaves only stub', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', value: 'test'}, function () {
-        db.get('foo', function (err, doc) {
-          db.remove(doc, function (err, res) {
-            db.get('foo', { rev: res.rev }, function (err, doc) {
-              doc.should.deep.equal({
-                _id: res.id,
-                _rev: res.rev,
-                _deleted: true
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Remove doc twice with specified id', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({_id: 'specifiedId', test: 'somestuff'}).then(function () {
-        return db.get('specifiedId');
-      }).then(function (doc) {
-        return db.remove(doc);
-      }).then(function () {
-        return db.put({
-          _id: 'specifiedId',
-          test: 'somestuff2'
-        });
-      }).then(function () {
-        return db.get('specifiedId');
-      }).then(function (doc) {
-        return db.remove(doc);
-      });
-    });
-
-    it('Remove doc, no callback', function (done) {
-      var db = new PouchDB(dbs.name);
-      var changes = db.changes({
-        live: true,
-        include_docs: true
-      }).on('change', function (change) {
-        if (change.doc._deleted) {
-          changes.cancel();
-        }
-      }).on('complete', function (result) {
-        result.status.should.equal('cancelled');
-        done();
-      }).on('error', done);
-      db.post({ _id: 'somestuff' }, function (err, res) {
-        db.remove({
-          _id: res.id,
-          _rev: res.rev
-        });
-      });
-    });
-
-    it('Delete document without id', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.remove({test: 'ing'}, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('Delete document with many args', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (info) {
-        return db.remove(doc._id, info.rev, {});
-      });
-    });
-
-    it('Delete document with many args, callback style', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      db.put(doc, function (err, info) {
-        should.not.exist(err);
-        db.remove(doc._id, info.rev, {}, function (err) {
-          should.not.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Delete doc with id + rev + no opts', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (info) {
-        return db.remove(doc._id, info.rev);
-      });
-    });
-
-    it('Delete doc with id + rev + no opts, callback style', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      db.put(doc, function (err, info) {
-        should.not.exist(err);
-        db.remove(doc._id, info.rev, function (err) {
-          should.not.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Delete doc with doc + opts', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (info) {
-        doc._rev = info.rev;
-        return db.remove(doc, {});
-      });
-    });
-
-    it('Delete doc with doc + opts, callback style', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      db.put(doc, function (err, info) {
-        should.not.exist(err);
-        doc._rev = info.rev;
-        db.remove(doc, {}, function (err) {
-          should.not.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Delete doc with rev in opts', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (info) {
-        return db.remove(doc, {rev: info.rev});
-      });
-    });
-
-    it('Bulk docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { test: 'somestuff' },
-          { test: 'another' }
-        ]
-      }, function (err, infos) {
-        infos.length.should.equal(2);
-        infos[0].ok.should.equal(true);
-        infos[1].ok.should.equal(true);
-        done();
-      });
-    });
-
-    it('Bulk docs with a promise', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { test: 'somestuff' },
-          { test: 'another' }
-        ]
-      }).then(function (infos) {
-        infos.length.should.equal(2);
-        infos[0].ok.should.equal(true);
-        infos[1].ok.should.equal(true);
-        done();
-      }).catch(done);
-    });
-
-    it('Basic checks', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.info(function (err, info) {
-        var updateSeq = info.update_seq;
-        var doc = {_id: '0', a: 1, b: 1};
-        info.doc_count.should.equal(0);
-        db.put(doc, function (err, res) {
-          res.ok.should.equal(true);
-          res.should.have.property('id');
-          res.should.have.property('rev');
-          db.info(function (err, info) {
-            info.doc_count.should.equal(1);
-            info.update_seq.should.not.equal(updateSeq);
-            db.get(doc._id, function (err, doc) {
-              doc._id.should.equal(res.id);
-              doc._rev.should.equal(res.rev);
-              db.get(doc._id, { revs_info: true }, function (err, doc) {
-                doc._revs_info[0].status.should.equal('available');
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('update with invalid rev', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({test: 'somestuff'}, function (err, info) {
-        should.not.exist(err);
-        db.put({
-          _id: info.id,
-          _rev: 'undefined',
-          another: 'test'
-        }, function (err) {
-          should.exist(err);
-          err.status.should.equal(PouchDB.Errors.INVALID_REV.status);
-          err.message.should.equal(PouchDB.Errors.INVALID_REV.message,
-                                   'correct error message returned');
-          done();
-        });
-      });
-    });
-
-    it('Doc validation', function (done) {
-      var bad_docs = [
-        {'_zing': 4},
-        {'_zoom': 'hello'},
-        {'zane': 'goldfish',
-         '_fan': 'something smells delicious'},
-        {'_bing': {'wha?': 'soda can'}}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: bad_docs }, function (err) {
-        err.status.should.equal(PouchDB.Errors.DOC_VALIDATION.status);
-        err.message.should.equal(PouchDB.Errors.DOC_VALIDATION.message +
-                                 ': _zing',
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('Replication fields (#2442)', function (done) {
-      var doc = {
-        '_replication_id': 'test',
-        '_replication_state': 'triggered',
-        '_replication_state_time': 1,
-        '_replication_stats': {}
-      };
-      var db = new PouchDB(dbs.name);
-      db.post(doc, function (err, resp) {
-        should.not.exist(err);
-
-        db.get(resp.id, function (err, doc2) {
-          should.not.exist(err);
-
-          doc2._replication_id.should.equal('test');
-          doc2._replication_state.should.equal('triggered');
-          doc2._replication_state_time.should.equal(1);
-          doc2._replication_stats.should.eql({});
-
-          done();
-        });
-      });
-    });
-
-    it('Testing issue #48', function (done) {
-      var docs = [
-        {'_id': '0'}, {'_id': '1'}, {'_id': '2'},
-        {'_id': '3'}, {'_id': '4'}, {'_id': '5'}
-      ];
-      var TO_SEND = 5;
-      var sent = 0;
-      var complete = 0;
-      var timer;
-
-      var db = new PouchDB(dbs.name);
-
-      var bulkCallback = function (err) {
-        should.not.exist(err);
-        if (++complete === TO_SEND) {
-          done();
-        }
-      };
-
-      var save = function () {
-        if (++sent === TO_SEND) {
-          clearInterval(timer);
-        }
-        db.bulkDocs({docs: docs}, bulkCallback);
-      };
-
-      timer = setInterval(save, 10);
-    });
-
-    it('Testing valid id', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({
-        '_id': 123,
-        test: 'somestuff'
-      }, function (err) {
-        should.exist(err);
-        err.error.should.equal(PouchDB.Errors.INVALID_ID.error);
-        done();
-      });
-    });
-
-    it('Put doc without _id should fail', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({test: 'somestuff' }, function (err) {
-        should.exist(err);
-        err.message.should.equal(PouchDB.Errors.MISSING_ID.message,
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('Put doc with bad reserved id should fail', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({
-        _id: '_i_test',
-        test: 'somestuff'
-      }, function (err) {
-        should.exist(err);
-        err.status.should.equal(PouchDB.Errors.RESERVED_ID.status);
-        err.message.should.equal(PouchDB.Errors.RESERVED_ID.message,
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('update_seq persists', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function () {
-        new PouchDB(dbs.name, function (err, db) {
-          db.info(function (err, info) {
-            info.update_seq.should.not.equal(0);
-            info.doc_count.should.equal(1);
-            done();
-          });
-        });
-      });
-    });
-
-    it('deletions persists', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'staticId', contents: 'stuff'};
-
-      function writeAndDelete(cb) {
-        db.put(doc, function (err, info) {
-          db.remove({
-            _id: info.id,
-            _rev: info.rev
-          }, function () {
-            cb();
-          });
-        });
-      }
-
-      writeAndDelete(function () {
-        writeAndDelete(function () {
-          db.put(doc, function () {
-            db.get(doc._id, { conflicts: true }, function (err, details) {
-              details.should.not.have.property('_conflicts');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('#4126 should not store raw Dates', function () {
-      var date = new Date();
-      var date2 = new Date();
-      var date3 = new Date();
-      var origDocs = [
-        { _id: '1', mydate: date },
-        { _id: '2', array: [date2] },
-        { _id: '3', deep: { deeper: { deeperstill: date3 } }
-        }
-      ];
-      return new PouchDB(dbs.name).then(function (db) {
-        return db.bulkDocs(origDocs).then(function () {
-          return db.allDocs({include_docs: true});
-        }).then(function (res) {
-          var docs = res.rows.map(function (row) {
-            delete row.doc._rev;
-            return row.doc;
-          });
-          docs.should.deep.equal([
-            { _id: '1', mydate: date.toJSON() },
-            { _id: '2', array: [date2.toJSON()] },
-            { _id: '3', deep: { deeper: { deeperstill: date3.toJSON() } }
-            }
-          ]);
-          origDocs[0].mydate.should.be.instanceof(Date, 'date not modified');
-          origDocs[1].array[0].should.be.instanceof(Date, 'date not modified');
-          origDocs[2].deep.deeper.deeperstill.should.be.instanceof(Date,
-            'date not modified');
-        });
-      });
-    });
-
-    it('Create a db with a reserved name', function () {
-      var db = new PouchDB('__proto__');
-      return db.info().then(function () {
-        return db.destroy();
-      });
-    });
-
-    it('Error when document is not an object', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc1 = [{ _id: 'foo' }, { _id: 'bar' }];
-      var doc2 = 'this is not an object';
-      var count = 5;
-      var callback = function (err) {
-        should.exist(err);
-        count--;
-        if (count === 0) {
-          done();
-        }
-      };
-      db.post(doc1, callback);
-      db.post(doc2, callback);
-      db.put(doc1, callback);
-      db.put(doc2, callback);
-      db.bulkDocs({docs: [doc1, doc2]}, callback);
-    });
-
-    it('Test instance update_seq updates correctly', function (done) {
-      new PouchDB(dbs.name, function (err, db1) {
-        var db2 = new PouchDB(dbs.name);
-        db1.post({ a: 'doc' }, function () {
-          db1.info(function (err, db1Info) {
-            db2.info(function (err, db2Info) {
-              db1Info.update_seq.should.not.equal(0);
-              db2Info.update_seq.should.not.equal(0);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Error works', function () {
-      var newError = PouchDB.utils
-        .createError(PouchDB.Errors.BAD_REQUEST, 'love needs no message');
-      newError.status.should.equal(PouchDB.Errors.BAD_REQUEST.status);
-      newError.name.should.equal(PouchDB.Errors.BAD_REQUEST.name);
-      newError.message.should.equal(PouchDB.Errors.BAD_REQUEST.message,
-                                    'correct error message returned');
-      newError.reason.should.equal('love needs no message');
-    });
-
-    it('Fail to fetch a doc after db was deleted', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        var db2 = new PouchDB(dbs.name);
-        var doc = { _id: 'foodoc' };
-        var doc2 = { _id: 'foodoc2' };
-        db.put(doc, function () {
-          db2.put(doc2, function () {
-            db.allDocs(function (err, docs) {
-              docs.total_rows.should.equal(2);
-              db.destroy(function (err) {
-                should.not.exist(err);
-                db2 = new PouchDB(dbs.name);
-                db2.get(doc._id, function (err) {
-                  err.status.should.equal(404);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Fail to fetch a doc after db was deleted', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        var db2 = new PouchDB(dbs.name);
-        var doc = { _id: 'foodoc' };
-        var doc2 = { _id: 'foodoc2' };
-        db.put(doc, function () {
-          db2.put(doc2, function () {
-            db.allDocs(function (err, docs) {
-              docs.total_rows.should.equal(2);
-              db.destroy().then(function () {
-                db2 = new PouchDB(dbs.name);
-                db2.get(doc._id, function (err, doc) {
-                  should.not.exist(doc);
-                  err.status.should.equal(404);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Cant add docs with empty ids', function (done) {
-      var docs = [
-        {},
-        { _id: null },
-        { _id: undefined },
-        { _id: '' },
-        { _id: {} },
-        { _id: '_underscored_id' }
-      ];
-      var num = docs.length;
-      var db = new PouchDB(dbs.name);
-      docs.forEach(function (doc) {
-        db.put(doc, function (err) {
-          should.exist(err);
-          if (!--num) {
-            done();
-          }
-        });
-      });
-    });
-
-    it('Test doc with percent in ID', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        foo: 'bar',
-        _id: 'foo%bar'
-      };
-      return db.put(doc).then(function (res) {
-        res.id.should.equal('foo%bar');
-        doc.foo.should.equal('bar');
-        return db.get('foo%bar');
-      }).then(function (doc) {
-        doc._id.should.equal('foo%bar');
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var x = res.rows[0];
-        x.id.should.equal('foo%bar');
-        x.doc._id.should.equal('foo%bar');
-        x.key.should.equal('foo%bar');
-        should.exist(x.doc._rev);
-      });
-    });
-
-    it('db.info should give correct name', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.info().then(function (info) {
-        info.db_name.should.equal('testdb');
-        done();
-      });
-    });
-
-    it('db.info should give auto_compaction = false (#2744)', function () {
-      var db = new PouchDB(dbs.name, { auto_compaction: false});
-      return db.info().then(function (info) {
-        info.auto_compaction.should.equal(false);
-      });
-    });
-
-    it('db.info should give auto_compaction = true (#2744)', function () {
-      var db = new PouchDB(dbs.name, { auto_compaction: true});
-      return db.info().then(function (info) {
-        // http doesn't support auto compaction
-        info.auto_compaction.should.equal(db.type() !== 'http');
-      });
-    });
-
-    it('db.info should give adapter name (#3567)', function () {
-      var db = new PouchDB(dbs.name);
-      return db.info().then(function (info) {
-        info.adapter.should.equal(db.type());
-      });
-    });
-
-    it('db.info should give correct doc_count', function (done) {
-      new PouchDB(dbs.name).then(function (db) {
-        db.info().then(function (info) {
-          info.doc_count.should.equal(0);
-          return db.bulkDocs({docs : [{_id : '1'}, {_id : '2'}, {_id : '3'}]});
-        }).then(function () {
-          return db.info();
-        }).then(function (info) {
-          info.doc_count.should.equal(3);
-          return db.get('1');
-        }).then(function (doc) {
-          return db.remove(doc);
-        }).then(function () {
-          return db.info();
-        }).then(function (info) {
-          info.doc_count.should.equal(2);
-          done();
-        }, done);
-      }, done);
-    });
-
-    it('putting returns {ok: true}', function () {
-      // in couch, it's {ok: true} and in cloudant it's {},
-      // but the http adapter smooths this out
-      return new PouchDB(dbs.name).then(function (db) {
-        return db.put({_id: '_local/foo'}).then(function (info) {
-          true.should.equal(info.ok, 'putting local returns ok=true');
-          return db.put({_id: 'quux'});
-        }).then(function (info) {
-          true.should.equal(info.ok, 'putting returns ok=true');
-          return db.bulkDocs([ {_id: '_local/bar'}, {_id: 'baz'} ]);
-        }).then(function (info) {
-          info.should.have.length(2, 'correct num bulk docs');
-          true.should.equal(info[0].ok, 'bulk docs says ok=true #1');
-          true.should.equal(info[1].ok, 'bulk docs says ok=true #2');
-          return db.post({});
-        }).then(function (info) {
-          true.should.equal(info.ok, 'posting returns ok=true');
-        });
-      });
-    });
-    it('putting is override-able', function (done) {
-      var db = new PouchDB(dbs.name);
-      var called = 0;
-      var plugin = {
-        initPull: function () {
-          this.oldPut = this.put;
-          this.put = function () {
-            if (typeof arguments[arguments.length - 1] === 'function') {
-              called++;
-            }
-            return this.oldPut.apply(this, arguments);
-          };
-        },
-        cleanupPut: function () {
-          this.put = this.oldPut;
-        }
-      };
-      PouchDB.plugin(plugin);
-      db.initPull();
-      return db.put({foo: 'bar'}, 'anid').then(function () {
-        called.should.be.above(0, 'put was called');
-        return db.get('anid');
-      }).then(function (doc) {
-        doc.foo.should.equal('bar', 'correct doc');
-      }).then(function () {
-        done();
-      }, done);
-    });
-
-    it('issue 2779, deleted docs, old revs COUCHDB-292', function (done) {
-      var db =  new PouchDB(dbs.name);
-      var rev;
-
-      db.put({_id: 'foo'}).then(function (resp) {
-        rev = resp.rev;
-        return db.remove('foo', rev);
-      }).then(function () {
-        return db.get('foo');
-      }).catch(function () {
-        return db.put({_id: 'foo', _rev: rev});
-      }).then(function () {
-        done(new Error('should never have got here'));
-      }, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('issue 2779, correct behavior for undeleting', function () {
-
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db =  new PouchDB(dbs.name);
-      var rev;
-
-      function checkNumRevisions(num) {
-        return db.get('foo', {
-          open_revs: 'all',
-          revs: true
-        }).then(function (fullDocs) {
-          fullDocs[0].ok._revisions.ids.should.have.length(num);
-        });
-      }
-
-      return db.put({_id: 'foo'}).then(function (resp) {
-        rev = resp.rev;
-        return checkNumRevisions(1);
-      }).then(function () {
-        return db.remove('foo', rev);
-      }).then(function () {
-        return checkNumRevisions(2);
-      }).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        rev = res.rows[0].value.rev;
-        return db.put({_id: 'foo', _rev: rev});
-      }).then(function () {
-        return checkNumRevisions(3);
-      });
-    });
-
-    it('issue 2888, successive deletes and writes', function () {
-      var db = new PouchDB(dbs.name);
-      var rev;
-
-      function checkNumRevisions(num) {
-        return db.get('foo', {
-          open_revs: 'all',
-          revs: true
-        }).then(function (fullDocs) {
-          fullDocs[0].ok._revisions.ids.should.have.length(num);
-        });
-      }
-      return db.put({ _id: 'foo' }).then(function (resp) {
-        rev = resp.rev;
-        return checkNumRevisions(1);
-      }).then(function () {
-        return db.remove('foo', rev);
-      }).then(function () {
-        return checkNumRevisions(2);
-      }).then(function () {
-        return db.put({ _id: 'foo' });
-      }).then(function (res) {
-        rev = res.rev;
-        return checkNumRevisions(3);
-      }).then(function () {
-        return db.remove('foo', rev);
-      }).then(function () {
-        return checkNumRevisions(4);
-      });
-    });
-
-    it('2 invalid puts', function (done) {
-      var db = new PouchDB(dbs.name);
-      var called = 0;
-      var cb = function () {
-        if (++called === 2) {
-          done();
-        }
-      };
-      db.put({_id: 'foo', _zing: 'zing'}, cb);
-      db.put({_id: 'bar', _zing: 'zing'}, cb);
-    });
-
-    it('Docs save "null" value', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({_id: 'doc', foo: null}).then(function () {
-        return db.get('doc');
-      }).then(function (doc) {
-        (typeof doc.foo).should.equal('object');
-        should.not.exist(doc.foo);
-        Object.keys(doc).sort().should.deep.equal(['_id', '_rev', 'foo']);
-      });
-    });
-
-    it('db.type() returns a type', function () {
-      var db = new PouchDB(dbs.name);
-      db.type().should.be.a('string');
-    });
-
-    it('#4788 db.type() is synchronous', function () {
-      new PouchDB(dbs.name).type.should.be.a('function');
-      new PouchDB(dbs.name).type.should.be.a('function');
-    });
-
-    it('replace PouchDB.destroy() (express-pouchdb#203)', function (done) {
-      var old = PouchDB.destroy;
-      PouchDB.destroy = function (name, callback) {
-        var db = new PouchDB(name);
-        return db.destroy(callback);
-      };
-      // delete a non-existing db, should be fine.
-      PouchDB.destroy(dbs.name, function (err, resp) {
-        PouchDB.destroy = old;
-
-        done(err, resp);
-      });
-    });
-
-    it('3968, keeps all object fields', function () {
-      var db =  new PouchDB(dbs.name);
-      /* jshint -W001 */
-      var doc = {
-        _id: "x",
-        type: "testdoc",
-        watch: 1,
-        unwatch: 1,
-        constructor: 1,
-        toString: 1,
-        toSource: 1,
-        toLocaleString: 1,
-        propertyIsEnumerable: 1,
-        isPrototypeOf: 1,
-        hasOwnProperty: 1
-      };
-      return db.put(doc).then(function () {
-        return db.get(doc._id);
-      }).then(function (savedDoc) {
-        // We shouldnt need to delete from doc here (#4273)
-        should.not.exist(doc._rev);
-        should.not.exist(doc._rev_tree);
-
-        delete savedDoc._rev;
-        savedDoc.should.deep.equal(doc);
-      });
-    });
-
-    it('4712 invalid rev for new doc generates conflict', function () {
-      // CouchDB 1.X has a bug which allows this insertion via bulk_docs
-      // (which PouchDB uses for all document insertions)
-      if (adapter === 'http' && !testUtils.isCouchMaster()) {
-        return;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var newdoc = {
-        '_id': 'foobar',
-        '_rev': '1-123'
-      };
-
-      return db.put(newdoc).then(function () {
-        throw new Error('expected an error');
-      }, function (err) {
-        err.should.have.property('status', 409);
-      });
-    });
-
-    if (adapter === 'local') {
-      // TODO: this test fails in the http adapter in Chrome
-      it('should allow unicode doc ids', function (done) {
-        var db = new PouchDB(dbs.name);
-        var ids = [
-          // "PouchDB is awesome" in Japanese, contains 1-3 byte chars
-          '\u30d1\u30a6\u30c1\u30e5DB\u306f\u6700\u9ad8\u3060',
-          '\u03B2', // 2-byte utf-8 char: 3b2
-          '\uD843\uDF2D', // exotic 4-byte utf-8 char: 20f2d
-          '\u0000foo\u0000bar\u0001baz\u0002quux', // like mapreduce
-          '\u0000',
-          '\u30d1'
-        ];
-        var numDone = 0;
-        ids.forEach(function (id) {
-          var doc = {_id : id, foo : 'bar'};
-          db.put(doc).then(function (info) {
-            doc._rev = info.rev;
-            return db.put(doc);
-          }).then(function () {
-            return db.get(id);
-          }).then(function (resp) {
-            resp._id.should.equal(id);
-            if (++numDone === ids.length) {
-              done();
-            }
-          }, done);
-        });
-      });
-
-      // this test only really makes sense for IDB
-      it('should have same blob support for 2 dbs', function () {
-        var db1 = new PouchDB(dbs.name);
-        return db1.info().then(function () {
-          var db2 = new PouchDB(dbs.name);
-          return db2.info().then(function () {
-            if (typeof db1._blobSupport !== 'undefined') {
-              db1._blobSupport.should.equal(db2._blobSupport,
-                'same blob support');
-            } else {
-              true.should.equal(true);
-            }
-          });
-        });
-      });
-    }
-  });
-});
diff --git a/tests/integration/test.bulk_docs.js b/tests/integration/test.bulk_docs.js
deleted file mode 100644
index 2543522..0000000
--- a/tests/integration/test.bulk_docs.js
+++ /dev/null
@@ -1,1052 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-
-function makeDocs(start, end, templateDoc) {
-  var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : '{}';
-  if (end === undefined) {
-    end = start;
-    start = 0;
-  }
-  var docs = [];
-  for (var i = start; i < end; i++) {
-    /*jshint evil:true */
-    var newDoc = eval('(' + templateDocSrc + ')');
-    newDoc._id = i.toString();
-    newDoc.integer = i;
-    newDoc.string = i.toString();
-    docs.push(newDoc);
-  }
-  return docs;
-}
-
-adapters.forEach(function (adapter) {
-  describe('test.bulk_docs.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    var authors = [
-      {name: 'Dale Harvey', commits: 253},
-      {name: 'Mikeal Rogers', commits: 42},
-      {name: 'Johannes J. Schmidt', commits: 13},
-      {name: 'Randall Leeds', commits: 9}
-    ];
-
-    it('Testing bulk docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = makeDocs(5);
-      db.bulkDocs({ docs: docs }, function (err, results) {
-        results.should.have.length(5, 'results length matches');
-        for (var i = 0; i < 5; i++) {
-          results[i].id.should.equal(docs[i]._id, 'id matches');
-          should.exist(results[i].rev, 'rev is set');
-          // Update the doc
-          docs[i]._rev = results[i].rev;
-          docs[i].string = docs[i].string + '.00';
-        }
-        db.bulkDocs({ docs: docs }, function (err, results) {
-          results.should.have.length(5, 'results length matches');
-          for (i = 0; i < 5; i++) {
-            results[i].id.should.equal(i.toString(), 'id matches again');
-            // set the delete flag to delete the docs in the next step
-            docs[i]._rev = results[i].rev;
-            docs[i]._deleted = true;
-          }
-          db.put(docs[0], function () {
-            db.bulkDocs({ docs: docs }, function (err, results) {
-              results[0].name.should.equal(
-                'conflict', 'First doc should be in conflict');
-              should.not.exist(results[0].rev, 'no rev in conflict');
-              for (i = 1; i < 5; i++) {
-                results[i].id.should.equal(i.toString());
-                should.exist(results[i].rev);
-              }
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('No id in bulk docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      var newdoc = {
-        '_id': 'foobar',
-        'body': 'baz'
-      };
-      db.put(newdoc, function (err, doc) {
-        should.exist(doc.ok);
-        var docs = [
-          {
-            '_id': newdoc._id,
-            '_rev': newdoc._rev,
-            'body': 'blam'
-          },
-          {
-            '_id': newdoc._id,
-            '_rev': newdoc._rev,
-            '_deleted': true
-          }
-        ];
-        db.bulkDocs({ docs: docs }, function (err, results) {
-          results[0].should.have.property('name', 'conflict');
-          results[1].should.have.property('name', 'conflict');
-          done();
-        });
-      });
-    });
-
-    it('No _rev and new_edits=false', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        _id: 'foo',
-        integer: 1
-      }];
-      db.bulkDocs({ docs: docs }, { new_edits: false }, function (err) {
-        should.exist(err, 'error reported');
-        done();
-      });
-    });
-
-    it('Test empty bulkDocs', function () {
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs([]);
-    });
-
-    it('Test many bulkDocs', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      for (var i = 0; i < 201; i++) {
-        docs.push({_id: i.toString()});
-      }
-      return db.bulkDocs(docs);
-    });
-
-    it('Test errors on invalid doc id', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': '_invalid',
-        foo: 'bar'
-      }];
-      db.bulkDocs({ docs: docs }, function (err, info) {
-        err.status.should.equal(PouchDB.Errors.RESERVED_ID.status,
-                                'correct error status returned');
-        should.not.exist(info, 'info is empty');
-        done();
-      });
-    });
-
-    it('Test two errors on invalid doc id', function (done) {
-      var docs = [
-        {'_id': '_invalid', foo: 'bar'},
-        {'_id': 123, foo: 'bar'}
-      ];
-
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, function (err, info) {
-        err.status.should.equal(PouchDB.Errors.RESERVED_ID.status,
-                                'correct error returned');
-        should.not.exist(info, 'info is empty');
-        done();
-      });
-    });
-
-    it('No docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ 'doc': [{ 'foo': 'bar' }] }, function (err) {
-        err.status.should.equal(PouchDB.Errors.MISSING_BULK_DOCS.status,
-                                'correct error returned');
-        err.message.should.equal(PouchDB.Errors.MISSING_BULK_DOCS.message,
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('Jira 911', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {'_id': '0', 'a': 0},
-        {'_id': '1', 'a': 1},
-        {'_id': '1', 'a': 1},
-        {'_id': '3', 'a': 3}
-      ];
-      db.bulkDocs({ docs: docs }, function (err, results) {
-        results[1].id.should.equal('1', 'check ordering');
-        should.not.exist(results[1].name, 'first id succeded');
-        results[2].name.should.equal('conflict', 'second conflicted');
-        results.should.have.length(4, 'got right amount of results');
-        done();
-      });
-    });
-
-    it('Test multiple bulkdocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: authors }, function () {
-        db.bulkDocs({ docs: authors }, function () {
-          db.allDocs(function (err, result) {
-            result.total_rows.should.equal(8, 'correct number of results');
-            done();
-          });
-        });
-      });
-    });
-
-    it('#2935 new_edits=false correct number', function () {
-      var docs = [
-        {
-          "_id": "EE35E",
-          "_rev": "4-70b26",
-          "_deleted": true,
-          "_revisions": {
-            "start": 4,
-            "ids": ["70b26", "9f454", "914bf", "7fdf8"]
-          }
-        }, {
-          "_id": "EE35E",
-          "_rev": "3-f6d28",
-          "_revisions": {"start": 3, "ids": ["f6d28", "914bf", "7fdf8"]}
-        }
-      ];
-
-      var db = new PouchDB(dbs.name);
-
-      return db.bulkDocs({docs: docs, new_edits: false}).then(function (res) {
-        res.should.deep.equal([]);
-        return db.allDocs();
-      }).then(function (res) {
-        res.total_rows.should.equal(1);
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1);
-      });
-    });
-
-    it('#2935 new_edits=false correct number 2', function () {
-      var docs = [
-        {
-          "_id": "EE35E",
-          "_rev": "3-f6d28",
-          "_revisions": {"start": 3, "ids": ["f6d28", "914bf", "7fdf8"]}
-        }, {
-          "_id": "EE35E",
-          "_rev": "4-70b26",
-          "_deleted": true,
-          "_revisions": {
-            "start": 4,
-            "ids": ["70b26", "9f454", "914bf", "7fdf8"]
-          }
-        }
-      ];
-
-      var db = new PouchDB(dbs.name);
-
-      return db.bulkDocs({docs: docs, new_edits: false}).then(function (res) {
-        res.should.deep.equal([]);
-        return db.allDocs();
-      }).then(function (res) {
-        res.total_rows.should.equal(1);
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1);
-      });
-    });
-
-    it('#2935 new_edits=false with single unauthorized', function (done) {
-
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapter !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === undefined) {
-              throw {unauthorized: 'Document must have a foo.'};
-            }
-          }.toString()
-        };
-
-        var db = new PouchDB(dbs.name);
-
-        db.put(ddoc).then(function () {
-          return db.bulkDocs({
-            docs: [
-              {
-                '_id': 'doc0',
-                '_rev': '1-x',
-                'foo': 'bar',
-                '_revisions': {
-                  'start': 1,
-                  'ids': ['x']
-                }
-              }, {
-                '_id': 'doc1',
-                '_rev': '1-x',
-                '_revisions': {
-                  'start': 1,
-                  'ids': ['x']
-                }
-              }, {
-                '_id': 'doc2',
-                '_rev': '1-x',
-                'foo': 'bar',
-                '_revisions': {
-                  'start': 1,
-                  'ids': ['x']
-                }
-              }
-            ]
-          }, {new_edits: false});
-        }).then(function (res) {
-          res.should.have.length(1);
-          should.exist(res[0].error);
-          res[0].id.should.equal('doc1');
-        }).then(done);
-      });
-    });
-
-    it('Deleting _local docs with bulkDocs' , function () {
-      var db = new PouchDB(dbs.name);
-
-      var rev1;
-      var rev2;
-      var rev3;
-      return db.put({_id: '_local/godzilla'}).then(function (info) {
-        rev1 = info.rev;
-        return db.put({_id: 'mothra'});
-      }).then(function (info) {
-        rev2 = info.rev;
-        return db.put({_id: 'rodan'});
-      }).then(function (info) {
-        rev3 = info.rev;
-        return db.bulkDocs([
-          {_id: 'mothra', _rev: rev2, _deleted: true},
-          {_id: '_local/godzilla', _rev: rev1, _deleted: true},
-          {_id: 'rodan', _rev: rev3, _deleted: true}
-        ]);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (info) {
-        info.rows.should.have.length(0);
-        return db.get('_local/godzilla').then(function () {
-          throw new Error('expected 404');
-        }, function (err) {
-          should.exist(err);
-        });
-      });
-    });
-
-    if (adapter === 'local') {
-      // these tests crash CouchDB with a 500, neat
-      // https://issues.apache.org/jira/browse/COUCHDB-2758
-
-      it('Deleting _local docs with bulkDocs, not found', function () {
-        var db = new PouchDB(dbs.name);
-
-        var rev2;
-        var rev3;
-        return db.put({_id: 'mothra'}).then(function (info) {
-          rev2 = info.rev;
-          return db.put({_id: 'rodan'});
-        }).then(function (info) {
-          rev3 = info.rev;
-          return db.bulkDocs([
-            {_id: 'mothra', _rev: rev2, _deleted: true},
-            {_id: '_local/godzilla', _rev: '1-fake', _deleted: true},
-            {_id: 'rodan', _rev: rev3, _deleted: true}
-          ]);
-        }).then(function (res) {
-          should.not.exist(res[0].error);
-          should.exist(res[1].error);
-          should.not.exist(res[2].error);
-        });
-      });
-
-      it('Deleting _local docs with bulkDocs, wrong rev', function () {
-        var db = new PouchDB(dbs.name);
-
-        var rev2;
-        var rev3;
-        return db.put({_id: '_local/godzilla'}).then(function () {
-          return db.put({_id: 'mothra'});
-        }).then(function (info) {
-          rev2 = info.rev;
-          return db.put({_id: 'rodan'});
-        }).then(function (info) {
-          rev3 = info.rev;
-          return db.bulkDocs([
-            {_id: 'mothra', _rev: rev2, _deleted: true},
-            {_id: '_local/godzilla', _rev: '1-fake', _deleted: true},
-            {_id: 'rodan', _rev: rev3, _deleted: true}
-          ]);
-        }).then(function (res) {
-          should.not.exist(res[0].error);
-          should.exist(res[1].error);
-          should.not.exist(res[2].error);
-        });
-      });
-    }
-
-    it('Bulk with new_edits=false', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': 'foo',
-        '_rev': '2-x',
-        '_revisions': {
-          'start': 2,
-          'ids': ['x', 'a']
-        }
-      }, {
-        '_id': 'foo',
-        '_rev': '2-y',
-        '_revisions': {
-          'start': 2,
-          'ids': ['y', 'a']
-        }
-      }];
-      db.bulkDocs({docs: docs}, {new_edits: false}, function () {
-        db.get('foo', {open_revs: 'all'}, function (err, res) {
-          res.sort(function (a, b) {
-            return a.ok._rev < b.ok._rev ? -1 :
-              a.ok._rev > b.ok._rev ? 1 : 0;
-          });
-          res.length.should.equal(2);
-          res[0].ok._rev.should.equal('2-x', 'doc1 ok');
-          res[1].ok._rev.should.equal('2-y', 'doc2 ok');
-          done();
-        });
-      });
-    });
-
-    it('Testing successive new_edits to the same doc', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': 'foobar123',
-        '_rev': '1-x',
-        'bar': 'huzzah',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }];
-
-      db.bulkDocs({docs: docs, new_edits: false}, function (err) {
-        should.not.exist(err);
-        db.bulkDocs({docs: docs, new_edits: false}, function (err) {
-          should.not.exist(err);
-          db.get('foobar123', function (err, res) {
-            res._rev.should.equal('1-x');
-            done();
-          });
-        });
-      });
-    });
-
-    it('#3062 bulkDocs with staggered seqs', function () {
-      return new PouchDB(dbs.name).then(function (db) {
-        var docs = [];
-        for (var i = 10; i <= 20; i++) {
-          docs.push({ _id: 'doc-' + i});
-        }
-        return db.bulkDocs({docs: docs}).then(function (infos) {
-          docs.forEach(function (doc, i) {
-            doc._rev = infos[i].rev;
-          });
-          var docsToUpdate = docs.filter(function (doc, i) {
-            return i % 2 === 1;
-          });
-          docsToUpdate.reverse();
-          return db.bulkDocs({docs: docsToUpdate});
-        }).then(function (infos) {
-          infos.map(function (x) {
-            return {id: x.id, error: !!x.error, rev: (typeof x.rev)};
-          }).should.deep.equal([
-            { error: false, id: 'doc-19', rev: 'string'},
-            { error: false, id: 'doc-17', rev: 'string'},
-            { error: false, id: 'doc-15', rev: 'string'},
-            { error: false, id: 'doc-13', rev: 'string'},
-            { error: false, id: 'doc-11', rev: 'string'}
-          ]);
-        });
-      });
-    });
-
-    it('Testing successive new_edits to the same doc, different content',
-      function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var docsA = [{
-        '_id': 'foo321',
-        '_rev': '1-x',
-        'bar' : 'baz',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }, {
-        '_id' : 'fee321',
-        'bar': 'quux',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }];
-
-      var docsB = [{
-        '_id': 'foo321',
-        '_rev': '1-x',
-        'bar' : 'zam', // this update should be rejected
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }, {
-        '_id' : 'faa321',
-        '_rev': '1-x',
-        'bar': 'zul',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }];
-
-      db.bulkDocs({docs: docsA, new_edits: false}, function (err) {
-        should.not.exist(err);
-        db.changes().on('complete', function (result) {
-          var ids = result.results.map(function (row) {
-            return row.id;
-          });
-          ids.should.include("foo321");
-          ids.should.include("fee321");
-          ids.should.not.include("faa321");
-
-          var update_seq = result.last_seq;
-          db.bulkDocs({docs: docsB, new_edits: false}, function (err) {
-            should.not.exist(err);
-            db.changes({
-              since: update_seq
-            }).on('complete', function (result) {
-              var ids = result.results.map(function (row) {
-                return row.id;
-              });
-              ids.should.not.include("foo321");
-              ids.should.not.include("fee321");
-              ids.should.include("faa321");
-
-              db.get('foo321', function (err, res) {
-                res._rev.should.equal('1-x');
-                res.bar.should.equal("baz");
-                db.info(function (err, info) {
-                  info.doc_count.should.equal(3);
-                  done();
-                });
-              });
-            }).on('error', done);
-          });
-        }).on('error', done);
-      });
-    });
-
-    it('Testing successive new_edits to two doc', function () {
-
-      var db = new PouchDB(dbs.name);
-      var doc1 = {
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      };
-      var doc2 = {
-        '_id': 'bar',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      };
-
-      return db.put(doc1, {new_edits: false}).then(function () {
-        return db.put(doc2, {new_edits: false});
-      }).then(function () {
-        return db.put(doc1, {new_edits: false});
-      }).then(function () {
-        return db.get('foo');
-      }).then(function () {
-        return db.get('bar');
-      });
-    });
-
-    it('Deletion with new_edits=false', function () {
-
-      var db = new PouchDB(dbs.name);
-      var doc1 = {
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      };
-      var doc2 = {
-        '_deleted': true,
-        '_id': 'foo',
-        '_rev': '2-y',
-        '_revisions': {
-          'start': 2,
-          'ids': ['y', 'x']
-        }
-      };
-
-      return db.put(doc1, {new_edits: false}).then(function () {
-        return db.put(doc2, {new_edits: false});
-      }).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        res.rows[0].value.rev.should.equal('2-y');
-        res.rows[0].value.deleted.should.equal(true);
-      });
-    });
-
-    it('Deletion with new_edits=false, no history', function () {
-
-      var db = new PouchDB(dbs.name);
-      var doc1 = {
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      };
-      var doc2 = {
-        '_deleted': true,
-        '_id': 'foo',
-        '_rev': '2-y'
-      };
-
-      return db.put(doc1, {new_edits: false}).then(function () {
-        return db.put(doc2, {new_edits: false});
-      }).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        res.rows[0].value.rev.should.equal('1-x');
-        should.equal(!!res.rows[0].value.deleted, false);
-      });
-    });
-
-    it('Modification with new_edits=false, no history', function () {
-
-      var db = new PouchDB(dbs.name);
-      var doc1 = {
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      };
-      var doc2 = {
-        '_id': 'foo',
-        '_rev': '2-y'
-      };
-
-      return db.put(doc1, {new_edits: false}).then(function () {
-        return db.put(doc2, {new_edits: false});
-      }).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        res.rows[0].value.rev.should.equal('2-y');
-      });
-    });
-
-    it('Deletion with new_edits=false, no history, no revisions', function () {
-
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        '_deleted': true,
-        '_id': 'foo',
-        '_rev': '2-y'
-      };
-
-      return db.put(doc, {new_edits: false}).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        res.rows[0].value.rev.should.equal('2-y');
-        res.rows[0].value.deleted.should.equal(true);
-      });
-    });
-
-    it('Testing new_edits=false in req body', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': 'foo',
-        '_rev': '2-x',
-        '_revisions': {
-          'start': 2,
-          'ids': ['x', 'a']
-        }
-      }, {
-        '_id': 'foo',
-        '_rev': '2-y',
-        '_revisions': {
-          'start': 2,
-          'ids': ['y', 'a']
-        }
-      }];
-      db.bulkDocs({docs: docs, new_edits: false}, function () {
-        db.get('foo', {open_revs: 'all'}, function (err, res) {
-          res.sort(function (a, b) {
-            return a.ok._rev < b.ok._rev ? -1 :
-              a.ok._rev > b.ok._rev ? 1 : 0;
-          });
-          res.length.should.equal(2);
-          res[0].ok._rev.should.equal('2-x', 'doc1 ok');
-          res[1].ok._rev.should.equal('2-y', 'doc2 ok');
-          done();
-        });
-      });
-    });
-
-    it('656 regression in handling deleted docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [{
-          _id: 'foo',
-          _rev: '1-a',
-          _deleted: true
-        }]
-      }, { new_edits: false }, function () {
-        db.get('foo', function (err) {
-          should.exist(err, 'deleted');
-          err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                   'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                   'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should.equal('deleted',
-          //                          'correct error reason returned');
-          done();
-        });
-      });
-    });
-
-    it('Test quotes in doc ids', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [{ _id: '\'your_sql_injection_script_here\'' }];
-      db.bulkDocs({docs: docs}, function (err) {
-        should.not.exist(err, 'got error: ' + JSON.stringify(err));
-        db.get('foo', function (err) {
-          should.exist(err, 'deleted');
-          done();
-        });
-      });
-    });
-
-    it('Bulk docs empty list', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: [] }, function (err) {
-        done(err);
-      });
-    });
-
-    it('handles simultaneous writes', function (done) {
-      var db1 = new PouchDB(dbs.name);
-      var db2 = new PouchDB(dbs.name);
-      var id = 'fooId';
-      var errorNames = [];
-      var ids = [];
-      var numDone = 0;
-      function callback(err, res) {
-        should.not.exist(err);
-        if (res[0].error) {
-          errorNames.push(res[0].name);
-        } else {
-          ids.push(res[0].id);
-        }
-        if (++numDone === 2) {
-          errorNames.should.deep.equal(['conflict']);
-          ids.should.deep.equal([id]);
-          done();
-        }
-      }
-      db1.bulkDocs({docs : [{_id : id}]}, callback);
-      db2.bulkDocs({docs : [{_id : id}]}, callback);
-    });
-
-    it('bulk docs input by array', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = makeDocs(5);
-      db.bulkDocs(docs, function (err, results) {
-        results.should.have.length(5, 'results length matches');
-        for (var i = 0; i < 5; i++) {
-          results[i].id.should.equal(docs[i]._id, 'id matches');
-          should.exist(results[i].rev, 'rev is set');
-          // Update the doc
-          docs[i]._rev = results[i].rev;
-          docs[i].string = docs[i].string + '.00';
-        }
-        db.bulkDocs(docs, function (err, results) {
-          results.should.have.length(5, 'results length matches');
-          for (i = 0; i < 5; i++) {
-            results[i].id.should.equal(i.toString(), 'id matches again');
-            // set the delete flag to delete the docs in the next step
-            docs[i]._rev = results[i].rev;
-            docs[i]._deleted = true;
-          }
-          db.put(docs[0], function () {
-            db.bulkDocs(docs, function (err, results) {
-              results[0].name.should.equal(
-                'conflict', 'First doc should be in conflict');
-              should.not.exist(results[0].rev, 'no rev in conflict');
-              for (i = 1; i < 5; i++) {
-                results[i].id.should.equal(i.toString());
-                should.exist(results[i].rev);
-              }
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Bulk empty list', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs([], function (err) {
-        done(err);
-      });
-    });
-
-    it('Bulk docs not an array', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: 'foo' }, function (err) {
-        should.exist(err, 'error reported');
-        err.status.should.equal(PouchDB.Errors.MISSING_BULK_DOCS.status,
-                                'correct error status returned');
-        err.message.should.equal(PouchDB.Errors.MISSING_BULK_DOCS.message,
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('Bulk docs not an object', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: ['foo'] }, function (err) {
-        should.exist(err, 'error reported');
-        err.status.should.equal(PouchDB.Errors.NOT_AN_OBJECT.status,
-                                'correct error status returned');
-        err.message.should.equal(PouchDB.Errors.NOT_AN_OBJECT.message,
-                                 'correct error message returned');
-      });
-      db.bulkDocs({ docs: [[]] }, function (err) {
-        should.exist(err, 'error reported');
-        err.status.should.equal(PouchDB.Errors.NOT_AN_OBJECT.status,
-                                'correct error status returned');
-        err.message.should.equal(PouchDB.Errors.NOT_AN_OBJECT.message,
-                                 'correct error message returned');
-        done();
-      });
-    });
-
-    it('Bulk docs two different revisions to same document id', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docid = "mydoc";
-
-      function uuid() {
-          return PouchDB.utils.uuid(32, 16).toLowerCase();
-      }
-
-      // create a few of rando, good revisions
-      var numRevs = 3;
-      var uuids = [];
-      for (var i = 0; i < numRevs - 1; i++) {
-          uuids.push(uuid());
-      }
-
-      // branch 1
-      var a_conflict = uuid();
-      var a_doc = {
-        _id: docid,
-        _rev: numRevs + '-' + a_conflict,
-        _revisions: {
-          start: numRevs,
-          ids: [ a_conflict ].concat(uuids)
-        }
-      };
-
-      // branch 2
-      var b_conflict = uuid();
-      var b_doc = {
-        _id: docid,
-        _rev: numRevs + '-' + b_conflict,
-        _revisions: {
-          start: numRevs,
-          ids: [ b_conflict ].concat(uuids)
-        }
-      };
-
-      // push the conflicted documents
-      return db.bulkDocs([ a_doc, b_doc ], { new_edits: false })
-
-      .then(function () {
-        return db.get(docid, { open_revs: "all" }).then(function (resp) {
-          resp.length.should.equal(2, 'correct number of open revisions');
-          resp[0].ok._id.should.equal(docid, 'rev 1, correct document id');
-          resp[1].ok._id.should.equal(docid, 'rev 2, correct document id');
-
-          // order of revisions is not specified
-          ((resp[0].ok._rev === a_doc._rev &&
-            resp[1].ok._rev === b_doc._rev) ||
-          (resp[0].ok._rev === b_doc._rev &&
-            resp[1].ok._rev === a_doc._rev)).should.equal(true);
-        });
-      })
-
-      .then(function () { done(); }, done);
-    });
-
-    it('4204 respect revs_limit', function () {
-      var db = new PouchDB(dbs.name);
-
-      // simulate 5000 normal commits with two conflicts at the very end
-      function uuid() {
-        return PouchDB.utils.uuid(32, 16).toLowerCase();
-      }
-
-      var isSafari = (typeof process === 'undefined' || process.browser) &&
-        /Safari/.test(window.navigator.userAgent) &&
-        !/Chrome/.test(window.navigator.userAgent);
-
-      var numRevs = isSafari ? 10 : 5000;
-      var expected = isSafari ? 10 : 1000;
-      var uuids = [];
-
-      for (var i = 0; i < numRevs - 1; i++) {
-        uuids.push(uuid());
-      }
-      var conflict1 = 'a' + uuid();
-
-      var doc1 = {
-        _id: 'doc',
-        _rev: numRevs + '-' + conflict1,
-        _revisions: {
-          start: numRevs,
-          ids: [conflict1].concat(uuids)
-        }
-      };
-
-      return db.bulkDocs([doc1], {new_edits: false}).then(function () {
-        return db.get('doc', {revs: true});
-      }).then(function (doc) {
-        doc._revisions.ids.length.should.equal(expected);
-      });
-    });
-
-    it('2839 implement revs_limit', function (done) {
-
-      // We only implement revs_limit locally
-      if (adapter === 'http') {
-        return done();
-      }
-
-      var LIMIT = 50;
-      var db = new PouchDB(dbs.name, {revs_limit: LIMIT});
-
-      // simulate 5000 normal commits with two conflicts at the very end
-      function uuid() {
-        return PouchDB.utils.uuid(32, 16).toLowerCase();
-      }
-
-      var numRevs = 5000;
-      var uuids = [];
-      for (var i = 0; i < numRevs - 1; i++) {
-        uuids.push(uuid());
-      }
-      var conflict1 = 'a' + uuid();
-      var doc1 = {
-        _id: 'doc',
-        _rev: numRevs + '-' + conflict1,
-        _revisions: {
-          start: numRevs,
-          ids: [conflict1].concat(uuids)
-        }
-      };
-
-      db.bulkDocs([doc1], {new_edits: false}).then(function () {
-        return db.get('doc', {revs: true});
-      }).then(function (doc) {
-        doc._revisions.ids.length.should.equal(LIMIT);
-        done();
-      }).catch(done);
-    });
-
-    it('4372 revs_limit deletes old revisions of the doc', function (done) {
-
-      // We only implement revs_limit locally
-      if (adapter === 'http') {
-        return done();
-      }
-
-      var db = new PouchDB(dbs.name, {revs_limit: 2});
-
-      // old revisions are always deleted with auto compaction
-      if (db.auto_compaction) {
-        return done();
-      }
-
-      var revs = [];
-      db.put({v: 1}, 'doc').then(function (v1) {
-        revs.push(v1.rev);
-        return db.put({v: 2}, 'doc', revs[0]);
-      }).then(function (v2) {
-        revs.push(v2.rev);
-        return db.put({v: 3}, 'doc', revs[1]);
-      }).then(function () {
-        // the v2 revision is still in the db
-        return db.get('doc', {rev: revs[1]});
-      }).then(function (v2) {
-        v2.v.should.equal(2);
-
-        return db.get('doc', {rev: revs[0]}).then(function () {
-          // the v1 revision is not in the db anymore
-          done(new Error('v1 should be missing'));
-        }).catch(function (error) {
-          error.message.should.equal('missing');
-          done();
-        });
-      }).catch(done);
-    });
-
-    it('4712 invalid rev for new doc generates conflict', function () {
-      // CouchDB 1.X has a bug which allows this insertion via bulk_docs
-      // (which PouchDB uses for all document insertions)
-      if (adapter === 'http' && !testUtils.isCouchMaster()) {
-        return;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var newdoc = {
-        '_id': 'foobar',
-        '_rev': '1-123'
-      };
-
-      return db.bulkDocs({ docs: [newdoc] }).then (function (results) {
-        results[0].should.have.property('status', 409);
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.bulk_get.js b/tests/integration/test.bulk_get.js
deleted file mode 100644
index 69c01d8..0000000
--- a/tests/integration/test.bulk_get.js
+++ /dev/null
@@ -1,184 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.bulk_get.js-' + adapter, function () {
-
-    var dbs = {};
-    beforeEach(function (done) {
-      dbs = {name: testUtils.adapterUrl(adapter, 'testdb')};
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    it('test bulk get with rev specified', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', val: 1}).then(function (response) {
-        var rev = response.rev;
-        db.bulkGet({
-          docs: [
-            {id: 'foo', rev: rev}
-          ]
-        }).then(function (response) {
-          var result = response.results[0];
-          result.id.should.equal("foo");
-          result.docs[0].ok._rev.should.equal(rev);
-          done();
-        });
-      });
-    });
-
-    it('test bulk get with no rev specified', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', val: 1}).then(function (response) {
-        var rev = response.rev;
-        db.bulkGet({
-          docs: [
-            {id: 'foo'}
-          ]
-        }).then(function (response) {
-          var result = response.results[0];
-          result.id.should.equal("foo");
-          result.docs[0].ok._rev.should.equal(rev);
-          done();
-        });
-      });
-    });
-
-    it('_revisions is not returned by default', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', val: 1}).then(function (response) {
-        var rev = response.rev;
-        db.bulkGet({
-          docs: [
-            {id: 'foo', rev: rev}
-          ]
-        }).then(function (response) {
-          var result = response.results[0];
-          should.not.exist(result.docs[0].ok._revisions);
-          done();
-        });
-      });
-    });
-
-    it('_revisions is returned when specified', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', val: 1}).then(function (response) {
-        var rev = response.rev;
-        db.bulkGet({
-          docs: [
-            {id: 'foo', rev: rev}
-          ],
-          revs: true
-        }).then(function (response) {
-          var result = response.results[0];
-          result.docs[0].ok._revisions.ids[0].should.equal(rev.substring(2));
-          done();
-        });
-      });
-    });
-
-    it('_revisions is returned when specified, using implicit rev',
-    function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo', val: 1}).then(function (response) {
-        var rev = response.rev;
-        db.bulkGet({
-          docs: [
-            {id: 'foo'}
-          ],
-          revs: true
-        }).then(function (response) {
-          var result = response.results[0];
-          result.docs[0].ok._revisions.ids[0].should.equal(rev.substring(2));
-          done();
-        });
-      });
-    });
-
-    it('attachments are not included by default', function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.put({
-        _id: 'foo',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      }).then(function (response) {
-        var rev = response.rev;
-
-        db.bulkGet({
-          docs: [
-            {id: 'foo', rev: rev}
-          ]
-        }).then(function (response) {
-          var result = response.results[0];
-          result.docs[0].ok._attachments['foo.txt'].stub.should.equal(true);
-          done();
-        });
-      });
-    });
-
-    it('attachments are included when specified', function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.put({
-        _id: 'foo',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      }).then(function (response) {
-        var rev = response.rev;
-
-        db.bulkGet({
-          docs: [
-            {id: 'foo', rev: rev}
-          ],
-          attachments: true
-        }).then(function (response) {
-          var result = response.results[0];
-          result.docs[0].ok._attachments['foo.txt'].data
-            .should.equal("VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=");
-          done();
-        });
-      });
-    });
-
-    it('attachments are included when specified, using implicit rev',
-    function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.put({
-        _id: 'foo',
-        _attachments: {
-          'foo.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      }).then(function () {
-        db.bulkGet({
-          docs: [
-            {id: 'foo'}
-          ],
-          attachments: true
-        }).then(function (response) {
-          var result = response.results[0];
-          result.docs[0].ok._attachments['foo.txt'].data
-            .should.equal("VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=");
-          done();
-        });
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.changes.js b/tests/integration/test.changes.js
deleted file mode 100644
index 16a5d7d..0000000
--- a/tests/integration/test.changes.js
+++ /dev/null
@@ -1,2538 +0,0 @@
-
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-
-  describe('test.changes.js-' + adapter, function () {
-
-    var dbs = {};
-
-    // if it exists, return the single element
-    // which has the specific id. Else retun null.
-    // useful for finding elements within a _changes feed
-    function findById(array, id) {
-      var result = array.filter(function (i) {
-        return i.id === id;
-      });
-
-      //
-      if (result.length === 1) {
-        return result[0];
-      }
-    }
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapter, 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('All changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function () {
-        var promise = db.changes({
-          }).on('change', function (change) {
-            change.should.not.have.property('doc');
-            change.should.have.property('seq');
-            done();
-          });
-        should.exist(promise);
-        promise.cancel.should.be.a('function');
-      });
-    });
-
-    it('Promise resolved when changes cancelled', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3},
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7},
-        {_id: '8', integer: 9},
-        {_id: '9', integer: 9},
-        {_id: '10', integer: 10}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, function () {
-        var changeCount = 0;
-        var promise = db.changes().on('change', function handler() {
-          changeCount++;
-          if (changeCount === 5) {
-            promise.cancel();
-            promise.removeListener('change', handler);
-          }
-        });
-        should.exist(promise);
-        should.exist(promise.then);
-        promise.then.should.be.a('function');
-        promise.then(
-        function (result) {
-          changeCount.should.equal(5, 'changeCount');
-          should.exist(result);
-          result.should.deep.equal({status: 'cancelled'});
-          done();
-        }, function (err) {
-          changeCount.should.equal(5, 'changeCount');
-          should.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Changes Since', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3},
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7},
-        {_id: '8', integer: 9},
-        {_id: '9', integer: 9},
-        {_id: '10', integer: 10},
-        {_id: '11', integer: 11}
-      ];
-      var db = new PouchDB(dbs.name);
-
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          var docs2 = [
-            {_id: '12', integer: 12},
-            {_id: '13', integer: 13}
-          ];
-
-          db.bulkDocs({ docs: docs2 }, function () {
-            var promise = db.changes({
-              since: update_seq
-            }).on('complete', function (results) {
-              results.results.length.should.be.at.least(2);
-              done();
-            });
-            should.exist(promise);
-            promise.cancel.should.be.a('function');
-          });
-        });
-      });
-    });
-
-    it('Changes Since and limit limit 1', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          var docs2 = [
-            {_id: '3', integer: 3},
-            {_id: '4', integer: 4}
-          ];
-
-          db.bulkDocs({ docs: docs2 }, function () {
-            db.changes({
-              since: update_seq,
-              limit: 1
-            }).on('complete', function (results) {
-              results.results.length.should.equal(1);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Changes Since and limit limit 0', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          var docs2 = [
-            {_id: '3', integer: 3},
-            {_id: '4', integer: 4}
-          ];
-
-          db.bulkDocs({ docs: docs2 }, function () {
-            db.changes({
-              since: update_seq,
-              limit: 0
-            }).on('complete', function (results) {
-              results.results.length.should.equal(1);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Changes limit', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '2', integer: 11},
-        {_id: '3', integer: 12}
-      ];
-      var db = new PouchDB(dbs.name);
-      // we use writeDocs since bulkDocs looks to have undefined
-      // order of doing insertions
-      testUtils.writeDocs(db, docs1, function (err, info) {
-        docs2[0]._rev = info[2].rev;
-        docs2[1]._rev = info[3].rev;
-
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          db.put(docs2[0], function (err, info) {
-            docs2[0]._rev = info.rev;
-            db.put(docs2[1], function (err, info) {
-              docs2[1]._rev = info.rev;
-              db.changes({
-                limit: 2,
-                since: update_seq,
-                include_docs: true
-              }).on('complete', function (results) {
-                results = results.results;
-                results.length.should.equal(2);
-
-                // order is not guaranteed
-                var first = results[0];
-                var second = results[1];
-                if (first.id === '3') {
-                  second = first;
-                  first = results[1];
-                }
-                first.id.should.equal('2');
-                first.doc.integer.should.equal(docs2[0].integer);
-                first.doc._rev.should.equal(docs2[0]._rev);
-                second.id.should.equal('3');
-                second.doc.integer.should.equal(docs2[1].integer);
-                second.doc._rev.should.equal(docs2[1]._rev);
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Changes with filter not present in ddoc', function (done) {
-      this.timeout(15000);
-      var docs = [
-        {_id: '1', integer: 1},
-        { _id: '_design/foo',
-          integer: 4,
-          filters: { even: 'function (doc) { return doc.integer % 2 === 1; }' }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: 'foo/odd',
-          limit: 2,
-          include_docs: true
-        }).on('error', function (err) {
-          err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                  'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                               'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should.equal('missing json key: odd');
-          done();
-        });
-      });
-    });
-
-    it('Changes with `filters` key not present in ddoc', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          views: {
-            even: {
-              map: 'function (doc) { if (doc.integer % 2 === 1)' +
-               ' { emit(doc._id, null) }; }'
-            }
-          }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: 'foo/even',
-          limit: 2,
-          include_docs: true
-        }).on('error', function (err) {
-          err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                  'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                               'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should.equal('missing json key: filters');
-          done();
-        });
-      });
-    });
-
-    it('Changes limit and filter', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2}
-      ];
-      var db = new PouchDB(dbs.name);
-
-      var docs2 = [
-        {_id: '3', integer: 3},
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          filters: { even: 'function (doc) { return doc.integer % 2 === 1; }' }
-        }
-      ];
-
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          testUtils.writeDocs(db, docs2, function () {
-            var promise = db.changes({
-              filter: 'foo/even',
-              limit: 2,
-              since: update_seq,
-              include_docs: true
-            }).on('complete', function (results) {
-              results.results.length.should.equal(2);
-              var three = findById(results.results, '3');
-              three.doc.integer.should.equal(3);
-              var five = findById(results.results, '5');
-              five.doc.integer.should.equal(5);
-              done();
-            }).on('error', done);
-            should.exist(promise);
-            promise.cancel.should.be.a('function');
-          });
-        });
-      });
-    });
-
-    it('Changes with shorthand function name', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {
-          _id: '_design/even',
-          integer: 3,
-          filters: { even: 'function (doc) { return doc.integer % 2 === 0; }' }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-
-      db.bulkDocs({ docs: docs }, function () {
-        var promise = db.changes({
-          filter: 'even',
-          include_docs: true
-        }).on('complete', function (results) {
-          results.results.length.should.equal(2);
-          var zero = findById(results.results, '0');
-          zero.doc.integer.should.equal(0);
-          var two = findById(results.results, '2');
-          two.doc.integer.should.equal(2);
-          done();
-        }).on('error', done);
-        should.exist(promise);
-        promise.cancel.should.be.a('function');
-      });
-    });
-
-    it('Changes with filter from nonexistent ddoc', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1}
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: 'foobar/odd'
-        }).on('error', function (err) {
-          should.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('Changes with view not present in ddoc', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          views:
-            { even:
-              { map: 'function (doc) { if (doc.integer % 2 === 1) { ' +
-                     'emit(doc._id, null) }; }' } }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: '_view',
-          view: 'foo/odd'
-        }).on('error', function (err) {
-          err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                  'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                               'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should.equal('missing json key: odd');
-          done();
-        });
-      });
-    });
-
-    it('Changes with `views` key not present in ddoc', function (done) {
-      var docs = [
-        {_id: '1', integer: 1},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          filters: { even: 'function (doc) { return doc.integer % 2 === 1; }' }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: '_view',
-          view: 'foo/even'
-        }).on('error', function (err) {
-          err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                  'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                               'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should.equal('missing json key: views',
-          //                         'correct error reason returned');
-          done();
-        });
-      });
-    });
-
-    it('#4451 Changes with invalid view filter', function (done) {
-      var docs = [
-        {_id: '1', integer: 1},
-        {
-          _id: '_design/foo',
-          filters: { even: 'function (doc) { return doc.integer % 2 === 1; }' }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs(docs).then(function () {
-        db.changes({filter: 'a/b/c'}).on('error', function () {
-          done('should not be called');
-        }).on('complete', function () {
-          done();
-        });
-      });
-    });
-
-    it('3356 throw inside a filter', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({
-        _id: "_design/test",
-        filters: {
-          test: function () {
-            throw new Error(); // syntaxerrors can't be caught either.
-          }.toString()
-        }
-      }).then(function () {
-        db.changes({filter: 'test/test'}).then(function () {
-          done('should have thrown');
-        }).catch(function () {
-          done();
-        });
-      });
-    });
-
-    it('Changes with missing param `view` in request', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          views: { even: { map: 'function (doc) { if (doc.integer % 2 === 1) ' +
-                           '{ emit(doc._id, null) }; }' } }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, docs, function () {
-        db.changes({
-          filter: '_view'
-        }).on('error', function (err) {
-          err.status.should.equal(PouchDB.Errors.BAD_REQUEST.status,
-                                  'correct error status returned');
-          err.message.should.equal(PouchDB.Errors.BAD_REQUEST.message,
-                               'correct error message returned');
-          // todo: does not work in pouchdb-server.
-          // err.reason.should
-          //   .equal('`view` filter parameter is not provided.',
-          //          'correct error reason returned');
-          done();
-        });
-      });
-    });
-
-    it('Changes limit and view instead of filter', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.info(function (err, info) {
-          var update_seq = info.update_seq;
-
-          var docs2 = [
-            {_id: '3', integer: 3},
-            {_id: '4', integer: 4},
-            {_id: '5', integer: 5},
-            {
-              _id: '_design/foo',
-              integer: 4,
-              views: { even: { map: 'function (doc) ' +
-                '{ if (doc.integer % 2 === 1) ' +
-                '{ emit(doc._id, null) }; }'
-                }
-              }
-            }
-          ];
-
-          db.bulkDocs({ docs: docs2 }, function () {
-
-            db.changes({
-              filter: '_view',
-              view: 'foo/even',
-              limit: 2,
-              since: update_seq,
-              include_docs: true
-            }).on('complete', function (results) {
-              var changes = results.results;
-              changes.length.should.equal(2);
-
-              findById(changes, '3')
-                .doc.integer.should.equal(3);
-
-              findById(changes, '5')
-                .doc.integer.should.equal(5);
-
-              done();
-            }).on('error', done);
-          });
-        });
-      });
-    });
-
-    it('Changes last_seq', function (done) {
-      // this test doesn't really make sense for clustered
-      // CouchDB because changes is unordered and last_seq might
-      // not equal the last seq in the _changes feed (although it
-      // should evaluate to the same thing on the server).
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          filters: { even: 'function (doc) { return doc.integer % 2 === 1; }' }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      db.changes().on('complete', function (results) {
-        results.last_seq.should.equal(0);
-        db.bulkDocs({ docs: docs }, function () {
-          db.changes().on('complete', function (results) {
-            results.last_seq.should.equal(5);
-            db.changes({
-              filter: 'foo/even'
-            }).on('complete', function (results) {
-              results.last_seq.should.equal(5);
-              results.results.length.should.equal(2);
-              done();
-            }).on('error', done);
-          }).on('error', done);
-        });
-      }).on('error', done);
-    });
-
-    it('Immediately cancel changes', function () {
-      // fixes code coverage by ensuring the changes() listener
-      // emits 'complete' even if the db's task queue isn't
-      // ready yet
-      return new PouchDB.utils.Promise(function (resolve, reject) {
-        var db = new PouchDB(dbs.name);
-        var changes = db.changes({live: true});
-        changes.on('error', reject);
-        changes.on('complete', resolve);
-        changes.cancel();
-      });
-    });
-
-    it('Changes with invalid ddoc view name', function () {
-      return new PouchDB.utils.Promise(function (resolve, reject) {
-        var db = new PouchDB(dbs.name);
-        db.post({});
-        var changes = db.changes({live: true, filter: '_view', view: ''});
-        changes.on('error', resolve);
-        changes.on('change', reject);
-      });
-    });
-
-    it('Changes with invalid ddoc view name 2', function () {
-      return new PouchDB.utils.Promise(function (resolve, reject) {
-        var db = new PouchDB(dbs.name);
-        db.post({});
-        var changes = db.changes({live: true, filter: '_view', view: 'a/b/c'});
-        changes.on('error', resolve);
-        changes.on('change', reject);
-      });
-    });
-
-    if (adapter === 'local') {
-      // This test crashes due to an invalid JSON response from CouchDB:
-      // https://issues.apache.org/jira/browse/COUCHDB-2765
-      // We could remove the "if" check and put a try/catch in our
-      // JSON parsing, but since this is a super-rare bug it may not be
-      // worth our time. This test does increase code coverage for our
-      // own local code, though.
-      it('Changes with invalid ddoc with no map function', function () {
-        // CouchDB 2.X does not allow saving of invalid design docs,
-        // so this test is not valid
-        if (testUtils.isCouchMaster()) {
-          return PouchDB.utils.Promise.resolve();
-        }
-
-        var db = new PouchDB(dbs.name);
-        return db.put({
-          _id: '_design/name',
-          views: {
-            name: {
-              empty: 'sad face'
-            }
-          }
-        }).then(function () {
-          return new PouchDB.utils.Promise(function (resolve, reject) {
-            var changes = db.changes({
-              live: true,
-              filter: '_view',
-              view: 'name/name'
-            });
-            changes.on('error', resolve);
-            changes.on('change', reject);
-          });
-        });
-      });
-    }
-
-    it('Changes with invalid ddoc with no filter function', function () {
-      // CouchDB 2.X does not allow saving of invalid design docs,
-      // so this test is not valid
-      if (testUtils.isCouchMaster()) {
-        return PouchDB.utils.Promise.resolve();
-      }
-
-      var db = new PouchDB(dbs.name);
-      return db.put({
-        _id: '_design/name',
-        views: {
-          name: {
-            empty: 'sad face'
-          }
-        }
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var changes = db.changes({
-            live: true,
-            filter: 'name/name'
-          });
-          changes.on('error', resolve);
-          changes.on('change', reject);
-        });
-      });
-    });
-
-    it('Changes last_seq with view instead of filter', function (done) {
-      // this test doesn't really make sense for clustered
-      // CouchDB because changes is unordered and last_seq might
-      // not equal the last seq in the _changes feed (although it
-      // should evaluate to the same thing on the server).
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3},
-        {
-          _id: '_design/foo',
-          integer: 4,
-          views:
-            { even:
-              { map: 'function (doc) { if (doc.integer % 2 === 1) { ' +
-                     'emit(doc._id, null) }; }' } }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      db.changes().on('complete', function (results) {
-        results.last_seq.should.equal(0);
-        db.bulkDocs({ docs: docs }, function () {
-          db.changes().on('complete', function (results) {
-            results.last_seq.should.equal(5);
-            db.changes({
-              filter: '_view',
-              view: 'foo/even'
-            }).on('complete', function (results) {
-              results.last_seq.should.equal(5);
-              results.results.length.should.equal(2);
-              done();
-            }).on('error', done);
-          }).on('error', done);
-        });
-      }).on('error', done);
-    });
-
-    it('Changes with style = all_docs', function (done) {
-      var simpleTree = [
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-b', value: 'foo b'},
-         {_id: 'foo', _rev: '3-c', value: 'foo c'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-d', value: 'foo d'},
-         {_id: 'foo', _rev: '3-e', value: 'foo e'},
-         {_id: 'foo', _rev: '4-f', value: 'foo f'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-g', value: 'foo g', _deleted: true}]
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.putTree(db, simpleTree, function () {
-        db.changes().on('complete', function (res) {
-          res.results[0].changes.length.should.equal(1);
-          res.results[0].changes[0].rev.should.equal('4-f');
-          db.changes({
-            style: 'all_docs'
-          }).on('complete', function (res) {
-            res.results[0].changes.length.should.equal(3);
-            var changes = res.results[0].changes;
-            changes.sort(function (a, b) {
-              return a.rev < b.rev;
-            });
-            changes[0].rev.should.equal('4-f');
-            changes[1].rev.should.equal('3-c');
-            changes[2].rev.should.equal('2-g');
-            done();
-          }).on('error', done);
-        }).on('error', done);
-      });
-    });
-
-    it('Changes with style = all_docs and a callback for complete',
-      function (done) {
-      var simpleTree = [
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-b', value: 'foo b'},
-         {_id: 'foo', _rev: '3-c', value: 'foo c'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-d', value: 'foo d'},
-         {_id: 'foo', _rev: '3-e', value: 'foo e'},
-         {_id: 'foo', _rev: '4-f', value: 'foo f'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-g', value: 'foo g', _deleted: true}]
-      ];
-      var db = new PouchDB(dbs.name);
-      testUtils.putTree(db, simpleTree, function () {
-        db.changes(function (err, res) {
-          res.results[0].changes.length.should.equal(1);
-          res.results[0].changes[0].rev.should.equal('4-f');
-          db.changes({
-            style: 'all_docs'
-          }, function (err, res) {
-            should.not.exist(err);
-            res.results[0].changes.length.should.equal(3);
-            var changes = res.results[0].changes;
-            changes.sort(function (a, b) {
-              return a.rev < b.rev;
-            });
-            changes[0].rev.should.equal('4-f');
-            changes[1].rev.should.equal('3-c');
-            changes[2].rev.should.equal('2-g');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Changes limit = 0', function (done) {
-      var docs = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, function () {
-        db.changes({
-          limit: 0
-        }).on('complete', function (results) {
-          results.results.length.should.equal(1);
-          done();
-        }).on('error', done);
-      });
-    });
-
-    // Note for the following test that CouchDB's implementation of /_changes
-    // with `descending=true` ignores any `since` parameter.
-    it('Descending changes', function (done) {
-      // _changes in CouchDB 2.0 does not guarantee order
-      // so skip this test
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-      var db = new PouchDB(dbs.name);
-      db.post({_id: '0', test: 'ing'}, function () {
-        db.post({_id: '1', test: 'ing'}, function () {
-          db.post({_id: '2', test: 'ing'}, function () {
-            db.changes({
-              descending: true,
-              since: 1
-            }).on('complete', function (results) {
-              results.results.length.should.equal(3);
-              var ids = ['2', '1', '0'];
-              results.results.forEach(function (row, i) {
-                row.id.should.equal(ids[i]);
-              });
-              done();
-            }).on('error', done);
-          });
-        });
-      });
-    });
-
-    it('Changes doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function () {
-        db.changes({
-          include_docs: true
-        }).on('change', function (change) {
-          change.doc._id.should.equal(change.id);
-          change.doc._rev.should
-            .equal(change.changes[change.changes.length - 1].rev);
-          done();
-        });
-      });
-    });
-
-    // Note for the following test that CouchDB's implementation of /_changes
-    // with `descending=true` ignores any `since` parameter.
-    it('Descending many changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      var num = 100;
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      var changes = 0;
-      db.bulkDocs({ docs: docs }, function (err) {
-        if (err) {
-          return done(err);
-        }
-        db.changes({
-          descending: true
-        }).on('change', function () {
-          changes++;
-        }).on('complete', function () {
-          changes.should.equal(num, 'correct number of changes');
-          done();
-        }).on('error', function (err) {
-          done(err);
-        });
-      });
-    });
-
-    it('live-changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      var changes = db.changes({
-        live: true
-      }).on('complete', function () {
-        count.should.equal(1);
-        done();
-      }).on('change', function (change) {
-        count += 1;
-        change.should.not.have.property('doc');
-        count.should.equal(1);
-        changes.cancel();
-      });
-      db.post({ test: 'adoc' });
-    });
-
-    it('Multiple watchers', function (done) {
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      var changes1Complete = false;
-      var changes2Complete = false;
-      function checkCount() {
-        if (changes1Complete && changes2Complete) {
-          count.should.equal(2);
-          done();
-        }
-      }
-      var changes1 = db.changes({
-        live: true
-      }).on('complete', function () {
-        changes1Complete = true;
-        checkCount();
-      }).on('change', function () {
-        count += 1;
-        changes1.cancel();
-        changes1 = null;
-      }).on('error', done);
-      var changes2 = db.changes({
-        live: true
-      }).on('complete', function () {
-        changes2Complete = true;
-        checkCount();
-      }).on('change', function () {
-        count += 1;
-        changes2.cancel();
-        changes2 = null;
-      }).on('error', done);
-      db.post({test: 'adoc'});
-    });
-
-    it('Continuous changes doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      var changes = db.changes({
-        live: true,
-        include_docs: true
-      }).on('complete', function (result) {
-        result.status.should.equal('cancelled');
-        done();
-      }).on('change', function (change) {
-        change.should.have.property('doc');
-        change.doc.should.have.property('_rev');
-        changes.cancel();
-      }).on('error', done);
-      db.post({ test: 'adoc' });
-    });
-
-    it('Cancel changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      var interval;
-      var docPosted = false;
-
-      // We want to wait for a period of time after the final
-      // document was posted to ensure we didnt see another
-      // change
-      function waitForDocPosted() {
-        if (!docPosted) {
-          return;
-        }
-        clearInterval(interval);
-        setTimeout(function () {
-          count.should.equal(1);
-          done();
-        }, 200);
-      }
-
-      var changes = db.changes({
-        live: true
-      }).on('complete', function (result) {
-        result.status.should.equal('cancelled');
-        // This setTimeout ensures that once we cancel a change we dont recieve
-        // subsequent callbacks, so it is needed
-        interval = setInterval(waitForDocPosted, 100);
-      }).on('change', function () {
-        count += 1;
-        if (count === 1) {
-          changes.cancel();
-          db.post({ test: 'another doc' }, function (err) {
-            if (err) {
-              return done(err);
-            }
-            docPosted = true;
-          });
-        }
-      });
-      db.post({ test: 'adoc' });
-    });
-
-
-    it("#3579 changes firing 1 too many times", function () {
-      var db = new PouchDB(dbs.name);
-      var Promise = PouchDB.utils.Promise;
-      return db.bulkDocs([{}, {}, {}]).then(function () {
-        var changes = db.changes({
-          since: 'now',
-          live: true,
-          include_docs: true
-        });
-        return Promise.all([
-          new Promise(function (resolve, reject) {
-            changes.on('error', reject);
-            changes.on('change', function (change) {
-              changes.cancel();
-              resolve(change);
-            });
-          }),
-          new Promise(function (resolve) {
-            setTimeout(resolve, 50);
-          }).then(function () {
-              return db.put({_id: 'foobar'});
-            })
-        ]);
-      }).then(function (result) {
-        var change = result[0];
-        change.id.should.equal('foobar');
-        change.doc._id.should.equal('foobar');
-      });
-    });
-
-    it('Kill database while listening to live changes', function (done) {
-      var db = new PouchDB(dbs.name);
-
-      db.changes({live: true})
-        .on('error', function () { done(); })
-        .on('complete', function () { done(); })
-        .on('change', function () { db.destroy().catch(done); });
-
-      db.post({ test: 'adoc' });
-    });
-
-    it('#3136 style=all_docs', function () {
-
-      var db = new PouchDB(dbs.name);
-
-      var chain = PouchDB.utils.Promise.resolve();
-
-      var docIds = ['b', 'c', 'a', 'z', 'd', 'e'];
-
-      docIds.forEach(function (docId) {
-        chain = chain.then(function () {
-          return db.put({_id: docId});
-        });
-      });
-
-      return chain.then(function () {
-        return db.changes({style: 'all_docs'});
-      }).then(function (res) {
-        var ids = res.results.map(function (x) {
-          return x.id;
-        });
-        ids.should.include.members(docIds);
-      });
-    });
-
-    it('#4191 revs_diff causes endless loop', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      return db.bulkDocs({
-        "new_edits": false,
-        "docs": [{"_id": "799","_rev":"1-d22"}
-        ]}).then(function () {
-        return db.bulkDocs({
-          "new_edits": false,
-          "docs": [{"_id": "3E1", "_rev": "1-ab5"}]
-        });
-      }).then(function () {
-        return db.bulkDocs(
-          { new_edits: false,
-            docs:
-              [ { _id: 'FB3', _rev: '1-363' },
-                { _id: '27C', _rev: '1-4c3' },
-                { _id: 'BD6', _rev: '1-de0' },
-                { _id: '1E9', _rev: '1-451' } ] }
-        );
-      }).then(function () {
-        return db.changes({style: 'all_docs', limit: 100});
-      }).then(function (res) {
-        var lastSeq = res.last_seq;
-        return db.changes({since: lastSeq, style: 'all_docs', limit: 100});
-      }).then(function (res) {
-        res.results.should.have.length(0);
-      });
-    });
-
-    it('#3136 style=all_docs & include_docs', function () {
-
-      var db = new PouchDB(dbs.name);
-
-      var chain = PouchDB.utils.Promise.resolve();
-
-      var docIds = ['b', 'c', 'a', 'z', 'd', 'e'];
-
-      docIds.forEach(function (docId) {
-        chain = chain.then(function () {
-          return db.put({_id: docId});
-        });
-      });
-
-      return chain.then(function () {
-        return db.changes({
-          style: 'all_docs',
-          include_docs: true
-        });
-      }).then(function (res) {
-        var ids = res.results.map(function (x) {
-          return x.id;
-        });
-        ids.should.include.members(docIds);
-      });
-    });
-
-    it('#3136 tricky changes, limit/descending', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-
-      var docs = [
-        {
-          _id: 'alpha',
-          _rev: '1-a',
-          _revisions: {
-            start: 1,
-            ids: ['a']
-          }
-        }, {
-          _id: 'beta',
-          _rev: '1-b',
-          _revisions: {
-            start: 1,
-            ids: ['b']
-          }
-        }, {
-          _id: 'gamma',
-          _rev: '1-b',
-          _revisions: {
-            start: 1,
-            ids: ['b']
-          }
-        }, {
-          _id: 'alpha',
-          _rev: '2-d',
-          _revisions: {
-            start: 2,
-            ids: ['d', 'a']
-          }
-        }, {
-          _id: 'beta',
-          _rev: '2-e',
-          _revisions: {
-            start: 2,
-            ids: ['e', 'b']
-          }
-        }, {
-          _id: 'beta',
-          _rev: '3-f',
-          _deleted: true,
-          _revisions: {
-            start: 3,
-            ids: ['f', 'e', 'b']
-          }
-        }
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      var seqs = [];
-
-      docs.forEach(function (doc) {
-        chain = chain.then(function () {
-          return db.bulkDocs([doc], {new_edits: false}).then(function () {
-            return db.changes({doc_ids: [doc._id]});
-          }).then(function (res) {
-            seqs.push(res.results[0].seq);
-          });
-        });
-      });
-
-      function normalizeResult(result) {
-        // order of changes doesn't matter
-        result.results.forEach(function (ch) {
-          ch.changes = ch.changes.sort(function (a, b) {
-            return a.rev < b.rev ? -1 : 1;
-          });
-        });
-      }
-
-      return chain.then(function () {
-        return db.changes();
-      }).then(function (result) {
-        normalizeResult(result);
-        result.should.deep.equal({
-          "results": [
-            {
-              "seq": seqs[2],
-              "id": "gamma",
-              "changes": [{ "rev": "1-b"}
-              ]
-            },
-            {
-              "seq": seqs[3],
-              "id": "alpha",
-              "changes": [{ "rev": "2-d"}
-              ]
-            },
-            {
-              "seq": seqs[5],
-              "id": "beta",
-              "deleted": true,
-              "changes": [{ "rev": "3-f"}
-              ]
-            }
-          ],
-          "last_seq": seqs[5]
-        });
-        return db.changes({limit: 0});
-      }).then(function (result) {
-        normalizeResult(result);
-        result.should.deep.equal({
-          "results": [{
-            "seq": seqs[2],
-            "id": "gamma",
-            "changes": [{"rev": "1-b"}]
-          }],
-          "last_seq": seqs[2]
-        }, '1:' + JSON.stringify(result));
-        return db.changes({limit: 1});
-      }).then(function (result) {
-        normalizeResult(result);
-        result.should.deep.equal({
-          "results": [{
-            "seq": seqs[2],
-            "id": "gamma",
-            "changes": [{"rev": "1-b"}]
-          }],
-          "last_seq": seqs[2]
-        }, '2:' + JSON.stringify(result));
-        return db.changes({limit: 2});
-      }).then(function (result) {
-        normalizeResult(result);
-        result.should.deep.equal({
-          "results": [{
-            "seq": seqs[2],
-            "id": "gamma",
-            "changes": [{"rev": "1-b"}]
-          }, {"seq": seqs[3], "id": "alpha", "changes": [{"rev": "2-d"}]}],
-          "last_seq": seqs[3]
-        }, '3:' + JSON.stringify(result));
-        return db.changes({limit: 1, descending: true});
-      }).then(function (result) {
-        normalizeResult(result);
-        result.should.deep.equal({
-          "results": [{
-            "seq": seqs[5],
-            "id": "beta",
-            "changes": [{"rev": "3-f"}],
-            "deleted": true
-          }],
-          "last_seq": seqs[5]
-        }, '4:' + JSON.stringify(result));
-        return db.changes({limit: 2, descending: true});
-      }).then(function (result) {
-        normalizeResult(result);
-        var expected = {
-          "results": [{
-            "seq": seqs[5],
-            "id": "beta",
-            "changes": [{"rev": "3-f"}],
-            "deleted": true
-          }, {"seq": seqs[3], "id": "alpha", "changes": [{"rev": "2-d"}]}],
-          "last_seq": seqs[3]
-        };
-        result.should.deep.equal(expected, '5:' + JSON.stringify(result) +
-        ', shoulda got: ' + JSON.stringify(expected));
-        return db.changes({descending: true});
-      }).then(function (result) {
-        normalizeResult(result);
-        var expected = {
-          "results": [{
-            "seq": seqs[5],
-            "id": "beta",
-            "changes": [{"rev": "3-f"}],
-            "deleted": true
-          }, {"seq": seqs[3], "id": "alpha", "changes": [{"rev": "2-d"}]}, {
-            "seq": seqs[2],
-            "id": "gamma",
-            "changes": [{"rev": "1-b"}]
-          }],
-          "last_seq": seqs[2]
-        };
-        result.should.deep.equal(expected, '6:' + JSON.stringify(result) +
-        ', shoulda got: ' + JSON.stringify(expected));
-      });
-    });
-
-    it('#3176 winningRev has a lower seq, descending', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var tree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-e',
-            _deleted: true,
-            _revisions: {start: 2, ids: ['e', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-g',
-            _revisions: {start: 3, ids: ['g', 'e', 'a']}
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-c',
-            _revisions: {start: 3, ids: ['c', 'b', 'a']}
-          }
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      var seqs = [0];
-
-      function getExpected(i) {
-        var expecteds = [
-          {
-            "results": [
-              {
-                "seq": seqs[1],
-                "id": "foo",
-                "changes": [{"rev": "3-g"}]
-              }
-            ],
-            "last_seq" : seqs[1]
-          },
-          {
-            "results": [
-              {
-                "seq": seqs[2],
-                "id": "foo",
-                "changes": [{"rev": "3-g"}]
-              }
-            ],
-            "last_seq" : seqs[2]
-          }
-        ];
-        return expecteds[i];
-      }
-
-      function normalizeResult(result) {
-        // order of changes doesn't matter
-        result.results.forEach(function (ch) {
-          ch.changes = ch.changes.sort(function (a, b) {
-            return a.rev < b.rev ? -1 : 1;
-          });
-        });
-      }
-
-      tree.forEach(function (docs, i) {
-        chain = chain.then(function () {
-          return db.bulkDocs(docs, {new_edits: false}).then(function () {
-            return db.changes({
-              descending: true
-            });
-          }).then(function (result) {
-            seqs.push(result.last_seq);
-            var expected = getExpected(i);
-            normalizeResult(result);
-            result.should.deep.equal(expected,
-            i + ': should get: ' + JSON.stringify(expected) +
-            ', but got: ' + JSON.stringify(result));
-          });
-        });
-      });
-      return chain;
-    });
-
-    it('#3136 winningRev has a lower seq, style=all_docs', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var tree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-e',
-            _deleted: true,
-            _revisions: {start: 2, ids: ['e', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-g',
-            _revisions: {start: 3, ids: ['g', 'e', 'a']}
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-c',
-            _revisions: {start: 3, ids: ['c', 'b', 'a']}
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-d',
-            _revisions: {start: 2, ids: ['d', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-h',
-            _revisions: {start: 3, ids: ['h', 'd', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '4-f',
-            _revisions: {start: 4, ids: ['f', 'h', 'd', 'a']}
-          }
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      var seqs = [0];
-
-      function getExpected(i) {
-        var expecteds = [
-          {
-            "results": [
-              {
-                "seq": seqs[1],
-                "id": "foo",
-                "changes": [{"rev": "3-g"}],
-                "doc": {"_id": "foo", "_rev": "3-g"}
-              }
-            ],
-            "last_seq" : seqs[1]
-          },
-          {
-            "results": [
-              {
-                "seq": seqs[2],
-                "id": "foo",
-                "changes": [{"rev": "3-c"}, {"rev": "3-g"}],
-                "doc": {"_id": "foo", "_rev": "3-g"}
-              }
-            ],
-            "last_seq" : seqs[2]
-          },
-          {
-            "results": [
-              {
-                "seq": seqs[3],
-                "id": "foo",
-                "changes": [{"rev": "3-c"}, {"rev": "3-g"}, {"rev": "4-f"}],
-                "doc": {"_id": "foo", "_rev": "4-f"}
-              }
-            ],
-            "last_seq" : seqs[3]
-          }
-        ];
-        return expecteds[i];
-      }
-
-      function normalizeResult(result) {
-        // order of changes doesn't matter
-        result.results.forEach(function (ch) {
-          ch.changes = ch.changes.sort(function (a, b) {
-            return a.rev < b.rev ? -1 : 1;
-          });
-        });
-      }
-
-      tree.forEach(function (docs, i) {
-        chain = chain.then(function () {
-          return db.bulkDocs(docs, {new_edits: false}).then(function () {
-            return db.changes({
-              style: 'all_docs',
-              since: seqs[seqs.length - 1],
-              include_docs: true
-            });
-          }).then(function (result) {
-            seqs.push(result.last_seq);
-            var expected = getExpected(i);
-            normalizeResult(result);
-            result.should.deep.equal(expected,
-            i + ': should get: ' + JSON.stringify(expected) +
-            ', but got: ' + JSON.stringify(result));
-          });
-        });
-      });
-      return chain;
-    });
-
-    it('#3136 winningRev has a lower seq, style=all_docs 2', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var tree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-e',
-            _deleted: true,
-            _revisions: {start: 2, ids: ['e', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-g',
-            _revisions: {start: 3, ids: ['g', 'e', 'a']}
-          }
-        ], [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}
-          },
-          {
-            _id: 'foo',
-            _rev: '3-c',
-            _revisions: {start: 3, ids: ['c', 'b', 'a']}
-          }
-        ], [
-          {
-            _id: 'bar',
-            _rev: '1-z',
-            _revisions: {start: 1, ids: ['z']}
-          }
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      var seqs = [0];
-
-      tree.forEach(function (docs) {
-        chain = chain.then(function () {
-          return db.bulkDocs(docs, {new_edits: false}).then(function () {
-            return db.changes();
-          }).then(function (result) {
-            seqs.push(result.last_seq);
-          });
-        });
-      });
-
-      return chain.then(function () {
-
-        var expecteds = [
-          {
-            "results": [{
-              "seq": seqs[2],
-              "id": "foo",
-              "changes": [{"rev": "3-c"}, {"rev": "3-g"}]
-            }, {"seq": seqs[3], "id": "bar", "changes": [{"rev": "1-z"}]}],
-            "last_seq": seqs[3]
-          },
-          {
-            "results": [{
-              "seq": seqs[2],
-              "id": "foo",
-              "changes": [{"rev": "3-c"}, {"rev": "3-g"}]
-            }, {"seq": seqs[3], "id": "bar", "changes": [{"rev": "1-z"}]}],
-            "last_seq": seqs[3]
-          },
-          {
-            "results": [{"seq": seqs[3], "id": "bar",
-              "changes": [{"rev": "1-z"}]}],
-            "last_seq": seqs[3]
-          },
-          {"results": [], "last_seq": seqs[3]}
-        ];
-
-        var chain2 = PouchDB.utils.Promise.resolve();
-
-        function normalizeResult(result) {
-          // order of changes doesn't matter
-          result.results.forEach(function (ch) {
-            ch.changes = ch.changes.sort(function (a, b) {
-              return a.rev < b.rev ? -1 : 1;
-            });
-          });
-        }
-
-        seqs.forEach(function (seq, i) {
-          chain2 = chain2.then(function () {
-            return db.changes({
-              since: seq,
-              style: 'all_docs'
-            }).then(function (res) {
-              normalizeResult(res);
-              res.should.deep.equal(expecteds[i], 'since=' + seq +
-              ': got: ' +
-              JSON.stringify(res) +
-              ', shoulda got: ' +
-              JSON.stringify(expecteds[i]));
-            });
-          });
-        });
-        return chain2;
-      });
-    });
-
-    it('#3136 winningRev has a higher seq, using limit', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var tree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}
-          }
-        ], [
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}
-          }
-        ], [
-          {
-            _id: 'bar',
-            _rev: '1-x',
-            _revisions: {start: 1, ids: ['x']}
-          }
-        ], [
-          {
-            _id: 'foo',
-            _rev: '2-c',
-            _deleted: true,
-            _revisions: {start: 2, ids: ['c', 'a']}
-          }
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      var seqs = [0];
-
-      tree.forEach(function (docs) {
-        chain = chain.then(function () {
-          return db.bulkDocs(docs, {new_edits: false}).then(function () {
-            return db.changes().then(function (result) {
-              seqs.push(result.last_seq);
-            });
-          });
-        });
-      });
-
-      return chain.then(function () {
-
-        var expecteds = [{
-          "results": [{
-            "seq": seqs[3],
-            "id": "bar",
-            "changes": [{"rev": "1-x"}],
-            "doc": {"_id": "bar", "_rev": "1-x"}
-          }],
-          "last_seq": seqs[3]
-        },
-          {
-            "results": [{
-              "seq": seqs[3],
-              "id": "bar",
-              "changes": [{"rev": "1-x"}],
-              "doc": {"_id": "bar", "_rev": "1-x"}
-            }],
-            "last_seq": seqs[3]
-          },
-          {
-            "results": [{
-              "seq": seqs[3],
-              "id": "bar",
-              "changes": [{"rev": "1-x"}],
-              "doc": {"_id": "bar", "_rev": "1-x"}
-            }],
-            "last_seq": seqs[3]
-          },
-          {
-            "results": [{
-              "seq": seqs[4],
-              "id": "foo",
-              "changes": [{"rev": "2-b"}, {"rev": "2-c"}],
-              "doc": {"_id": "foo", "_rev": "2-b"}
-            }],
-            "last_seq": seqs[4]
-          },
-          {"results": [], "last_seq": seqs[4]}
-        ];
-
-        var chain2 = PouchDB.utils.Promise.resolve();
-
-        function normalizeResult(result) {
-          // order of changes doesn't matter
-          result.results.forEach(function (ch) {
-            ch.changes = ch.changes.sort(function (a, b) {
-              return a.rev < b.rev ? -1 : 1;
-            });
-          });
-        }
-
-        seqs.forEach(function (seq, i) {
-          chain2 = chain2.then(function () {
-            return db.changes({
-              style: 'all_docs',
-              since: seq,
-              limit: 1,
-              include_docs: true
-            });
-          }).then(function (result) {
-            normalizeResult(result);
-            result.should.deep.equal(expecteds[i],
-              i + ': got: ' + JSON.stringify(result) +
-              ', shoulda got: ' + JSON.stringify(expecteds[i]));
-          });
-        });
-        return chain2;
-      });
-    });
-
-    it('changes-filter', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7}
-      ];
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      db.bulkDocs({ docs: docs1 }, function () {
-        var changes = db.changes({
-          filter: function (doc) {
-            return doc.integer % 2 === 0;
-          },
-          live: true
-        }).on('complete', function (result) {
-          result.status.should.equal('cancelled');
-          done();
-        }).on('change', function () {
-          count += 1;
-          if (count === 4) {
-            changes.cancel();
-          }
-        }).on('error', done);
-        db.bulkDocs({ docs: docs2 });
-      });
-    });
-
-    it('changes-filter with query params', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7}
-      ];
-      var params = { 'abc': true };
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      db.bulkDocs({ docs: docs1 }, function () {
-        var changes = db.changes({
-          filter: function (doc, req) {
-            if (req.query.abc) {
-              return doc.integer % 2 === 0;
-            }
-          },
-          query_params: params,
-          live: true
-        }).on('complete', function (result) {
-          result.status.should.equal('cancelled');
-          done();
-        }).on('change', function () {
-          count += 1;
-          if (count === 4) {
-            changes.cancel();
-          }
-        }).on('error', done);
-        db.bulkDocs({ docs: docs2 });
-      });
-    });
-
-    it('Non-live changes filter', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.changes().on('complete', function (allChanges) {
-          db.changes({
-            filter: function (doc) {
-              return doc.integer % 2 === 0;
-            }
-          }).on('complete', function (filteredChanges) {
-            // Should get docs 0 and 2 if the filter
-            // has been applied correctly.
-            filteredChanges.results.length.should.equal(2);
-            filteredChanges.last_seq.should.deep.equal(allChanges.last_seq);
-            done();
-          }).on('error', done);
-        }).on('error', done);
-      });
-    });
-
-    it('Non-live changes filter, descending', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.changes({
-          descending: true
-        }).on('complete', function (allChanges) {
-          db.changes({
-            descending: true,
-            filter: function (doc) {
-              return doc.integer > 2;
-            }
-          }).on('complete', function (filteredChanges) {
-            // Should get docs 2 and 3 if the filter
-            // has been applied correctly.
-            filteredChanges.results.length.should.equal(1);
-            filteredChanges.last_seq.should.deep.equal(allChanges.last_seq);
-            done();
-          }).on('error', done);
-        }).on('error', done);
-      });
-    });
-
-    it('#2569 Non-live doc_ids filter', function () {
-      var docs = [
-        {_id: '0'},
-        {_id: '1'},
-        {_id: '2'},
-        {_id: '3'}
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          doc_ids: ['1', '3']
-        });
-      }).then(function (changes) {
-        var ids = changes.results.map(function (x) {
-          return x.id;
-        });
-        ids.sort().should.deep.equal(['1', '3']);
-      });
-    });
-
-    it('#2569 Big non-live doc_ids filter', function () {
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        var id = '';
-        for (var j = 0; j < 50; j++) {
-          // make a huge id
-          id += PouchDB.utils.btoa(Math.random().toString());
-        }
-        docs.push({_id: id});
-      }
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          doc_ids: [docs[1]._id, docs[3]._id]
-        });
-      }).then(function (changes) {
-        var ids = changes.results.map(function (x) {
-          return x.id;
-        });
-        var expectedIds = [docs[1]._id, docs[3]._id];
-        ids.sort().should.deep.equal(expectedIds.sort());
-      });
-    });
-
-    it('#2569 Live doc_ids filter', function () {
-      var docs = [
-        {_id: '0'},
-        {_id: '1'},
-        {_id: '2'},
-        {_id: '3'}
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var retChanges = [];
-          var changes = db.changes({
-            doc_ids: ['1', '3'],
-            live: true
-          }).on('change', function (change) {
-            retChanges.push(change);
-            if (retChanges.length === 2) {
-              changes.cancel();
-              resolve(retChanges);
-            }
-          }).on('error', reject);
-        });
-      }).then(function (changes) {
-        var ids = changes.map(function (x) {
-          return x.id;
-        });
-        var expectedIds = ['1', '3'];
-        ids.sort().should.deep.equal(expectedIds);
-      });
-    });
-
-    it('#2569 Big live doc_ids filter', function () {
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        var id = '';
-        for (var j = 0; j < 50; j++) {
-          // make a huge id
-          id += PouchDB.utils.btoa(Math.random().toString());
-        }
-        docs.push({_id: id});
-      }
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var retChanges = [];
-          var changes = db.changes({
-            doc_ids: [docs[1]._id, docs[3]._id],
-            live: true
-          }).on('change', function (change) {
-            retChanges.push(change);
-            if (retChanges.length === 2) {
-              changes.cancel();
-              resolve(retChanges);
-            }
-          }).on('error', reject);
-        });
-      }).then(function (changes) {
-        var ids = changes.map(function (x) {
-          return x.id;
-        });
-        var expectedIds = [docs[1]._id, docs[3]._id];
-        ids.sort().should.deep.equal(expectedIds.sort());
-      });
-    });
-
-    it('#2569 Non-live doc_ids filter with filter=_doc_ids', function () {
-      var docs = [
-        {_id: '0'},
-        {_id: '1'},
-        {_id: '2'},
-        {_id: '3'}
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          filter: '_doc_ids',
-          doc_ids: ['1', '3']
-        });
-      }).then(function (changes) {
-        var ids = changes.results.map(function (x) {
-          return x.id;
-        });
-        ids.sort().should.deep.equal(['1', '3']);
-      });
-    });
-
-    it('#2569 Live doc_ids filter with filter=_doc_ids', function () {
-      var docs = [
-        {_id: '0'},
-        {_id: '1'},
-        {_id: '2'},
-        {_id: '3'}
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs(docs).then(function () {
-        return db.changes({
-          filter: '_doc_ids',
-          doc_ids: ['1', '3']
-        });
-      }).then(function (changes) {
-        var ids = changes.results.map(function (x) {
-          return x.id;
-        });
-        ids.sort().should.deep.equal(['1', '3']);
-      });
-    });
-
-    it('Changes to same doc are grouped', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '2', integer: 11},
-        {_id: '3', integer: 12}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function (err, info) {
-        docs2[0]._rev = info[2].rev;
-        docs2[1]._rev = info[3].rev;
-        db.put(docs2[0], function () {
-          db.put(docs2[1], function () {
-            db.changes({
-              include_docs: true
-            }).on('complete', function (changes) {
-              changes.results.length.should.equal(4);
-
-              var second = findById(changes.results, '2');
-              second.changes.length.should.equal(1);
-              second.doc.integer.should.equal(11);
-              done();
-            }).on('error', done);
-          });
-        });
-      });
-    });
-
-    it('Changes with conflicts are handled correctly', function (testDone) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '2', integer: 11},
-        {_id: '3', integer: 12}
-      ];
-      new PouchDB(dbs.name).then(function (localdb) {
-        var remotedb = new PouchDB(dbs.remote);
-        return localdb.bulkDocs({ docs: docs1 }).then(function (info) {
-          docs2[0]._rev = info[2].rev;
-          docs2[1]._rev = info[3].rev;
-          return localdb.put(docs2[0]).then(function () {
-            return localdb.put(docs2[1]).then(function (info) {
-              var rev2 = info.rev;
-              return PouchDB.replicate(localdb, remotedb).then(function () {
-                // update remote once, local twice, then replicate from
-                // remote to local so the remote losing conflict is later in
-                // the tree
-                return localdb.put({
-                  _id: '3',
-                  _rev: rev2,
-                  integer: 20
-                }).then(function (resp) {
-                  var rev3Doc = {
-                    _id: '3',
-                    _rev: resp.rev,
-                    integer: 30
-                  };
-                  return localdb.put(rev3Doc).then(function (resp) {
-                    var rev4local = resp.rev;
-                    var rev4Doc = {
-                      _id: '3',
-                      _rev: rev2,
-                      integer: 100
-                    };
-                    return remotedb.put(rev4Doc).then(function (resp) {
-                      var remoterev = resp.rev;
-                      return PouchDB.replicate(remotedb, localdb).then(
-                        function () {
-                        return localdb.changes({
-                          include_docs: true,
-                          style: 'all_docs',
-                          conflicts: true
-                        }).on('error', testDone)
-                        .then(function (changes) {
-                            changes.results.length.should.equal(4);
-                            var ch = findById(changes.results, '3');
-                            ch.changes.length.should.equal(2);
-                            ch.doc.integer.should.equal(30);
-                            ch.doc._rev.should.equal(rev4local);
-                            ch.changes.should.deep.equal([
-                              { rev: rev4local },
-                              { rev: remoterev }
-                            ]);
-
-                            ch.doc.should.have.property('_conflicts');
-                            ch.doc._conflicts.length.should.equal(1);
-                            ch.doc._conflicts[0].should.equal(remoterev);
-                          });
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        }).then(function () {
-          testDone();
-        }, testDone);
-      });
-    });
-
-    it('Change entry for a deleted doc', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function (err, info) {
-        var rev = info[3].rev;
-        db.remove({
-          _id: '3',
-          _rev: rev
-        }, function () {
-          db.changes({
-            include_docs: true
-          }).on('complete', function (changes) {
-            changes.results.length.should.equal(4);
-            var ch = findById(changes.results, '3');
-            // sequence numbers are not incremental in CouchDB 2.0
-            if (!testUtils.isCouchMaster()) {
-              ch.seq.should.equal(5);
-            }
-            ch.deleted.should.equal(true);
-            done();
-          }).on('error', done);
-        });
-      });
-    });
-
-    it('changes large number of docs', function (done) {
-      var docs = [];
-      var num = 30;
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, function () {
-        db.changes().on('complete', function (res) {
-          res.results.length.should.equal(num);
-          done();
-        }).on('error', done);
-      });
-    });
-
-    it('Calling db.changes({since: \'now\'})', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: [{ foo: 'bar' }] }, function () {
-        db.info(function (err, info) {
-          var api = db.changes({
-            since: 'now'
-          }).on('complete', function (res) {
-            // last_seq and update_seq might be encoded differently
-            // in clustered CouchDB - they cannot be reliably compared.
-            if (!testUtils.isCouchMaster()) {
-              res.last_seq.should.equal(info.update_seq);
-            }
-            done();
-          }).on('error', done);
-          api.should.be.an('object');
-          api.cancel.should.be.an('function');
-        });
-      });
-    });
-
-    //Duplicate to make sure both api options work.
-    it('Calling db.changes({since: \'latest\'})', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: [{ foo: 'bar' }] }, function () {
-        db.info(function (err, info) {
-          var api = db.changes({
-            since: 'latest'
-          }).on('complete', function (res) {
-            // last_seq and update_seq might be encoded differently
-            // in clustered CouchDB - they cannot be reliably compared.
-            if (!testUtils.isCouchMaster()) {
-              res.last_seq.should.equal(info.update_seq);
-            }
-            done();
-          }).on('error', done);
-          api.should.be.an('object');
-          api.cancel.should.be.an('function');
-        });
-      });
-    });
-
-    it('Closing db does not cause a crash if changes cancelled',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var called = 0;
-      function checkDone() {
-        called++;
-        if (called === 2) {
-          done();
-        }
-      }
-      db.bulkDocs({ docs: [{ foo: 'bar' }] }, function () {
-        var changes = db.changes({
-          live: true
-        }).on('complete', function (result) {
-          result.status.should.equal('cancelled');
-          checkDone();
-        });
-        should.exist(changes);
-        changes.cancel.should.be.a('function');
-        changes.cancel();
-        db.close(function (error) {
-          should.not.exist(error);
-          checkDone();
-        });
-      });
-    });
-
-    it('fire-complete-on-cancel', function (done) {
-      var db = new PouchDB(dbs.name);
-      var cancelled = false;
-      var changes = db.changes({
-        live: true
-      }).on('complete', function (result) {
-        cancelled.should.equal(true);
-        should.exist(result);
-        if (result) {
-          result.status.should.equal('cancelled');
-        }
-        done();
-      }).on('error', done);
-      should.exist(changes);
-      changes.cancel.should.be.a('function');
-      setTimeout(function () {
-        cancelled = true;
-        changes.cancel();
-      }, 100);
-    });
-
-    it('changes are not duplicated', function (done) {
-      var db = new PouchDB(dbs.name);
-      var called = 0;
-      var changes = db.changes({
-        live: true
-      }).on('change', function () {
-        called++;
-        if (called === 1) {
-          setTimeout(function () {
-            changes.cancel();
-          }, 1000);
-        }
-      }).on('complete', function () {
-        called.should.equal(1);
-        done();
-      });
-      db.post({key: 'value'});
-    });
-
-    it('supports return_docs=false', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      var num = 10;
-      for (var i = 0; i < num; i++) {
-        docs.push({ _id: 'doc_' + i});
-      }
-      var changes = 0;
-      db.bulkDocs({ docs: docs }, function (err) {
-        if (err) {
-          return done(err);
-        }
-        db.changes({
-          descending: true,
-          return_docs: false
-        }).on('change', function () {
-          changes++;
-        }).on('complete', function (results) {
-          results.results.should.have.length(0, '0 results returned');
-          changes.should.equal(num, 'correct number of changes');
-          done();
-        }).on('error', function (err) {
-          done(err);
-        });
-      });
-    });
-
-    // TODO: Remove 'returnDocs' in favor of 'return_docs' in a future release
-    it('supports returnDocs=false', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [];
-      var num = 10;
-      for (var i = 0; i < num; i++) {
-        docs.push({ _id: 'doc_' + i});
-      }
-      var changes = 0;
-      db.bulkDocs({ docs: docs }, function (err) {
-        if (err) {
-          return done(err);
-        }
-        db.changes({
-          descending: true,
-          returnDocs: false
-        }).on('change', function () {
-          changes++;
-        }).on('complete', function (results) {
-          results.results.should.have.length(0, '0 results returned');
-          changes.should.equal(num, 'correct number of changes');
-          done();
-        }).on('error', function (err) {
-          done(err);
-        });
-      });
-    });
-
-    it('should respects limit', function (done) {
-      var docs1 = [
-        {_id: '_local/foo'},
-        {_id: 'a', integer: 0},
-        {_id: 'b', integer: 1},
-        {_id: 'c', integer: 2},
-        {_id: 'd', integer: 3}
-      ];
-      var called = 0;
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.changes({
-          limit: 1
-        }).on('change', function () {
-          (called++).should.equal(0);
-        }).on('complete', function () {
-          setTimeout(function () {
-            done();
-          }, 50);
-        });
-      });
-    });
-
-    it.skip('should respects limit with live replication', function (done) {
-      var docs1 = [
-        {_id: '_local/foo'},
-        {_id: 'a', integer: 0},
-        {_id: 'b', integer: 1},
-        {_id: 'c', integer: 2},
-        {_id: 'd', integer: 3}
-      ];
-      var called = 0;
-      var doneCalled = 0;
-      function calldone() {
-        doneCalled++;
-        if (doneCalled === 2) {
-          done();
-        }
-      }
-      var db = new PouchDB(dbs.name);
-      db.changes({
-        limit: 1,
-        live: true
-      }).on('change', function (ch) {
-        ch.id.should.equal('a');
-        (called++).should.equal(0);
-      }).on('complete', function () {
-        calldone();
-      });
-      db.bulkDocs({ docs: docs1 }).then(calldone);
-    });
-
-    it('doesn\'t throw if opts.complete is undefined', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({_id: 'foo'}).then(function () {
-        db.changes().on('change', function () {
-          done();
-        }).on('error', function (err) {
-          done(err);
-        });
-      }, done);
-    });
-
-    it('it handles a bunch of individual changes in live replication',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var len = 80;
-      var called = 0;
-      var changesDone = false;
-      var changesWritten = 0;
-      var changes = db.changes({live: true});
-
-      changes.on('change', function () {
-        called++;
-        if (called === len) {
-          changes.cancel();
-        }
-      }).on('error', done).on('complete', function () {
-        changesDone = true;
-        maybeDone();
-      });
-
-      var i = -1;
-
-      function maybeDone() {
-        if (changesDone && changesWritten === len) {
-          done();
-        }
-      }
-
-      function after() {
-        changesWritten++;
-        db.listeners('destroyed').should.have.length.lessThan(5);
-        maybeDone();
-      }
-
-      while (++i < len) {
-        db.post({}).then(after).catch(done);
-      }
-
-    });
-
-    it('changes-filter without filter', function (done) {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7}
-      ];
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      db.bulkDocs({ docs: docs1 }, function () {
-        var changes = db.changes({
-          live: true
-        }).on('complete', function (result) {
-          result.status.should.equal('cancelled');
-          done();
-        }).on('change', function () {
-          count += 1;
-          if (count === 8) {
-            changes.cancel();
-          }
-        }).on('error', done);
-        db.bulkDocs({ docs: docs2 });
-      });
-    });
-  });
-});
-
-describe('changes-standalone', function () {
-
-  it('Changes reports errors', function (done) {
-    this.timeout(2000);
-    var db = new PouchDB('http://infiniterequest.com', { skipSetup: true });
-    db.changes({
-      timeout: 1000
-    }).on('error', function (err) {
-      should.exist(err);
-      done();
-    });
-  });
-
-});
diff --git a/tests/integration/test.compaction.js b/tests/integration/test.compaction.js
deleted file mode 100644
index 24571ab..0000000
--- a/tests/integration/test.compaction.js
+++ /dev/null
@@ -1,2111 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-var autoCompactionAdapters = ['local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.compaction.js-' + adapter, function () {
-    if (testUtils.isCouchMaster()) {
-      return true;
-    }
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-    
-    it('#3350 compact should return {ok: true}', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.compact(function (err, result) {
-        should.not.exist(err);
-        result.should.eql({ok: true});
-
-        done();
-      });
-    });
-
-    it('compact with options object', function () {
-      var db = new PouchDB(dbs.name);
-      return db.compact({}).then(function (result) {
-        result.should.eql({ok: true});
-      });
-    });
-
-    it('#2913 massively parallel compaction', function () {
-      var db = new PouchDB(dbs.name);
-      var tasks = [];
-      for (var i = 0; i < 30; i++) {
-        tasks.push(i);
-      }
-
-      return PouchDB.utils.Promise.all(tasks.map(function (i) {
-        var doc = {_id: 'doc_' + i};
-        return db.put(doc).then(function () {
-          return db.compact();
-        }).then(function () {
-          return db.get('doc_' + i);
-        }).then(function (doc) {
-          return db.put(doc);
-        }).then(function () {
-          return db.compact();
-        });
-      }));
-    });
-
-    it('Compaction document with no revisions to remove', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo', value: 'bar'};
-      db.put(doc, function () {
-        db.compact(function () {
-          db.get('foo', function (err) {
-            done(err);
-          });
-        });
-      });
-    });
-
-    it('Compation on empty db', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.compact(function () {
-        done();
-      });
-    });
-
-    it('Compation on empty db with interval option', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.compact({ interval: 199 }, function () {
-        done();
-      });
-    });
-
-    it('Simple compation test', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: 'foo',
-        value: 'bar'
-      };
-      db.post(doc, function (err, res) {
-        var rev1 = res.rev;
-        doc._rev = rev1;
-        doc.value = 'baz';
-        db.post(doc, function (err, res) {
-          var rev2 = res.rev;
-          db.compact(function () {
-            db.get('foo', { rev: rev1 }, function (err) {
-              err.status.should.equal(404);
-              err.name.should.equal(
-                'not_found', 'compacted document is missing'
-              );
-              db.get('foo', { rev: rev2 }, function (err) {
-                done(err);
-              });
-            });
-          });
-        });
-      });
-    });
-
-    var checkBranch = function (db, docs, callback) {
-      function check(i) {
-        var doc = docs[i];
-        db.get(doc._id, { rev: doc._rev }, function (err) {
-          if (i < docs.length - 1) {
-            should.exist(err, 'should be compacted: ' + doc._rev);
-            err.status.should.equal(404, 'compacted!');
-            check(i + 1);
-          } else {
-            should.not.exist(err, 'should not be compacted: ' + doc._rev);
-            callback();
-          }
-        });
-      }
-      check(0);
-    };
-
-    var checkTree = function (db, tree, callback) {
-      function check(i) {
-        checkBranch(db, tree[i], function () {
-          if (i < tree.length - 1) {
-            check(i + 1);
-          } else {
-            callback();
-          }
-        });
-      }
-      check(0);
-    };
-
-    var exampleTree = [
-      [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-       {_id: 'foo', _rev: '2-b', value: 'foo b'},
-       {_id: 'foo', _rev: '3-c', value: 'foo c'}
-      ],
-      [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-       {_id: 'foo', _rev: '2-d', value: 'foo d'},
-       {_id: 'foo', _rev: '3-e', value: 'foo e'},
-       {_id: 'foo', _rev: '4-f', value: 'foo f'}
-      ],
-      [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-       {_id: 'foo', _rev: '2-g', value: 'foo g'},
-       {_id: 'foo', _rev: '3-h', value: 'foo h'},
-       {_id: 'foo', _rev: '4-i', value: 'foo i'},
-       {_id: 'foo', _rev: '5-j', _deleted: true, value: 'foo j'}
-      ]
-    ];
-
-    var exampleTree2 = [
-      [{_id: 'bar', _rev: '1-m', value: 'bar m'},
-       {_id: 'bar', _rev: '2-n', value: 'bar n'},
-       {_id: 'bar', _rev: '3-o', _deleted: true, value: 'foo o'}
-      ],
-      [{_id: 'bar', _rev: '2-n', value: 'bar n'},
-       {_id: 'bar', _rev: '3-p', value: 'bar p'},
-       {_id: 'bar', _rev: '4-r', value: 'bar r'},
-       {_id: 'bar', _rev: '5-s', value: 'bar s'}
-      ],
-      [{_id: 'bar', _rev: '3-p', value: 'bar p'},
-       {_id: 'bar', _rev: '4-t', value: 'bar t'},
-       {_id: 'bar', _rev: '5-u', value: 'bar u'}
-      ]
-    ];
-
-    it('Compact more complicated tree', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        testUtils.putTree(db, exampleTree, function () {
-          db.compact(function () {
-            checkTree(db, exampleTree, function () {
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Compact two times more complicated tree', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.putTree(db, exampleTree, function () {
-        db.compact(function () {
-          db.compact(function () {
-            checkTree(db, exampleTree, function () {
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Compact database with at least two documents', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.putTree(db, exampleTree, function () {
-        testUtils.putTree(db, exampleTree2, function () {
-          db.compact(function () {
-            checkTree(db, exampleTree, function () {
-              checkTree(db, exampleTree2, function () {
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Compact deleted document', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function (err, res) {
-        var firstRev = res.rev;
-        db.remove({
-          _id: 'foo',
-          _rev: firstRev
-        }, function () {
-          db.compact(function () {
-            db.get('foo', { rev: firstRev }, function (err) {
-              should.exist(err, 'got error');
-              err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                      'correct error status returned');
-              err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                   'correct error message returned');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Compact db with sql-injecty doc id', function (done) {
-      var db = new PouchDB(dbs.name);
-      var id = '\'sql_injection_here';
-      db.put({ _id: id }, function (err, res) {
-        var firstRev = res.rev;
-        db.remove({
-          _id: id,
-          _rev: firstRev
-        }, function () {
-          db.compact(function () {
-            db.get(id, { rev: firstRev }, function (err) {
-              should.exist(err, 'got error');
-              err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                      'correct error status returned');
-              err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                   'correct error message returned');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-
-    function getRevisions(db, docId) {
-      return db.get(docId, {
-        revs: true,
-        open_revs: 'all'
-      }).then(function (docs) {
-        var combinedResult = [];
-        return PouchDB.utils.Promise.all(docs.map(function (doc) {
-          doc = doc.ok;
-          // convert revision IDs into full _rev hashes
-          var start = doc._revisions.start;
-          return PouchDB.utils.Promise.all(
-            doc._revisions.ids.map(function (id, i) {
-              var rev = (start - i) + '-' + id;
-              return db.get(docId, {rev: rev}).then(function (doc) {
-                return { rev: rev, doc: doc };
-              }).catch(function (err) {
-                if (err.status !== 404) {
-                  throw err;
-                }
-                return { rev: rev };
-              });
-            })).then(function (docsAndRevs) {
-              combinedResult = combinedResult.concat(docsAndRevs);
-            });
-        })).then(function () {
-          return combinedResult;
-        });
-      });
-    }
-
-    it('Compaction removes non-leaf revs (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(1);
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(2);
-        should.exist(docsAndRevs[0].doc);
-        should.exist(docsAndRevs[1].doc);
-        return db.compact();
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(2);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-      });
-    });
-
-    it('Compaction removes non-leaf revs pt 2 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('Compaction removes non-leaf revs pt 3 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      var docs = [
-        {
-          _id: 'foo',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'foo',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'foo',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }, {
-          _id: 'foo',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }
-      ];
-
-      return db.bulkDocs(docs, {new_edits: false}).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(4);
-        should.exist(docsAndRevs[0].doc);
-        should.exist(docsAndRevs[1].doc);
-        should.exist(docsAndRevs[2].doc);
-        should.exist(docsAndRevs[3].doc);
-        return db.compact();
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(4);
-        var asMap = {};
-        docsAndRevs.forEach(function (docAndRev) {
-          asMap[docAndRev.rev] = docAndRev.doc;
-        });
-        // only leafs remain
-        should.not.exist(asMap['1-a1']);
-        should.not.exist(asMap['2-a2']);
-        should.exist(asMap['3-a3']);
-        should.exist(asMap['1-b1']);
-      });
-    });
-
-    it('Compaction removes non-leaf revs pt 4 (#2807)', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        doc._deleted = true;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        delete doc._deleted;
-        return db.put(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('Compaction removes non-leaf revs pt 5 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        doc._deleted = true;
-        return db.put(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('#2931 - synchronous putAttachment + compact', function () {
-
-      var db = new PouchDB(dbs.name);
-      var queue = db.put({_id: 'doc'});
-
-      var otherPromises = [];
-
-      for (var i = 0; i < 50; i++) {
-        /* jshint loopfunc:true */
-        queue = queue.then(function () {
-          return db.get('doc').then(function (doc) {
-            doc._attachments = doc._attachments || {};
-            var blob = testUtils.makeBlob(
-              PouchDB.utils.btoa(Math.random().toString()),
-              'text/plain');
-            return db.putAttachment(doc._id, 'att.txt', doc._rev, blob,
-              'text/plain');
-          });
-        });
-        queue.then(function () {
-          var promise = PouchDB.utils.Promise.all([
-            db.compact(),
-            db.compact(),
-            db.compact(),
-            db.compact(),
-            db.compact()
-          ]);
-          otherPromises.push(promise);
-          return promise;
-        });
-      }
-      return queue.then(function () {
-        return PouchDB.utils.Promise.all(otherPromises);
-      });
-    });
-
-    it('#2931 - synchronous putAttachment + compact 2', function () {
-
-      var db = new PouchDB(dbs.name);
-      var queue = db.put({_id: 'doc'});
-
-      var compactQueue = PouchDB.utils.Promise.resolve();
-
-      for (var i = 0; i < 50; i++) {
-        /* jshint loopfunc:true */
-        queue = queue.then(function () {
-          return db.get('doc').then(function (doc) {
-            doc._attachments = doc._attachments || {};
-            var blob = testUtils.makeBlob(
-              PouchDB.utils.btoa(Math.random().toString()),
-              'text/plain');
-            return db.putAttachment(doc._id, 'att.txt', doc._rev, blob,
-              'text/plain');
-          });
-        });
-        queue.then(function () {
-          compactQueue = compactQueue.then(function () {
-            return PouchDB.utils.Promise.all([
-              db.compact(),
-              db.compact(),
-              db.compact(),
-              db.compact(),
-              db.compact()
-            ]);
-          });
-        });
-      }
-      return queue.then(function () {
-        return compactQueue;
-      });
-    });
-
-    //
-    // NO MORE HTTP TESTS AFTER THIS POINT!
-    //
-    // We're testing some very local-specific functionality
-    //
-
-
-    if (autoCompactionAdapters.indexOf(adapter) === -1) {
-      return;
-    }
-
-    //
-    // Tests for issue #2818 follow, which make some assumptions
-    // about how binary data is stored, so they don't pass in
-    // CouchDB. Namely, PouchDB dedups attachments based on
-    // md5sum, whereas CouchDB does not.
-    //
-
-    // per https://en.wikipedia.org/wiki/MD5,
-    // these two should have colliding md5sums
-    var att1 = '0THdAsXm7sRpPZoGmK/5XC/KtQcSRn6r' +
-      'QARYPrj7f4lVrTQGCfSzAoPkiIMl8UFaCFEl6PfNyZ/Z' +
-      'Hb1ygDc8W9iCPjFWNI9brm2s1DbJGcbdU+I0h9oD/' +
-      'QI5YwbSSM2g6Z8zQg9XfujOVLZwgCgNHsaY' +
-      'Iby2qIOTlvllq2/3KnA=';
-    var att2 = '0THdAsXm7sRpPZoGmK/5XC/KtYcSRn6r' +
-      'QARYPrj7f4lVrTQGCfSzAoPkiIMlcUFaCFEl6PfNyZ/Z' +
-      'Hb3ygDc8W9iCPjFWNI9brm2s1DbJGcbdU+K0h9oD/' +
-      'QI5YwbSSM2g6Z8zQg9XfujOVLZwgKgNHsaY' +
-      'Iby2qIOTlvllK2/3KnA=';
-
-    it('#2818 md5 collision (sanity check)', function () {
-      //
-      // CouchDB will throw!
-      //
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc1 = {
-        _id: 'doc1',
-        _attachments: {
-          'att.txt': {
-            data: att1,
-            content_type: 'application/octet-stream'
-          }
-        }
-      };
-      var doc2 = {
-        _id: 'doc2',
-        _attachments: {
-          'att.txt': {
-            data: att2,
-            content_type: 'application/octet-stream'
-          }
-        }
-      };
-      var doc3 = {
-        _id: 'doc3',
-        _attachments: {
-          'att.txt': {
-            data: '1' + att2.substring(1), // distractor
-            content_type: 'application/octet-stream'
-          }
-        }
-      };
-      return db.put(doc1).then(function () {
-        return db.put(doc2);
-      }).then(function () {
-        return db.put(doc3);
-      }).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var md1 = res.rows[0].doc._attachments['att.txt'].digest;
-        var md2 = res.rows[1].doc._attachments['att.txt'].digest;
-        var md3 = res.rows[2].doc._attachments['att.txt'].digest;
-        md1.should.not.equal(md3, 'md5 sums should not collide');
-        md2.should.not.equal(md3, 'md5 sums should not collide');
-        md1.should.equal(md2,
-          'md5 sums should collide. if not, other #2818 tests will fail');
-      }).then(function () {
-        return PouchDB.utils.Promise.all(['doc1', 'doc2'].map(function (id) {
-          return db.get(id, {attachments: true});
-        })).then(function (docs) {
-          var data1 = docs[0]._attachments['att.txt'].data;
-          var data2 = docs[1]._attachments['att.txt'].data;
-          data1.should.equal(data2,
-            'yay, we are vulnerable to md5sum collision (1)');
-          att1.should.equal(data2,
-              'att1 is the final one, not att2');
-        });
-      });
-    });
-
-    it('#2818 md5 collision between revs (sanity check)', function () {
-      //
-      // CouchDB will throw!
-      //
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc1 = {
-        _id: 'doc1',
-        _attachments: {
-          'att.txt': {
-            data: att1,
-            content_type: 'application/octet-stream'
-          }
-        }
-      };
-      var rev1;
-      var rev2;
-      return db.put(doc1).then(function (res) {
-        rev1 = doc1._rev = res.rev;
-        doc1._attachments['att.txt'].data = att2;
-        return db.put(doc1);
-      }).then(function (res) {
-        rev2 = res.rev;
-        return PouchDB.utils.Promise.all([rev1, rev2].map(function (rev) {
-          return db.get('doc1', {rev: rev, attachments: true});
-        }));
-      }).then(function (docs) {
-        var data1 = docs[0]._attachments['att.txt'].data;
-        var data2 = docs[1]._attachments['att.txt'].data;
-        data1.should.equal(data2,
-          'yay, we are vulnerable to md5sum collision');
-      });
-    });
-
-    it('#2818 doesn\'t throw 412, thanks to digest', function () {
-      //
-      // CouchDB will throw!
-      //
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc1 = {
-        _id: 'doc1',
-        _attachments: {
-          'att.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      };
-
-      return db.put(doc1).then(function () {
-        return db.get('doc1');
-      }).then(function (doc1) {
-        var doc2 = {
-          _id: 'doc2',
-          _attachments: {
-            'att.txt': {
-              stub: true,
-              digest: doc1._attachments['att.txt'].digest,
-              content_type: 'text/plain'
-            }
-          }
-        };
-        return db.put(doc2);
-      });
-    });
-
-    it('#2818 Compaction removes attachments', function () {
-      // now that we've established no 412s thanks to digests,
-      // we can use that to detect true attachment deletion
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {
-        _id: 'doc1',
-        _attachments: {
-          'deleteme.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      };
-      var digest;
-      return db.put(doc).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        digest = doc._attachments['deleteme.txt'].digest;
-        delete doc._attachments['deleteme.txt'];
-        doc._attachments['retainme.txt'] = {
-          data: 'dG90bw==', // 'toto'
-          content_type: 'text/plain'
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        doc._attachments['newatt.txt'] = {
-          content_type: "text/plain",
-          digest: digest,
-          stub: true
-        };
-        return db.put(doc).then(function () {
-          throw new Error('shouldn\'t have gotten here');
-        }, function (err) {
-          err.status.should.equal(412);
-        });
-      });
-    });
-
-    it('#2818 Compaction removes attachments given conflicts', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] },
-          _attachments: {
-            'att.txt': {
-              data: 'Zm9vYmFy', // 'foobar'
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] },
-          _attachments: {
-            'att.txt': {
-              data: 'dG90bw==', // 'toto'
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] },
-          _attachments: {
-            'att.txt': {
-              data: 'Ym9uZ28=', // 'bongo'
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] },
-          _attachments: {
-            'att.txt': {
-              data: 'enV6dQ==', // 'zuzu'
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-
-      var allDigests = [];
-      var digestsToForget = [];
-      var digestsToRemember = [];
-      return db.bulkDocs({
-        docs: docs,
-        new_edits: false
-      }).then(function () {
-        return PouchDB.utils.Promise.all([
-          '1-a1', '2-a2', '3-a3', '1-b1'
-        ].map(function (rev) {
-          return db.get('fubar', {rev: rev, attachments: true});
-        }));
-      }).then(function (docs) {
-        digestsToForget.push(docs[0]._attachments['att.txt'].digest);
-        digestsToForget.push(docs[1]._attachments['att.txt'].digest);
-        digestsToRemember.push(docs[2]._attachments['att.txt'].digest);
-        digestsToRemember.push(docs[3]._attachments['att.txt'].digest);
-
-        allDigests = allDigests.concat(digestsToForget).concat(
-          digestsToRemember);
-
-        return PouchDB.utils.Promise.all(allDigests.map(function (digest) {
-          var doc = {
-            _attachments: {
-              'newatt.txt': {
-                content_type: "text/plain",
-                digest: digest,
-                stub: true
-              }
-            }
-          };
-          return db.post(doc).then(function (res) {
-            return db.remove(res.id, res.rev);
-          });
-        }));
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return PouchDB.utils.Promise.all(digestsToForget.map(
-            function (digest) {
-          var doc = {
-            _attachments: {
-              'newatt.txt': {
-                content_type: "text/plain",
-                digest: digest,
-                stub: true
-              }
-            }
-          };
-          return db.post(doc).then(function () {
-            throw new Error('shouldn\'t have gotten here');
-          }, function (err) {
-            err.status.should.equal(412);
-          });
-        }));
-      }).then(function () {
-        return PouchDB.utils.Promise.all(digestsToRemember.map(
-            function (digest) {
-          var doc = {
-            _attachments: {
-              'newatt.txt': {
-                content_type: "text/plain",
-                digest: digest,
-                stub: true
-              }
-            }
-          };
-          return db.post(doc);
-        }));
-      });
-    });
-
-    it('#2818 Compaction retains attachments if unorphaned', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = {
-        _id: 'doc1',
-        _attachments: {
-          'deleteme.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      };
-      var digest;
-      return db.put(doc).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        digest = doc._attachments['deleteme.txt'].digest;
-        delete doc._attachments['deleteme.txt'];
-        doc._attachments['retainme.txt'] = {
-          data: 'dG90bw==', // 'toto'
-          content_type: 'text/plain'
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.put({
-          _id: 'doc2',
-          _attachments: {
-            'nodontdeleteme.txt': {
-              data: 'Zm9vYmFy', // 'foobar'
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        doc._attachments['newatt.txt'] = {
-          content_type: "text/plain",
-          digest: digest,
-          stub: true
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        // ok, now let's really delete them
-        var docs = [
-          {
-            _id: 'doc1',
-            _rev: res.rows[0].value.rev
-          },
-          {
-            _id: 'doc2',
-            _rev: res.rows[1].value.rev
-          }
-        ];
-        return db.bulkDocs(docs);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        var doc = {
-          _attachments: {
-            'foo.txt': {
-              content_type: "text/plain",
-              digest: digest,
-              stub: true
-            }
-          }
-        };
-        return db.post(doc).then(function () {
-          throw new Error('shouldn\'t have gotten here');
-        }, function (err) {
-          err.status.should.equal(412);
-        });
-      });
-    });
-
-    it('#2818 successive new_edits okay with attachments', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        },
-        _attachments: {
-          'att.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      }];
-      var digest;
-      return db.bulkDocs({docs: docs, new_edits: false}).then(function () {
-        return db.bulkDocs({docs: docs, new_edits: false});
-      }).then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        doc._rev.should.equal('1-x');
-        digest = doc._attachments['att.txt'].digest;
-      }).then(function () {
-        var doc = {
-          _attachments: {
-            'foo.txt': {
-              content_type: "text/plain",
-              digest: digest,
-              stub: true
-            }
-          }
-        };
-        return db.post(doc);
-      });
-    });
-
-    it('#2818 Compaction really replaces attachments', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      return db.put({
-        _id: 'doc1',
-        _attachments: {
-          'att.txt': {
-            data: att1,
-            content_type: 'application/octet-stream'
-          }
-        }
-      }).then(function () {
-        return db.get('doc1', {attachments: true});
-      }).then(function (doc1) {
-        doc1._attachments['att.txt'].data.should.equal(att1, 'doc1');
-        return db.put({
-          _id: 'doc2',
-          _attachments: {
-            'att.txt': {
-              data: att2,
-              content_type: 'application/octet-stream'
-            }
-          }
-        });
-      }).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        res.rows[0].doc._attachments['att.txt'].digest.should.equal(
-          res.rows[1].doc._attachments['att.txt'].digest,
-          'digests collide'
-        );
-        return db.get('doc1', {attachments: true});
-      }).then(function (doc1) {
-        doc1._attachments['att.txt'].data.should.equal(att1,
-          'doc1 has original att, indicating we didn\'t overwrite it');
-        return db.get('doc2', {attachments: true});
-      }).then(function (doc2) {
-        doc2._attachments['att.txt'].data.should.equal(att1,
-          'doc2 also has original att');
-        return db.remove(doc2);
-      }).then(function () {
-        return db.get('doc1');
-      }).then(function (doc1) {
-        return db.remove(doc1);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.put({
-          _id: 'doc3',
-          _attachments: {
-            'att.txt': {
-              data: att2,
-              content_type: 'application/octet-stream'
-            }
-          }
-        });
-      }).then(function () {
-        return db.put({
-          _id: 'doc4',
-          _attachments: {
-            'att.txt': {
-              data: att1,
-              content_type: 'application/octet-stream'
-            }
-          }
-        });
-      }).then(function () {
-        return db.get('doc3', {attachments: true});
-      }).then(function (doc3) {
-        doc3._attachments['att.txt'].data.should.equal(att2,
-          'md5-colliding content was really replaced');
-        return db.get('doc4', {attachments: true});
-      }).then(function (doc4) {
-        doc4._attachments['att.txt'].data.should.equal(att2,
-          'md5-colliding content was really replaced');
-      });
-    });
-
-    it('#2818 Many orphaned attachments', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var docs = [
-        {
-          _id: 'doc1',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att2.txt': {
-              data: PouchDB.utils.btoa('2'),
-              content_type: 'text/plain'
-            },
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc2',
-          _attachments: {
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc3',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            },
-            'att7.txt': {
-              data: PouchDB.utils.btoa('7'),
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-
-      var digestsToForget;
-      var digestsToRemember;
-      return db.bulkDocs(docs).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var allAtts = {};
-        res.rows.forEach(function (row) {
-          Object.keys(row.doc._attachments).forEach(function (attName) {
-            var att = row.doc._attachments[attName];
-            allAtts[attName] = att.digest;
-          });
-        });
-        digestsToForget = [
-          allAtts['att2.txt'],
-          allAtts['att3.txt'],
-          allAtts['att4.txt'],
-          allAtts['att5.txt']
-        ];
-        digestsToRemember = [
-          allAtts['att1.txt'],
-          allAtts['att6.txt'],
-          allAtts['att7.txt']
-        ];
-        return db.get('doc1');
-      }).then(function (doc1) {
-        return db.remove(doc1);
-      }).then(function () {
-        return db.get('doc2');
-      }).then(function (doc2) {
-        return db.remove(doc2);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-            digestsToRemember.map(function (digest) {
-          return db.post({
-            _attachments: {
-              'baz.txt' : {
-                stub: true,
-                digest: digest,
-                content_type: 'text/plain'
-              }
-            }
-          });
-        }));
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-            digestsToForget.map(function (digest) {
-          return db.post({
-            _attachments: {
-              'baz.txt' : {
-                stub: true,
-                digest: digest,
-                content_type: 'text/plain'
-              }
-            }
-          }).then(function () {
-            throw new Error('shouldn\'t have gotten here');
-          }, function (err) {
-            err.status.should.equal(412);
-          });
-        }));
-      });
-    });
-
-    it('#3092 atts should be ignored when _deleted - bulkDocs', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = { _id: 'doc1'};
-      return db.put(doc).then(function (info) {
-        doc._rev = info.rev;
-        doc._deleted = true;
-        doc._attachments = {
-          'att1.txt': {
-            data: PouchDB.utils.btoa('1'),
-            content_type: 'application/octet-stream'
-          }
-        };
-        return db.bulkDocs([doc]);
-      }).then(function () {
-        return db.post({
-          _attachments: {
-            'baz.txt' : {
-              stub: true,
-              digest: 'md5-xMpCOKC5I4INzFCab3WEmw==',
-              content_type: 'application/octet-stream'
-            }
-          }
-        }).then(function () {
-          throw new Error('shouldn\'t have gotten here');
-        }, function (err) {
-          err.status.should.equal(412);
-        });
-      });
-    });
-
-    it('#3091 atts should be ignored when _deleted - put', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var doc = { _id: 'doc1'};
-      return db.put(doc).then(function (info) {
-        doc._rev = info.rev;
-        doc._deleted = true;
-        doc._attachments = {
-          'att1.txt': {
-            data: PouchDB.utils.btoa('1'),
-            content_type: 'application/octet-stream'
-          }
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.post({
-          _attachments: {
-            'baz.txt' : {
-              stub: true,
-              digest: 'md5-xMpCOKC5I4INzFCab3WEmw==',
-              content_type: 'application/octet-stream'
-            }
-          }
-        }).then(function () {
-          throw new Error('shouldn\'t have gotten here');
-        }, function (err) {
-          err.status.should.equal(412);
-        });
-      });
-    });
-
-    it('#3089 Many orphaned atts w/ parallel compaction', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var docs = [
-        {
-          _id: 'doc1',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att2.txt': {
-              data: PouchDB.utils.btoa('2'),
-              content_type: 'text/plain'
-            },
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc2',
-          _attachments: {
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc3',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            },
-            'att7.txt': {
-              data: PouchDB.utils.btoa('7'),
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-
-      var digestsToForget;
-      var digestsToRemember;
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var allAtts = {};
-        res.rows.forEach(function (row) {
-          Object.keys(row.doc._attachments).forEach(function (attName) {
-            var att = row.doc._attachments[attName];
-            allAtts[attName] = att.digest;
-          });
-        });
-        digestsToForget = [
-          allAtts['att2.txt'],
-          allAtts['att3.txt'],
-          allAtts['att4.txt'],
-          allAtts['att5.txt']
-        ];
-        digestsToRemember = [
-          allAtts['att1.txt'],
-          allAtts['att6.txt'],
-          allAtts['att7.txt']
-        ];
-        return db.allDocs({keys: ['doc1', 'doc2']});
-      }).then(function (res) {
-        var docs = res.rows.map(function (row) {
-          return {
-            _deleted: true,
-            _id: row.id,
-            _rev: row.value.rev
-          };
-        });
-        return db.bulkDocs(docs);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToRemember.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            });
-          }));
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToForget.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              throw new Error('shouldn\'t have gotten here');
-            }, function (err) {
-              err.status.should.equal(412);
-            });
-          }));
-      });
-    });
-
-    it('#3089 Same att orphaned by many documents', function () {
-      // In this test, a single attachment is shared by many docs,
-      // which are all deleted in a single bulkDocs. This is to
-      // hunt down race conditions in our orphan compaction.
-
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-
-      var docs = [];
-      for (var i = 0; i < 100; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }
-
-      return db.bulkDocs(docs).then(function (results) {
-        results.forEach(function (res, i) {
-          docs[i]._rev = res.rev;
-        });
-        return db.get(docs[0]._id);
-      }).then(function (doc) {
-        var digest = doc._attachments['att1.txt'].digest;
-        docs.forEach(function (doc) {
-          doc._deleted = true;
-        });
-        return db.bulkDocs(docs).then(function () {
-          return db.compact();
-        }).then(function () {
-          return db.post({
-            _attachments: {
-              'baz.txt' : {
-                stub: true,
-                digest: digest,
-                content_type: 'text/plain'
-              }
-            }
-          }).then(function () {
-            throw new Error('shouldn\'t have gotten here');
-          }, function (err) {
-            err.status.should.equal(412);
-          });
-        });
-      });
-    });
-
-    //
-    // AUTO-COMPACTION TESTS FOLLOW
-    // http adapters need not apply!
-    //
-
-    it('Auto-compaction test', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {_id: 'doc', val: '1'};
-      db.post(doc, function (err, res) {
-        var rev1 = res.rev;
-        doc._rev = rev1;
-        doc.val = '2';
-        db.post(doc, function (err, res) {
-          var rev2 = res.rev;
-          doc._rev = rev2;
-          doc.val = '3';
-          db.post(doc, function (err, res) {
-            var rev3 = res.rev;
-            db.get('doc', { rev: rev1 }, function (err) {
-              err.status.should.equal(404, 'rev-1 should be missing');
-              err.name.should.equal(
-                'not_found', 'rev-1 should be missing'
-              );
-              db.get('doc', { rev: rev2 }, function (err) {
-                err.status.should.equal(404, 'rev-2 should be missing');
-                err.name.should.equal(
-                  'not_found', 'rev-2 should be missing'
-                );
-                db.get('doc', { rev: rev3 }, function (err) {
-                  done(err);
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('#3251 massively parallel autocompaction while getting', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-
-      var doc = {_id: 'foo'};
-
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-      }).then(function () {
-
-        var updatePromise = PouchDB.utils.Promise.resolve();
-
-        for (var i  = 0; i < 20; i++) {
-          /* jshint loopfunc: true */
-          updatePromise = updatePromise.then(function () {
-            return db.put(doc).then(function (res) {
-              doc._rev = res.rev;
-            });
-          });
-        }
-
-        var tasks = [updatePromise];
-        for (var ii = 0; ii < 300; ii++) {
-          /* jshint loopfunc: true */
-          var task = db.get('foo');
-          for (var j =0; j < 10; j++) {
-            task = task.then(function () {
-              return new PouchDB.utils.Promise(function (resolve) {
-                setTimeout(resolve, Math.floor(Math.random() * 10));
-              });
-            }).then(function () {
-              return db.get('foo');
-            });
-          }
-          tasks.push(task);
-        }
-        return PouchDB.utils.Promise.all(tasks);
-      });
-    });
-
-    it('#3251 massively parallel autocompaction while allDocsing', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-
-      var doc = {_id: 'foo'};
-
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-      }).then(function () {
-
-        var updatePromise = PouchDB.utils.Promise.resolve();
-
-        for (var i  = 0; i < 20; i++) {
-          /* jshint loopfunc: true */
-          updatePromise = updatePromise.then(function () {
-            return db.put(doc).then(function (res) {
-              doc._rev = res.rev;
-            });
-          });
-        }
-
-        var tasks = [updatePromise];
-        for (var ii = 0; ii < 300; ii++) {
-          /* jshint loopfunc: true */
-          var task = db.allDocs({key: 'foo', include_docs: true});
-          for (var j =0; j < 10; j++) {
-            task = task.then(function () {
-              return new PouchDB.utils.Promise(function (resolve) {
-                setTimeout(resolve, Math.floor(Math.random() * 10));
-              });
-            }).then(function () {
-              return db.allDocs({key: 'foo', include_docs: true});
-            });
-          }
-          tasks.push(task);
-        }
-        return PouchDB.utils.Promise.all(tasks);
-      });
-    });
-
-    it('#3251 massively parallel autocompaction while changesing', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-
-      var doc = {_id: 'foo'};
-
-      // we know we're going to reach this because of all the changes()
-      // we're doing at once
-      db.setMaxListeners(1000);
-
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-      }).then(function () {
-
-        var updatePromise = PouchDB.utils.Promise.resolve();
-
-        for (var i  = 0; i < 20; i++) {
-          /* jshint loopfunc: true */
-          updatePromise = updatePromise.then(function () {
-            return db.put(doc).then(function (res) {
-              doc._rev = res.rev;
-            });
-          });
-        }
-
-        var tasks = [updatePromise];
-        for (var ii = 0; ii < 300; ii++) {
-          /* jshint loopfunc: true */
-          var task = db.changes({include_docs: true});
-          for (var j =0; j < 10; j++) {
-            task = task.then(function () {
-              return new PouchDB.utils.Promise(function (resolve) {
-                setTimeout(resolve, Math.floor(Math.random() * 10));
-              });
-            }).then(function () {
-              return db.changes({include_docs: true});
-            });
-          }
-          tasks.push(task);
-        }
-        return PouchDB.utils.Promise.all(tasks);
-      });
-    });
-
-    it('#3089 Many orphaned attachments w/ auto-compaction', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var docs = [
-        {
-          _id: 'doc1',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att2.txt': {
-              data: PouchDB.utils.btoa('2'),
-              content_type: 'text/plain'
-            },
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc2',
-          _attachments: {
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc3',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            },
-            'att7.txt': {
-              data: PouchDB.utils.btoa('7'),
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-
-      var digestsToForget;
-      var digestsToRemember;
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var allAtts = {};
-        res.rows.forEach(function (row) {
-          Object.keys(row.doc._attachments).forEach(function (attName) {
-            var att = row.doc._attachments[attName];
-            allAtts[attName] = att.digest;
-          });
-        });
-        digestsToForget = [
-          allAtts['att2.txt'],
-          allAtts['att3.txt'],
-          allAtts['att4.txt'],
-          allAtts['att5.txt']
-        ];
-        digestsToRemember = [
-          allAtts['att1.txt'],
-          allAtts['att6.txt'],
-          allAtts['att7.txt']
-        ];
-        return db.get('doc1');
-      }).then(function (doc1) {
-        return db.remove(doc1);
-      }).then(function () {
-        return db.get('doc2');
-      }).then(function (doc2) {
-        return db.remove(doc2);
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToRemember.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            });
-          }));
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToForget.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              throw new Error('shouldn\'t have gotten here');
-            }, function (err) {
-              err.status.should.equal(412);
-            });
-          }));
-      });
-    });
-
-    it('#3089 Many orphaned atts w/ parallel auto-compaction', function () {
-      // now that we've established md5sum collisions,
-      // we can use that to detect true attachment replacement
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var docs = [
-        {
-          _id: 'doc1',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att2.txt': {
-              data: PouchDB.utils.btoa('2'),
-              content_type: 'text/plain'
-            },
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc2',
-          _attachments: {
-            'att3.txt': {
-              data: PouchDB.utils.btoa('3'),
-              content_type: 'text/plain'
-            },
-            'att4.txt': {
-              data: PouchDB.utils.btoa('4'),
-              content_type: 'text/plain'
-            },
-            'att5.txt': {
-              data: PouchDB.utils.btoa('5'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            }
-          }
-        }, {
-          _id: 'doc3',
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            },
-            'att6.txt': {
-              data: PouchDB.utils.btoa('6'),
-              content_type: 'text/plain'
-            },
-            'att7.txt': {
-              data: PouchDB.utils.btoa('7'),
-              content_type: 'text/plain'
-            }
-          }
-        }
-      ];
-
-      var digestsToForget;
-      var digestsToRemember;
-      return db.bulkDocs(docs).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        var allAtts = {};
-        res.rows.forEach(function (row) {
-          Object.keys(row.doc._attachments).forEach(function (attName) {
-            var att = row.doc._attachments[attName];
-            allAtts[attName] = att.digest;
-          });
-        });
-        digestsToForget = [
-          allAtts['att2.txt'],
-          allAtts['att3.txt'],
-          allAtts['att4.txt'],
-          allAtts['att5.txt']
-        ];
-        digestsToRemember = [
-          allAtts['att1.txt'],
-          allAtts['att6.txt'],
-          allAtts['att7.txt']
-        ];
-        return db.allDocs({keys: ['doc1', 'doc2']});
-      }).then(function (res) {
-        var docs = res.rows.map(function (row) {
-          return {
-            _deleted: true,
-            _id: row.id,
-            _rev: row.value.rev
-          };
-        });
-        return db.bulkDocs(docs);
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToRemember.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            });
-          }));
-      }).then(function () {
-        return PouchDB.utils.Promise.all(
-          digestsToForget.map(function (digest) {
-            return db.post({
-              _attachments: {
-                'baz.txt' : {
-                  stub: true,
-                  digest: digest,
-                  content_type: 'text/plain'
-                }
-              }
-            }).then(function () {
-              throw new Error('shouldn\'t have gotten here');
-            }, function (err) {
-              err.status.should.equal(412);
-            });
-          }));
-      });
-    });
-
-    it('#3089 Auto-compaction retains atts if unorphaned', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {
-        _id: 'doc1',
-        _attachments: {
-          'deleteme.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      };
-      var digest;
-      return db.put(doc).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        digest = doc._attachments['deleteme.txt'].digest;
-        delete doc._attachments['deleteme.txt'];
-        doc._attachments['retainme.txt'] = {
-          data: 'dG90bw==', // 'toto'
-          content_type: 'text/plain'
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.put({
-          _id: 'doc2',
-          _attachments: {
-            'nodontdeleteme.txt': {
-              data: 'Zm9vYmFy', // 'foobar'
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }).then(function () {
-        return db.get('doc1');
-      }).then(function (doc) {
-        doc._attachments['newatt.txt'] = {
-          content_type: "text/plain",
-          digest: digest,
-          stub: true
-        };
-        return db.put(doc);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        // ok, now let's really delete them
-        var docs = [
-          {
-            _id: 'doc1',
-            _rev: res.rows[0].value.rev
-          },
-          {
-            _id: 'doc2',
-            _rev: res.rows[1].value.rev
-          }
-        ];
-        return db.bulkDocs(docs);
-      }).then(function () {
-        var doc = {
-          _attachments: {
-            'foo.txt': {
-              content_type: "text/plain",
-              digest: digest,
-              stub: true
-            }
-          }
-        };
-        return db.post(doc).then(function () {
-          throw new Error('shouldn\'t have gotten here');
-        }, function (err) {
-          err.status.should.equal(412);
-        });
-      });
-    });
-
-    it('#2818 successive new_edits okay with attachments', function () {
-      var db = new PouchDB(dbs.name);
-      var docs = [{
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        },
-        _attachments: {
-          'att.txt': {
-            data: 'Zm9vYmFy', // 'foobar'
-            content_type: 'text/plain'
-          }
-        }
-      }];
-      var digest;
-      return db.bulkDocs({docs: docs, new_edits: false}).then(function () {
-        return db.bulkDocs({docs: docs, new_edits: false});
-      }).then(function () {
-        return db.get('foo', {attachments: true});
-      }).then(function (doc) {
-        doc._rev.should.equal('1-x');
-        digest = doc._attachments['att.txt'].digest;
-      }).then(function () {
-        var doc = {
-          _attachments: {
-            'foo.txt': {
-              content_type: "text/plain",
-              digest: digest,
-              stub: true
-            }
-          }
-        };
-        return db.post(doc);
-      });
-    });
-
-    it('Auto-compaction removes non-leaf revs (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(1);
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(2);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-      });
-    });
-
-    it('Auto-compaction removes non-leaf revs pt 2 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('Auto-compaction removes non-leaf revs pt 3 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-
-      var docs = [
-        {
-          _id: 'foo',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'foo',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'foo',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }, {
-          _id: 'foo',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }
-      ];
-
-      return db.bulkDocs(docs, {new_edits: false}).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(4);
-        var asMap = {};
-        docsAndRevs.forEach(function (docAndRev) {
-          asMap[docAndRev.rev] = docAndRev.doc;
-        });
-        // only leafs remain
-        should.not.exist(asMap['1-a1']);
-        should.not.exist(asMap['2-a2']);
-        should.exist(asMap['3-a3']);
-        should.exist(asMap['1-b1']);
-      });
-    });
-
-    it('Auto-compaction removes non-leaf revs pt 4 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        doc._deleted = true;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        delete doc._deleted;
-        return db.put(doc);
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('Auto-compaction removes non-leaf revs pt 5 (#2807)', function () {
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        doc._deleted = true;
-        return db.put(doc);
-      }).then(function () {
-        return getRevisions(db, 'foo');
-      }).then(function (docsAndRevs) {
-        docsAndRevs.should.have.length(3);
-        should.exist(docsAndRevs[0].doc);
-        should.not.exist(docsAndRevs[1].doc);
-        should.not.exist(docsAndRevs[2].doc);
-      });
-    });
-
-    it('#3089 Same att orphaned by many docs, auto-compact', function () {
-      // In this test, a single attachment is shared by many docs,
-      // which are all deleted in a single bulkDocs. This is to
-      // hunt down race conditions in our orphan compaction.
-
-      var db = new PouchDB(dbs.name, {auto_compaction: true});
-
-      var docs = [];
-      for (var i = 0; i < 100; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'att1.txt': {
-              data: PouchDB.utils.btoa('1'),
-              content_type: 'text/plain'
-            }
-          }
-        });
-      }
-
-      return db.bulkDocs(docs).then(function (results) {
-        results.forEach(function (res, i) {
-          docs[i]._rev = res.rev;
-        });
-        return db.get(docs[0]._id);
-      }).then(function (doc) {
-        var digest = doc._attachments['att1.txt'].digest;
-        docs.forEach(function (doc) {
-          doc._deleted = true;
-        });
-        return db.bulkDocs(docs).then(function () {
-          return db.post({
-            _attachments: {
-              'baz.txt' : {
-                stub: true,
-                digest: digest,
-                content_type: 'text/plain'
-              }
-            }
-          }).then(function () {
-            throw new Error('shouldn\'t have gotten here');
-          }, function (err) {
-            err.status.should.equal(412);
-          });
-        });
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.conflicts.js b/tests/integration/test.conflicts.js
deleted file mode 100644
index 9134500..0000000
--- a/tests/integration/test.conflicts.js
+++ /dev/null
@@ -1,534 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.conflicts.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('Testing conflicts', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: 'foo', a: 1, b: 1};
-      db.put(doc, function (err, res) {
-        doc._rev = res.rev;
-        should.exist(res.ok, 'Put first document');
-        db.get('foo', function (err, doc2) {
-          doc._id.should.equal(doc2._id);
-          doc.should.have.property('_rev');
-          doc2.should.have.property('_rev');
-          doc.a = 2;
-          doc2.a = 3;
-          db.put(doc, function (err, res) {
-            should.exist(res.ok, 'Put second doc');
-            db.put(doc2, function (err) {
-              err.name.should.equal('conflict', 'Put got a conflicts');
-              db.changes().on('complete', function (results) {
-                results.results.should.have.length(1);
-                doc2._rev = undefined;
-                db.put(doc2, function (err) {
-                  err.name.should.equal('conflict', 'Another conflict');
-                  done();
-                });
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing conflicts', function (done) {
-      var doc = {_id: 'fubar', a: 1, b: 1};
-      var db = new PouchDB(dbs.name);
-      db.put(doc, function (err, ndoc) {
-        doc._rev = ndoc.rev;
-        db.remove(doc, function () {
-          delete doc._rev;
-          db.put(doc, function (err, ndoc) {
-            if (err) {
-              return done(err);
-            }
-            should.exist(ndoc.ok, 'written previously deleted doc without rev');
-            done();
-          });
-        });
-      });
-    });
-
-    it('#2882/#2883 last_seq for empty db', function () {
-      // CouchDB 2.0 sequence numbers are not
-      // incremental so skip this test
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      return db.changes().then(function (changes) {
-        changes.last_seq.should.equal(0);
-        changes.results.should.have.length(0);
-        return db.info();
-      }).then(function (info) {
-        info.update_seq.should.equal(0);
-      });
-    });
-
-    it('#2882/#2883 last_seq when putting parent before leaf', function () {
-      // CouchDB 2.0 sequence numbers are not
-      // incremental so skip this test
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-
-      var db = new PouchDB(dbs.name);
-      var lastSeq;
-      return db.bulkDocs({
-        docs: [
-          {
-            _id: 'fubar',
-            _rev: '2-a2',
-            _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-          }, {
-            _id: 'fubar',
-            _rev: '1-a1',
-            _revisions: { start: 1, ids: [ 'a1' ] }
-          }
-        ],
-        new_edits: false
-      }).then(function () {
-        return db.changes();
-      }).then(function (changes) {
-        lastSeq = changes.last_seq;
-        changes.results[0].changes[0].rev.should.equal('2-a2');
-        changes.results[0].seq.should.equal(lastSeq);
-        return db.info();
-      }).then(function (info) {
-        info.update_seq.should.equal(lastSeq);
-      });
-    });
-
-    // Each revision includes a list of previous revisions. The
-    // revision with the longest revision history list becomes the
-    // winning revision. If they are the same, the _rev values are
-    // compared in ASCII sort order, and the highest wins. So, in our
-    // example, 2-de0ea16f8621cbac506d23a0fbbde08a beats
-    // 2-7c971bb974251ae8541b8fe045964219.
-
-    it('Conflict resolution 1', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '1-a',
-          _revisions: {
-            start: 1,
-            ids: [ 'a' ]
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b',
-          _revisions: {
-            start: 1,
-            ids: [ 'b' ]
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '1-1',
-          _revisions: {
-            start: 1,
-            ids: [ '1' ]
-          }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('1-b', 'Correct revision wins');
-        return db.bulkDocs({
-          new_edits: false,
-          docs: [{
-            _id: 'fubar',
-            _rev: '2-2',
-            _revisions: {
-              start: 2,
-              ids: [ '2', '1' ]
-            }
-          }]
-        });
-      }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('2-2', 'Correct revision wins');
-      });
-    });
-
-    it('Conflict resolution 2', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '2-a',
-          _revisions: {
-            start: 2,
-            ids: [ 'a' ]
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b',
-          _revisions: {
-            start: 1,
-            ids: [ 'b' ]
-          }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('2-a', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 3', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '10-a',
-          _revisions: {
-            start: 10,
-            ids: [ 'a' ]
-          }
-        }, {
-          _id: 'fubar',
-          _rev: '2-b',
-          _revisions: {
-            start: 2,
-            ids: [ 'b' ]
-          }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('10-a', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 4-a', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('1-b1', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 4-b', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('1-b1', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 4-c', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-          doc._rev.should.equal('1-b1', 'Correct revision wins');
-          return db.info();
-        }).then(function (info) {
-          info.doc_count.should.equal(1, 'Correct number of docs');
-        });
-    });
-
-    it('Conflict resolution 4-d', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('1-b1', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 4-e', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '3-a3',
-          _revisions: { start: 3, ids: [ 'a3', 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '1-a1',
-          _revisions: { start: 1, ids: [ 'a1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('1-b1', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 5-a', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-c1',
-          _revisions: { start: 1, ids: [ 'c1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('2-a2', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 5-b', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-c1',
-          _revisions: { start: 1, ids: [ 'c1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('2-a2', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('Conflict resolution 5-c', function () {
-      var docs = [
-        {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-b1',
-          _revisions: { start: 1, ids: [ 'b1' ] }
-        }, {
-          _id: 'fubar',
-          _deleted: true,
-          _rev: '1-c1',
-          _revisions: { start: 1, ids: [ 'c1' ] }
-        }, {
-          _id: 'fubar',
-          _rev: '2-a2',
-          _revisions: { start: 2, ids: [ 'a2', 'a1' ] }
-        }
-      ];
-      var db = new PouchDB(dbs.name);
-      return db.bulkDocs({ docs: docs, new_edits: false }).then(function () {
-        return db.get('fubar');
-      }).then(function (doc) {
-        doc._rev.should.equal('2-a2', 'Correct revision wins');
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(1, 'Correct number of docs');
-      });
-    });
-
-    it('#2543 excessive recursion with merging', function () {
-      var chain = PouchDB.utils.Promise.resolve();
-
-      var db = new PouchDB(dbs.name);
-
-      function addTask(batch) {
-        return function () {
-          var docs = [];
-          for (var i = 0; i < 50; i++) {
-            var hash = batch + 'a' +  i;
-            docs.push({
-              _id: 'foo',
-              _rev: '2-' + hash,
-              _revisions: {
-                start: 2,
-                ids: [hash, 'a']
-              }
-            });
-          }
-          return db.bulkDocs(docs, {new_edits: false});
-        };
-      }
-
-      chain = chain.then(function () {
-        return db.bulkDocs([{
-          _id: 'foo',
-          _rev: '1-a'
-        }], {new_edits: false});
-      });
-
-      for (var i = 0; i < 10; i++) {
-        chain = chain.then(addTask(i));
-      }
-      return chain;
-    });
-
-    it('local conflicts', function (done) {
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-      var db = new PouchDB(dbs.name);
-      return db.put({foo: 'bar'}, '_local/baz').then(function (result) {
-        return db.put({foo: 'bar'}, '_local/baz', result.res);
-      }).then(function () {
-        return db.put({foo: 'bar'}, '_local/baz');
-      }, function (e) {
-        should.not.exist(e, 'shouldn\'t error yet');
-        done(e);
-      }).then(undefined, function (e) {
-        should.exist(e, 'error when you have a conflict');
-        done();
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.constructor.js b/tests/integration/test.constructor.js
deleted file mode 100644
index 844e17d..0000000
--- a/tests/integration/test.constructor.js
+++ /dev/null
@@ -1,64 +0,0 @@
-'use strict';
-
-describe('constructor errors', function () {
-  it('should error on an undefined name', function (done) {
-    var notAName;
-    new PouchDB(notAName, function (err, db) {
-      should.exist(err);
-      done(db);
-    });
-  });
-  it('should error on an undefined adapter', function (done) {
-    new PouchDB('foo', {adapter : 'myFakeAdapter'}, function (err, db) {
-      should.exist(err);
-      err.message.should
-        .equal('Adapter is missing',
-               'should give the correct error message');
-      done(db);
-    });
-  });
-  it('should error on a null name', function (done) {
-    var notAName = null;
-    new PouchDB(notAName).then(done, function (err) {
-      should.exist(err);
-      err.message.should
-        .equal('Missing/invalid DB name',
-               'should give the correct error message');
-      done();
-    });
-  });
-  describe('it should always return methods', function () {
-    it('put', function (done) {
-      new PouchDB().put({
-        _id: 'lala'
-      }, function (err, resp) {
-        should.exist(err);
-        err.message.should
-          .equal('Missing/invalid DB name',
-                 'should give the correct error message');
-        done(resp);
-      });
-    });
-    it('post', function (done) {
-      new PouchDB().post({
-        something: 'lala'
-      }).then(done, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-    it('get', function (done) {
-      var nothing;
-      new PouchDB(nothing).get('something', function (err, resp) {
-        should.exist(err);
-        done(resp);
-      });
-    });
-    it('allDocs', function (done) {
-      new PouchDB().allDocs().then(done, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.defaults.js b/tests/integration/test.defaults.js
deleted file mode 100644
index 60df103..0000000
--- a/tests/integration/test.defaults.js
+++ /dev/null
@@ -1,194 +0,0 @@
-'use strict';
-if (!process.env.LEVEL_ADAPTER &&
-    !process.env.LEVEL_PREFIX && !process.env.AUTO_COMPACTION) {
-  // these tests don't make sense for anything other than default leveldown
-  var path = require('path');
-  var mkdirp = require('mkdirp');
-  var rimraf = require('rimraf');
-
-  describe('defaults', function () {
-
-    beforeEach(function () {
-      return new PouchDB('mydb').destroy().then(function () {
-        return new PouchDB('mydb', {db: require('memdown')}).destroy();
-      });
-    });
-
-    afterEach(function (done) {
-      rimraf.sync('./tmp/_pouch_.');
-      rimraf.sync('./tmp/path');
-      done();
-    });
-
-    it('should allow prefixes', function () {
-      var prefix = './tmp/path/to/db/1/';
-      var dir = path.join(prefix, '/tmp/');
-      var dir2 = path.join('./tmp/_pouch_./', prefix);
-      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
-      mkdirp.sync(dir);
-      mkdirp.sync(dir2);
-      mkdirp.sync(dir3);
-
-      return new PouchDB('mydb', {
-        prefix: prefix
-      }).then(function (db) {
-        return db.info().then(function (info1) {
-          info1.db_name.should.equal('mydb');
-          return db.destroy();
-        });
-      });
-    });
-
-    it('should allow us to set a prefix by default', function () {
-      var prefix = './tmp/path/to/db/2/';
-      var dir = path.join(prefix, '/tmp/');
-      var dir2 = path.join('./tmp/_pouch_./', prefix);
-      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
-      mkdirp.sync(dir);
-      mkdirp.sync(dir2);
-      mkdirp.sync(dir3);
-
-      var CustomPouch = PouchDB.defaults({
-        prefix: prefix
-      });
-      /* jshint newcap:false */
-      var db = CustomPouch({name: 'mydb'});
-      return db.info().then(function (info1) {
-        info1.db_name.should.equal('mydb');
-        return db.destroy();
-      });
-    });
-
-    it('should allow us to use memdown', function () {
-      var opts = { name: 'mydb', db: require('memdown') };
-      return new PouchDB(opts).then(function (db) {
-        return db.put({_id: 'foo'}).then(function () {
-          return new PouchDB('mydb').then(function (otherDB) {
-            return db.info().then(function (info1) {
-              return otherDB.info().then(function (info2) {
-                info1.doc_count.should.not.equal(info2.doc_count);
-                return otherDB.destroy();
-              }).then(function () {
-                return db.destroy();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should allow us to destroy memdown', function () {
-      var opts = {db: require('memdown') };
-      return new PouchDB('mydb', opts).then(function (db) {
-        return db.put({_id: 'foo'}).then(function () {
-          return new PouchDB('mydb', opts).then(function (otherDB) {
-            return db.info().then(function (info1) {
-              return otherDB.info().then(function (info2) {
-                info1.doc_count.should.equal(info2.doc_count);
-                return otherDB.destroy();
-              }).then(function () {
-                return new PouchDB('mydb', opts).then(function (db3) {
-                  return db3.info().then(function (info) {
-                    info.doc_count.should.equal(0);
-                    return db3.destroy();
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should allow us to use memdown by default', function () {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-      return new CustomPouch('mydb').then(function (db) {
-        return db.put({_id: 'foo'}).then(function () {
-          return new PouchDB('mydb').then(function (otherDB) {
-            return db.info().then(function (info1) {
-              return otherDB.info().then(function (info2) {
-                info1.doc_count.should.not.equal(info2.doc_count);
-                return otherDB.destroy();
-              }).then(function () {
-                return db.destroy();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should inform us when using memdown', function () {
-      var opts = { name: 'mydb', db: require('memdown') };
-      return new PouchDB(opts).then(function (db) {
-        return db.info().then(function (info) {
-          info.backend_adapter.should.equal('MemDOWN');
-        });
-      });
-    });
-
-    it('constructor emits destroyed when using defaults', function () {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-
-      return new CustomPouch('mydb').then(function (db) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          CustomPouch.once('destroyed', function (name) {
-            name.should.equal('mydb');
-            resolve();
-          });
-          db.destroy();
-        });
-      });
-    });
-
-    it('db emits destroyed when using defaults', function () {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-
-      return new CustomPouch('mydb').then(function (db) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          db.once('destroyed', resolve);
-          db.destroy();
-        });
-      });
-    });
-
-    it('constructor emits creation event', function (done) {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-
-      CustomPouch.once('created', function (name) {
-        name.should.equal('mydb', 'should be same thing');
-        done();
-      });
-      new PouchDB('mydb');
-    });
-
-    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
-    // but better to test it explicitly
-    it('PouchDB emits destroyed when using defaults', function () {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-
-      return new CustomPouch('mydb').then(function (db) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          PouchDB.once('destroyed', function (name) {
-            name.should.equal('mydb');
-            resolve();
-          });
-          db.destroy();
-        });
-      });
-    });
-
-    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
-    // but better to test it explicitly
-    it('PouchDB emits created when using defaults', function (done) {
-      var CustomPouch = PouchDB.defaults({db: require('memdown')});
-
-      PouchDB.once('created', function (name) {
-        name.should.equal('mydb', 'should be same thing');
-        done();
-      });
-      new CustomPouch('mydb');
-    });
-
-  });
-}
diff --git a/tests/integration/test.design_docs.js b/tests/integration/test.design_docs.js
deleted file mode 100644
index 408438d..0000000
--- a/tests/integration/test.design_docs.js
+++ /dev/null
@@ -1,120 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.design_docs.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    var doc = {
-      _id: '_design/foo',
-      views: {
-        scores: {
-          map: 'function (doc) { if (doc.score) { emit(null, doc.score); } }',
-          reduce: 'function (keys, values, rereduce) { return sum(values); }'
-        }
-      },
-      filters: { even: 'function (doc) { return doc.integer % 2 === 0; }' }
-    };
-
-    it('Test writing design doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post(doc, function (err) {
-        should.not.exist(err, 'Wrote design doc');
-        db.get('_design/foo', function (err) {
-          done(err);
-        });
-      });
-    });
-
-    it('Changes filter', function (done) {
-      var docs1 = [
-        doc,
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '4', integer: 4},
-        {_id: '5', integer: 5},
-        {_id: '6', integer: 6},
-        {_id: '7', integer: 7}
-      ];
-
-      var db = new PouchDB(dbs.name);
-      var count = 0;
-      db.bulkDocs({ docs: docs1 }, function () {
-        var changes = db.changes({
-          live: true,
-          filter: 'foo/even'
-        }).on('change', function () {
-          count += 1;
-          if (count === 4) {
-            changes.cancel();
-          }
-        }).on('complete', function (result) {
-          result.status.should.equal('cancelled');
-          done();
-        }).on('error', done);
-        db.bulkDocs({ docs: docs2 }, {});
-      });
-    });
-
-    it('Basic views', function (done) {
-      var docs1 = [
-        doc,
-        {_id: 'dale', score: 3},
-        {_id: 'mikeal', score: 5},
-        {_id: 'max', score: 4},
-        {_id: 'nuno', score: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs1 }, function () {
-        db.query('foo/scores', { reduce: false }, function (err, result) {
-          result.rows.should.have.length(4, 'Correct # of results');
-          db.query('foo/scores', function (err, result) {
-            result.rows[0].value.should.equal(15, 'Reduce gave correct result');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Concurrent queries', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          doc,
-          {_id: 'dale', score: 3}
-        ]
-      }, function () {
-        var cnt = 0;
-        db.query('foo/scores', { reduce: false }, function (err, result) {
-          result.rows.should.have.length(1, 'Correct # of results');
-          if (++cnt === 2) {
-            done();
-          }
-        });
-        db.query('foo/scores', { reduce: false }, function (err, result) {
-          result.rows.should.have.length(1, 'Correct # of results');
-          if (++cnt === 2) {
-            done();
-          }
-        });
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.events.js b/tests/integration/test.events.js
deleted file mode 100644
index 924ad92..0000000
--- a/tests/integration/test.events.js
+++ /dev/null
@@ -1,113 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-
-adapters.forEach(function (adapter) {
-  describe('test.events.js-' + adapter, function () {
-
-    var dbs = {};
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('PouchDB emits creation event', function (done) {
-      PouchDB.once('created', function (name) {
-        name.should.equal(dbs.name, 'should be same thing');
-        done();
-      });
-      new PouchDB(dbs.name);
-    });
-
-    it('PouchDB emits destruction event', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        db.destroy();
-      }).once('destroyed', function () {
-        new PouchDB(dbs.name, function () {
-          done();
-        });
-      });
-    });
-
-    it('PouchDB emits destruction event on PouchDB object', function (done) {
-      PouchDB.once('destroyed', function (name) {
-        name.should.equal(dbs.name, 'should have the same name');
-        new PouchDB(dbs.name, function () {
-          done();
-        });
-      });
-      new PouchDB(dbs.name, function (err, db) {
-        db.destroy();
-      });
-    });
-
-    it('PouchDB emits destroyed when using {name: foo}', function () {
-      return new PouchDB({name: 'testdb'}).then(function (db) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          PouchDB.once('destroyed', function (name) {
-            name.should.equal('testdb');
-            resolve();
-          });
-          db.destroy();
-        });
-      });
-    });
-
-    it('db emits destroyed on all DBs', function () {
-      var db1 = new PouchDB('testdb');
-      var db2 = new PouchDB('testdb');
-
-      return new PouchDB.utils.Promise(function (resolve) {
-        var called = 0;
-        function checkDone() {
-          if (++called === 2) {
-            resolve();
-          }
-        }
-        db1.once('destroyed', checkDone);
-        db2.once('destroyed', checkDone);
-        db1.destroy();
-      });
-    });
-
-    it('3900 db emits destroyed event', function () {
-      return new PouchDB('testdb').then(function (db) {
-        return new PouchDB.utils.Promise(function (resolve) {
-          db.once('destroyed', function () {
-            resolve();
-          });
-          db.destroy();
-        });
-      });
-    });
-
-    it('3900 db emits destroyed event 2', function () {
-      var db = new PouchDB('testdb');
-      return new PouchDB.utils.Promise(function (resolve) {
-        db.once('destroyed', function () {
-          resolve();
-        });
-        db.destroy();
-      });
-    });
-
-    it('emit creation event', function (done) {
-      var db = new PouchDB(dbs.name).on('created', function (newDB) {
-        db.should.equal(newDB, 'should be same thing');
-        done();
-      });
-    });
-
-    it('#4168 multiple constructor calls don\'t leak listeners', function () {
-      for (var i = 0; i < 50; i++) {
-        new PouchDB(dbs.name);
-      }
-    });
-
-  });
-});
diff --git a/tests/integration/test.get.js b/tests/integration/test.get.js
deleted file mode 100644
index 8627237..0000000
--- a/tests/integration/test.get.js
+++ /dev/null
@@ -1,738 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.get.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    var origDocs = [
-      {_id: '0', a: 1, b: 1},
-      {_id: '3', a: 4, b: 16},
-      {_id: '1', a: 2, b: 4},
-      {_id: '2', a: 3, b: 9}
-    ];
-
-    it('Get doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        db.get(info.id, function (err, doc) {
-          doc.should.have.property('test');
-          db.get(info.id + 'asdf', function (err) {
-            err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                    'correct error status returned');
-            err.name.should.equal(PouchDB.Errors.MISSING_DOC.name,
-                                  'correct error name returned');
-            err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                    'correct error message returned');
-            // todo: does not work in pouchdb-server.
-            // err.reason.should.equal(PouchDB.Errors.MISSING_DOC.reason,
-            //                           'correct error reason returned');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Get design doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({
-        _id: '_design/someid',
-        test: 'somestuff'
-      }, function (err, info) {
-        db.get(info.id, function () {
-          db.get(info.id + 'asdf', function (err) {
-            err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                    'correct error status returned');
-            err.name.should.equal(PouchDB.Errors.MISSING_DOC.name,
-                                  'correct error name returned');
-            err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                    'correct error message returned');
-            // todo: does not work in pouchdb-server.
-            // err.reason.should.equal(PouchDB.Errors.MISSING_DOC.reason,
-            //                           'correct error reason returned');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Check error of deleted document', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        db.remove({
-          _id: info.id,
-          _rev: info.rev
-        }, function () {
-          db.get(info.id, function (err) {
-            err.status.should.equal(PouchDB.Errors.MISSING_DOC.status,
-                                      'correct error status returned');
-            err.name.should.equal(PouchDB.Errors.MISSING_DOC.name,
-                                      'correct error name returned');
-            err.message.should.equal(PouchDB.Errors.MISSING_DOC.message,
-                                      'correct error message returned');
-            // todo: does not work in pouchdb-server.
-            // err.reason.should.equal(PouchDB.Errors.MISSING_DOC.reason,
-            //                          'correct error reason returned');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Get revisions of removed doc', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      db.post({ test: 'somestuff' }, function (err, info) {
-        var rev = info.rev;
-        db.remove({
-          test: 'somestuff',
-          _id: info.id,
-          _rev: info.rev
-        }, function () {
-          db.get(info.id, { rev: rev }, function (err) {
-            should.not.exist(err);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Testing get with rev', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-          function () {
-          db.get('3', function (err, parent) {
-            // add conflicts
-            var pRevId = parent._rev.split('-')[1];
-            var conflicts = [
-              {
-                _id: '3',
-                _rev: '2-aaa',
-                value: 'x',
-                _revisions: {
-                  start: 2,
-                  ids: [
-                    'aaa',
-                    pRevId
-                  ]
-                }
-              },
-              {
-                _id: '3',
-                _rev: '3-bbb',
-                value: 'y',
-                _deleted: true,
-                _revisions: {
-                  start: 3,
-                  ids: [
-                    'bbb',
-                    'some',
-                    pRevId
-                  ]
-                }
-              },
-              {
-                _id: '3',
-                _rev: '4-ccc',
-                value: 'z',
-                _revisions: {
-                  start: 4,
-                  ids: [
-                    'ccc',
-                    'even',
-                    'more',
-                    pRevId
-                  ]
-                }
-              }
-            ];
-            db.put(conflicts[0], { new_edits: false }, function () {
-              db.put(conflicts[1], { new_edits: false }, function () {
-                db.put(conflicts[2], { new_edits: false }, function () {
-                  db.get('3', { rev: '2-aaa' }, function (err, doc) {
-                    doc._rev.should.equal('2-aaa');
-                    doc.value.should.equal('x');
-                    db.get('3', { rev: '3-bbb' }, function (err, doc) {
-                      doc._rev.should.equal('3-bbb');
-                      doc.value.should.equal('y');
-                      db.get('3', { rev: '4-ccc' }, function (err, doc) {
-                        doc._rev.should.equal('4-ccc');
-                        doc.value.should.equal('z');
-                        done();
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing rev format', function (done) {
-      var revs = [];
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        revs.unshift(info.rev.split('-')[1]);
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test1'
-        }, function (err, info2) {
-          revs.unshift(info2.rev.split('-')[1]);
-          db.put({
-            _id: info.id,
-            _rev: info2.rev,
-            last: 'test2'
-          }, function (err, info3) {
-            revs.unshift(info3.rev.split('-')[1]);
-            db.get(info.id, { revs: true }, function (err, doc) {
-              doc._revisions.start.should.equal(3);
-              revs.should.deep.equal(doc._revisions.ids);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test opts.revs=true with rev other than winning', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var docs = [
-        {_id: 'foo', _rev: '1-a', value: 'foo a'},
-        {_id: 'foo', _rev: '2-b', value: 'foo b'},
-        {_id: 'foo', _rev: '3-c', value: 'foo c'},
-        {_id: 'foo', _rev: '4-d', value: 'foo d'}
-      ];
-      testUtils.putBranch(db, docs, function () {
-        db.get('foo', {
-          rev: '3-c',
-          revs: true
-        }, function (err, doc) {
-          doc._revisions.ids.length.should.equal(3, 'correct revisions length');
-          doc._revisions.start.should.equal(3, 'correct revisions start');
-          doc._revisions.ids[0].should.equal('c', 'correct rev');
-          doc._revisions.ids[1].should.equal('b', 'correct rev');
-          doc._revisions.ids[2].should.equal('a', 'correct rev');
-          done();
-        });
-      });
-    });
-
-    it('Test opts.revs=true return only winning branch', function (done) {
-      var db = new PouchDB(dbs.name);
-      var simpleTree = [
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-b', value: 'foo b'},
-         {_id: 'foo', _rev: '3-c', value: 'foo c'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-d', value: 'foo d'},
-         {_id: 'foo', _rev: '3-e', value: 'foo e'},
-         {_id: 'foo', _rev: '4-f', value: 'foo f'}
-        ]
-      ];
-      testUtils.putTree(db, simpleTree, function () {
-        db.get('foo', { revs: true }, function (err, doc) {
-          doc._revisions.ids.length.should.equal(4, 'correct revisions length');
-          doc._revisions.start.should.equal(4, 'correct revisions start');
-          doc._revisions.ids[0].should.equal('f', 'correct rev');
-          doc._revisions.ids[1].should.equal('e', 'correct rev');
-          doc._revisions.ids[2].should.equal('d', 'correct rev');
-          doc._revisions.ids[3].should.equal('a', 'correct rev');
-          done();
-        });
-      });
-    });
-
-    it('Test get with simple revs_info', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err, info) {
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }, function (err, info) {
-          db.put({
-            _id: info.id,
-            _rev: info.rev,
-            a: 'change'
-          }, function () {
-            db.get(info.id, { revs_info: true }, function (err, doc) {
-              doc._revs_info.length.should.equal(3, 'updated a doc with put');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test get with revs_info on tree', function (done) {
-      var db = new PouchDB(dbs.name);
-      var simpleTree = [
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-b', value: 'foo b'},
-         {_id: 'foo', _rev: '3-c', value: 'foo c'}],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-d', value: 'foo d'},
-         {_id: 'foo', _rev: '3-e', _deleted: true}]
-      ];
-      testUtils.putTree(db, simpleTree, function () {
-        db.get('foo', { revs_info: true }, function (err, doc) {
-          var revs = doc._revs_info;
-          revs.length.should.equal(3, 'correct number of revs');
-          revs[0].rev.should.equal('3-c', 'rev ok');
-          revs[1].rev.should.equal('2-b', 'rev ok');
-          revs[2].rev.should.equal('1-a', 'rev ok');
-          done();
-        });
-      });
-    });
-
-    it('Test get with revs_info on compacted tree', function (done) {
-      // _compact endpoint is not exposed in CouchDB 2.0
-      // (it's exposed via a private port). Skip
-      // this test for now
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-
-      var db = new PouchDB(dbs.name);
-      var simpleTree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            value: 'foo a'
-          },
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            value: 'foo d'
-          },
-          {
-            _id: 'foo',
-            _rev: '3-c',
-            value: 'foo c'
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            value: 'foo a'
-          },
-          {
-            _id: 'foo',
-            _rev: '2-d',
-            value: 'foo d'
-          },
-          {
-            _id: 'foo',
-            _rev: '3-e',
-            _deleted: true
-          }
-        ]
-      ];
-      testUtils.putTree(db, simpleTree, function () {
-        db.compact(function () {
-          db.get('foo', { revs_info: true }, function (err, doc) {
-            var revs = doc._revs_info;
-            revs.length.should.equal(3, 'correct number of revs');
-            revs[0].rev.should.equal('3-c', 'rev ok');
-            revs[0].status.should.equal('available', 'not compacted');
-            revs[1].rev.should.equal('2-b', 'rev ok');
-            revs[1].status.should.equal('missing', 'compacted');
-            revs[2].rev.should.equal('1-a', 'rev ok');
-            revs[2].status.should.equal('missing', 'compacted');
-            done();
-          });
-        });
-      });
-    });
-
-    it('#2951 Parallelized gets with 409s/404s', function () {
-      var db = new PouchDB(dbs.name);
-
-      var numSimultaneous = 20;
-      var numDups = 3;
-
-      var tasks = [];
-
-      for (var i = 0; i < numSimultaneous; i++) {
-        var key = Math.random().toString();
-        for (var j = 0; j < numDups; j++) {
-          tasks.push(key);
-        }
-      }
-
-      function getDocWithDefault(db, id, defaultDoc) {
-        return db.get(id).catch(function (err) {
-          /* istanbul ignore if */
-          if (err.status !== 404) {
-            throw err;
-          }
-          defaultDoc._id = id;
-          return db.put(defaultDoc).catch(function (err) {
-            /* istanbul ignore if */
-            if (err.status !== 409) { // conflict
-              throw err;
-            }
-          }).then(function () {
-            return db.get(id);
-          });
-        });
-      }
-
-      return PouchDB.utils.Promise.all(tasks.map(function (task) {
-        return getDocWithDefault(db, task, {foo: 'bar'});
-      }));
-    });
-
-    it('#2951 Parallelized _local gets with 409s/404s', function () {
-      var db = new PouchDB(dbs.name);
-
-      var numSimultaneous = 20;
-      var numDups = 3;
-
-      var tasks = [];
-
-      for (var i = 0; i < numSimultaneous; i++) {
-        var key = Math.random().toString();
-        for (var j = 0; j < numDups; j++) {
-          tasks.push('_local/' + key);
-        }
-      }
-
-      function getDocWithDefault(db, id, defaultDoc) {
-        return db.get(id).catch(function (err) {
-          /* istanbul ignore if */
-          if (err.status !== 404) {
-            throw err;
-          }
-          defaultDoc._id = id;
-          return db.put(defaultDoc).catch(function (err) {
-            /* istanbul ignore if */
-            if (err.status !== 409) { // conflict
-              throw err;
-            }
-          }).then(function () {
-            return db.get(id);
-          });
-        });
-      }
-
-      return PouchDB.utils.Promise.all(tasks.map(function (task) {
-        return getDocWithDefault(db, task, {foo: 'bar'});
-      }));
-    });
-
-    it('Test get with conflicts', function (done) {
-      var db = new PouchDB(dbs.name);
-      var simpleTree = [
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            value: 'foo a'
-          },
-          {
-            _id: 'foo',
-            _rev: '2-b',
-            value: 'foo b'
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            value: 'foo a'
-          },
-          {
-            _id: 'foo',
-            _rev: '2-c',
-            value: 'foo c'
-          }
-        ],
-        [
-          {
-            _id: 'foo',
-            _rev: '1-a',
-            value: 'foo a'
-          },
-          {
-            _id: 'foo',
-            _rev: '2-d',
-            value: 'foo d',
-            _deleted: true
-          }
-        ]
-      ];
-      testUtils.putTree(db, simpleTree, function () {
-        db.get('foo', { conflicts: true }, function (err, doc) {
-          doc._rev.should.equal('2-c', 'correct rev');
-          doc._conflicts.length.should.equal(1, 'just one conflict');
-          doc._conflicts[0].should.equal('2-b', 'just one conflict');
-          done();
-        });
-      });
-    });
-
-    it('Retrieve old revision', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      db.post({ version: 'first' }, function (err, info) {
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          version: 'second'
-        }, function (err) {
-          should.not.exist(err);
-          db.get(info.id, { rev: info.rev }, function (err, oldRev) {
-            oldRev.version.should.equal('first', 'Fetched old revision');
-            db.get(info.id, { rev: '1-nonexistentRev' }, function (err) {
-              should.exist(err, 'Non existent row error correctly reported');
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing get open_revs="all"', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-        function () {
-        db.get('3', function (err, parent) {
-          // add conflicts
-          var previd = parent._rev.split('-')[1];
-          var conflicts = [
-            {
-              _id: '3',
-              _rev: '2-aaa',
-              value: 'x',
-              _revisions: {
-                start: 2,
-                ids: [
-                  'aaa',
-                  previd
-                ]
-              }
-            },
-            {
-              _id: '3',
-              _rev: '3-bbb',
-              value: 'y',
-              _deleted: true,
-              _revisions: {
-                start: 3,
-                ids: [
-                  'bbb',
-                  'some',
-                  previd
-                ]
-              }
-            },
-            {
-              _id: '3',
-              _rev: '4-ccc',
-              value: 'z',
-              _revisions: {
-                start: 4,
-                ids: [
-                  'ccc',
-                  'even',
-                  'more',
-                  previd
-                ]
-              }
-            }
-          ];
-          db.put(conflicts[0], { new_edits: false }, function () {
-            db.put(conflicts[1], { new_edits: false }, function () {
-              db.put(conflicts[2], { new_edits: false }, function () {
-                db.get('3', { open_revs: 'all' }, function (err, res) {
-                  var i;
-                  res = res.map(function (row) {
-                    return row.ok;
-                  });
-                  res.sort(function (a, b) {
-                    return a._rev === b._rev ? 0 : a._rev < b._rev ? -1 : 1;
-                  });
-                  res.length.should.equal(conflicts.length);
-                  for (i = 0; i < conflicts.length; i++) {
-                    conflicts[i]._rev.should.equal(res[i]._rev, 'correct rev');
-                  }
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing get with some open_revs', function (done) {
-      var db = new PouchDB(dbs.name);
-      testUtils.writeDocs(db, JSON.parse(JSON.stringify(origDocs)),
-        function () {
-        db.get('3', function (err, parent) {
-          // add conflicts
-          var previd = parent._rev.split('-')[1];
-          var conflicts = [
-            {
-              _id: '3',
-              _rev: '2-aaa',
-              value: 'x',
-              _revisions: {
-                start: 2,
-                ids: [
-                  'aaa',
-                  previd
-                ]
-              }
-            },
-            {
-              _id: '3',
-              _rev: '3-bbb',
-              value: 'y',
-              _deleted: true,
-              _revisions: {
-                start: 3,
-                ids: [
-                  'bbb',
-                  'some',
-                  previd
-                ]
-              }
-            },
-            {
-              _id: '3',
-              _rev: '4-ccc',
-              value: 'z',
-              _revisions: {
-                start: 4,
-                ids: [
-                  'ccc',
-                  'even',
-                  'more',
-                  previd
-                ]
-              }
-            }
-          ];
-          db.put(conflicts[0], { new_edits: false }, function () {
-            db.put(conflicts[1], { new_edits: false }, function () {
-              db.put(conflicts[2], { new_edits: false }, function () {
-                db.get('3', {
-                  open_revs: [
-                    '2-aaa',
-                    '5-nonexistent',
-                    '3-bbb'
-                  ]
-                }, function (err, res) {
-                  res.sort(function (a, b) {
-                    if (a.ok) {
-                      if (b.ok) {
-                        var x = a.ok._rev, y = b.ok._rev;
-                        return x === y ? 0 : x < y ? -1 : 1;
-                      } else {
-                        return -1;
-                      }
-                    }
-                    return 1;
-                  });
-                  res.length.should.equal(3, 'correct number of open_revs');
-                  res[0].ok._rev.should.equal('2-aaa', 'ok');
-                  res[1].ok._rev.should.equal('3-bbb', 'ok');
-                  res[2].missing.should.equal('5-nonexistent', 'ok');
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing get with open_revs and revs', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-b', value: 'foo b'}
-        ],
-        [{_id: 'foo', _rev: '1-a', value: 'foo a'},
-         {_id: 'foo', _rev: '2-c', value: 'foo c'}]
-      ];
-      testUtils.putTree(db, docs, function () {
-        db.get('foo', {
-          open_revs: ['2-b'],
-          revs: true
-        }, function (err, res) {
-          var doc = res[0].ok;
-          doc._revisions.ids.length.should.equal(2, 'got two revs');
-          doc._revisions.ids[0].should.equal('b', 'got correct rev');
-          done();
-        });
-      });
-    });
-
-    it('Testing get with open_revs on nonexistent doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.get('nonexistent', { open_revs: ['2-whatever'] }, function (err, res) {
-        res.length.should.equal(1, 'just one result');
-        res[0].missing.should.equal('2-whatever', 'just one result');
-        db.get('nonexistent', { open_revs: 'all' }, function (err) {
-          // CouchDB 1.X doesn't handle this situation correctly
-          // CouchDB 2.0 fixes it (see COUCHDB-2517)
-          testUtils.isCouchDB(function (isCouchDB) {
-            if (isCouchDB && !testUtils.isCouchMaster()) {
-              return done();
-            }
-
-            err.status.should.equal(404);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Testing get with open_revs with wrong params', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.put({ _id: 'foo' }, function () {
-        db.get('foo', {
-          open_revs: {
-            'whatever': 'which is',
-            'not an array': 'or all string'
-          }
-        }, function (err) {
-          var acceptable_errors = ['unknown_error', 'bad_request'];
-          acceptable_errors.indexOf(err.name)
-            .should.not.equal(-1, 'correct error');
-          // unfortunately!
-          db.get('foo', {
-            open_revs: [
-              '1-almost',
-              '2-correct',
-              'keys'
-            ]
-          }, function (err) {
-            err.name.should.equal('bad_request', 'correct error');
-            done();
-          });
-        });
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.http.js b/tests/integration/test.http.js
deleted file mode 100644
index 69a92ed..0000000
--- a/tests/integration/test.http.js
+++ /dev/null
@@ -1,208 +0,0 @@
-'use strict';
-
-describe('test.http.js', function () {
-
-  var dbs = {};
-
-  beforeEach(function (done) {
-    dbs.name = testUtils.adapterUrl('http', 'test_http');
-    testUtils.cleanup([dbs.name], done);
-  });
-
-  after(function (done) {
-    testUtils.cleanup([dbs.name], done);
-  });
-
-  // TODO: Remove `skipSetup` in favor of `skip_setup` in a future release
-  it('Create a pouch without DB setup (skipSetup)', function (done) {
-    var instantDB;
-    testUtils.isCouchDB(function (isCouchDB) {
-      if (!isCouchDB) {
-        return done();
-      }
-      new PouchDB(dbs.name).then(function (db) {
-        db.destroy(function () {
-          instantDB = new PouchDB(dbs.name, { skipSetup: true });
-          instantDB.post({ test: 'abc' }, function (err) {
-            should.exist(err);
-            err.name.should.equal('not_found', 'Skipped setup of database');
-            done();
-          });
-        });
-      });
-    });
-  });
-
-  it('Create a pouch without DB setup (skip_setup)', function (done) {
-    var instantDB;
-    testUtils.isCouchDB(function (isCouchDB) {
-      if (!isCouchDB) {
-        return done();
-      }
-      new PouchDB(dbs.name).then(function (db) {
-        db.destroy(function () {
-          instantDB = new PouchDB(dbs.name, { skip_setup: true });
-          instantDB.post({ test: 'abc' }, function (err) {
-            should.exist(err);
-            err.name.should.equal('not_found', 'Skipped setup of database');
-            done();
-          });
-        });
-      });
-    });
-  });
-
-  it('Issue 1269 redundant _changes requests', function (done) {
-    var docs = [];
-    var num = 100;
-    for (var i = 0; i < num; i++) {
-      docs.push({
-        _id: 'doc_' + i,
-        foo: 'bar_' + i
-      });
-    }
-    var db = new PouchDB(dbs.name);
-    db.bulkDocs({ docs: docs }, function () {
-      db.info(function (err, info) {
-        var update_seq = info.update_seq;
-
-        var callCount = 0;
-        var ajax = PouchDB.utils.ajax;
-        PouchDB.utils.ajax = function (opts) {
-          if (/_changes/.test(opts.url)) {
-            callCount++;
-          }
-          ajax.apply(this, arguments);
-        };
-        db.changes({
-          since: update_seq
-        }).on('change', function () {
-        }).on('complete', function () {
-          callCount.should.equal(1, 'One _changes call to complete changes');
-          PouchDB.utils.ajax = ajax;
-          done();
-        }).on('error', done);
-      });
-    });
-  });
-
-  it('handle ddocs with slashes', function (done) {
-    var ddoc = {
-      _id: '_design/foo/bar'
-    };
-    var db = new PouchDB(dbs.name);
-    db.bulkDocs({ docs: [ddoc] }, function () {
-      db.get(ddoc._id, function (err, doc) {
-        should.not.exist(err);
-        doc._id.should.equal(ddoc._id, 'Correct doc returned');
-        done();
-      });
-    });
-  });
-
-  it('#2853 test uri parsing usernames/passwords', function () {
-    var uri = PouchDB.utils.parseUri(
-      'http://u%24ern%40me:p%26%24%24w%40rd@foo.com');
-    uri.password.should.equal('p&$$w@rd');
-    uri.user.should.equal('u$ern@me');
-    uri.host.should.equal('foo.com');
-  });
-
-  it('Properly escape url params #4008', function () {
-    var ajax = PouchDB.utils.ajax;
-    PouchDB.utils.ajax = function (opts) {
-      opts.url.should.not.contain('[');
-      ajax.apply(this, arguments);
-    };
-    var db = new PouchDB(dbs.name);
-    return db.changes({doc_ids: ['1']}).then(function () {
-      PouchDB.utils.ajax = ajax;
-    });
-  });
-
-  it('Allows the "ajax timeout" to extend "changes timeout"', function (done) {
-    var timeout = 120000;
-    var db = new PouchDB(dbs.name, {
-      skipSetup: true,
-      ajax: {
-        timeout: timeout
-      }
-    });
-
-    var ajax = PouchDB.utils.ajax;
-    var ajaxOpts;
-    PouchDB.utils.ajax = function (opts) {
-      if (/changes/.test(opts.url)) {
-        ajaxOpts = opts;
-        changes.cancel();
-      }
-      ajax.apply(this, arguments);
-    };
-
-    var changes = db.changes();
-
-    changes.on('complete', function () {
-      should.exist(ajaxOpts);
-      ajaxOpts.timeout.should.equal(timeout);
-      PouchDB.utils.ajax = ajax;
-      done();
-    });
-
-  });
-
-  it('Test custom header', function () {
-    var db = new PouchDB(dbs.name, {
-      headers: {
-        'X-Custom': 'some-custom-header'
-      }
-    });
-    return db.info();
-  });
-
-  it('getUrl() works (used by plugins)', function () {
-    var db = new PouchDB(dbs.name);
-    db.getUrl().should.match(/^http/);
-  });
-
-  it('getHeaders() works (used by plugins)', function () {
-    var db = new PouchDB(dbs.name);
-    db.getHeaders().should.deep.equal({});
-  });
-
-  it('test url too long error for allDocs()', function () {
-    var docs = [];
-    var numDocs = 75;
-    for (var i = 0; i < numDocs; i++) {
-      docs.push({
-        _id: 'fairly_long_doc_name_' + i
-      });
-    }
-    var db = new PouchDB(dbs.name);
-    return db.bulkDocs(docs).then(function () {
-      return db.allDocs({
-        keys: docs.map(function (x) { return x._id; })
-      });
-    }).then(function (res) {
-      res.rows.should.have.length(numDocs);
-    });
-  });
-
-  it('4358 db.info rejects when server is down', function () {
-    var db = new PouchDB('http://example.com/foo');
-    return db.info().then(function () {
-      throw new Error('expected an error');
-    }).catch(function (err) {
-      should.exist(err);
-    });
-  });
-
-  it('4358 db.destroy rejects when server is down', function () {
-    var db = new PouchDB('http://example.com/foo');
-    return db.destroy().then(function () {
-      throw new Error('expected an error');
-    }).catch(function (err) {
-      should.exist(err);
-    });
-  });
-
-});
diff --git a/tests/integration/test.issue1175.js b/tests/integration/test.issue1175.js
deleted file mode 100644
index 87d0bcd..0000000
--- a/tests/integration/test.issue1175.js
+++ /dev/null
@@ -1,96 +0,0 @@
-'use strict';
-function MockDatabase(statusCodeToReturn, dataToReturn) {
-  this.once = this.removeListener = function () {};
-  this.type = function () { return 'mock'; };
-  this.id = function (callback) {
-    if (callback) {
-      callback(123);
-    } else {
-      return PouchDB.utils.Promise.resolve(123);
-    }
-  };
-  this.get = function () {
-    return new PouchDB.utils.Promise(function (fulfill, reject) {
-      setTimeout(function () {
-        if (statusCodeToReturn !== 200) {
-          reject({ status: statusCodeToReturn });
-        } else {
-          fulfill(dataToReturn);
-        }
-      }, 0);
-    });
-  };
-  this.changes = function (opts) {
-    if (opts.complete) {
-      opts.complete(null, {results: []});
-    }
-    var promise = PouchDB.utils.Promise.resolve({results: []});
-    promise.on = function () { return this; };
-    return promise;
-  };
-  this.put = function () {
-    return PouchDB.utils.Promise.resolve();
-  };
-}
-function getCallback(expectError, done) {
-  // returns a function which expects to be called within a certain time.
-  // Fails the test otherwise
-  var maximumTimeToWait = 500;
-  var hasBeenCalled = false;
-  var err;
-  function callback(error) {
-    hasBeenCalled = true;
-    err = error;
-  }
-  function timeOutCallback() {
-    hasBeenCalled.should.equal(true, 'callback has been called');
-    if (!expectError) {
-      should.not.exist(err, 'error expectation fulfilled');
-    }
-    done();
-  }
-  setTimeout(timeOutCallback, maximumTimeToWait);
-  return callback;
-}
-describe('replication-http-errors:', function () {
-  it('Initial replication is ok if source returns HTTP 404', function (done) {
-    var source = new MockDatabase(404, null);
-    var target = new MockDatabase(200, {});
-    PouchDB.replicate(source, target, {}, getCallback(false, done));
-  });
-  it('Initial replication is ok if target returns HTTP 404', function (done) {
-    var source = new MockDatabase(200, {});
-    var target = new MockDatabase(404, null);
-    PouchDB.replicate(source, target, {}, getCallback(false, done));
-  });
-  it('Initial replication is ok if source and target return HTTP 200',
-    function (done) {
-    var source = new MockDatabase(200, {});
-    var target = new MockDatabase(200, {});
-    PouchDB.replicate(source, target, {}, getCallback(false, done));
-  });
-  it('Initial replication returns err if source returns HTTP 500',
-    function (done) {
-    var source = new MockDatabase(500, null);
-    var target = new MockDatabase(200, {});
-    PouchDB.replicate(source, target, {retry: false}, getCallback(true, done));
-  });
-  it('Initial replication returns err if target returns HTTP 500',
-    function (done) {
-    var source = new MockDatabase(200, {});
-    var target = new MockDatabase(500, null);
-    PouchDB.replicate(source, target, {retry: false}, getCallback(true, done));
-  });
-  it('Initial replication returns err if target and source return HTTP 500',
-    function (done) {
-    var source = new MockDatabase(500, null);
-    var target = new MockDatabase(500, null);
-    PouchDB.replicate(source, target, {retry: false}, getCallback(true, done));
-  });
-  it('Subsequent replication returns err if source return HTTP 500',
-    function (done) {
-    var source = new MockDatabase(500, null);
-    var target = new MockDatabase(200, { last_seq: 456 });
-    PouchDB.replicate(source, target, {retry: false}, getCallback(true, done));
-  });
-});
diff --git a/tests/integration/test.issue221.js b/tests/integration/test.issue221.js
deleted file mode 100644
index 05b8c74..0000000
--- a/tests/integration/test.issue221.js
+++ /dev/null
@@ -1,85 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-adapters.forEach(function (adapters) {
-  describe('test.issue221.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    it('Testing issue #221', function () {
-      var doc = {_id: '0', integer: 0};
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // Write a doc in CouchDB.
-      return remote.put(doc).then(function (results) {
-        // Update the doc.
-        doc._rev = results.rev;
-        doc.integer = 1;
-        return remote.put(doc);
-      }).then(function () {
-        // Compact the db.
-        return remote.compact();
-      }).then(function () {
-       return remote.get(doc._id, { revs_info: true });
-      }).then(function (data) {
-        var correctRev = data._revs_info[0];
-        return local.replicate.from(remote).then(function () {
-          // Check the Pouch doc.
-          return local.get(doc._id, function (err, results) {
-            results._rev.should.equal(correctRev.rev);
-            results.integer.should.equal(1);
-          });
-        });
-      });
-    });
-
-    it('Testing issue #221 again', function () {
-      if (testUtils.isCouchMaster()) {
-        return;
-      }
-      var doc = {_id: '0', integer: 0};
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // Write a doc in CouchDB.
-      return remote.put(doc).then(function (results) {
-        doc._rev = results.rev;
-        // Second doc so we get 2 revisions from replicate.
-        return remote.put(doc);
-      }).then(function (results) {
-        doc._rev = results.rev;
-        return local.replicate.from(remote);
-      }).then(function () {
-        doc.integer = 1;
-        // One more change
-        return remote.put(doc);
-      }).then(function () {
-        // Testing if second replications fails now
-        return local.replicate.from(remote);
-      }).then(function () {
-        return local.get(doc._id);
-      }).then(function (results) {
-        results.integer.should.equal(1);
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.issue3179.js b/tests/integration/test.issue3179.js
deleted file mode 100644
index fb11c1e..0000000
--- a/tests/integration/test.issue3179.js
+++ /dev/null
@@ -1,325 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'http'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-adapters.forEach(function (adapters) {
-  describe('test.issue3179.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('#3179 conflicts synced, non-live replication', function () {
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return local.put({ _id: '1'}).then(function () {
-        return local.replicate.to(remote).then(function () {
-          return remote.replicate.to(local);
-        });
-      }).then(function () {
-        return local.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return local.put(doc);
-        });
-      }).then(function () {
-        return remote.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return remote.put(doc);
-        });
-      }).then(function () {
-        return local.replicate.to(remote).then(function () {
-          return remote.replicate.to(local);
-        });
-      }).then(function () {
-        return local.get('1', {conflicts: true}).then(function (doc) {
-          return local.remove(doc._id, doc._conflicts[0]);
-        });
-      }).then(function () {
-        return local.replicate.to(remote).then(function () {
-          return remote.replicate.to(local);
-        });
-      }).then(function () {
-        return local.get('1', {conflicts: true, revs: true});
-      }).then(function (localDoc) {
-        return remote.get('1', {
-          conflicts: true,
-          revs: true
-        }).then(function (remoteDoc) {
-          remoteDoc.should.deep.equal(localDoc);
-        });
-      });
-    });
-
-    it('#3179 conflicts synced, non-live sync', function () {
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return local.put({ _id: '1'}).then(function () {
-        return local.sync(remote);
-      }).then(function () {
-        return local.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return local.put(doc);
-        });
-      }).then(function () {
-        return remote.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return remote.put(doc);
-        });
-      }).then(function () {
-        return local.sync(remote);
-      }).then(function () {
-        return local.get('1', {conflicts: true}).then(function (doc) {
-          return local.remove(doc._id, doc._conflicts[0]);
-        });
-      }).then(function () {
-        return local.sync(remote);
-      }).then(function () {
-        return local.get('1', {conflicts: true, revs: true});
-      }).then(function (localDoc) {
-        return remote.get('1', {
-          conflicts: true,
-          revs: true
-        }).then(function (remoteDoc) {
-          remoteDoc.should.deep.equal(localDoc);
-        });
-      });
-    });
-
-    it('#3179 conflicts synced, live sync', function () {
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var sync = local.sync(remote, { live: true });
-
-      function waitForUptodate() {
-
-        function defaultToEmpty(promise) {
-          return promise.catch(function (err) {
-            if (err.status !== 404) {
-              throw err;
-            }
-            return {_revisions: []};
-          });
-        }
-
-        return defaultToEmpty(local.get('1', {
-          revs: true,
-          conflicts: true
-        })).then(function (localDoc) {
-          return defaultToEmpty(remote.get('1', {
-            revs: true,
-            conflicts: true
-          })).then(function (remoteDoc) {
-            var revsEqual = JSON.stringify(localDoc._revisions) ===
-              JSON.stringify(remoteDoc._revisions);
-            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
-              JSON.stringify(remoteDoc._conflicts || []);
-            if (!revsEqual || !conflictsEqual) {
-              return waitForUptodate();
-            }
-          });
-        });
-      }
-
-      function waitForConflictsResolved() {
-        return new PouchDB.utils.Promise(function (resolve) {
-          var changes = remote.changes({
-            live: true,
-            include_docs: true,
-            conflicts: true
-          }).on('change', function (change) {
-            if (!('_conflicts' in change.doc)) {
-              changes.cancel();
-            }
-          });
-          changes.on('complete', resolve);
-        });
-      }
-
-      function cleanup() {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          sync.on('complete', resolve);
-          sync.on('error', reject);
-          sync.cancel();
-          sync = null;
-        });
-      }
-
-      return local.put({ _id: '1'}).then(function () {
-        return waitForUptodate();
-      }).then(function () {
-        sync.cancel();
-        return waitForUptodate();
-      }).then(function () {
-        return local.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return local.put(doc);
-        });
-      }).then(function () {
-        return remote.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return remote.put(doc);
-        });
-      }).then(function () {
-        sync = local.sync(remote, { live: true });
-        return waitForUptodate();
-      }).then(function () {
-        return local.get('1', {conflicts: true}).then(function (doc) {
-          return local.remove(doc._id, doc._conflicts[0]);
-        });
-      }).then(function () {
-        return waitForConflictsResolved();
-      }).then(function () {
-        return local.get('1', {conflicts: true, revs: true});
-      }).then(function (localDoc) {
-        return remote.get('1', {
-          conflicts: true,
-          revs: true
-        }).then(function (remoteDoc) {
-          remoteDoc.should.deep.equal(localDoc);
-        });
-      }).then(function () {
-        return cleanup();
-      }, function (err) {
-        return cleanup().then(function () {
-          throw err;
-        });
-      });
-    });
-
-    it('#3179 conflicts synced, live repl', function () {
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var repl1 = local.replicate.to(remote, { live: true });
-      var repl2 = local.replicate.from(remote, { live: true });
-
-      function waitForConflictsResolved() {
-        return new PouchDB.utils.Promise(function (resolve) {
-          var changes = remote.changes({
-            live: true,
-            include_docs: true,
-            conflicts: true
-          }).on('change', function (change) {
-            if (!('_conflicts' in change.doc)) {
-              changes.cancel();
-            }
-          });
-          changes.on('complete', resolve);
-        });
-      }
-
-      function waitForUptodate() {
-
-        function defaultToEmpty(promise) {
-          return promise.catch(function (err) {
-            if (err.status !== 404) {
-              throw err;
-            }
-            return {_revisions: []};
-          });
-        }
-
-        return defaultToEmpty(local.get('1', {
-          revs: true,
-          conflicts: true
-        })).then(function (localDoc) {
-          return defaultToEmpty(remote.get('1', {
-            revs: true,
-            conflicts: true
-          })).then(function (remoteDoc) {
-            var revsEqual = JSON.stringify(localDoc._revisions) ===
-              JSON.stringify(remoteDoc._revisions);
-            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
-              JSON.stringify(remoteDoc._conflicts || []);
-            if (!revsEqual || !conflictsEqual) {
-              return waitForUptodate();
-            }
-          });
-        });
-      }
-
-      function cleanup() {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var numDone = 0;
-
-          function checkDone() {
-            if (++numDone === 2) {
-              resolve();
-            }
-          }
-          repl1.on('complete', checkDone);
-          repl2.on('complete', checkDone);
-          repl1.on('error', reject);
-          repl2.on('error', reject);
-          repl1.cancel();
-          repl2.cancel();
-          repl1 = null;
-          repl2 = null;
-        });
-      }
-
-      return local.put({ _id: '1'}).then(function () {
-        return waitForUptodate();
-      }).then(function () {
-        repl1.cancel();
-        repl2.cancel();
-        return waitForUptodate();
-      }).then(function () {
-        return local.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return local.put(doc);
-        });
-      }).then(function () {
-        return remote.get('1').then(function (doc) {
-          doc.foo = Math.random();
-          return remote.put(doc);
-        });
-      }).then(function () {
-        repl1 = local.replicate.to(remote, { live: true });
-        repl2 = local.replicate.from(remote, { live: true });
-        return waitForUptodate();
-      }).then(function () {
-        return local.get('1', {conflicts: true}).then(function (doc) {
-          return local.remove(doc._id, doc._conflicts[0]);
-        });
-      }).then(function () {
-        return waitForConflictsResolved();
-      }).then(function () {
-        return local.get('1', {conflicts: true, revs: true});
-      }).then(function (localDoc) {
-        return remote.get('1', {
-          conflicts: true,
-          revs: true
-        }).then(function (remoteDoc) {
-          remoteDoc.should.deep.equal(localDoc);
-        });
-      }).then(function () {
-        return cleanup();
-      }, function (err) {
-        return cleanup().then(function () {
-          throw err;
-        });
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.issue3646.js b/tests/integration/test.issue3646.js
deleted file mode 100644
index 086d24e..0000000
--- a/tests/integration/test.issue3646.js
+++ /dev/null
@@ -1,245 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-
-adapters.forEach(function (adapter) {
-  describe('test.issue3646.js- ' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    it('Should finish with 0 documents', function () {
-      var db = new PouchDB(dbs.name);
-
-      return db.bulkDocs(data[0], {new_edits: false}).then(function () {
-        return db.bulkDocs(data[1], {new_edits: false});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(0, 'all docs length is 0');
-        res.total_rows.should.equal(0);
-        return db.allDocs({keys: ['b74e3b45'], include_docs: true});
-      }).then(function (res) {
-        var first = res.rows[0];
-        should.equal(first.value.deleted, true, 'all docs value.deleted');
-        first.value.rev.should.equal('6-441f43a31c89dc68a7cc934ce5779bf8');
-        res.total_rows.should.equal(0);
-        return db.info();
-      }).then(function (info) {
-        info.doc_count.should.equal(0, 'doc_count is 0');
-        return db.changes({include_docs: true});
-      }).then(function (changes) {
-        changes.results.should.have.length(1);
-        var first = changes.results[0];
-        first.doc._rev.should.equal('6-441f43a31c89dc68a7cc934ce5779bf8');
-        should.equal(first.deleted, true, 'changes metadata.deleted');
-        should.equal(first.doc._deleted, true, 'changes doc._deleted');
-      });
-    });
-
-    var data = [
-      {
-        "docs": [
-          {
-            "_revisions": {
-              "start": 2,
-              "ids": [
-                "4e16ac64356d4358bf1bdb4857fc299f",
-                "aed67b17ea5ba6b78e704ad65d3fb5db"
-              ]
-            },
-            "_rev": "2-4e16ac64356d4358bf1bdb4857fc299f",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 2,
-              "ids": [
-                "3757f03a178b34284361c89303cf8c35",
-                "0593f4c87b24f0f9b620526433929bb0"
-              ]
-            },
-            "_rev": "2-3757f03a178b34284361c89303cf8c35",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 3,
-              "ids": [
-                "f28d17ab990dcadd20ad38860fde9f11",
-                "6cf4b9e2115d7e884292b97aa8765285",
-                "dcfdf66ab61873ee512a9ccf3e3731a1"
-              ]
-            },
-            "_rev": "3-f28d17ab990dcadd20ad38860fde9f11",
-            "_id": "b74e3b45"
-          },
-          {
-            "_revisions": {
-              "start": 3,
-              "ids": [
-                "4d93920c00a4a7269095b22ff4329b3c",
-                "7190eca51acb2b302a89ed1204ac2813",
-                "017eba7ef1e4f529143f463779822627"
-              ]
-            },
-            "_rev": "3-4d93920c00a4a7269095b22ff4329b3c",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 3,
-              "ids": [
-                "91b47d7b889feb36eaf9336c071f00cc",
-                "0e3379b8f9128e6062d13eeb98ec538e",
-                "1c006ce18b663e2a031ced4669797c28"
-              ]
-            },
-            "_rev": "3-91b47d7b889feb36eaf9336c071f00cc",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 4,
-              "ids": [
-                "2c3c860d421fc9f6cc82e4fb811dc8e2",
-                "4473170dcffa850aca381b4f644b2947",
-                "3524a871600080f5e30e59a292b02a3f",
-                "89eb0b5131800963bb7caf1fc83b6242"
-              ]
-            },
-            "_rev": "4-2c3c860d421fc9f6cc82e4fb811dc8e2",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 6,
-              "ids": [
-                "441f43a31c89dc68a7cc934ce5779bf8",
-                "4c7f8b00508144d049d18668d17e552a",
-                "e8431fb3b448f3457c5b2d77012fa8b4",
-                "f2e7dc8102123e13ca792a0a05ca6235",
-                "37a13a5c1e2ce5926a3ffcda7e669106",
-                "78739468c87b30f76d067a2d7f373803"
-              ]
-            },
-            "_rev": "6-441f43a31c89dc68a7cc934ce5779bf8",
-            "_id": "b74e3b45",
-            "_deleted": true
-          }
-        ]
-      },
-      {
-        "docs": [
-          {
-            "_revisions": {
-              "start": 2,
-              "ids": [
-                "3757f03a178b34284361c89303cf8c35",
-                "0593f4c87b24f0f9b620526433929bb0"
-              ]
-            },
-            "_rev": "2-3757f03a178b34284361c89303cf8c35",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 2,
-              "ids": [
-                "4e16ac64356d4358bf1bdb4857fc299f",
-                "aed67b17ea5ba6b78e704ad65d3fb5db"
-              ]
-            },
-            "_rev": "2-4e16ac64356d4358bf1bdb4857fc299f",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 3,
-              "ids": [
-                "91b47d7b889feb36eaf9336c071f00cc",
-                "0e3379b8f9128e6062d13eeb98ec538e",
-                "1c006ce18b663e2a031ced4669797c28"
-              ]
-            },
-            "_rev": "3-91b47d7b889feb36eaf9336c071f00cc",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 3,
-              "ids": [
-                "4d93920c00a4a7269095b22ff4329b3c",
-                "7190eca51acb2b302a89ed1204ac2813",
-                "017eba7ef1e4f529143f463779822627"
-              ]
-            },
-            "_rev": "3-4d93920c00a4a7269095b22ff4329b3c",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 4,
-              "ids": [
-                "2c3c860d421fc9f6cc82e4fb811dc8e2",
-                "4473170dcffa850aca381b4f644b2947",
-                "3524a871600080f5e30e59a292b02a3f",
-                "89eb0b5131800963bb7caf1fc83b6242"
-              ]
-            },
-            "_rev": "4-2c3c860d421fc9f6cc82e4fb811dc8e2",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 4,
-              "ids": [
-                "dbaa7e6c02381c2c0ec5259572387d7c",
-                "f28d17ab990dcadd20ad38860fde9f11",
-                "6cf4b9e2115d7e884292b97aa8765285",
-                "dcfdf66ab61873ee512a9ccf3e3731a1"
-              ]
-            },
-            "_rev": "4-dbaa7e6c02381c2c0ec5259572387d7c",
-            "_id": "b74e3b45",
-            "_deleted": true
-          },
-          {
-            "_revisions": {
-              "start": 6,
-              "ids": [
-                "441f43a31c89dc68a7cc934ce5779bf8",
-                "4c7f8b00508144d049d18668d17e552a",
-                "e8431fb3b448f3457c5b2d77012fa8b4",
-                "f2e7dc8102123e13ca792a0a05ca6235",
-                "37a13a5c1e2ce5926a3ffcda7e669106",
-                "78739468c87b30f76d067a2d7f373803"
-              ]
-            },
-            "_rev": "6-441f43a31c89dc68a7cc934ce5779bf8",
-            "_id": "b74e3b45",
-            "_deleted": true
-          }
-        ]
-      }
-    ];
-  });
-});
diff --git a/tests/integration/test.issue915.js b/tests/integration/test.issue915.js
deleted file mode 100644
index 10de8cc..0000000
--- a/tests/integration/test.issue915.js
+++ /dev/null
@@ -1,39 +0,0 @@
-'use strict';
-if (!process.env.LEVEL_ADAPTER &&
-    !process.env.LEVEL_PREFIX &&
-    !process.env.AUTO_COMPACTION &&
-    !process.env.ADAPTER) {
-  // these tests don't make sense for anything other than default leveldown
-  var fs = require('fs');
-  describe('Remove DB', function () {
-    afterEach(function (done) {
-      fs.unlink('./tmp/_pouch_veryimportantfiles/something', function () {
-        fs.rmdir('./tmp/_pouch_veryimportantfiles/', function () {
-          done();
-        });
-      });
-    });
-    it('Put a file in the db, then destroy it', function (done) {
-      new PouchDB('veryimportantfiles', function (err, db) {
-        fs.writeFile('./tmp/_pouch_veryimportantfiles/something',
-                     new Buffer('lalala'), function () {
-          db.destroy(function (err) {
-            if (err) {
-              return done(err);
-            }
-            fs.readFile('./tmp/_pouch_veryimportantfiles/something',
-                        {encoding: 'utf8'}, function (err, resp) {
-              if (err) {
-                return done(err);
-              }
-              resp.should
-                .equal('lalala',
-                       './tmp/veryimportantfiles/something was not removed');
-              done();
-            });
-          });
-        });
-      });
-    });
-  });
-}
diff --git a/tests/integration/test.local_docs.js b/tests/integration/test.local_docs.js
deleted file mode 100644
index 42cc818..0000000
--- a/tests/integration/test.local_docs.js
+++ /dev/null
@@ -1,215 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.local_docs.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    it('local docs - put then get', function () {
-      var db = new PouchDB(dbs.name);
-      return db.put({_id: '_local/foo'}).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.rev.should.be.a('string');
-        res.ok.should.equal(true);
-        return db.get('_local/foo');
-      });
-    });
-
-    it('local docs - put then get w/ revisions', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: '_local/foo'
-      };
-      return db.put(doc).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.rev.should.be.a('string');
-        res.ok.should.equal(true);
-        return db.get('_local/foo');
-      }).then(function (doc) {
-        should.not.exist(doc._revisions);
-        doc._revisions = {start: 0, ids: ['1']};
-        return db.put(doc);
-      }).then(function () {
-        return db.get('_local/foo');
-      }).then(function (doc) {
-        should.not.exist(doc._revisions);
-      });
-    });
-
-    it('local docs - put then remove then get', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.rev.should.equal('0-0');
-        res.ok.should.equal(true);
-        return db.get('_local/foo').then(function (doc) {
-          should.not.exist(doc);
-        }).catch(function (err) {
-          err.name.should.equal('not_found');
-        });
-      });
-    });
-
-    it('local docs - put after remove', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.rev.should.equal('0-0');
-        res.ok.should.equal(true);
-        delete doc._rev;
-        return db.put(doc);
-      });
-    });
-
-    it('local docs - put after remove, check return vals', function () {
-      // as long as it starts with 0-, couch
-      // treats it as a new local doc
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/quux'};
-      return db.put(doc).then(function (res) {
-        res.rev.should.equal('0-1');
-        res.ok.should.equal(true);
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        res.rev.should.equal('0-2');
-        res.ok.should.equal(true);
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        res.rev.should.equal('0-3');
-        res.ok.should.equal(true);
-      });
-    });
-
-    it('local docs - remove missing', function () {
-      var db = new PouchDB(dbs.name);
-      return db.remove({
-        _id: '_local/foo',
-        _rev: '1-fake'
-      }).then(function () {
-        throw new Error('should not be here');
-      }, function (err) {
-        err.name.should.be.a('string');
-      });
-    });
-
-    it('local docs - put after put w/ deleted:true', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        doc._deleted = true;
-        return db.put(doc);
-      }).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.rev.should.equal('0-0');
-        res.ok.should.equal(true);
-        delete doc._deleted;
-        delete doc._rev;
-        return db.put(doc);
-      });
-    });
-
-    it('local docs - put after remove with a rev', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function (res) {
-        res.id.should.equal('_local/foo');
-        res.ok.should.equal(true);
-        res.rev.should.equal('0-0');
-        delete doc._rev;
-        return db.put(doc);
-      });
-    });
-
-    it('local docs - multiple removes', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function (res) {
-        res.rev.should.equal('0-0');
-        delete doc._rev;
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function (res) {
-        res.rev.should.equal('0-0');
-      });
-    });
-
-    it('local docs - get unknown', function () {
-      var db = new PouchDB(dbs.name);
-      return db.get('_local/foo').then(function (doc) {
-        should.not.exist(doc);
-      }).catch(function (err) {
-        err.name.should.equal('not_found');
-      });
-    });
-
-    it('local docs - put unknown', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo', _rev: '1-fake'};
-      return db.put(doc).then(function (res) {
-        should.not.exist(res);
-      }).catch(function (err) {
-        err.name.should.be.a('string');
-      });
-    });
-
-    it('local docs - put new and conflicting', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function () {
-        return db.put(doc);
-      }).then(function (res) {
-        should.not.exist(res);
-      }).catch(function (err) {
-        err.name.should.be.a('string');
-      });
-    });
-
-    it('local docs - put modified and conflicting', function () {
-      var db = new PouchDB(dbs.name);
-      var doc = {_id: '_local/foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.put(doc);
-      }).then(function () {
-        return db.put(doc);
-      }).then(function (res) {
-        should.not.exist(res);
-      }).catch(function (err) {
-        err.name.should.be.a('string');
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.migration.js b/tests/integration/test.migration.js
deleted file mode 100644
index 4cb30c1..0000000
--- a/tests/integration/test.migration.js
+++ /dev/null
@@ -1,162 +0,0 @@
-'use strict';
-if (!process.env.LEVEL_ADAPTER &&
-    !process.env.LEVEL_PREFIX &&
-    !process.env.AUTO_COMPACTION &&
-    !process.env.ADAPTER) {
-  // these tests don't make sense for anything other than default leveldown
-  var fs = require('fs');
-  var ncp = require('ncp').ncp;
-
-  ncp.limit = 16;
-
-  describe('migration one', function () {
-    beforeEach(function (done) {
-      var input =
-        fs.createReadStream('./tests/integration/leveldb/oldStyle.uuid');
-      input.on('end', function () {
-        ncp('./tests/integration/leveldb/oldStyle',
-            './tmp/_pouch_oldStyle', done);
-      });
-      input.pipe(fs.createWriteStream('./tmp/_pouch_oldStyle.uuid'));
-    });
-    it('should work', function () {
-      return new PouchDB('oldStyle').then(function (db) {
-        return db.get('doc').then(function (doc) {
-          doc.something.should.equal('awesome');
-          return db.destroy();
-        });
-      });
-    });
-  });
-  describe('migration two', function () {
-    beforeEach(function (done) {
-      ncp('./tests/integration/leveldb/middleStyle',
-          './tmp/_pouch_middleStyle', done);
-    });
-    it('should work', function () {
-      return new PouchDB('middleStyle').then(function (db) {
-        db.id().then(function (id) {
-          id.should.equal('8E049E64-784A-3209-8DD6-97C29D7A5868');
-          return db.get('_local/foo');
-        }).then(function (resp) {
-          resp.something.should.equal('else');
-          return db.allDocs();
-        }).then(function (resp) {
-          resp.total_rows.should.equal(1);
-          resp.rows[0].id.should.equal('_design/foo');
-          return db.destroy();
-        });
-      });
-    });
-  });
-
-  // sanity check to ensure we don't actually need to migrate
-  // attachments for #2818
-  describe('#2818 no migration needed for attachments', function () {
-    beforeEach(function (done) {
-      ncp('./tests/integration/leveldb/lateStyle',
-          './tmp/_pouch_lateStyle', done);
-    });
-    it('should work', function () {
-      return new PouchDB('lateStyle', {
-        auto_compaction: false
-      }).then(function (db) {
-        return db.put({
-          _id: 'doc_b',
-          _attachments: {
-            'att.txt': {
-              data: 'Zm9v', // 'foo'
-              content_type: 'text/plain'
-            }
-          }
-        }).then(function () {
-          return db.get('doc_b');
-        }).then(function (doc) {
-          return db.remove(doc);
-        }).then(function () {
-          return db.compact();
-        }).then(function () {
-          return db.get('doc_a', {attachments: true});
-        }).then(function (doc) {
-          doc._attachments['att.txt'].data.should.equal('Zm9vYmFy');
-          doc._attachments['att2.txt'].data.should.equal('Zm9vYmFy');
-          doc._attachments['att3.txt'].data.should.equal('Zm9v');
-          return db.destroy();
-        });
-      });
-    });
-  });
-
-  // Sanity check for the fix in 3136 that guards against successive
-  // new_edits to the same rev, ensuring it ignores duplicates.
-  //
-  // In the olden days, <=3.2.0, if you bulk-pushed with new_edits=false
-  // the same rev multiple times, LevelDB would keep incrementing the seq
-  // and keep writing new revs. This was fixed, but when we do _changes,
-  // we have to guard against these duplicate seqs for backwards compat.
-  //
-  // This test is very similar to the test.bulk_docs.js test:
-  // 'Testing successive new_edits to the same doc, different content'
-
-  describe('#3136 no migration needed for overwritten revs', function () {
-    beforeEach(function (done) {
-      ncp('./tests/integration/leveldb/laterStyle',
-        './tmp/_pouch_laterStyle', done);
-    });
-    it('should work', function () {
-      var db = new PouchDB('laterStyle');
-
-      // basically this a db where I did a very pathological thing:
-      //var docsA = [{
-      //  '_id': 'foo',
-      //  '_rev': '1-x',
-      //  'bar' : 'baz',
-      //  '_revisions': {
-      //    'start': 1,
-      //    'ids': ['x']
-      //  }
-      //}, {
-      //  '_id' : 'fee',
-      //  '_rev': '1-x',
-      //  '_revisions': {
-      //    'start': 1,
-      //    'ids': ['x']
-      //  }
-      //}];
-      //var docsB = [{
-      //  '_id': 'foo',
-      //  '_rev': '1-x',
-      //  'bar' : 'zam', // this update should be rejected
-      //  '_revisions': {
-      //    'start': 1,
-      //    'ids': ['x']
-      //  }
-      //}];
-      //
-      //db.bulkDocs(docsA, {new_edits: false});
-      //db.bulkDocs(docsB, {new_edits: false});
-
-
-      return db.changes({include_docs: true}).then(function (result) {
-        // the important thing is that 'zam' is ignored. see
-        // the other test in test.bulk_docs.js for details
-        var expected = {
-          "results": [{
-            "id": "fee",
-            "changes": [{"rev": "1-x"}],
-            "doc": {"_id": "fee", "_rev": "1-x"},
-            "seq": 1
-          }, {
-            "id": "foo",
-            "changes": [{"rev": "1-x"}],
-            "doc": {"bar": "baz", "_id": "foo", "_rev": "1-x"},
-            "seq": 2
-          }],
-          "last_seq": 2
-        };
-        result.should.deep.equal(expected);
-        return db.destroy();
-      });
-    });
-  });
-}
diff --git a/tests/integration/test.replication.js b/tests/integration/test.replication.js
deleted file mode 100644
index 37d5cf4..0000000
--- a/tests/integration/test.replication.js
+++ /dev/null
@@ -1,4390 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-var downAdapters = ['local'];
-
-adapters.forEach(function (adapters) {
-  describe('suite2 test.replication.js-' + adapters[0] + '-' + adapters[1],
-    function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    var docs = [
-      {_id: '0', integer: 0, string: '0'},
-      {_id: '1', integer: 1, string: '1'},
-      {_id: '2', integer: 2, string: '2'}
-    ];
-
-    // simplify for easier deep equality checks
-    function simplifyChanges(res) {
-      var changes = res.results.map(function (change) {
-        if (testUtils.isSyncGateway() &&
-          change.doc && change.doc._conflicts) {
-          // CSG does not render conflict metadata inline
-          // in the document. Remove it for comparisons.
-          delete change.doc._conflicts;
-        }
-        return {
-          id: change.id,
-          deleted: change.deleted,
-          changes: change.changes.map(function (x) {
-            return x.rev;
-          }).sort(),
-          doc: change.doc
-        };
-      });
-
-      // in CouchDB 2.0, changes is not guaranteed to be
-      // ordered
-      if (testUtils.isCouchMaster() || testUtils.isSyncGateway()) {
-        changes.sort(function (a, b) {
-          return a.id > b.id;
-        });
-      }
-      // CSG will send a change event when just the ACL changed
-      if (testUtils.isSyncGateway()) {
-        changes = changes.filter(function (change){
-          return change.id !== "_user/";
-        });
-      }
-      return changes;
-    }
-
-    function verifyInfo(info, expected) {
-      if (!testUtils.isCouchMaster()) {
-        if (typeof info.doc_count === 'undefined') {
-          // info is from Sync Gateway, which allocates an extra seqnum
-          // for user access control purposes.
-          info.update_seq.should.be.within(expected.update_seq,
-            expected.update_seq + 1, 'update_seq');
-        } else {
-          info.update_seq.should.equal(expected.update_seq, 'update_seq');
-        }
-      }
-      if (info.doc_count) { // info is NOT from Sync Gateway
-        info.doc_count.should.equal(expected.doc_count, 'doc_count');
-      }
-    }
-
-    it('Test basic pull replication', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.from(dbs.remote, function (err, result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test basic pull replication plain api', function (done) {
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        PouchDB.replicate(dbs.remote, dbs.name, {}, function (err, result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          new PouchDB(dbs.name).info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test basic pull replication plain api 2', function (done) {
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        PouchDB.replicate(
-          dbs.remote, dbs.name).on('complete', function (result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          new PouchDB(dbs.name).info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test pull replication with many changes', function (done) {
-      var remote = new PouchDB(dbs.remote);
-
-      var numDocs = 201;
-      var docs = [];
-      for (var i = 0; i < numDocs; i++) {
-        docs.push({_id: i.toString()});
-      }
-
-      remote.bulkDocs({ docs: docs }, {}, function (err) {
-        should.not.exist(err);
-        PouchDB.replicate(
-          dbs.remote, dbs.name).on('complete', function (result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          new PouchDB(dbs.name).info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: numDocs,
-              doc_count: numDocs
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test basic pull replication with funny ids', function (done) {
-      var docs = [
-        {_id: '4/5', integer: 0, string: '0'},
-        {_id: '3&2', integer: 1, string: '1'},
-        {_id: '1>0', integer: 2, string: '2'}
-      ];
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({docs: docs}, function () {
-        db.replicate.from(dbs.remote, function (err, result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('pull replication with many changes + a conflict (#2543)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      // simulate 5000 normal commits with two conflicts at the very end
-      function uuid() {
-        return PouchDB.utils.uuid(32, 16).toLowerCase();
-      }
-
-      var numRevs = 5000;
-      var isSafari = (typeof process === 'undefined' || process.browser) &&
-        /Safari/.test(window.navigator.userAgent) &&
-        !/Chrome/.test(window.navigator.userAgent);
-      if (isSafari) {
-        numRevs = 10; // fuck safari, we've hit the storage limit again
-      }
-
-      var uuids = [];
-      for (var i = 0; i < numRevs - 1; i++) {
-        uuids.push(uuid());
-      }
-      var conflict1 = 'a' + uuid();
-      var conflict2 = 'b' + uuid();
-
-      var doc1 = {
-        _id: 'doc',
-        _rev: numRevs + '-' + conflict1,
-        _revisions: {
-          start: numRevs,
-          ids: [conflict1].concat(uuids)
-        }
-      };
-      var doc2 = {
-        _id: 'doc',
-        _rev: numRevs + '-' + conflict2,
-        _revisions: {
-          start: numRevs,
-          ids: [conflict2].concat(uuids)
-        }
-      };
-      return remote.bulkDocs([doc1], {new_edits: false}).then(function () {
-        return remote.replicate.to(db);
-      }).then(function (result) {
-        result.ok.should.equal(true);
-        result.docs_written.should.equal(1, 'correct # docs written (1)');
-        return db.info();
-      }).then(function (info) {
-        if (!testUtils.isSyncGateway() || info.doc_count) {
-          info.doc_count.should.equal(1, 'doc_count');
-        }
-        return db.get('doc', {open_revs: "all"});
-      }).then(function (doc) {
-        doc[0].ok._id.should.equal("doc");
-        doc[0].ok._rev.should.equal(doc1._rev);
-        return remote.bulkDocs([doc2], {new_edits: false});
-      }).then(function () {
-        return remote.replicate.to(db);
-      }).then(function (result) {
-        result.ok.should.equal(true);
-        result.docs_written.should.equal(1, 'correct # docs written (2)');
-        return db.info();
-      }).then(function (info) {
-        if (!testUtils.isSyncGateway() || info.doc_count) {
-          info.doc_count.should.equal(1, 'doc_count');
-        }
-        return db.get('doc', {open_revs: "all"});
-      }).then(function (docs) {
-        // order with open_revs is unspecified
-        docs.sort(function (a, b) {
-          return a.ok._rev < b.ok._rev ? -1 : 1;
-        });
-        docs[0].ok._id.should.equal("doc");
-        docs[1].ok._id.should.equal("doc");
-        docs[0].ok._rev.should.equal(doc1._rev);
-        docs[1].ok._rev.should.equal(doc2._rev);
-      });
-    });
-
-    it('issue 2779, undeletion when replicating', function () {
-      if (testUtils.isCouchMaster()) {
-        return true;
-      }
-      var db =  new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var rev;
-
-      function checkNumRevisions(num) {
-        return db.get('foo', {
-          open_revs: 'all',
-          revs: true
-        }).then(function (fullDocs) {
-          fullDocs[0].ok._revisions.ids.should.have.length(num,
-            'local is correct');
-        }).then(function () {
-          return remote.get('foo', {
-            open_revs: 'all',
-            revs: true
-          });
-        }).then(function (fullDocs) {
-          fullDocs[0].ok._revisions.ids.should.have.length(num,
-            'remote is correct');
-        });
-      }
-
-      return db.put({_id: 'foo'}).then(function (resp) {
-        rev = resp.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return checkNumRevisions(1);
-      }).then(function () {
-        return db.remove('foo', rev);
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return checkNumRevisions(2);
-      }).then(function () {
-        return db.allDocs({keys: ['foo']});
-      }).then(function (res) {
-        if (testUtils.isSyncGateway() && !res.rows[0].value) {
-          return remote.get('foo', {open_revs:'all'}).then(function (doc){
-            return db.put({_id: 'foo', _rev: doc[0].ok._rev});
-          });
-        } else {
-          rev = res.rows[0].value.rev;
-          return db.put({_id: 'foo', _rev: rev});
-        }
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return checkNumRevisions(3);
-      });
-    });
-
-    it('Test pull replication with many conflicts', function (done) {
-      var remote = new PouchDB(dbs.remote);
-
-      var numRevs = 200; // repro "url too long" error with open_revs
-      var docs = [];
-      for (var i = 0; i < numRevs; i++) {
-        var rev =  '1-' + PouchDB.utils.uuid(32, 16).toLowerCase();
-        docs.push({_id: 'doc', _rev: rev});
-      }
-
-      remote.bulkDocs({ docs: docs }, {new_edits: false}, function (err) {
-        should.not.exist(err);
-        PouchDB.replicate(
-          dbs.remote, dbs.name).on('complete', function (result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          var db = new PouchDB(dbs.name);
-          db.info(function (err, info) {
-            should.not.exist(err);
-            info.doc_count.should.equal(1, 'doc_count');
-            db.get('doc', {open_revs: "all"}, function (err, docs) {
-              should.not.exist(err);
-              var okDocs = docs.filter(function (doc) { return doc.ok; });
-              okDocs.should.have.length(numRevs);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test correct # docs replicated with staggered revs', function (done) {
-      // ensure we don't just process all the open_revs with
-      // every replication; we should only process the current subset
-      var remote = new PouchDB(dbs.remote);
-
-      var docs = [{_id: 'doc', _rev: '1-a'}, {_id: 'doc', _rev: '1-b'}];
-      remote.bulkDocs({ docs: docs }, {new_edits: false}, function (err) {
-        should.not.exist(err);
-        PouchDB.replicate(
-          dbs.remote, dbs.name).on('complete', function (result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(2);
-          result.docs_read.should.equal(2);
-          var docs = [{_id: 'doc', _rev: '1-c'}, {_id: 'doc', _rev: '1-d'}];
-          remote.bulkDocs({ docs: docs }, {new_edits: false}, function (err) {
-            should.not.exist(err);
-            PouchDB.replicate(
-              dbs.remote, dbs.name).on('complete', function (result) {
-              result.docs_written.should.equal(2);
-              result.docs_read.should.equal(2);
-              var db = new PouchDB(dbs.name);
-              db.info(function (err, info) {
-                should.not.exist(err);
-                info.doc_count.should.equal(1, 'doc_count');
-                db.get('doc', {open_revs: "all"}, function (err, docs) {
-                  should.not.exist(err);
-                  var okDocs = docs.filter(function (doc) {
-                    return doc.ok;
-                  });
-                  okDocs.should.have.length(4);
-                  done();
-                });
-              });
-            }).on('error', done);
-          });
-        }).on('error', done);
-      });
-    });
-
-    it('Local DB contains documents', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.bulkDocs({ docs: docs }, {}, function () {
-          db.replicate.from(dbs.remote, function () {
-            db.allDocs(function (err, result) {
-              result.rows.length.should.equal(docs.length);
-              db.info(function (err, info) {
-                if (!testUtils.isCouchMaster()) {
-                  info.update_seq.should.be.above(2, 'update_seq local');
-                }
-                info.doc_count.should.equal(3, 'doc_count local');
-                remote.info(function (err, info) {
-                  if (!testUtils.isCouchMaster()) {
-                    info.update_seq.should.be.above(2, 'update_seq remote');
-                  }
-                  if (!testUtils.isSyncGateway() || info.doc_count) {
-                    info.doc_count.should.equal(3, 'doc_count remote');
-                  }
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test basic push replication', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.to(dbs.remote, function (err, result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test basic push replication take 2', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.to(dbs.remote, function () {
-          remote.allDocs(function (err, result) {
-            result.rows.length.should.equal(docs.length);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 3,
-                doc_count: 3
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test basic push replication sequence tracking', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      db.put(doc1, function () {
-        db.replicate.to(dbs.remote, function (err, result) {
-          result.docs_read.should.equal(1);
-          db.replicate.to(dbs.remote, function (err, result) {
-            result.docs_read.should.equal(0);
-            db.replicate.to(dbs.remote, function (err, result) {
-              result.docs_read.should.equal(0);
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 1,
-                  doc_count: 1
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test checkpoint', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.from(dbs.remote, function (err, result) {
-          result.ok.should.equal(true);
-          result.docs_written.should.equal(docs.length);
-          db.replicate.from(dbs.remote, function (err, result) {
-            result.ok.should.equal(true);
-            result.docs_written.should.equal(0);
-            result.docs_read.should.equal(0);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 3,
-                doc_count: 3
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test live pull checkpoint', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }).then(function () {
-        var changeCount = docs.length;
-        var changes = db.changes({
-          live: true
-        }).on('change', function () {
-          if (--changeCount) {
-            return;
-          }
-          replication.cancel();
-          changes.cancel();
-        }).on('complete', function () {
-          db.replicate.from(dbs.remote).on('complete', function (details) {
-            details.docs_read.should.equal(0);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 3,
-                doc_count: 3
-              });
-              done();
-            });
-          });
-        }).on('error', done);
-        var replication = db.replicate.from(remote, { live: true });
-      });
-    });
-
-    it('Test live push checkpoint', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      function complete(details) {
-
-        if (testUtils.isSyncGateway()) {
-          // TODO investigate why Sync Gateway sometimes reads a
-          // document. This seems to come up 1 more in the browser
-          // and 0 more in node, but I've seen 1 in node.
-          details.docs_read.should.be.within(0, 1);
-        } else {
-          details.docs_read.should.equal(0);
-        }
-
-        db.info(function (err, info) {
-          verifyInfo(info, {
-            update_seq: 3,
-            doc_count: 3
-          });
-          done();
-        });
-      }
-
-      var finished = 0;
-      function isFinished() {
-        if (++finished !== 2) {
-          return;
-        }
-        db.replicate.to(dbs.remote)
-          .on('error', done)
-          .on('complete', complete);
-      }
-
-      db.bulkDocs({ docs: docs }).then(function () {
-
-        var changeCount = docs.length;
-        function onChange() {
-          if (--changeCount) {
-            return;
-          }
-          replication.cancel();
-          changes.cancel();
-        }
-
-        var changes = remote.changes({live: true})
-          .on('error', done)
-          .on('change', onChange)
-          .on('complete', isFinished);
-
-        var replication = db.replicate.to(remote, {live: true})
-          .on('error', done)
-          .on('complete', isFinished);
-
-      }).catch(done);
-    });
-
-    it('Test checkpoint 2', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc = {_id: '3', count: 0};
-      remote.put(doc, {}, function (err, results) {
-        db.replicate.from(dbs.remote, function (err, result) {
-          result.ok.should.equal(true);
-          doc._rev = results.rev;
-          doc.count++;
-          remote.put(doc, {}, function (err, results) {
-            doc._rev = results.rev;
-            doc.count++;
-            remote.put(doc, {}, function () {
-              db.replicate.from(dbs.remote, function (err, result) {
-                result.ok.should.equal(true);
-                result.docs_written.should.equal(1);
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 2,
-                    doc_count: 1
-                  });
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test checkpoint 3 :)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc = {_id: '3', count: 0};
-      db.put(doc, {}, function (err, results) {
-        PouchDB.replicate(db, remote, {}, function (err, result) {
-          result.ok.should.equal(true);
-          doc._rev = results.rev;
-          doc.count++;
-          db.put(doc, {}, function (err, results) {
-            doc._rev = results.rev;
-            doc.count++;
-            db.put(doc, {}, function () {
-              PouchDB.replicate(db, remote, {}, function (err, result) {
-                result.ok.should.equal(true);
-                result.docs_written.should.equal(1);
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 3,
-                    doc_count: 1
-                  });
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('#3136 open revs returned correctly 1', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {_id: 'foo'};
-      var chain = PouchDB.utils.Promise.resolve().then(function () {
-        return db.put(doc);
-      });
-
-      function addConflict(i) {
-        chain = chain.then(function () {
-          return db.bulkDocs({
-            docs: [{
-              _id: 'foo',
-              _rev: '2-' + i
-            }],
-            new_edits: false
-          });
-        });
-      }
-
-      for (var i = 0; i < 50; i++) {
-        addConflict(i);
-      }
-      return chain.then(function () {
-        var revs1;
-        var revs2;
-        return db.get('foo', {
-          conflicts: true,
-          revs: true,
-          open_revs: 'all'
-        }).then(function (res) {
-          revs1 = res.map(function (x) {
-            return x.ok._rev;
-          }).sort();
-          return db.replicate.to(remote);
-        }).then(function () {
-          return remote.get('foo', {
-            conflicts: true,
-            revs: true,
-            open_revs: 'all'
-          });
-        }).then(function (res) {
-          revs2 = res.map(function (x) {
-            return x.ok._rev;
-          }).sort();
-          revs1.should.deep.equal(revs2);
-        });
-      });
-    });
-
-    it('#3136 open revs returned correctly 2', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {_id: 'foo'};
-      var chain = PouchDB.utils.Promise.resolve().then(function () {
-        return db.put(doc);
-      });
-
-      function addConflict(i) {
-        chain = chain.then(function () {
-          return db.bulkDocs({
-            docs: [{
-              _id: 'foo',
-              _rev: '2-' + i,
-              _deleted: (i % 3 === 1)
-            }],
-            new_edits: false
-          });
-        });
-      }
-
-      for (var i = 0; i < 50; i++) {
-        addConflict(i);
-      }
-      return chain.then(function () {
-        var revs1;
-        var revs2;
-        return db.get('foo', {
-          conflicts: true,
-          revs: true,
-          open_revs: 'all'
-        }).then(function (res) {
-          revs1 = res.map(function (x) {
-            return x.ok._rev;
-          }).sort();
-          return db.replicate.to(remote);
-        }).then(function () {
-          return remote.get('foo', {
-            conflicts: true,
-            revs: true,
-            open_revs: 'all'
-          });
-        }).then(function (res) {
-          revs2 = res.map(function (x) {
-            return x.ok._rev;
-          }).sort();
-          revs1.should.deep.equal(revs2);
-        });
-      });
-    });
-
-    it('#3136 winningRev has a lower seq', function () {
-      var db1 = new PouchDB(dbs.name);
-      var db2 = new PouchDB(dbs.remote);
-      var tree = [
-        [
-          {_id: 'foo', _rev: '1-a',
-           _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-e', _deleted: true,
-           _revisions: { start: 2, ids: ['e', 'a']}},
-          {_id: 'foo', _rev: '3-g',
-           _revisions: { start: 3, ids: ['g', 'e', 'a']}}
-        ],
-        [
-          {_id: 'foo', _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}},
-          {_id: 'foo', _rev: '3-c',
-            _revisions: {start: 3, ids: ['c', 'b', 'a']}}
-        ],
-        [
-          {_id: 'foo', _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-d',
-            _revisions: {start: 2, ids: ['d', 'a']}},
-          {_id: 'foo', _rev: '3-h',
-            _revisions: {start: 3, ids: ['h', 'd', 'a']}},
-          {_id: 'foo', _rev: '4-f',
-            _revisions: {start: 4, ids: ['f', 'h', 'd', 'a']}}
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      tree.forEach(function (docs) {
-        chain = chain.then(function () {
-          var revs1;
-          var revs2;
-
-          return db1.bulkDocs({
-            docs: docs,
-            new_edits: false
-          }).then(function () {
-            return db1.replicate.to(db2);
-          }).then(function () {
-            return db1.get('foo', {
-              open_revs: 'all',
-              revs: true,
-              conflicts: true
-            });
-          }).then(function (res1) {
-            revs1 = res1.map(function (x) {
-              return x.ok._rev;
-            }).sort();
-
-            return db2.get('foo', {
-              open_revs: 'all',
-              revs: true,
-              conflicts: true
-            });
-          }).then(function (res2) {
-            revs2 = res2.map(function (x) {
-              return x.ok._rev;
-            }).sort();
-            revs1.should.deep.equal(revs2, 'same revs');
-          });
-        });
-      });
-      return chain;
-    });
-
-    it('#3136 same changes with style=all_docs', function () {
-      var db1 = new PouchDB(dbs.name);
-      var db2 = new PouchDB(dbs.remote);
-      var tree = [
-        [
-          {_id: 'foo', _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-e', _deleted: true,
-            _revisions: { start: 2, ids: ['e', 'a']}},
-          {_id: 'foo', _rev: '3-g',
-            _revisions: { start: 3, ids: ['g', 'e', 'a']}}
-        ],
-        [
-          {_id: 'foo', _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-b',
-            _revisions: {start: 2, ids: ['b', 'a']}},
-          {_id: 'foo', _rev: '3-c',
-            _revisions: {start: 3, ids: ['c', 'b', 'a']}}
-        ],
-        [
-          {_id: 'foo', _rev: '1-a',
-            _revisions: {start: 1, ids: ['a']}},
-          {_id: 'foo', _rev: '2-d',
-            _revisions: {start: 2, ids: ['d', 'a']}},
-          {_id: 'foo', _rev: '3-h',
-            _revisions: {start: 3, ids: ['h', 'd', 'a']}},
-          {_id: 'foo', _rev: '4-f',
-            _revisions: {start: 4, ids: ['f', 'h', 'd', 'a']}}
-        ]
-      ];
-
-      var chain = PouchDB.utils.Promise.resolve();
-      tree.forEach(function (docs) {
-        chain = chain.then(function () {
-          var changes1;
-          var changes2;
-
-          return db1.bulkDocs({
-            docs: docs,
-            new_edits: false
-          }).then(function () {
-            return db1.replicate.to(db2);
-          }).then(function () {
-            return db1.changes({style: 'all_docs'});
-          }).then(function (res1) {
-            changes1 = simplifyChanges(res1);
-            return db2.changes({style: 'all_docs'});
-          }).then(function (res2) {
-            changes2 = simplifyChanges(res2);
-
-            changes1.should.deep.equal(changes2, 'same changes');
-          });
-        });
-      });
-      return chain;
-    });
-
-    it('#3136 style=all_docs with conflicts', function () {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '2', integer: 11},
-        {_id: '3', integer: 12}
-      ];
-      var rev2;
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      return db.bulkDocs({ docs: docs1 }).then(function (info) {
-        docs2[0]._rev = info[2].rev;
-        docs2[1]._rev = info[3].rev;
-        return db.put(docs2[0]);
-      }).then(function () {
-        return db.put(docs2[1]);
-      }).then(function (info) {
-        rev2 = info.rev;
-        return PouchDB.replicate(db, remote);
-      }).then(function () {
-        // update remote once, local twice, then replicate from
-        // remote to local so the remote losing conflict is later in
-        // the tree
-        return db.put({
-          _id: '3',
-          _rev: rev2,
-          integer: 20
-        });
-      }).then(function (resp) {
-        var rev3Doc = {
-          _id: '3',
-          _rev: resp.rev,
-          integer: 30
-        };
-        return db.put(rev3Doc);
-      }).then(function () {
-        var rev4Doc = {
-          _id: '3',
-          _rev: rev2,
-          integer: 100
-        };
-        return remote.put(rev4Doc).then(function () {
-          return PouchDB.replicate(remote, db).then(function () {
-            return PouchDB.replicate(db, remote);
-          }).then(function () {
-            return db.changes({
-              include_docs: true,
-              style: 'all_docs',
-              conflicts: true
-            });
-          }).then(function (localChanges) {
-            return remote.changes({
-              include_docs: true,
-              style: 'all_docs',
-              conflicts: true
-            }).then(function (remoteChanges) {
-              localChanges = simplifyChanges(localChanges);
-              remoteChanges = simplifyChanges(remoteChanges);
-
-              localChanges.should.deep.equal(remoteChanges,
-                'same changes');
-            });
-          });
-        });
-      });
-    });
-
-    it('#3136 style=all_docs with conflicts reversed', function () {
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var docs2 = [
-        {_id: '2', integer: 11},
-        {_id: '3', integer: 12}
-      ];
-      var rev2;
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      return db.bulkDocs({ docs: docs1 }).then(function (info) {
-        docs2[0]._rev = info[2].rev;
-        docs2[1]._rev = info[3].rev;
-        return db.put(docs2[0]);
-      }).then(function () {
-        return db.put(docs2[1]);
-      }).then(function (info) {
-        rev2 = info.rev;
-        return PouchDB.replicate(db, remote);
-      }).then(function () {
-        // update remote once, local twice, then replicate from
-        // remote to local so the remote losing conflict is later in
-        // the tree
-        return db.put({
-          _id: '3',
-          _rev: rev2,
-          integer: 20
-        });
-      }).then(function (resp) {
-        var rev3Doc = {
-          _id: '3',
-          _rev: resp.rev,
-          integer: 30
-        };
-        return db.put(rev3Doc);
-      }).then(function () {
-        var rev4Doc = {
-          _id: '3',
-          _rev: rev2,
-          integer: 100
-        };
-        return remote.put(rev4Doc).then(function () {
-          return PouchDB.replicate(remote, db).then(function () {
-            return PouchDB.replicate(db, remote);
-          }).then(function () {
-            return db.changes({
-              include_docs: true,
-              style: 'all_docs',
-              conflicts: true,
-              descending: true
-            });
-          }).then(function (localChanges) {
-            return remote.changes({
-              include_docs: true,
-              style: 'all_docs',
-              conflicts: true,
-              descending: true
-            }).then(function (remoteChanges) {
-              localChanges = simplifyChanges(localChanges);
-              remoteChanges = simplifyChanges(remoteChanges);
-
-              localChanges.should.deep.equal(remoteChanges,
-                'same changes');
-            });
-          });
-        });
-      });
-    });
-
-    it('Test checkpoint read only 3 :)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var put = function (doc) {
-        return db.bulkDocs({docs: [doc]}).then(function (resp) {
-          return resp[0];
-        });
-      };
-      var err = {
-        "message": "_writer access is required for this request",
-        "name": "unauthorized",
-        "status": 401
-      };
-      db.put = function () {
-        if (typeof arguments[arguments.length - 1] === 'function') {
-          arguments[arguments.length - 1](err);
-        } else {
-          return PouchDB.utils.Promise.reject(err);
-        }
-      };
-      var doc = {_id: '3', count: 0};
-      put(doc).then(function (results) {
-        return PouchDB.replicate(db, remote).then(function (result) {
-          result.ok.should.equal(true);
-          doc._rev = results.rev;
-          doc.count++;
-          return put(doc);
-        });
-      }).then(function (results) {
-        doc._rev = results.rev;
-        doc.count++;
-        return put(doc);
-      }).then(function () {
-        return PouchDB.replicate(db, remote);
-      }).then(function (result) {
-        result.ok.should.equal(true);
-        result.docs_written.should.equal(1);
-        db.info(function (err, info) {
-          verifyInfo(info, {
-            update_seq: 3,
-            doc_count: 1
-          });
-          done();
-        });
-      }, function (a) {
-        done(JSON.stringify(a, false, 4));
-      });
-    });
-
-    it('Testing allDocs with some conflicts (issue #468)', function (done) {
-      var db1 = new PouchDB(dbs.name);
-      var db2 = new PouchDB(dbs.remote);
-      // we indeed needed replication to create failing test here!
-      var doc = {_id: 'foo', _rev: '1-a', value: 'generic'};
-      db1.put(doc, { new_edits: false }, function () {
-        db2.put(doc, { new_edits: false }, function () {
-          testUtils.putAfter(db2, {
-            _id: 'foo',
-            _rev: '2-b',
-            value: 'db2'
-          }, '1-a', function () {
-            testUtils.putAfter(db1, {
-              _id: 'foo',
-              _rev: '2-c',
-              value: 'whatever'
-            }, '1-a', function () {
-              testUtils.putAfter(db1, {
-                _id: 'foo',
-                _rev: '3-c',
-                value: 'db1'
-              }, '2-c', function () {
-                db1.get('foo', function (err, doc) {
-                  doc.value.should.equal('db1');
-                  db2.get('foo', function (err, doc) {
-                    doc.value.should.equal('db2');
-                    PouchDB.replicate(db1, db2, function () {
-                      PouchDB.replicate(db2, db1, function () {
-                        db1.get('foo', function (err, doc) {
-                          doc.value.should.equal('db1');
-                          db2.get('foo', function (err, doc) {
-                            doc.value.should.equal('db1');
-                            db1.allDocs({ include_docs: true },
-                              function (err, res) {
-                              res.rows.should.have.length.above(0, 'first');
-                              // redundant but we want to test it
-                              res.rows[0].doc.value.should.equal('db1');
-                              db2.allDocs({ include_docs: true },
-                                function (err, res) {
-                                res.rows.should.have.length.above(0, 'second');
-                                res.rows[0].doc.value.should.equal('db1');
-                                db1.info(function (err, info) {
-                                  // if auto_compaction is enabled, will
-                                  // be 5 because 2-c goes "missing" and
-                                  // the other db tries to re-put it
-                                  if (!testUtils.isCouchMaster()) {
-                                    info.update_seq.should.be.within(4, 5);
-                                  }
-                                  info.doc_count.should.equal(1);
-                                  db2.info(function (err, info2) {
-                                    verifyInfo(info2, {
-                                      update_seq: 3,
-                                      doc_count: 1
-                                    });
-                                    done();
-                                  });
-                                });
-                              });
-                            });
-                          });
-                        });
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    // CouchDB will not generate a conflict here, it uses a deteministic
-    // method to generate the revision number, however we cannot copy its
-    // method as it depends on erlangs internal data representation
-    it('Test basic conflict', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      var doc2 = {_id: 'adoc', bar: 'baz'};
-      db.put(doc1, function () {
-        remote.put(doc2, function () {
-     db.replicate.to(dbs.remote, function () {
-            remote.get('adoc', { conflicts: true }, function (err, result) {
-              result.should.have.property('_conflicts');
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 1,
-                  doc_count: 1
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test _conflicts key', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      var doc2 = {_id: 'adoc', bar: 'baz'};
-      var ddoc = {
-        "_id": "_design/conflicts",
-        views: {
-          conflicts: {
-            map: function (doc) {
-              if (doc._conflicts) {
-                emit(doc._id, [doc._rev].concat(doc._conflicts));
-              }
-            }.toString()
-          }
-        }
-      };
-      remote.put(ddoc, function () {
-        db.put(doc1, function () {
-          remote.put(doc2, function () {
-            db.replicate.to(dbs.remote, function () {
-              remote.query('conflicts/conflicts', {
-                reduce: false,
-                conflicts: true
-              }, function (_, res) {
-                res.rows.length.should.equal(1);
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 1,
-                    doc_count: 1
-                  });
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test basic live pull replication', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        var count = 0;
-        var finished = 0;
-        var isFinished = function () {
-          if (++finished !== 2) {
-            return;
-          }
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 4,
-              doc_count: 4
-            });
-            done();
-          });
-        };
-        var rep = db.replicate.from(dbs.remote, {
-          live: true
-        }).on('complete', isFinished);
-        var changes = db.changes({
-          live: true
-        }).on('change', function () {
-          ++count;
-          if (count === 3) {
-            return remote.put(doc1);
-          }
-          if (count === 4) {
-            rep.cancel();
-            changes.cancel();
-          }
-        }).on('complete', isFinished).on('error', done);
-      });
-    });
-
-    it('Test basic live push replication', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      db.bulkDocs({ docs: docs }, {}, function () {
-        var count = 0;
-        var finished = 0;
-        var isFinished = function () {
-          if (++finished !== 2) {
-            return;
-          }
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 4,
-              doc_count: 4
-            });
-            done();
-          });
-        };
-        var rep = remote.replicate.from(db, {
-          live: true
-        }).on('complete', isFinished);
-        var changes = remote.changes({
-          live: true
-        }).on('change', function () {
-          ++count;
-          if (count === 3) {
-            return db.put(doc1);
-          }
-          if (count === 4) {
-            rep.cancel();
-            changes.cancel();
-          }
-        }).on('complete', isFinished).on('error', done);
-      });
-    });
-
-    it('test-cancel-pull-replication', function (done) {
-      new PouchDB(dbs.remote, function (err, remote) {
-        var db = new PouchDB(dbs.name);
-        var docs = [
-          {_id: '0', integer: 0, string: '0'},
-          {_id: '1', integer: 1, string: '1'},
-          {_id: '2', integer: 2, string: '2'}
-        ];
-        var doc1 = {_id: 'adoc', foo: 'bar' };
-        var doc2 = {_id: 'anotherdoc', foo: 'baz'};
-        remote.bulkDocs({ docs: docs }, {}, function () {
-          var count = 0;
-          var replicate = db.replicate.from(remote, {
-            live: true
-          }).on('complete', function () {
-            remote.put(doc2);
-            setTimeout(function () {
-              changes.cancel();
-            }, 100);
-          });
-          var changes = db.changes({
-            live: true
-          }).on('complete', function () {
-            count.should.equal(4);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 4,
-                doc_count: 4
-              });
-              done();
-            });
-          }).on('change', function () {
-            ++count;
-            if (count === 3) {
-              remote.put(doc1);
-            }
-            if (count === 4) {
-              replicate.cancel();
-            }
-          }).on('error', done);
-        });
-      });
-    });
-
-    it('Test basic events', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }).then(function () {
-        db.replicate.to(dbs.remote)
-        .on('complete', function (res) {
-          should.exist(res);
-          db.replicate.to('http://0.0.0.0:13370')
-          .on('error', function (res) {
-            should.exist(res);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Replication filter', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      remote.bulkDocs({ docs: docs1 }, function () {
-        db.replicate.from(remote, {
-          filter: function (doc) {
-            return doc.integer % 2 === 0;
-          }
-        }).on('error', done).on('complete', function () {
-          db.allDocs(function (err, docs) {
-            if (err) { done(err); }
-            docs.rows.length.should.equal(2);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 2,
-                doc_count: 2
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Replication with different filters', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var more_docs = [
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 4, string: '4'}
-      ];
-      remote.bulkDocs({ docs: docs }, function () {
-        db.replicate.from(remote, {
-          filter: function (doc) {
-            return doc.integer % 2 === 0;
-          }
-        }, function () {
-          remote.bulkDocs({ docs: more_docs }, function () {
-            db.replicate.from(remote, {}, function (err, response) {
-              response.docs_written.should.equal(3);
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 5,
-                  doc_count: 5
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Replication doc ids', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var thedocs = [
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 4, string: '4'},
-        {_id: '5', integer: 5, string: '5'}
-      ];
-      remote.bulkDocs({ docs: thedocs }, function () {
-        db.replicate.from(remote, {
-          doc_ids: ['3', '4']
-        }, function (err, response) {
-          response.docs_written.should.equal(2);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 2,
-              doc_count: 2
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('2204 Invalid doc_ids', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var thedocs = [
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 4, string: '4'},
-        {_id: '5', integer: 5, string: '5'}
-      ];
-      return remote.bulkDocs({docs: thedocs}).then(function () {
-        return db.replicate.from(remote, {doc_ids: 'foo'});
-      }).catch(function (err) {
-        err.name.should.equal('bad_request');
-        err.reason.should.equal("`doc_ids` filter parameter is not a list.");
-      });
-    });
-
-    it('Replication since', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs1 = [
-        {_id: '1', integer: 1, string: '1'},
-        {_id: '2', integer: 2, string: '2'},
-        {_id: '3', integer: 3, string: '3'}
-      ];
-      remote.bulkDocs({ docs: docs1 }, function () {
-        remote.info(function (err, info) {
-          var update_seq = info.update_seq;
-          var docs2 = [
-            {_id: '4', integer: 4, string: '4'},
-            {_id: '5', integer: 5, string: '5'}
-          ];
-          remote.bulkDocs({ docs: docs2 }, function () {
-            db.replicate.from(remote, {
-              since: update_seq
-            }).on('complete', function (result) {
-              result.docs_written.should.equal(2);
-              db.replicate.from(remote, {
-                since: 0
-              }).on('complete', function (result) {
-                result.docs_written.should.equal(3);
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 5,
-                    doc_count: 5
-                  });
-                  done();
-                });
-              }).on('error', done);
-            }).on('error', done);
-          });
-        });
-      });
-    });
-
-    it('Replication with same filters', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var more_docs = [
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 4, string: '4'}
-      ];
-      remote.bulkDocs({ docs: docs }, function () {
-        db.replicate.from(remote, {
-          filter: function (doc) {
-            return doc.integer % 2 === 0;
-          }
-        }, function () {
-          remote.bulkDocs({ docs: more_docs }, function () {
-            db.replicate.from(remote, {
-              filter: function (doc) {
-                return doc.integer % 2 === 0;
-              }
-            }, function (err, response) {
-              response.docs_written.should.equal(1);
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 3,
-                  doc_count: 3
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Replication with filter that leads to some empty batches (#2689)',
-       function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 1},
-        {_id: '3', integer: 1},
-        {_id: '4', integer: 2},
-        {_id: '5', integer: 2}
-      ];
-      remote.bulkDocs({ docs: docs1 }, function () {
-        db.replicate.from(remote, {
-          batch_size: 2,
-          filter: function (doc) {
-            return doc.integer % 2 === 0;
-          }
-        }).on('complete', function () {
-          db.allDocs(function (err, docs) {
-            if (err) { done(err); }
-            docs.rows.length.should.equal(3);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 3,
-                doc_count: 3
-              });
-              done();
-            });
-          });
-        }).on('error', done);
-      });
-    });
-
-    it('Replication with deleted doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs1 = [
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3},
-        {_id: '4', integer: 4, _deleted: true}
-      ];
-      remote.bulkDocs({ docs: docs1 }, function () {
-        db.replicate.from(remote, function () {
-          db.allDocs(function (err, res) {
-            res.total_rows.should.equal(4);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 5,
-                doc_count: 4
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Replication with doc deleted twice', function (done) {
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs }).then(function () {
-        return remote.get('0');
-      }).then(function (doc) {
-        return remote.remove(doc);
-      }).then(function () {
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.total_rows.should.equal(2);
-        return remote.allDocs({ keys: [ '0' ] });
-      }).then(function (res) {
-        var row = res.rows[0];
-        should.not.exist(row.error);
-        // set rev to latest so we go at the end (otherwise new
-        // rev is 1 and the subsequent remove below won't win)
-        var doc = {
-          _id: '0',
-          integer: 10,
-          string: '10',
-          _rev: row.value.rev
-        };
-        return remote.put(doc);
-      }).then(function () {
-        return remote.get('0');
-      }).then(function (doc) {
-        return remote.remove(doc);
-      }).then(function () {
-        return db.replicate.from(remote);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.total_rows.should.equal(2);
-        db.info(function (err, info) {
-          verifyInfo(info, {
-            update_seq: 4,
-            doc_count: 2
-          });
-          done();
-        });
-      }).catch(function (err) {
-        done(JSON.stringify(err, false, 4));
-      });
-    });
-
-    it('Replication notifications', function (done) {
-      var changes = 0;
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var onChange = function (c) {
-        changes += c.docs.length;
-
-        if (changes === 3) {
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        }
-      };
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.from(dbs.remote).on('change', onChange);
-      });
-    });
-
-    it('Replication with remote conflict', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc = {_id: 'test', test: 'Remote 1'}, winningRev;
-      remote.post(doc, function (err, resp) {
-        doc._rev = resp.rev;
-        PouchDB.replicate(remote, db, function () {
-          doc.test = 'Local 1';
-          db.put(doc, function () {
-            doc.test = 'Remote 2';
-            remote.put(doc, function (err, resp) {
-              doc._rev = resp.rev;
-              doc.test = 'Remote 3';
-              remote.put(doc, function (err, resp) {
-                winningRev = resp.rev;
-                PouchDB.replicate(db, remote, function () {
-                  PouchDB.replicate(remote, db, function () {
-                    remote.get('test', { revs_info: true },
-                      function (err, remotedoc) {
-                      db.get('test', { revs_info: true },
-                        function (err, localdoc) {
-                        localdoc._rev.should.equal(winningRev);
-                        remotedoc._rev.should.equal(winningRev);
-                        db.info(function (err, info) {
-                          verifyInfo(info, {
-                            update_seq: 3,
-                            doc_count: 1
-                          });
-                          done();
-                        });
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Replicate and modify three times', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {
-        _id: 'foo',
-        generation: 1
-      };
-
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.get('foo');
-      }).then(function (doc) {
-        doc.generation.should.equal(1);
-        doc.generation = 2;
-        return remote.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return remote.replicate.to(db);
-      }).then(function () {
-        return db.get('foo');
-      }).then(function (doc) {
-        doc.generation.should.equal(2);
-        doc.generation = 3;
-        return db.put(doc);
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return db.get('foo', {conflicts: true});
-      }).then(function (doc) {
-        doc.generation.should.equal(3);
-        should.not.exist(doc._conflicts);
-      }).then(function () {
-        return remote.get('foo', {conflicts: true});
-      }).then(function (doc) {
-        doc.generation.should.equal(3);
-        should.not.exist(doc._conflicts);
-      });
-    });
-
-    function waitForChange(db, fun) {
-      return new PouchDB.utils.Promise(function (resolve) {
-        var remoteChanges = db.changes({live: true, include_docs: true});
-        remoteChanges.on('change', function (change) {
-          if (fun(change)) {
-            remoteChanges.cancel();
-            resolve();
-          }
-        });
-      });
-    }
-
-    it('live replication, starting offline', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      // id() is the first thing called
-      var origId = remote.id;
-      var i = 0;
-      remote.id = function () {
-        // Reject only the first 3 times
-        if (++i <= 3) {
-          return Promise.reject(new Error('flunking you'));
-        }
-        return origId.apply(remote, arguments);
-      };
-
-      return remote.post({}).then(function () {
-        return new Promise(function (resolve, reject) {
-          var rep = db.replicate.from(remote, {
-            live: true
-          });
-          rep.on('error', reject);
-        }).then(function () {
-            throw new Error('should have thrown error');
-          }, function (err) {
-            should.exist(err);
-          });
-      });
-    });
-
-    it('Replicates deleted docs (issue #2636)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var replication = db.replicate.to(remote, {
-        live: true
-      });
-
-      return db.post({}).then(function (res) {
-        var doc = {
-          _id: res.id,
-          _rev: res.rev
-        };
-        return db.remove(doc);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(0, 'deleted locally');
-      }).then(function () {
-        return waitForChange(remote, function (change) {
-          return change.deleted === true;
-        });
-      }).then(function () {
-        return remote.allDocs();
-      }).then(function (res) {
-        replication.cancel();
-        res.rows.should.have.length(0, 'deleted in remote');
-      });
-    });
-
-    it('Replicates deleted docs w/ delay (issue #2636)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var replication = db.replicate.to(remote, {
-        live: true
-      });
-
-      var doc;
-      return db.post({}).then(function (res) {
-        doc = {_id: res.id, _rev: res.rev};
-        return waitForChange(remote, function () { return true; });
-      }).then(function () {
-        return db.remove(doc);
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(0, 'deleted locally');
-      }).then(function () {
-        return waitForChange(remote, function (c) {
-          return c.id === doc._id && c.deleted;
-        });
-      }).then(function () {
-        return remote.allDocs();
-      }).then(function (res) {
-        replication.cancel();
-        res.rows.should.have.length(0, 'deleted in remote');
-      });
-    });
-
-    it('Replicates deleted docs w/ compaction', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var doc = {_id: 'foo'};
-      return db.put(doc).then(function (res) {
-        doc._rev = res.rev;
-        return db.replicate.to(remote);
-      }).then(function () {
-        return db.put(doc);
-      }).then(function (res) {
-        doc._rev = res.rev;
-        return db.remove(doc);
-      }).then(function () {
-        return db.compact();
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(0, 'deleted locally');
-      }).then(function () {
-        return db.replicate.to(remote);
-      }).then(function () {
-        return remote.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(0, 'deleted in remote');
-      });
-    });
-
-    it('Replicates modified docs (issue #2636)', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var replication = db.replicate.to(remote, {
-        live: true
-      });
-
-      return db.post({}).then(function (res) {
-        var doc = {
-          _id: res.id,
-          _rev: res.rev,
-          modified: 'yep'
-        };
-
-        return db.put(doc);
-      }).then(function () {
-        return db.allDocs({include_docs: true});
-      }).then(function (res) {
-        res.rows.should.have.length(1, 'one doc synced locally');
-        res.rows[0].doc.modified.should.equal('yep', 'modified locally');
-      }).then(function () {
-        return waitForChange(remote, function (change) {
-          return change.doc.modified === 'yep';
-        });
-      }).then(function () {
-        return remote.allDocs({include_docs: true});
-      }).then(function (res) {
-        replication.cancel();
-        res.rows.should.have.length(1, '1 doc in remote');
-        res.rows[0].doc.modified.should.equal('yep', 'modified in remote');
-      });
-    });
-
-    it('Replication of multiple remote conflicts (#789)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc = {_id: '789', _rev: '1-a', value: 'test'};
-      function createConflicts(db, callback) {
-        db.put(doc, { new_edits: false }, function () {
-          testUtils.putAfter(db, {
-            _id: '789',
-            _rev: '2-a',
-            value: 'v1'
-          }, '1-a', function () {
-            testUtils.putAfter(db, {
-              _id: '789',
-              _rev: '2-b',
-              value: 'v2'
-            }, '1-a', function () {
-              testUtils.putAfter(db, {
-                _id: '789',
-                _rev: '2-c',
-                value: 'v3'
-              }, '1-a', function () {
-                callback();
-              });
-            });
-          });
-        });
-      }
-      createConflicts(remote, function () {
-        db.replicate.from(remote, function (err, result) {
-          result.ok.should.equal(true);
-          // in this situation, all the conflicting revisions should be read and
-          // written to the target database (this is consistent with CouchDB)
-          result.docs_written.should.equal(3);
-          result.docs_read.should.equal(3);
-          db.info(function (err, info) {
-            if (!testUtils.isCouchMaster()) {
-              info.update_seq.should.be.above(0);
-            }
-            info.doc_count.should.equal(1);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Replicate large number of docs', function (done) {
-      if ('saucelabs' in testUtils.params()) {
-        return done();
-      }
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs = [];
-      var num = 30;
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      remote.bulkDocs({ docs: docs }, function () {
-        db.replicate.from(remote, {}, function () {
-          db.allDocs(function (err, res) {
-            res.total_rows.should.equal(num);
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 30,
-                doc_count: 30
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Ensure checkpoint after deletion', function (done) {
-      var db1name = dbs.name;
-      var adoc = { '_id': 'adoc' };
-      var newdoc = { '_id': 'newdoc' };
-      var db1 = new PouchDB(dbs.name);
-      var db2 = new PouchDB(dbs.remote);
-      db1.post(adoc, function () {
-        PouchDB.replicate(db1, db2).on('complete', function () {
-          db1.destroy(function () {
-            var fresh = new PouchDB(db1name);
-            fresh.post(newdoc, function () {
-              PouchDB.replicate(fresh, db2).on('complete', function () {
-                db2.allDocs(function (err, docs) {
-                  docs.rows.length.should.equal(2);
-                  done();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('issue #1001 cb as 3rd argument', function (done) {
-      PouchDB.replicate('http://example.com', dbs.name, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('issue #1001 cb as 4th argument', function (done) {
-      var url = 'http://example.com';
-      PouchDB.replicate(url, dbs.name, {}, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('issue #909 Filtered replication bails at paging limit',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs = [];
-      var num = 100;
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      num = 100;
-      var docList = [];
-      for (i = 0; i < num; i += 5) {
-        docList.push('doc_' + i);
-      }
-      // uncomment this line to test only docs higher than paging limit
-      docList = [
-        'doc_33',
-        'doc_60',
-        'doc_90'
-      ];
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.from(dbs.remote, {
-          live: false,
-          doc_ids: docList
-        }, function (err, result) {
-          result.docs_written.should.equal(docList.length);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 3,
-              doc_count: 3
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it.skip('(#1240) - get error', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      // 10 test documents
-      var num = 10;
-      var docs = [];
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      // Initialize remote with test documents
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        var get = remote.get;
-        function first_replicate() {
-          // Mock remote.get to fail writing doc_3 (fourth doc)
-          remote.get = function () {
-            // Simulate failure to get the document with id 'doc_4'
-            // This should block the replication at seq 4
-            if (arguments[0] === 'doc_4') {
-              arguments[2].apply(null, [{}]);
-            } else {
-              get.apply(this, arguments);
-            }
-          };
-          // Replicate and confirm failure, docs_written and target docs
-          db.replicate.from(remote, function (err, result) {
-            should.exist(err);
-            should.exist(result);
-            result.docs_written.should.equal(4);
-            function check_docs(id) {
-              if (!id) {
-                second_replicate();
-                return;
-              }
-              db.get(id, function (err, exists) {
-                if (exists) {
-                  should.not.exist(err);
-                } else {
-                  should.exist(err);
-                }
-                check_docs(docs.shift());
-              });
-            }
-            var docs = [
-              [
-                'doc_0',
-                true
-              ],
-              [
-                'doc_1',
-                true
-              ],
-              [
-                'doc_2',
-                true
-              ],
-              [
-                'doc_3',
-                false
-              ],
-              [
-                'doc_4',
-                false
-              ],
-              [
-                'doc_5',
-                false
-              ],
-              [
-                'doc_6',
-                false
-              ],
-              [
-                'doc_7',
-                false
-              ],
-              [
-                'doc_8',
-                false
-              ],
-              [
-                'doc_9',
-                false
-              ]
-            ];
-            check_docs(docs.shift());
-          });
-        }
-        function second_replicate() {
-          // Restore remote.get to original
-          remote.get = get;
-          // Replicate and confirm success, docs_written and target docs
-          db.replicate.from(remote, function (err, result) {
-            should.not.exist(err);
-            should.exist(result);
-            result.docs_written.should.equal(6);
-            function check_docs(id, exists) {
-              if (!id) {
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 6,
-                    doc_count: 6
-                  });
-                  done();
-                });
-                return;
-              }
-              db.get(id, function (err) {
-                if (exists) {
-                  should.not.exist(err);
-                } else {
-                  should.exist(err);
-                }
-                check_docs(docs.shift());
-              });
-            }
-            var docs = [
-              [
-                'doc_0',
-                true
-              ],
-              [
-                'doc_1',
-                true
-              ],
-              [
-                'doc_2',
-                true
-              ],
-              [
-                'doc_3',
-                true
-              ],
-              [
-                'doc_4',
-                true
-              ],
-              [
-                'doc_5',
-                true
-              ],
-              [
-                'doc_6',
-                true
-              ],
-              [
-                'doc_7',
-                true
-              ],
-              [
-                'doc_8',
-                true
-              ],
-              [
-                'doc_9',
-                true
-              ]
-            ];
-            check_docs(docs.shift());
-          });
-        }
-        // Done the test
-        first_replicate();
-      });
-    });
-
-    it.skip('Get error 2', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      // 10 test documents
-      var num = 10;
-      var docs = [];
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i
-        });
-      }
-      // Initialize remote with test documents
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        var get = remote.get;
-        function first_replicate() {
-          // Mock remote.get to fail writing doc_3 (fourth doc)
-          remote.get = function () {
-            // Simulate failure to get the document with id 'doc_4'
-            // This should block the replication at seq 4
-            if (arguments[0] === 'doc_4') {
-              arguments[2].apply(null, [{
-                status: 500,
-                error: 'mock error',
-                reason: 'mock get failure'
-              }]);
-            } else {
-              get.apply(this, arguments);
-            }
-          };
-          // Replicate and confirm failure, docs_written and target docs
-          db.replicate.from(remote, function (err, result) {
-            err.status.should.equal(500);
-            err.error.should.equal('Replication aborted');
-            err.reason.should.equal('src.get completed with error');
-            err.details.status.should.equal(500);
-            err.details.error.should.equal('mock error');
-            err.details.reason.should.equal('mock get failure');
-            result.errors[0].status.should.equal(500);
-            result.errors[0].error.should.equal('mock error');
-            result.errors[0].reason.should.equal('mock get failure');
-            result.docs_written.should.equal(4);
-            function check_docs(id) {
-              if (!id) {
-                second_replicate();
-                return;
-              }
-              db.get(id, function (err, exists) {
-                if (exists) {
-                  should.not.exist(err);
-                } else {
-                  should.exist(err);
-                }
-                check_docs(docs.shift());
-              });
-            }
-            var docs = [
-              [
-                'doc_0',
-                true
-              ],
-              [
-                'doc_1',
-                true
-              ],
-              [
-                'doc_2',
-                true
-              ],
-              [
-                'doc_3',
-                false
-              ],
-              [
-                'doc_4',
-                false
-              ],
-              [
-                'doc_5',
-                false
-              ],
-              [
-                'doc_6',
-                false
-              ],
-              [
-                'doc_7',
-                false
-              ],
-              [
-                'doc_8',
-                false
-              ],
-              [
-                'doc_9',
-                false
-              ]
-            ];
-            check_docs(docs.shift());
-          });
-        }
-        function second_replicate() {
-          // Restore remote.get to original
-          remote.get = get;
-          // Replicate and confirm success, docs_written and target docs
-          db.replicate.from(remote, function (err, result) {
-            should.not.exist(err);
-            should.exist(result);
-            result.docs_written.should.equal(6);
-            function check_docs(id, exists) {
-              if (!id) {
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 6,
-                    doc_count: 6
-                  });
-                  done();
-                });
-                return;
-              }
-              db.get(id, function (err) {
-                if (exists) {
-                  should.not.exist(err);
-                } else {
-                  should.exist(err);
-                }
-                check_docs(docs.shift());
-              });
-            }
-            var docs = [
-              [
-                'doc_0',
-                true
-              ],
-              [
-                'doc_1',
-                true
-              ],
-              [
-                'doc_2',
-                true
-              ],
-              [
-                'doc_3',
-                true
-              ],
-              [
-                'doc_4',
-                true
-              ],
-              [
-                'doc_5',
-                true
-              ],
-              [
-                'doc_6',
-                true
-              ],
-              [
-                'doc_7',
-                true
-              ],
-              [
-                'doc_8',
-                true
-              ],
-              [
-                'doc_9',
-                true
-              ]
-            ];
-            check_docs(docs.shift());
-          });
-        }
-        // Done the test
-        first_replicate();
-      });
-    });
-
-    it('(#4963) Ensure successful docs are saved but seq not updated if single doc fails to replicate', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      // 10 test documents
-      var num = 10;
-      var docs = [];
-      for (var i = 0; i < num; i++) {
-        docs.push({
-          _id: 'doc_' + i,
-          foo: 'bar_' + i,
-          // needed to cause the code to fetch using get
-          _attachments: {
-            text: {
-              content_type: 'text\/plain',
-              data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
-            }
-          }
-        });
-      }
-      // Initialize remote with test documents
-      remote.bulkDocs({ docs: docs }, {}, function (err, results) {
-        var bulkGet = remote.bulkGet;
-        function first_replicate() {
-          remote.bulkGet = function () {
-            var getResults = [];
-            for (var i = 0; i < docs.length; i++) {
-              var doc = docs[i];
-              getResults.push({
-                id: doc._id,
-                docs: [ {
-                  ok: {
-                    _id: doc._id,
-                    foo: doc.foo,
-                    _attachments: doc._attachments,
-                    _rev: results[i].rev
-                  }
-                } ]
-              });
-            }
-            // Mock remote.get to fail writing doc_3 (fourth doc)
-            getResults[3].docs[0] = { error: new Error('timeout') };
-            return Promise.resolve({ results: getResults });
-          };
-          // Replicate and confirm failure, docs_written and target docs
-          db.replicate.from(remote).then(function () {
-            done(new Error('First replication should fail'));
-          }).catch(function (err) {
-            // We expect that first replication should fail
-            should.exist(err);
-
-            err.result.ok.should.equal(false);
-            err.result.docs_written.should.equal(9);
-            err.result.last_seq.should.equal(0);
-
-            var docs = [
-              [ 'doc_0', true ],
-              [ 'doc_1', true ],
-              [ 'doc_2', true ],
-              [ 'doc_3', false ],
-              [ 'doc_4', true ],
-              [ 'doc_5', true ],
-              [ 'doc_6', true ],
-              [ 'doc_7', true ],
-              [ 'doc_8', true ],
-              [ 'doc_9', true ]
-            ];
-
-            function check_docs(id, exists) {
-              if (!id) {
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 9,
-                    doc_count: 9
-                  });
-
-                  second_replicate();
-                });
-                return;
-              }
-              db.get(id, function (err) {
-                if (exists) {
-                  should.not.exist(err);
-                } else {
-                  should.exist(err);
-                }
-                check_docs.apply(this, docs.shift());
-              });
-            }
-
-            check_docs.apply(this, docs.shift());
-          });
-        }
-        function second_replicate() {
-          // Restore remote.bulkGet to original
-          remote.bulkGet = bulkGet;
-          // Replicate and confirm success, docs_written and target docs
-          db.replicate.from(remote).then(function (result) {
-            should.exist(result);
-            result.docs_written.should.equal(1);
-            result.last_seq.should.equal(10);
-
-            var docs = [ 'doc_0', 'doc_1', 'doc_2', 'doc_3', 'doc_4', 'doc_5', 'doc_6', 'doc_7', 'doc_8', 'doc_9' ];
-
-            function check_docs(id) {
-              if (!id) {
-                db.info(function (err, info) {
-                  verifyInfo(info, {
-                    update_seq: 10,
-                    doc_count: 10
-                  });
-                  done();
-                });
-                return;
-              }
-              db.get(id, function (err) {
-                should.not.exist(err);
-                check_docs(docs.shift());
-              });
-            }
-
-            check_docs(docs.shift());
-          }).catch(done);
-        }
-        // Done the test
-        first_replicate();
-      });
-    });
-
-    it.skip("error updating checkpoint", function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({docs: docs}, {}, function () {
-        var get = remote.get;
-        var local_count = 0;
-        // Mock remote.get to fail writing doc_3 (fourth doc)
-        remote.get = function () {
-          // Simulate failure to get the checkpoint
-          if (arguments[0].slice(0, 6) === '_local') {
-            local_count++;
-            if (local_count === 2) {
-              arguments[1].apply(null, [{
-                status: 500,
-                error: 'mock get error',
-                reason: 'simulate an error updating the checkpoint'
-              }]);
-            } else {
-              get.apply(this, arguments);
-            }
-          } else {
-            get.apply(this, arguments);
-          }
-        };
-
-        db.replicate.from(remote).on('error', function (err) {
-          should.exist(err);
-          db.info(function (err, info) {
-            verifyInfo(info, {
-              update_seq: 2,
-              doc_count: 2
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    // Should not start replication over if last_seq mismatches in checkpoints
-    // and it can be resolved some other way
-    it('#3999-1 should not start over if last_seq mismatches', function () {
-
-      var source = new PouchDB(dbs.remote);
-      var mismatch = false;
-      var failWrite = false;
-      var checkpoint;
-      var checkpointCount = 0;
-
-      // 1. This is where we fake the mismatch:
-      var putte = source.put;
-
-      source.put = function (doc) {
-
-        // We need the checkpoint id so we can inspect it later
-        if (/local/.test(doc._id)) {
-          checkpointCount++;
-          checkpoint = doc._id;
-        }
-
-        if (failWrite && checkpointCount > 1) {
-          return PouchDB.utils.Promise.reject({
-            status: 0,
-            message: 'Database encountered an unknown error'
-          });
-        }
-
-        return putte.apply(this, arguments);
-      };
-
-      // 2. We measure that the replication starts in the expected
-      // place in the 'changes' function
-      var changes = source.changes;
-      source.changes = function (opts) {
-
-        if (mismatch) {
-          opts.since.should.not.equal(0);
-        }
-        return changes.apply(source, arguments);
-      };
-
-
-      var doc = { _id: '3', count: 0 };
-      var put;
-
-      return source.put({ _id: '4', count: 1 }, {}).then(function () {
-        return source.put(doc, {});
-      }).then(function (_put) {
-        put = _put;
-        // Do one replication, this replication
-        // will fail writing one checkpoint
-        failWrite = true;
-        return source.replicate.to(dbs.name, { batch_size: 1 });
-      }).catch(function () {
-        failWrite = false;
-      }).then(function () {
-        // Verify that checkpoints are indeed mismatching:
-        should.exist(checkpoint);
-        var target = new PouchDB(dbs.name);
-        return PouchDB.utils.Promise.all([
-          target.get(checkpoint),
-          source.get(checkpoint)
-        ]);
-      }).then(function (res) {
-        res[0].session_id.should.equal(res[1].session_id);
-        res[0].last_seq.should.not.equal(res[1].last_seq);
-
-        doc._rev = put.rev;
-        doc.count++;
-        return source.put(doc, {});
-      }).then(function () {
-        // Trigger the mismatch on the 2nd replication
-        mismatch = true;
-        return source.replicate.to(dbs.name);
-      });
-    });
-
-    it('#3999-2 should start over if no common session is found', function () {
-
-      var source = new PouchDB(dbs.remote);
-      var mismatch = false;
-      var writeStrange = false;
-      var checkpoint;
-      var checkpointCount = 0;
-
-      // 1. This is where we fake the mismatch:
-      var putte = source.put;
-      source.put = function (doc) {
-
-        // We need the checkpoint id so we can inspect it later
-        if (/local/.test(doc._id)) {
-          checkpointCount++;
-          checkpoint = doc._id;
-        }
-
-        if (!writeStrange || checkpointCount < 1) {
-          return putte.apply(this, arguments);
-        }
-
-        // Change session id of source checkpoint to mismatch
-        doc.session_id = "aaabbbbb";
-        doc.history[0].session_id = "aaabbbbb";
-        return putte.apply(this, arguments);
-      };
-
-      // 2. We measure that the replication starts in the expected
-      // place in the 'changes' function
-      var changes = source.changes;
-      source.changes = function (opts) {
-        if(mismatch) {
-          // We expect this replication to start over,
-          // so the correct value of since is 0
-          // if it's higher, the replication read the checkpoint
-          // without caring for session id
-          opts.since.should.equal(0);
-          mismatch = false;
-        }
-
-        return changes.apply(source, arguments);
-      };
-
-      var doc = { _id: '3', count: 0 };
-      var put;
-
-      return source.put(doc, {}).then(function (_put) {
-        put = _put;
-        writeStrange = true;
-        // Do one replication, to not start from 0
-        return source.replicate.to(dbs.name);
-      }).then(function () {
-        writeStrange = false;
-
-        // Verify that checkpoints are indeed mismatching:
-        should.exist(checkpoint);
-        var target = new PouchDB(dbs.name);
-        return PouchDB.utils.Promise.all([
-          target.get(checkpoint),
-          source.get(checkpoint)
-        ]);
-      }).then(function (res) {
-        // [0] = target checkpoint, [1] = source checkpoint
-        res[0].session_id.should.not.equal(res[1].session_id);
-
-        doc._rev = put.rev;
-        doc.count++;
-        return source.put(doc, {});
-      }).then(function () {
-        // Trigger the mismatch on the 2nd replication
-        mismatch = true;
-        return source.replicate.to(dbs.name);
-      });
-    });
-
-    it('#3999-3 should not start over if common session is found', function () {
-
-      var source = new PouchDB(dbs.remote);
-      var mismatch = false;
-      var writeStrange = false;
-      var checkpoint;
-      var checkpointCount = 0;
-
-      // 1. This is where we fake the mismatch:
-      var putte = source.put;
-      source.put = function (doc) {
-
-        // We need the checkpoint id so we can inspect it later
-        if (/local/.test(doc._id)) {
-          checkpointCount++;
-          checkpoint = doc._id;
-        }
-
-        if (!writeStrange || checkpointCount < 1) {
-          return putte.apply(this, arguments);
-        }
-
-        // Change session id of source checkpoint to mismatch
-        var session = doc.session_id;
-
-        doc.session_id = "aaabbbbb";
-        doc.history[0].session_id = "aaabbbbb";
-        // put a working session id in the history:
-        doc.history.push({
-          session_id: session,
-          last_seq: doc.last_seq
-        });
-        return putte.apply(this, arguments);
-      };
-
-      // 2. We measure that the replication starts in the expected
-      // place in the 'changes' function
-      var changes = source.changes;
-
-      source.changes = function (opts) {
-        if(mismatch) {
-          // If we resolve to 0, the checkpoint resolver has not
-          // been going through the sessions
-          opts.since.should.not.equal(0);
-
-          mismatch = false;
-        }
-
-        return changes.apply(source, arguments);
-      };
-
-
-      var doc = { _id: '3', count: 0 };
-      var put;
-
-      return source.put(doc, {}).then(function (_put) {
-        put = _put;
-        // Do one replication, to not start from 0
-        writeStrange = true;
-        return source.replicate.to(dbs.name);
-      }).then(function () {
-        writeStrange = false;
-        // Verify that checkpoints are indeed mismatching:
-        should.exist(checkpoint);
-        var target = new PouchDB(dbs.name);
-        return PouchDB.utils.Promise.all([
-          target.get(checkpoint),
-          source.get(checkpoint)
-        ]);
-      }).then(function (res) {
-        // [0] = target checkpoint, [1] = source checkpoint
-        res[0].session_id.should.not.equal(res[1].session_id);
-
-        doc._rev = put.rev;
-        doc.count++;
-        return source.put(doc, {});
-      }).then(function () {
-        // Trigger the mismatch on the 2nd replication
-        mismatch = true;
-        return source.replicate.to(dbs.name);
-      });
-    });
-
-    it('#3999-4 should "upgrade" an old checkpoint', function () {
-
-      var secondRound = false;
-      var writeStrange = false;
-      var checkpoint;
-      var checkpointCount = 0;
-      var source = new PouchDB(dbs.remote);
-      var target = new PouchDB(dbs.name);
-
-      // 1. This is where we fake the mismatch:
-      var putter = function (doc) {
-
-        // We need the checkpoint id so we can inspect it later
-        if (/local/.test(doc._id)) {
-          checkpointCount++;
-          checkpoint = doc._id;
-        }
-
-        var args = [].slice.call(arguments, 0);
-
-        // Write an old-style checkpoint on the first replication:
-        if (writeStrange && checkpointCount >= 1) {
-          var newDoc = {
-            _id: doc._id,
-            last_seq: doc.last_seq
-          };
-
-          args.shift();
-          args.unshift(newDoc);
-        }
-
-        if (this === source) {
-          return sourcePut.apply(this, args);
-        }
-
-        return targetPut.apply(this, args);
-      };
-
-      var sourcePut = source.put;
-      source.put = putter;
-      var targetPut =  target.put;
-      target.put = putter;
-
-      var changes = source.changes;
-      source.changes = function (opts) {
-        if (secondRound) {
-          // Test 1: Check that we read the old style local doc
-          // and didn't start from 0
-          opts.since.should.not.equal(0);
-        }
-        return changes.apply(source, arguments);
-      };
-
-       var doc = { _id: '3', count: 0 };
-
-       return source.put({ _id: '4', count: 1 }, {}).then(function () {
-         writeStrange = true;
-         return source.replicate.to(target);
-       }).then(function () {
-         writeStrange = false;
-         // Verify that we have old checkpoints:
-         should.exist(checkpoint);
-         var target = new PouchDB(dbs.name);
-         return PouchDB.utils.Promise.all([
-           target.get(checkpoint),
-           source.get(checkpoint)
-         ]);
-       }).then(function (res) {
-        // [0] = target checkpoint, [1] = source checkpoint
-        should.not.exist(res[0].session_id);
-        should.not.exist(res[1].session_id);
-
-         return source.put(doc, {});
-       }).then(function () {
-         // Do one replication, check that we start from expected last_seq
-         secondRound = true;
-         return source.replicate.to(target);
-       }).then(function () {
-         should.exist(checkpoint);
-         return source.get(checkpoint);
-       }).then(function (res) {
-         should.exist(res.version);
-         should.exist(res.replicator);
-         should.exist(res.session_id);
-         res.version.should.equal(1);
-         res.session_id.should.be.a('string');
-       });
-    });
-
-    it('(#1307) - replicate empty database', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.replicate.from(remote, function (err, result) {
-        should.not.exist(err);
-        should.exist(result);
-        result.docs_written.should.equal(0);
-        db.info(function (err, info) {
-          verifyInfo(info, {
-            update_seq: 0,
-            doc_count: 0
-          });
-          done();
-        });
-      });
-    });
-
-
-    // This fails as it somehow triggers an xhr abort in the http adapter in
-    // node which doesnt have xhr....
-    it.skip('Syncing should stop if one replication fails (issue 838)',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      var doc2 = {_id: 'anotherdoc', foo: 'baz'};
-      var finished = false;
-      var replications = db.replicate.sync(remote, {
-        live: true
-      }).on('complete',  function () {
-        if (finished) {
-          return;
-        }
-        finished = true;
-        remote.put(doc2, function () {
-          setTimeout(function () {
-            db.allDocs(function (err, res) {
-              res.total_rows.should.be.below(2);
-              done();
-            });
-          }, 100);
-        });
-      });
-      db.put(doc1, function () {
-        replications.pull.cancel();
-      });
-    });
-
-    it("Reporting write failures (#942)", function (done) {
-      var docs = [{_id: 'a', _rev: '1-a'}, {_id: 'b', _rev: '1-b'}];
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.bulkDocs({docs: docs}, {new_edits: false}, function () {
-        var bulkDocs = remote.bulkDocs;
-        var bulkDocsCallCount = 0;
-        remote.bulkDocs = function (content, opts, callback) {
-          return new PouchDB.utils.Promise(function (fulfill, reject) {
-            if (typeof callback !== 'function') {
-              callback = function (err, resp) {
-                if (err) {
-                  reject(err);
-                } else {
-                  fulfill(resp);
-                }
-              };
-            }
-
-            // mock a successful write for the first
-            // document and a failed write for the second
-            var doc = content.docs[0];
-
-            if (/^_local/.test(doc._id)) {
-              return bulkDocs.apply(remote, [content, opts, callback]);
-            }
-
-            if (bulkDocsCallCount === 0) {
-              bulkDocsCallCount++;
-              callback(null, [{ok: true, id: doc._id, rev: doc._rev}]);
-            } else if (bulkDocsCallCount === 1) {
-              bulkDocsCallCount++;
-              callback(null, [{
-                id: doc._id,
-                error: 'internal server error',
-                reason: 'test document write error'
-              }]);
-            } else {
-              bulkDocs.apply(remote, [content, opts, callback]);
-            }
-          });
-        };
-
-        db.replicate.to(remote, {batch_size: 1, retry: false},
-                        function (err, result) {
-          should.not.exist(result);
-          should.exist(err);
-          err.result.docs_read.should.equal(2, 'docs_read');
-          err.result.docs_written.should.equal(1, 'docs_written');
-          err.result.doc_write_failures.should.equal(1, 'doc_write_failures');
-          remote.bulkDocs = bulkDocs;
-          db.replicate.to(remote, {batch_size: 1, retry: false},
-                          function (err, result) {
-            // checkpoint should not be moved past first doc
-            // should continue from this point and retry second doc
-            result.docs_read.should.equal(1, 'second replication, docs_read');
-            result.docs_written.should
-              .equal(1, 'second replication, docs_written');
-            result.doc_write_failures.should
-              .equal(0, 'second replication, doc_write_failures');
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 2,
-                doc_count: 2
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it("Reporting write failures if whole saving fails (#942)",
-      function (done) {
-      var docs = [{_id: 'a', _rev: '1-a'}, {_id: 'b', _rev: '1-b'}];
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.bulkDocs({docs: docs}, {new_edits: false}, function () {
-        var bulkDocs = remote.bulkDocs;
-        remote.bulkDocs = function (docs, opts, callback) {
-          if (typeof callback !== 'function') {
-            return PouchDB.utils.Promise.reject(new Error());
-          }
-          callback(new Error());
-        };
-
-        db.replicate.to(remote, {batch_size: 1, retry: false},
-                        function (err, result) {
-          should.not.exist(result);
-          should.exist(err);
-          err.result.docs_read.should.equal(1, 'docs_read');
-          err.result.docs_written.should.equal(0, 'docs_written');
-          err.result.doc_write_failures.should.equal(1, 'doc_write_failures');
-          err.result.last_seq.should.equal(0, 'last_seq');
-          remote.bulkDocs = bulkDocs;
-          db.replicate.to(remote, {batch_size: 1, retry: false},
-                          function (err, result) {
-            result.doc_write_failures.should
-              .equal(0, 'second replication, doc_write_failures');
-            result.docs_written.should
-              .equal(2, 'second replication, docs_written');
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test consecutive replications with different query_params',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var myDocs = [
-        {_id: '0', integer: 0, string: '0'},
-        {_id: '1', integer: 1, string: '1'},
-        {_id: '2', integer: 2, string: '2'},
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 5, string: '5'}
-      ];
-      remote.bulkDocs({ docs: myDocs }, {}, function () {
-        var filterFun = function (doc, req) {
-          if (req.query.even) {
-            return doc.integer % 2 === 0;
-          } else {
-            return true;
-          }
-        };
-        db.replicate.from(dbs.remote, {
-          filter: filterFun,
-          query_params: { 'even': true }
-        }, function (err, result) {
-          result.docs_written.should.equal(2);
-          db.replicate.from(dbs.remote, {
-            filter: filterFun,
-            query_params: { 'even': false }
-          }, function (err, result) {
-            result.docs_written.should.equal(3);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test consecutive replications with different query_params and promises',
-      function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var myDocs = [
-        {_id: '0', integer: 0, string: '0'},
-        {_id: '1', integer: 1, string: '1'},
-        {_id: '2', integer: 2, string: '2'},
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 5, string: '5'}
-      ];
-      var filterFun;
-      remote.bulkDocs({ docs: myDocs }).then(function () {
-        filterFun = function (doc, req) {
-          if (req.query.even) {
-            return doc.integer % 2 === 0;
-          } else {
-            return true;
-          }
-        };
-        return db.replicate.from(dbs.remote, {
-          filter: filterFun,
-          query_params: { 'even': true }
-        });
-      }).then(function (result) {
-        result.docs_written.should.equal(2);
-        return db.replicate.from(dbs.remote, {
-          filter: filterFun,
-          query_params: { 'even': false }
-        });
-      }).then(function (result) {
-        result.docs_written.should.equal(3);
-        done();
-      }).catch(done);
-    });
-
-    it('Test consecutive replications with different doc_ids', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var myDocs = [
-        {_id: '0', integer: 0, string: '0'},
-        {_id: '1', integer: 1, string: '1'},
-        {_id: '2', integer: 2, string: '2'},
-        {_id: '3', integer: 3, string: '3'},
-        {_id: '4', integer: 5, string: '5'}
-      ];
-      remote.bulkDocs({ docs: myDocs }, {}, function () {
-        db.replicate.from(dbs.remote, {
-          doc_ids: ['0', '4']
-        }, function (err, result) {
-          result.docs_written.should.equal(2);
-          db.replicate.from(dbs.remote, {
-            doc_ids: ['1', '2', '3']
-          }, function (err, result) {
-            result.docs_written.should.equal(3);
-            db.replicate.from(dbs.remote, {
-              doc_ids: ['5']
-            }, function (err, result) {
-              result.docs_written.should.equal(0);
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 5,
-                  doc_count: 5
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('doc count after multiple replications', function (done) {
-
-      var runs = 2;
-      // helper. remove each document in db and bulk load docs into same
-      function rebuildDocuments(db, docs, callback) {
-        db.allDocs({ include_docs: true }, function (err, response) {
-          var count = 0;
-          var limit = response.rows.length;
-          if (limit === 0) {
-            bulkLoad(db, docs, callback);
-          }
-          response.rows.forEach(function (doc) {
-            db.remove(doc, function () {
-              ++count;
-              if (count === limit) {
-                bulkLoad(db, docs, callback);
-              }
-            });
-          });
-        });
-      }
-
-      // helper.
-      function bulkLoad(db, docs, callback) {
-        db.bulkDocs({ docs: docs }, function (err, results) {
-          if (err) {
-            console.error('Unable to bulk load docs.  Err: ' +
-                          JSON.stringify(err));
-            return;
-          }
-          callback(results);
-        });
-      }
-
-      // The number of workflow cycles to perform. 2+ was always failing
-      // reason for this test.
-      var workflow = function (name, remote, x) {
-        // some documents.  note that the variable Date component,
-        //thisVaries, makes a difference.
-        // when the document is otherwise static, couch gets the same hash
-        // when calculating revision.
-        // and the revisions get messed up in pouch
-        var docs = [
-          {
-            _id: '0',
-            integer: 0,
-            thisVaries: new Date(),
-            common: true
-          },
-          {
-            _id: '1',
-            integer: 1,
-            thisVaries: new Date(),
-            common: true
-          },
-          {
-            _id: '2',
-            integer: 2,
-            thisVaries: new Date(),
-            common: true
-          },
-          {
-            _id: '3',
-            integer: 3,
-            thisVaries: new Date(),
-            common: true
-          },
-          {
-            "_id": "_design/common",
-            views: {
-              common: {
-                map: function (doc) {
-                  if (doc.common) {
-                    emit(doc._id, doc._rev);
-                  }
-                }.toString()
-              }
-            }
-          }
-        ];
-        var dbr = new PouchDB(remote);
-        rebuildDocuments(dbr, docs, function () {
-          var db = new PouchDB(name);
-          db.replicate.from(remote, function () {
-            db.query('common/common', { reduce: false },
-              function (err, result) {
-                // -1 for the design doc
-                result.rows.length.should.equal(docs.length - 1);
-                if (--x) {
-                  workflow(name, remote, x);
-                } else {
-                  db.info(function (err, info) {
-                    verifyInfo(info, {
-                      update_seq: 5,
-                      doc_count: 5
-                    });
-                    done();
-                  });
-                }
-              }
-            );
-          });
-        });
-      };
-
-      workflow(dbs.name, dbs.remote, runs);
-    });
-
-    it('issue #300 rev id unique per doc', function (done) {
-      var remote = new PouchDB(dbs.remote);
-      var db = new PouchDB(dbs.name);
-      var docs = [{ _id: 'a' }, { _id: 'b' }];
-      remote.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.from(dbs.remote, function () {
-          db.allDocs(function (err, result) {
-            result.rows.length.should.equal(2);
-            result.rows[0].id.should.equal('a');
-            result.rows[1].id.should.equal('b');
-            db.info(function (err, info) {
-              verifyInfo(info, {
-                update_seq: 2,
-                doc_count: 2
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('issue #585 Store checkpoint on target db.', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docs = [{ _id: 'a' }, { _id: 'b' }];
-      db.bulkDocs({ docs: docs }, {}, function () {
-        db.replicate.to(dbs.remote, function (err, result) {
-          result.docs_written.should.equal(docs.length);
-          remote.destroy(function () {
-            db.replicate.to(dbs.remote, function (err, result) {
-              result.docs_written.should.equal(docs.length);
-              db.info(function (err, info) {
-                verifyInfo(info, {
-                  update_seq: 2,
-                  doc_count: 2
-                });
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-    it('should work with a read only source', function (done) {
-      var src = new PouchDB(dbs.name);
-      var target = new PouchDB(dbs.remote);
-      var err = {
-        "message": "_writer access is required for this request",
-        "name": "unauthorized",
-        "status": 401
-      };
-      src.bulkDocs({docs: [
-        {_id: '0', integer: 0, string: '0'},
-        {_id: '1', integer: 1, string: '1'},
-        {_id: '2', integer: 2, string: '2'}
-      ]}).then(function () {
-        src.put = function () {
-          if (typeof arguments[arguments.length - 1] === 'function') {
-            arguments[arguments.length - 1](err);
-          } else {
-            return PouchDB.utils.Promise.reject(err);
-          }
-        };
-        return src.replicate.to(target);
-      }).then(function () {
-        target.info(function (err, info) {
-          verifyInfo(info, {
-            update_seq: 3,
-            doc_count: 3
-          });
-          done();
-        });
-      }, function (a) {
-        done(JSON.stringify(a, false, 4));
-      });
-    });
-
-    it('issue #2342 update_seq after replication', function (done) {
-      var docs = [];
-      for (var i = 0; i < 10; i++) {
-        docs.push({_id: i.toString()});
-      }
-
-      var remote = new PouchDB(dbs.remote);
-      var db = new PouchDB(dbs.name);
-
-      remote.bulkDocs({ docs: docs }, {}, function (err, res) {
-        res.forEach(function (row, i) {
-          docs[i]._rev = row.rev;
-          if (i % 2 === 0) {
-            docs[i]._deleted = true;
-          }
-        });
-        remote.bulkDocs({docs: docs}, {}, function () {
-          db.replicate.from(dbs.remote, function () {
-            db.info(function (err, info) {
-              db.changes({
-                descending: true,
-                limit: 1
-              }).on('change', function (change) {
-                change.changes.should.have.length(1);
-
-                // not a valid assertion in CouchDB 2.0
-                if (!testUtils.isCouchMaster()) {
-                  change.seq.should.equal(info.update_seq);
-                }
-                done();
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('issue #2393 update_seq after new_edits + replication', function (done) {
-      // the assertions below do not hold in a clustered CouchDB
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-
-      var docs = [{
-        '_id': 'foo',
-        '_rev': '1-x',
-        '_revisions': {
-          'start': 1,
-          'ids': ['x']
-        }
-      }];
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      remote.bulkDocs({docs: docs, new_edits: false}, function (err) {
-        should.not.exist(err);
-        remote.bulkDocs({docs: docs, new_edits: false}, function (err) {
-          should.not.exist(err);
-          db.replicate.from(dbs.remote, function () {
-            db.info(function (err, info) {
-              var changes = db.changes({
-                descending: true,
-                limit: 1
-              }).on('change', function (change) {
-                change.changes.should.have.length(1);
-                change.seq.should.equal(info.update_seq);
-                changes.cancel();
-              }).on('complete', function () {
-                remote.info(function (err, info) {
-                  var rchanges = remote.changes({
-                    descending: true,
-                    limit: 1
-                  }).on('change', function (change) {
-                    change.changes.should.have.length(1);
-                    change.seq.should.equal(info.update_seq);
-                    rchanges.cancel();
-                  }).on('complete', function () {
-                    done();
-                  }).on('error', done);
-                });
-              }).on('error', done);
-            });
-          });
-        });
-      });
-    });
-
-    it('should cancel for live replication', function (done) {
-      var remote = new PouchDB(dbs.remote);
-      var db = new PouchDB(dbs.name);
-      var rep = db.replicate.from(remote, {live: true});
-      var called = false;
-      rep.on('change', function () {
-        if (called) {
-          done(new Error('called too many times!'));
-        } else {
-          called = true;
-          rep.cancel();
-          remote.put({}, 'foo').then(function () {
-            return remote.put({}, 'bar');
-          }).then(function () {
-            setTimeout(function () {
-              done();
-            }, 500);
-          });
-        }
-      });
-      remote.put({}, 'hazaa');
-    });
-
-    it('#2970 should replicate remote database w/ deleted conflicted revs',
-        function (done) {
-      var local = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docid = "mydoc";
-
-      function uuid() {
-        return PouchDB.utils.uuid(32, 16).toLowerCase();
-      }
-
-      // create a bunch of rando, good revisions
-      var numRevs = 5;
-      var uuids = [];
-      for (var i = 0; i < numRevs - 1; i++) {
-        uuids.push(uuid());
-      }
-
-      // good branch
-      // this branch is one revision ahead of the conflicted branch
-      var a_conflict = uuid();
-      var a_burner = uuid();
-      var a_latest = uuid();
-      var a_rev_num = numRevs + 2;
-      var a_doc = {
-        _id: docid,
-        _rev: a_rev_num + '-' + a_latest,
-        _revisions: {
-          start: a_rev_num,
-          ids: [ a_latest, a_burner, a_conflict ].concat(uuids)
-        }
-      };
-
-      // conflicted deleted branch
-      var b_conflict = uuid();
-      var b_deleted = uuid();
-      var b_rev_num = numRevs + 1;
-      var b_doc = {
-        _id: docid,
-        _rev: b_rev_num + '-' + b_deleted,
-        _deleted: true,
-        _revisions: {
-          start: b_rev_num,
-          ids: [ b_deleted, b_conflict ].concat(uuids)
-        }
-      };
-
-      // push the conflicted documents
-      return remote.bulkDocs([ a_doc, b_doc ], {
-        new_edits: false
-      }).then(function () {
-        return remote.get(docid, { open_revs: 'all' }).then(function (revs) {
-          revs.length.should.equal(2, 'correct number of open revisions');
-          revs[0].ok._id.should.equal(docid, 'rev 1, correct document id');
-          revs[1].ok._id.should.equal(docid, 'rev 2, correct document id');
-          // order of revisions is not specified
-          ((
-            revs[0].ok._rev === a_doc._rev &&
-            revs[1].ok._rev === b_doc._rev) ||
-          (
-            revs[0].ok._rev === b_doc._rev &&
-            revs[1].ok._rev === a_doc._rev)
-          ).should.equal(true);
-        });
-      })
-
-      // attempt to replicate
-      .then(function () {
-        return local.replicate.from(remote).then(function (result) {
-          result.ok.should.equal(true, 'replication result was ok');
-          // # of documents is 2 because deleted
-          // conflicted revision counts as one
-          result.docs_written.should.equal(2,
-            'replicated the correct number of documents');
-        });
-      })
-
-      .then(function () { done(); }, done);
-    });
-
-
-    // test validate_doc_update, which is a reasonable substitute
-    // for testing design doc replication of non-admin users, since we
-    // always test in admin party
-    it('#2268 dont stop replication if single forbidden', function (done) {
-
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === undefined) {
-              throw {forbidden: 'Document must have a foo.'};
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'bar'}, {foo: 'baz'}, {}, {foo: 'quux'}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(4);
-          res.docs_written.should.equal(3);
-          res.doc_write_failures.should.equal(1);
-          res.errors.should.have.length(1);
-
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(4); // 3 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(4); // 3 plus the invalid doc
-        }).then(done);
-      });
-    });
-
-    it('#2268 dont stop replication if single unauth', function (done) {
-
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === undefined) {
-              throw {unauthorized: 'Document must have a foo.'};
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'bar'}, {foo: 'baz'}, {}, {foo: 'quux'}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(4);
-          res.docs_written.should.equal(3);
-          res.doc_write_failures.should.equal(1);
-          res.errors.should.have.length(1);
-
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(4); // 3 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(4); // 3 plus the invalid doc
-        }).then(done);
-      });
-    });
-
-    it('#2268 dont stop replication if many unauth', function (done) {
-
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === undefined) {
-              throw {unauthorized: 'Document must have a foo.'};
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'bar'}, {foo: 'baz'}, {}, {foo: 'quux'}, {}, {},
-                      {foo: 'toto'}, {}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(8);
-          res.docs_written.should.equal(4);
-          res.doc_write_failures.should.equal(4);
-          res.errors.should.have.length(4);
-
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(5); // 4 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(8); // 4 valid and 4 invalid
-        }).then(done);
-      });
-    });
-
-    // Errors from validate_doc_update should have the message
-    // defined in PourchDB.Errors instead of the thrown value.
-    it('#3171 Forbidden validate_doc_update error message',
-        function (done) {
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === 'object') {
-              throw { forbidden: { foo: 'is object' } };
-            } else if (newDoc.foo === 'string') {
-              throw { forbidden: 'Document foo is string' };
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'string'}, {}, {foo: 'object'}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(3);
-          res.docs_written.should.equal(1);
-          res.doc_write_failures.should.equal(2);
-          res.errors.should.have.length(2);
-          res.errors.forEach(function (e) {
-            e.status.should.equal(PouchDB.Errors.FORBIDDEN.status,
-                                  'correct error status returned');
-            e.name.should.equal(PouchDB.Errors.FORBIDDEN.name,
-                                'correct error name returned');
-            e.message.should.equal(PouchDB.Errors.FORBIDDEN.message,
-                                   'correct error message returned');
-          });
-
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(2); // 1 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(3); // 1 valid and 2 invalid
-        }).then(done);
-      });
-    });
-
-    it.skip('Test immediate replication canceling', function (done) {
-      //See  http://pouchdb.com/guides/replication.html : Cancelling replication
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var replicationHandler = remote.replicate.to(db, {
-        live: true,
-        retry: true
-      });
-
-      replicationHandler.on('complete', function () {
-        done();
-      }).on('error', done);
-
-      replicationHandler.cancel();
-    });
-
-    it('#3171 Unauthorized validate_doc_update error message',
-        function (done) {
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo === 'object') {
-              throw { unauthorized: { foo: 'is object' } };
-            } else if (newDoc.foo === 'string') {
-              throw { unauthorized: 'Document foo is string' };
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'string'}, {}, {foo: 'object'}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(3);
-          res.docs_written.should.equal(1);
-          res.doc_write_failures.should.equal(2);
-          res.errors.should.have.length(2);
-          res.errors.forEach(function (e) {
-            e.status.should.equal(PouchDB.Errors.UNAUTHORIZED.status,
-                                  'correct error status returned');
-            e.name.should.equal(PouchDB.Errors.UNAUTHORIZED.name,
-                                'correct error name returned');
-            e.message.should.equal(PouchDB.Errors.UNAUTHORIZED.message,
-                                   'correct error message returned');
-          });
-
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(2); // 1 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(3); // 1 valid and 2 invalid
-        }).then(done);
-      });
-    });
-
-    it('#3070 Doc IDs with validate_doc_update errors',
-        function (done) {
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (adapters[1] !== 'http' || !isCouchDB) {
-          return done();
-        }
-
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo) {
-              throw { unauthorized: 'go away, no picture' };
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [{foo: 'string'}, {}, {foo: 'object'}];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          return db.replicate.to(dbs.remote);
-        }).then(function (res) {
-          var ids = [];
-          res.ok.should.equal(true);
-          res.docs_read.should.equal(3);
-          res.docs_written.should.equal(1);
-          res.doc_write_failures.should.equal(2);
-          res.errors.should.have.length(2);
-          res.errors.forEach(function (e) {
-            should.exist(e.id, 'get doc id with error message');
-            ids.push(e.id);
-          });
-          ids = ids.filter(function (id) {
-            return ids.indexOf(id) === ids.lastIndexOf(id);
-          });
-          ids.length.should.equal(res.errors.length,
-                                  'doc ids are unique');
-          return remote.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(2); // 1 plus the validate doc
-          return db.allDocs({limit: 0});
-        }).then(function (res) {
-          res.total_rows.should.equal(3); // 1 valid and 2 invalid
-        }).then(done);
-      });
-    });
-
-    it('#3270 triggers "denied" events', function (done) {
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (/*adapters[1] !== 'http' || */!isCouchDB) {
-          return done();
-        }
-        if (adapters[0] !== 'local' || adapters[1] !== 'http') {
-          return done();
-        }
-
-        var deniedErrors = [];
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo) {
-              throw { unauthorized: 'go away, no picture' };
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [
-            {_id: 'foo1', foo: 'string'},
-            {_id: 'nofoo'},
-            {_id: 'foo2', foo: 'object'}
-          ];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          var replication = db.replicate.to(dbs.remote);
-          replication.on('denied', function (error) {
-            deniedErrors.push(error);
-          });
-          return replication;
-        }).then(function () {
-          deniedErrors.length.should.equal(2);
-          deniedErrors[0].name.should.equal('unauthorized');
-          deniedErrors[1].name.should.equal('unauthorized');
-          done();
-        }).catch(done);
-      });
-    });
-
-    it('#3606 - live replication with filtered ddoc', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      return remote.bulkDocs([{
-          _id: '_design/myddoc',
-          filters: {
-            myfilter: function (doc) {
-              return doc.name === 'barbara';
-            }.toString()
-          }
-        },
-        {_id: 'a', name: 'anna'},
-        {_id: 'b', name: 'barbara'},
-        {_id: 'c', name: 'charlie'}
-      ]).then(function () {
-        return new Promise(function (resolve, reject) {
-          var replicate = remote.replicate.to(db, {
-            filter: 'myddoc/myfilter',
-            live: true
-          }).on('change', function () {
-            replicate.cancel();
-          }).on('complete', resolve)
-            .on('error', reject);
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('b');
-      });
-    });
-
-    it('#3606 - live repl with filtered ddoc+query_params', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      return remote.bulkDocs([{
-          _id: '_design/myddoc',
-          filters: {
-            myfilter: function (doc, req) {
-              return doc.name === req.query.name;
-            }.toString()
-          }
-        },
-        {_id: 'a', name: 'anna'},
-        {_id: 'b', name: 'barbara'},
-        {_id: 'c', name: 'charlie'}
-      ]).then(function () {
-        return new Promise(function (resolve, reject) {
-          var replicate = remote.replicate.to(db, {
-            filter: 'myddoc/myfilter',
-            query_params: {name: 'barbara'},
-            live: true
-          }).on('change', function () {
-            replicate.cancel();
-          }).on('complete', resolve)
-            .on('error', reject);
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('b');
-      });
-    });
-
-    it('#3606 - live repl with doc_ids', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      return remote.bulkDocs([{
-        _id: '_design/myddoc',
-          filters: {
-            myfilter: function (doc, req) {
-              return doc.name === req.query.name;
-            }.toString()
-          }
-        },
-        {_id: 'a', name: 'anna'},
-        {_id: 'b', name: 'barbara'},
-        {_id: 'c', name: 'charlie'}
-      ]).then(function () {
-        return new Promise(function (resolve, reject) {
-          var replicate = remote.replicate.to(db, {
-            doc_ids: ['b'],
-            live: true
-          }).on('change', function () {
-            replicate.cancel();
-          }).on('complete', resolve)
-            .on('error', reject);
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('b');
-      });
-    });
-
-    it('#3606 - live repl with view', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      return remote.bulkDocs([{
-        _id: '_design/myddoc',
-        views: {
-          mymap: {
-            map: function (doc) {
-              if (doc.name === 'barbara') {
-                emit(doc._id, null);
-              }
-            }.toString()
-          }
-        }
-      },
-        {_id: 'a', name: 'anna'},
-        {_id: 'b', name: 'barbara'},
-        {_id: 'c', name: 'charlie'}
-      ]).then(function () {
-        return new Promise(function (resolve, reject) {
-          var replicate = remote.replicate.to(db, {
-            filter: '_view',
-            view: 'myddoc/mymap',
-            live: true
-          }).on('change', function () {
-            replicate.cancel();
-          }).on('complete', resolve)
-            .on('error', reject);
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('b');
-      });
-    });
-
-    it('#3569 - 409 during replication', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      // we know we're easily going to go over that limit
-      // because of all the parallel replications we're doing
-      db.setMaxListeners(100);
-
-      function timeoutPromise(delay, fun) {
-        return new Promise(function (resolve) {
-          setTimeout(resolve, delay);
-        }).then(fun);
-      }
-
-      return Promise.all([
-        db.put({_id: 'foo'}).then(function () {
-          return db.get('foo');
-        }).then(function (doc) {
-          return db.remove(doc);
-        }).then(function () {
-          return db.replicate.to(remote);
-        }),
-        db.replicate.to(remote),
-        timeoutPromise(0, function () {
-          return db.replicate.to(remote);
-        }),
-        timeoutPromise(1, function () {
-          return db.replicate.to(remote);
-        }),
-        timeoutPromise(2, function () {
-          return db.replicate.to(remote);
-        })
-      ]).then(function () {
-        return db.info();
-      }).then(function (localInfo) {
-        return remote.info().then(function (remoteInfo) {
-          localInfo.doc_count.should.equal(remoteInfo.doc_count);
-        });
-      });
-    });
-
-    it('#3270 triggers "change" events with .docs property', function (done) {
-      var replicatedDocs = [];
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: docs }, {}).then(function () {
-        var replication = db.replicate.to(dbs.remote);
-        replication.on('change', function (change) {
-          replicatedDocs = replicatedDocs.concat(change.docs);
-        });
-        return replication;
-      })
-      .then(function () {
-        replicatedDocs.sort(function (a, b) {
-          return a._id > b._id ? 1 : -1;
-        });
-        replicatedDocs.length.should.equal(3);
-        replicatedDocs[0]._id.should.equal('0');
-        replicatedDocs[1]._id.should.equal('1');
-        replicatedDocs[2]._id.should.equal('2');
-        done();
-      })
-      .catch(done);
-    });
-
-    it('#3543 replication with a ddoc filter', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs([{
-        _id: '_design/myddoc',
-        filters: {
-          myfilter: function (doc) {
-            return doc._id === 'a';
-          }.toString()
-        }
-      },
-        {_id: 'a'},
-        {_id: 'b'},
-        {_id: 'c'}
-      ]).then(function () {
-        return remote.replicate.to(db, {filter: 'myddoc/myfilter'});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-        res.rows[0].id.should.equal('a');
-      });
-    });
-
-    it("#3578 replication with a ddoc filter w/ _deleted=true", function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs([{
-        _id: '_design/myddoc',
-        filters: {
-          myfilter: function (doc) {
-            return doc._id === 'a' || doc._id === 'b';
-          }.toString()
-        }
-      },
-        {_id: 'a'},
-        {_id: 'b'},
-        {_id: 'c'}
-      ]).then(function () {
-        return remote.replicate.to(db, {filter: 'myddoc/myfilter'});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(2);
-      }).then(function () {
-        return remote.get('a');
-      }).then(function (doc) {
-        doc._deleted = true;
-        return remote.put(doc);
-      }).then(function () {
-        return remote.replicate.to(db, {filter: 'myddoc/myfilter'});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(1);
-      });
-    });
-
-    it("#3578 replication with a ddoc filter w/ remove()", function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs([{
-        _id: '_design/myddoc',
-        filters: {
-          myfilter: function (doc) {
-            return doc._id === 'a' || doc._id === 'b';
-          }.toString()
-        }
-      },
-        {_id: 'a'},
-        {_id: 'b'},
-        {_id: 'c'}
-      ]).then(function () {
-        return remote.replicate.to(db, {filter: 'myddoc/myfilter'});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(2);
-      }).then(function (){
-        return remote.get('a');
-      }).then(function (doc) {
-        return remote.remove(doc);
-      }).then(function () {
-        return remote.replicate.to(db, {filter: 'myddoc/myfilter'});
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (docs) {
-        docs.rows.should.have.length(1);
-      });
-    });
-
-    it("#2454 info() call breaks taskqueue", function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      remote.bulkDocs(docs).then(function () {
-
-        var repl = db.replicate.from(remote, {live: true});
-        repl.on('complete', done.bind(null, null));
-
-        remote.info().then(function () {
-          repl.cancel();
-        }).catch(done);
-      }).catch(done);
-    });
-
-
-    it('4094 cant fetch server uuid', function (done) {
-
-      var ajax = PouchDB.utils.ajax;
-
-      PouchDB.utils.ajax = function (opts, cb) {
-        var uri = PouchDB.utils.parseUri(opts.url);
-        if (uri.path === '/') {
-          cb(new Error('flunking you'));
-        } else {
-          ajax.apply(this, arguments);
-        }
-      };
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var _complete = 0;
-      function complete() {
-        if (++_complete === 2) {
-          PouchDB.utils.ajax = ajax;
-          done();
-        }
-      }
-
-      var rep = db.replicate.from(remote, {live: true, retry: true})
-        .on('complete', complete);
-
-      var changes = db.changes({live: true}).on('change', function () {
-        rep.cancel();
-        changes.cancel();
-      }).on('complete', complete);
-
-      remote.post({a: 'doc'});
-    });
-
-    it('#4293 Triggers extra replication events', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var hasChange = false;
-      function change() {
-        hasChange = true;
-      }
-
-      var _complete = 0;
-      function complete() {
-        if (++_complete === 2) {
-          hasChange.should.equal(false);
-          done();
-        }
-      }
-
-      function paused() {
-        // Because every setTimeout should be justified :)
-        // We are testing a negative, that there are no extra events
-        // triggered from our replication, cancelling the replication will
-        // cancel the event anyway so we wait a short period and give it time
-        // to fire (since there is nothing to wait deteministically for)
-        // Without the setTimeout this will pass, just less likely to catch
-        // the failing case
-        setTimeout(function () {
-          push.cancel();
-          pull.cancel();
-        }, 100);
-      }
-
-      var push = remote.replicate.from(db, {live: true})
-        .on('paused', paused)
-        .on('complete', complete);
-
-      var pull = db.replicate.from(remote, {live: true})
-        .on('change', change)
-        .on('complete', complete);
-
-      db.post({a: 'doc'});
-    });
-
-    it('#4276 Triggers paused error', function (done) {
-
-      if (!(/http/.test(dbs.remote) && !/http/.test(dbs.name))) {
-        return done();
-      }
-
-      var err = {
-        "message": "_writer access is required for this request",
-        "name": "unauthorized",
-        "status": 401
-      };
-
-      var ajax = PouchDB.utils.ajax;
-      PouchDB.utils.ajax = function (opts, cb) {
-        cb(err);
-      };
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{foo: 'bar'}]).then(function () {
-
-        var repl = db.replicate.to(remote, {live: true, retry: true});
-
-        repl.on('paused', function (err) {
-          if (err) {
-            repl.cancel();
-          }
-        });
-        repl.on('complete', function () {
-          PouchDB.utils.ajax = ajax;
-          done();
-        });
-      });
-    });
-
-    it('Heartbeat gets passed', function (done) {
-
-      if (!(/http/.test(dbs.remote) && !/http/.test(dbs.name))) {
-        return done();
-      }
-
-      var seenHeartBeat = false;
-      var ajax = PouchDB.utils.ajax;
-      PouchDB.utils.ajax = function (opts) {
-        if (/heartbeat/.test(opts.url)) {
-          seenHeartBeat = true;
-        }
-        ajax.apply(this, arguments);
-      };
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs([{foo: 'bar'}]).then(function () {
-        return db.replicate.from(remote, {heartbeat: 10});
-      }).then(function () {
-        seenHeartBeat.should.equal(true);
-        PouchDB.utils.ajax = ajax;
-        done();
-      });
-    });
-
-    it('Timeout gets passed', function (done) {
-
-      if (!(/http/.test(dbs.remote) && !/http/.test(dbs.name))) {
-        return done();
-      }
-
-      var seenTimeout = false;
-      var ajax = PouchDB.utils.ajax;
-      PouchDB.utils.ajax = function (opts) {
-        // the http adapter takes 5s off the provided timeout
-        if (/timeout=15000/.test(opts.url)) {
-          seenTimeout = true;
-        }
-        ajax.apply(this, arguments);
-      };
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return remote.bulkDocs([{foo: 'bar'}]).then(function () {
-        return db.replicate.from(remote, {timeout: 20000});
-      }).then(function () {
-        seenTimeout.should.equal(true);
-        PouchDB.utils.ajax = ajax;
-        done();
-      });
-    });
-
-  });
-});
-
-// This test only needs to run for one configuration, and it slows stuff
-// down
-downAdapters.map(function () {
-
-  describe('suite2 test.replication.js-down-test', function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    it('replicate from down server test', function (done) {
-      var source = new PouchDB('http://infiniterequest.com', {
-        ajax: {timeout: 10}
-      });
-      var target = new PouchDB(dbs.name);
-      source.replicate.to(target, function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.replication_events.js b/tests/integration/test.replication_events.js
deleted file mode 100644
index 28920ff..0000000
--- a/tests/integration/test.replication_events.js
+++ /dev/null
@@ -1,257 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-
-adapters.forEach(function (adapters) {
-  var title = 'test.replication_events.js-' + adapters[0] + '-' + adapters[1];
-  describe('suite2 ' + title, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    it('#3852 Test basic starting empty', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var repl = db.replicate.to(dbs.remote, {retry: true, live: true});
-      var counter = 0;
-
-      repl.on('complete', function () { done(); });
-
-      repl.on('active', function () {
-        counter++;
-        if (!(counter === 2 || counter === 4)) {
-          done('active fired incorrectly');
-        }
-      });
-
-      repl.on('paused', function () {
-        counter++;
-        // We should receive a paused event when replication
-        // starts because there is nothing to replicate
-        if (counter === 1) {
-          db.bulkDocs([{_id: 'a'}, {_id: 'b'}]);
-        } else if (counter === 3) {
-          db.bulkDocs([{_id: 'c'}, {_id: 'd'}]);
-        } else if (counter === 5) {
-          repl.cancel();
-        } else {
-          done('paused fired incorrectly');
-        }
-      });
-    });
-
-
-    it('#3852 Test basic starting with docs', function (done) {
-
-      var db = new PouchDB(dbs.name);
-
-      db.bulkDocs([{_id: 'a'}, {_id: 'b'}]).then(function () {
-
-        var repl = db.replicate.to(dbs.remote, {retry: true, live: true});
-
-        var counter = 0;
-
-        repl.on('complete', function () { done(); });
-
-        repl.on('active', function () {
-          counter++;
-          if (!(counter === 1 || counter === 3 || counter === 5)) {
-            done('active fired incorrectly:' + counter);
-          }
-        });
-
-        repl.on('paused', function () {
-          counter++;
-          // We should receive a paused event when replication
-          // starts because there is nothing to replicate
-          if (counter === 2) {
-            db.bulkDocs([{_id: 'c'}, {_id: 'd'}]);
-          } else if (counter === 4) {
-            db.bulkDocs([{_id: 'e'}, {_id: 'f'}]);
-          } else if (counter === 6) {
-            repl.cancel();
-          } else {
-            done('paused fired incorrectly');
-          }
-        });
-      });
-    });
-
-    it('#3852 Test errors', function (done) {
-
-      if (!(/http/.test(dbs.remote) && !/http/.test(dbs.name))) {
-        // Only run test when remote is http and local is local
-        return done();
-      }
-
-      var db = new PouchDB(dbs.name);
-      var rejectAjax = true;
-      var ajax = PouchDB.utils.ajax;
-
-      PouchDB.utils.ajax = function (opts, cb) {
-        if (rejectAjax) {
-          cb(new Error('flunking you'));
-        } else {
-          ajax.apply(this, arguments);
-        }
-      };
-
-      db.bulkDocs([{_id: 'a'}, {_id: 'b'}]).then(function () {
-
-        var repl = db.replicate.to(dbs.remote, {
-          retry: true,
-          live: true,
-          back_off_function: function () { return 0; }
-        });
-
-        var counter = 0;
-
-        repl.on('complete', function () {
-          PouchDB.utils.ajax = ajax;
-          done();
-        });
-
-        repl.on('active', function () {
-          counter++;
-          if (counter === 2) {
-            // All good, wait for pause
-          } else if (counter === 4) {
-            // Lets start failing while active
-            rejectAjax = true;
-            db.bulkDocs([{_id: 'e'}, {_id: 'f'}]);
-          } else if (counter === 6) {
-            // All good, wait for pause
-          } else {
-            done('active fired incorrectly');
-          }
-        });
-
-        repl.on('paused', function (err) {
-          counter++;
-          // Replication starts with a paused(err) because ajax is
-          // failing
-          if (counter === 1) {
-            should.exist(err);
-            // Lets let the repliation start
-            rejectAjax = false;
-          } else if (counter === 3) {
-            db.bulkDocs([{_id: 'c'}, {_id: 'd'}]);
-          } else if (counter === 5) {
-            // We started failing while active, should have an error
-            // then we stop rejecting and should become active again
-            should.exist(err);
-            rejectAjax = false;
-          } else if (counter === 7) {
-            repl.cancel();
-          } else {
-            done('paused fired incorrectly');
-          }
-        });
-      }).catch(done);
-    });
-
-
-    // this test sets up a 2 way replication which initially transfers
-    // documents from a remote to a local database.
-    // At the same time, we insert documents locally - the changes
-    // should propagate to the remote database and then back to the
-    // local database via the live replications.
-    // Previously, this test resulted in 'change' events being
-    // generated for already-replicated documents. When PouchDB is working
-    // as expected, each remote document should be passed to a
-    // change event exactly once (though a change might contain multiple docs)
-    it('#4627 Test no duplicate changes in live replication', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var docId = -1;
-      var docsToGenerate = 10;
-      var lastChange = -1;
-      var firstReplication;
-      var secondReplication;
-      var completeCalls = 0;
-
-      function generateDocs(n) {
-        return Array.apply(null, new Array(n)).map(function () {
-          docId += 1;
-          return {
-            _id: docId.toString(),
-            foo: Math.random().toString()
-          };
-        });
-      }
-
-      function complete() {
-        completeCalls++;
-        if (completeCalls === 2) {
-          done();
-        }
-      }
-
-      remote.bulkDocs(generateDocs(docsToGenerate)).then(function () {
-        firstReplication = db.replicate.to(remote, {
-          live: true,
-          retry: true,
-          since: 0
-        })
-        .on('error', done)
-        .on('complete', complete);
-
-        secondReplication = remote.replicate.to(db, {
-          live: true,
-          retry: true,
-          since: 0
-        })
-        .on('error', done)
-        .on('complete', complete)
-        .on('change', function (feed) {
-          // attempt to detect changes loop
-          var ids = feed.docs.map(function (d) {
-            return parseInt(d._id, 10);
-          }).sort();
-
-          var firstChange = ids[0];
-          if (firstChange <= lastChange) {
-            done(new Error("Duplicate change events detected"));
-          }
-
-          lastChange = ids[ids.length - 1];
-
-          if (lastChange === docsToGenerate - 1) {
-            // if a change loop doesn't occur within 2 seconds, assume success
-            setTimeout(function () {
-              // success!
-              // cancelling the replications to clean up and trigger
-              // the 'complete' event, which in turn ends the test
-              firstReplication.cancel();
-              secondReplication.cancel();
-            }, 2000);
-          }
-
-          // write doc to local db - should round trip in _changes
-          // but not generate a change event
-          db.bulkDocs(generateDocs(1));
-        });
-      }).catch(done);
-    });
-  });
-});
diff --git a/tests/integration/test.reserved.js b/tests/integration/test.reserved.js
deleted file mode 100644
index c3a95dd..0000000
--- a/tests/integration/test.reserved.js
+++ /dev/null
@@ -1,72 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-adapters.forEach(function (adapters) {
-  describe('test.reserved.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('test docs with reserved javascript ids', function () {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      return db.bulkDocs([
-        {_id: 'constructor'},
-        {_id: 'toString'},
-        {_id: 'valueOf'},
-        {
-          _id: '_design/all',
-          views: {
-            all: {
-              map: function (doc) {
-                emit(doc._id);
-              }.toString()
-            }
-          }
-        }
-      ]).then(function () {
-        return db.allDocs({key: 'constructor'});
-      }).then(function (res) {
-        res.rows.should.have.length(1, 'allDocs with key');
-        return db.allDocs({keys: ['constructor']});
-      }).then(function (res) {
-        res.rows.should.have.length(1, 'allDocs with keys');
-        return db.allDocs();
-      }).then(function (res) {
-        res.rows.should.have.length(4, 'allDocs empty opts');
-        return db.query('all/all', {key: 'constructor'});
-      }).then(function (res) {
-        res.rows.should.have.length(1, 'query with key');
-        return db.query('all/all', {keys: ['constructor']});
-      }).then(function (res) {
-        res.rows.should.have.length(1, 'query with keys');
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          db.replicate.to(remote).on('complete', resolve).on('error', reject);
-        });
-      });
-    });
-
-    it('can create db with reserved name', function () {
-      return new PouchDB('constructor').then(function (db) {
-        return db.info().then(function () {
-          return db.destroy();
-        });
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.retry.js b/tests/integration/test.retry.js
deleted file mode 100644
index baf9a9f..0000000
--- a/tests/integration/test.retry.js
+++ /dev/null
@@ -1,574 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-adapters.forEach(function (adapters) {
-  var suiteName = 'test.retry.js-' + adapters[0] + '-' + adapters[1];
-  describe(suiteName, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('retry stuff', function (done) {
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-      var allDocs = remote.allDocs;
-
-      // Reject attempting to write 'foo' 3 times, then let it succeed
-      var i = 0;
-      remote.allDocs = function (opts) {
-        if (opts.keys[0] === 'foo') {
-          if (++i !== 3) {
-            return Promise.reject(new Error('flunking you'));
-          }
-        }
-        return allDocs.apply(remote, arguments);
-      };
-
-      var db = new PouchDB(dbs.name);
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      });
-
-      var paused = 0;
-      rep.on('paused', function (e) {
-        ++paused;
-        // The first paused event is the replication up to date
-        // and waiting on changes (no error)
-        if (paused === 1) {
-          should.not.exist(e);
-          return remote.put({}, 'foo').then(function () {
-            return remote.put({}, 'bar');
-          });
-        }
-        // Second paused event is due to failed writes, should
-        // have an error
-        if (paused === 2) {
-          should.exist(e);
-        }
-      });
-
-      var active = 0;
-      rep.on('active', function () {
-        ++active;
-      });
-
-      rep.on('complete', function () {
-        active.should.be.at.least(2);
-        paused.should.be.at.least(2);
-        done();
-      });
-
-      rep.catch(done);
-
-      var numChanges = 0;
-      rep.on('change', function (c) {
-        numChanges += c.docs_written;
-        if (numChanges === 3) {
-          rep.cancel();
-        }
-      });
-
-      remote.put({}, 'hazaa');
-    });
-
-    it('#3687 active event only fired once...', function (done) {
-
-      var remote = new PouchDB(dbs.remote);
-      var db = new PouchDB(dbs.name);
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      });
-
-      var paused = 0;
-      var error;
-      rep.on('paused', function (e) {
-        ++paused;
-        // The first paused event is the replication up to date
-        // and waiting on changes (no error)
-        try {
-          should.not.exist(e);
-        } catch (err) {
-          error = err;
-          rep.cancel();
-        }
-        if (paused === 1) {
-          return remote.put({}, 'foo');
-        } else {
-          rep.cancel();
-        }
-      });
-
-      var active = 0;
-      rep.on('active', function () {
-        ++active;
-      });
-
-      var numChanges = 0;
-      rep.on('change', function () {
-        ++numChanges;
-      });
-
-      rep.on('complete', function () {
-        try {
-          active.should.be.within(1, 2);
-          paused.should.equal(2);
-          numChanges.should.equal(2);
-          done(error);
-        } catch (err) {
-          done(err);
-        }
-      });
-
-      rep.catch(done);
-
-      remote.put({}, 'hazaa');
-    });
-
-    it('source doesn\'t leak "destroyed" event', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      var origGet = remote.get;
-      var i = 0;
-      remote.get = function () {
-        // Reject three times, every 5th time
-        if ((++i % 5 === 0) && i <= 15) {
-          return Promise.reject(new Error('flunking you'));
-        }
-        return origGet.apply(remote, arguments);
-      };
-
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      });
-
-      var numDocsToWrite = 10;
-
-      return remote.post({}).then(function () {
-        var originalNumListeners;
-        var posted = 0;
-
-        return new Promise(function (resolve, reject) {
-
-          var error;
-          function cleanup(err) {
-            if (err) {
-              error = err;
-            }
-            rep.cancel();
-          }
-          function finish() {
-            if (error) {
-              return reject(error);
-            }
-            resolve();
-          }
-
-          rep.on('complete', finish).on('error', cleanup);
-          rep.on('change', function () {
-            if (++posted < numDocsToWrite) {
-              remote.post({}).catch(cleanup);
-            } else {
-              db.info().then(function (info) {
-                if (info.doc_count === numDocsToWrite) {
-                  cleanup();
-                }
-              }).catch(cleanup);
-            }
-
-            try {
-              var numListeners = db.listeners('destroyed').length;
-              if (typeof originalNumListeners !== 'number') {
-                originalNumListeners = numListeners;
-              } else {
-                numListeners.should.equal(originalNumListeners,
-                  'numListeners should never increase');
-              }
-            } catch (err) {
-              cleanup(err);
-            }
-          });
-        });
-      });
-    });
-
-    it('target doesn\'t leak "destroyed" event', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      var origGet = remote.get;
-      var i = 0;
-      remote.get = function () {
-        // Reject three times, every 5th time
-        if ((++i % 5 === 0) && i <= 15) {
-          return Promise.reject(new Error('flunking you'));
-        }
-        return origGet.apply(remote, arguments);
-      };
-
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      });
-
-      var numDocsToWrite = 10;
-
-      return remote.post({}).then(function () {
-        var originalNumListeners;
-        var posted = 0;
-
-        return new Promise(function (resolve, reject) {
-
-          var error;
-          function cleanup(err) {
-            if (err) {
-              error = err;
-            }
-            rep.cancel();
-          }
-          function finish() {
-            if (error) {
-              return reject(error);
-            }
-            resolve();
-          }
-
-          rep.on('complete', finish).on('error', cleanup);
-          rep.on('change', function () {
-            if (++posted < numDocsToWrite) {
-              remote.post({}).catch(cleanup);
-            } else {
-              db.info().then(function (info) {
-                if (info.doc_count === numDocsToWrite) {
-                  cleanup();
-                }
-              }).catch(cleanup);
-            }
-
-            try {
-              var numListeners = remote.listeners('destroyed').length;
-              if (typeof originalNumListeners !== 'number') {
-                originalNumListeners = numListeners;
-              } else {
-                // special case for "destroy" - because there are
-                // two Changes() objects for local databases,
-                // there can briefly be one extra listener or one
-                // fewer listener. The point of this test is to ensure
-                // that the listeners don't grow out of control.
-                numListeners.should.be.within(
-                  originalNumListeners - 1,
-                  originalNumListeners + 1,
-                  'numListeners should never increase by +1/-1');
-              }
-            } catch (err) {
-              cleanup(err);
-            }
-          });
-        });
-      });
-    });
-
-    [
-      'complete', 'error', 'paused', 'active',
-      'change', 'cancel'
-    ].forEach(function (event) {
-      it('returnValue doesn\'t leak "' + event + '" event', function () {
-
-        var db = new PouchDB(dbs.name);
-        var remote = new PouchDB(dbs.remote);
-        var Promise = PouchDB.utils.Promise;
-
-        var origGet = remote.get;
-        var i = 0;
-        remote.get = function () {
-          // Reject three times, every 5th time
-          if ((++i % 5 === 0) && i <= 15) {
-            return Promise.reject(new Error('flunking you'));
-          }
-          return origGet.apply(remote, arguments);
-        };
-
-        var rep = db.replicate.from(remote, {
-          live: true,
-          retry: true,
-          back_off_function: function () { return 0; }
-        });
-
-        var numDocsToWrite = 10;
-
-        return remote.post({}).then(function () {
-          var originalNumListeners;
-          var posted = 0;
-
-          return new Promise(function (resolve, reject) {
-
-            var error;
-            function cleanup(err) {
-              if (err) {
-                error = err;
-              }
-              rep.cancel();
-            }
-            function finish() {
-              if (error) {
-                return reject(error);
-              }
-              resolve();
-            }
-
-            rep.on('complete', finish).on('error', cleanup);
-            rep.on('change', function () {
-              if (++posted < numDocsToWrite) {
-                remote.post({}).catch(cleanup);
-              } else {
-                db.info().then(function (info) {
-                  if (info.doc_count === numDocsToWrite) {
-                    cleanup();
-                  }
-                }).catch(cleanup);
-              }
-
-              try {
-                var numListeners = rep.listeners(event).length;
-                if (typeof originalNumListeners !== 'number') {
-                  originalNumListeners = numListeners;
-                } else {
-                  numListeners.should.equal(originalNumListeners,
-                    'numListeners should never increase');
-                }
-              } catch (err) {
-                cleanup(err);
-              }
-            });
-          });
-        });
-      });
-    });
-
-    it('returnValue doesn\'t leak "change" event w/ onChange', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      var origGet = remote.get;
-      var i = 0;
-      remote.get = function () {
-        // Reject three times, every 5th time
-        if ((++i % 5 === 0) && i <= 15) {
-          return Promise.reject(new Error('flunking you'));
-        }
-        return origGet.apply(remote, arguments);
-      };
-
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      }).on('change', function () {});
-
-      var numDocsToWrite = 10;
-
-      return remote.post({}).then(function () {
-        var originalNumListeners;
-        var posted = 0;
-
-        return new Promise(function (resolve, reject) {
-
-          var error;
-          function cleanup(err) {
-            if (err) {
-              error = err;
-            }
-            rep.cancel();
-          }
-          function finish() {
-            if (error) {
-              return reject(error);
-            }
-            resolve();
-          }
-
-          rep.on('complete', finish).on('error', cleanup);
-          rep.on('change', function () {
-            if (++posted < numDocsToWrite) {
-              remote.post({}).catch(cleanup);
-            } else {
-              db.info().then(function (info) {
-                if (info.doc_count === numDocsToWrite) {
-                  cleanup();
-                }
-              }).catch(cleanup);
-            }
-
-            try {
-              var numListeners = rep.listeners('change').length;
-              if (typeof originalNumListeners !== 'number') {
-                originalNumListeners = numListeners;
-              } else {
-                numListeners.should.equal(originalNumListeners,
-                  'numListeners should never increase');
-              }
-            } catch (err) {
-              cleanup(err);
-            }
-          });
-        });
-      });
-    });
-
-    it('retry many times, no leaks on any events', function () {
-      this.timeout(200000);
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var Promise = PouchDB.utils.Promise;
-
-      var flunked = 0;
-      var origGet = remote.get;
-      var i = 0;
-      remote.get = function () {
-        // Reject five times, every 5th time
-        if ((++i % 5 === 0) && i <= 25) {
-          flunked++;
-          return Promise.reject(new Error('flunking you'));
-        }
-        return origGet.apply(remote, arguments);
-      };
-
-      var rep = db.replicate.from(remote, {
-        live: true,
-        retry: true,
-        back_off_function: function () { return 0; }
-      });
-
-      var active = 0;
-      var paused = 0;
-      var numDocsToWrite = 50;
-
-      return remote.post({}).then(function () {
-        var originalNumListeners;
-        var posted = 0;
-
-        return new Promise(function (resolve, reject) {
-
-          var error;
-          function cleanup(err) {
-            if (err) {
-              error = err;
-            }
-            rep.cancel();
-          }
-          function finish() {
-            if (error) {
-              return reject(error);
-            }
-            resolve();
-          }
-          function getTotalListeners() {
-            var events = ['complete', 'error', 'paused', 'active',
-              'change', 'cancel'];
-            return events.map(function (event) {
-              return rep.listeners(event).length;
-            }).reduce(function (a, b) {return a + b; }, 0);
-          }
-
-          rep.on('complete', finish)
-            .on('error', cleanup)
-            .on('active', function () {
-            active++;
-          }).on('paused', function () {
-            paused++;
-          }).on('change', function () {
-            if (++posted < numDocsToWrite) {
-              remote.post({}).catch(cleanup);
-            } else {
-              db.info().then(function (info) {
-                if (info.doc_count === numDocsToWrite) {
-                  cleanup();
-                }
-              }).catch(cleanup);
-            }
-
-            try {
-              var numListeners = getTotalListeners();
-              if (typeof originalNumListeners !== 'number') {
-                originalNumListeners = numListeners;
-              } else {
-                numListeners.should.equal(originalNumListeners,
-                  'numListeners should never increase');
-              }
-            } catch (err) {
-              cleanup(err);
-            }
-          });
-        });
-      }).then(function () {
-        flunked.should.equal(5);
-        active.should.be.at.least(5);
-        paused.should.be.at.least(5);
-      });
-    });
-
-
-    it('4049 retry while starting offline', function (done) {
-
-      var ajax = PouchDB.utils.ajax;
-      var _called = 0;
-      var startFailing = false;
-
-      PouchDB.utils.ajax = function (opts, cb) {
-        if (!startFailing || ++_called > 3) {
-          ajax.apply(this, arguments);
-        } else {
-          cb(new Error('flunking you'));
-        }
-      };
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      remote.post({a: 'doc'}).then(function () {
-        startFailing = true;
-        var rep = db.replicate.from(remote, {live: true, retry: true})
-          .on('change', function () { rep.cancel(); });
-
-        rep.on('complete', function () {
-          PouchDB.utils.ajax = ajax;
-          done();
-        });
-      });
-
-    });
-
-  });
-});
diff --git a/tests/integration/test.revs_diff.js b/tests/integration/test.revs_diff.js
deleted file mode 100644
index 930fc5e..0000000
--- a/tests/integration/test.revs_diff.js
+++ /dev/null
@@ -1,167 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.revs_diff.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('Test revs diff', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var revs = [];
-      db.post({
-        test: 'somestuff',
-        _id: 'somestuff'
-      }, function (err, info) {
-        revs.push(info.rev);
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }, function (err, info2) {
-          revs.push(info2.rev);
-          db.revsDiff({ 'somestuff': revs }, function (err, results) {
-            results.should.not.include.keys('somestuff');
-            revs.push('2-randomid');
-            db.revsDiff({ 'somestuff': revs }, function (err, results) {
-              results.should.include.keys('somestuff');
-              results.somestuff.missing.should.have.length(1);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test revs diff with opts object', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var revs = [];
-      db.post({
-        test: 'somestuff',
-        _id: 'somestuff'
-      }, function (err, info) {
-        revs.push(info.rev);
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }, function (err, info2) {
-          revs.push(info2.rev);
-          db.revsDiff({ 'somestuff': revs }, {}, function (err, results) {
-            results.should.not.include.keys('somestuff');
-            revs.push('2-randomid');
-            db.revsDiff({ 'somestuff': revs }, function (err, results) {
-              results.should.include.keys('somestuff');
-              results.somestuff.missing.should.have.length(1);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Missing docs should be returned with all revisions', function (done) {
-      new PouchDB(dbs.name, function (err, db) {
-        var revs = ['1-a', '2-a', '2-b'];
-        db.revsDiff({'foo': revs }, function (err, results) {
-          results.should.include.keys('foo');
-          results.foo.missing.should.deep.equal(revs, 'listed all revs');
-          done();
-        });
-      });
-    });
-
-    it('Conflicting revisions that are available', function (done) {
-      var doc = {_id: '939', _rev: '1-a'};
-      function createConflicts(db, callback) {
-        db.put(doc, { new_edits: false }, function () {
-          testUtils.putAfter(db, {
-            _id: '939',
-            _rev: '2-a'
-          }, '1-a', function () {
-            testUtils.putAfter(db, {
-              _id: '939',
-              _rev: '2-b'
-            }, '1-a', callback);
-          });
-        });
-      }
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      createConflicts(db, function () {
-        db.revsDiff({'939': ['1-a', '2-a', '2-b']}, function (err, results) {
-          results.should.not.include.keys('939');
-          done();
-        });
-      });
-    });
-
-    it('Deleted revisions that are available', function (done) {
-      function createDeletedRevision(db, callback) {
-        db.put({
-          _id: '935',
-          _rev: '1-a'
-        }, { new_edits: false }, function () {
-          testUtils.putAfter(db, {
-            _id: '935',
-            _rev: '2-a',
-            _deleted: true
-          }, '1-a', callback);
-        });
-      }
-      var db = new PouchDB(dbs.name);
-      createDeletedRevision(db, function () {
-        db.revsDiff({'935': ['1-a', '2-a']}, function (err, results) {
-          results.should.not.include.keys('939');
-          done();
-        });
-      });
-    });
-
-    it('Revs diff with empty revs', function () {
-      return new PouchDB(dbs.name).then(function (db) {
-        return db.revsDiff({}).then(function (res) {
-          should.exist(res);
-        });
-      });
-    });
-
-    it('Test revs diff with reserved ID', function (done) {
-      var db = new PouchDB(dbs.name, {auto_compaction: false});
-      var revs = [];
-      db.post({
-        test: 'constructor',
-        _id: 'constructor'
-      }, function (err, info) {
-        revs.push(info.rev);
-        db.put({
-          _id: info.id,
-          _rev: info.rev,
-          another: 'test'
-        }, function (err, info2) {
-          revs.push(info2.rev);
-          db.revsDiff({ 'constructor': revs }, function (err, results) {
-            results.should.not.include.keys('constructor');
-            revs.push('2-randomid');
-            db.revsDiff({ 'constructor': revs }, function (err, results) {
-              results.should.include.keys('constructor');
-              results.constructor.missing.should.have.length(1);
-              done();
-            });
-          });
-        });
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.slash_id.js b/tests/integration/test.slash_id.js
deleted file mode 100644
index d939fb2..0000000
--- a/tests/integration/test.slash_id.js
+++ /dev/null
@@ -1,146 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-var repl_adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-adapters.forEach(function (adapter) {
-  describe('test.slash_ids.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('Insert a doc, putAttachment and allDocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docId = 'doc/with/slashes';
-      var attachmentId = 'attachment/with/slashes';
-      var blobData = 'attachment content';
-      var blob = testUtils.makeBlob(blobData);
-      var doc = {_id: docId, test: true};
-      db.put(doc, function (err, info) {
-        should.not.exist(err, 'saved doc');
-        info.id.should.equal('doc/with/slashes', 'id is the same as inserted');
-        db.putAttachment(docId, attachmentId, info.rev, blob, 'text/plain',
-                         function () {
-          db.getAttachment(docId, attachmentId, function (err, res) {
-            testUtils.readBlob(res, function () {
-              db.get(docId, function (err, res) {
-                res._id.should.equal(docId);
-                res._attachments.should.include.keys(attachmentId);
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('BulkDocs and changes', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: 'part/doc1', int: 1},
-        {_id: 'part/doc2', int: 2, _attachments: {
-          'attachment/with/slash': {
-            content_type: 'text/plain',
-            data: 'c29tZSBkYXRh'
-          }
-        }},
-        {_id: 'part/doc3', int: 3}
-      ];
-      db.bulkDocs({ docs: docs }, function (err, res) {
-        for (var i = 0; i < 3; i++) {
-          res[i].ok.should.equal(true, 'correctly inserted ' + docs[i]._id);
-        }
-        db.allDocs({
-          include_docs: true,
-          attachments: true
-        }, function (err, res) {
-          res.rows.sort(function (a, b) {
-            return a.doc.int - b.doc.int;
-          });
-          for (var i = 0; i < 3; i++) {
-            res.rows[i].doc._id.should
-              .equal(docs[i]._id, '(allDocs) correctly inserted ' +
-                     docs[i]._id);
-          }
-          res.rows[1].doc._attachments.should.include
-            .keys('attachment/with/slash');
-          db.changes().on('complete', function (res) {
-            res.results.sort(function (a, b) {
-              return a.id.localeCompare(b.id);
-            });
-            for (var i = 0; i < 3; i++) {
-              res.results[i].id.should
-                .equal(docs[i]._id, 'correctly inserted');
-            }
-            done();
-          }).on('error', done);
-        });
-      });
-    });
-
-  });
-});
-
-
-repl_adapters.forEach(function (adapters) {
-  describe('test.slash_ids.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'test_slash_ids');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_slash_ids_remmote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    afterEach(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    it('Attachments replicate', function (done) {
-      var binAttDoc = {
-        _id: 'bin_doc/with/slash',
-        _attachments: {
-          'foo/with/slash.txt': {
-            content_type: 'text/plain',
-            data: 'VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ='
-          }
-        }
-      };
-      var docs1 = [
-        binAttDoc,
-        {_id: '0', integer: 0},
-        {_id: '1', integer: 1},
-        {_id: '2', integer: 2},
-        {_id: '3', integer: 3}
-      ];
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      remote.bulkDocs({ docs: docs1 }, function () {
-        db.replicate.from(remote, function () {
-          db.get('bin_doc/with/slash', { attachments: true },
-            function (err, doc) {
-            binAttDoc._attachments['foo/with/slash.txt'].data.should
-              .equal(doc._attachments['foo/with/slash.txt'].data);
-            done();
-          });
-        });
-      });
-    });
-  });
-});
diff --git a/tests/integration/test.sync.js b/tests/integration/test.sync.js
deleted file mode 100644
index d20c2b1..0000000
--- a/tests/integration/test.sync.js
+++ /dev/null
@@ -1,806 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-adapters.forEach(function (adapters) {
-  describe('test.sync.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    it('PouchDB.sync event', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1, function () {
-        remote.put(doc2, function () {
-          PouchDB.sync(db, remote).on('complete', function (result) {
-            result.pull.ok.should.equal(true);
-            result.pull.docs_read.should.equal(1);
-            result.pull.docs_written.should.equal(1);
-            result.pull.errors.should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('sync throws errors in promise', function () {
-      var doc1 = {
-        _id: 'adoc',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: 'anotherdoc',
-        foo: 'baz'
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // intentionally throw an error during replication
-      remote.allDocs = function () {
-        return PouchDB.utils.Promise.reject(new Error('flunking you'));
-      };
-
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return db.sync(remote);
-      }).then(function () {
-        throw new Error('expected an error');
-      }, function (err) {
-        should.exist(err);
-        err.should.be.instanceof(Error);
-      });
-    });
-
-    it('sync throws errors in promise catch()', function () {
-      var doc1 = {
-        _id: 'adoc',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: 'anotherdoc',
-        foo: 'baz'
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // intentionally throw an error during replication
-      remote.allDocs = function () {
-        return PouchDB.utils.Promise.reject(new Error('flunking you'));
-      };
-
-      var landedInCatch = false;
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return db.sync(remote).catch(function (err) {
-          landedInCatch = true;
-          should.exist(err);
-          err.should.be.instanceof(Error);
-        });
-      }).then(function () {
-        if (!landedInCatch) {
-          throw new Error('expected catch(), not then()');
-        }
-      });
-    });
-
-    it('sync throws errors in error listener', function () {
-      var doc1 = {
-        _id: 'adoc',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: 'anotherdoc',
-        foo: 'baz'
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // intentionally throw an error during replication
-      remote.allDocs = function () {
-        return PouchDB.utils.Promise.reject(new Error('flunking you'));
-      };
-
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve) {
-          db.sync(remote).on('error', resolve);
-        });
-      }).then(function (err) {
-        should.exist(err);
-        err.should.be.instanceof(Error);
-      });
-    });
-
-    it('sync throws errors in callback', function () {
-      var doc1 = {
-        _id: 'adoc',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: 'anotherdoc',
-        foo: 'baz'
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      // intentionally throw an error during replication
-      remote.allDocs = function () {
-        return PouchDB.utils.Promise.reject(new Error('flunking you'));
-      };
-
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve) {
-          db.sync(remote, function (err) {
-            resolve(err);
-          }).catch(function () {
-            // avoid annoying chrome warning about uncaught (in promise)
-          });
-        });
-      }).then(function (err) {
-        should.exist(err);
-        err.should.be.instanceof(Error);
-      });
-    });
-
-    it('sync returns result in callback', function () {
-      var doc1 = {
-        _id: 'adoc',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: 'anotherdoc',
-        foo: 'baz'
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          db.sync(remote, function (err, res) {
-            if (err) {
-              return reject(err);
-            }
-            resolve(res);
-          });
-        });
-      }).then(function (res) {
-        should.exist(res);
-      });
-    });
-
-    it('PouchDB.sync callback', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1, function () {
-        remote.put(doc2, function () {
-          PouchDB.sync(db, remote, function (err, result) {
-            result.pull.ok.should.equal(true);
-            result.pull.docs_read.should.equal(1);
-            result.pull.docs_written.should.equal(1);
-            result.pull.errors.should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('PouchDB.sync promise', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return PouchDB.sync(db, remote);
-      }).then(function (result) {
-        result.pull.ok.should.equal(true);
-        result.pull.docs_read.should.equal(1);
-        result.pull.docs_written.should.equal(1);
-        result.pull.errors.should.have.length(0);
-        done();
-      }, done);
-    });
-
-    it('db.sync event', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1, function () {
-        remote.put(doc2, function () {
-          db.sync(remote).on('complete', function (result) {
-            result.pull.ok.should.equal(true);
-            result.pull.docs_read.should.equal(1);
-            result.pull.docs_written.should.equal(1);
-            result.pull.errors.should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('db.sync callback', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1, function () {
-        remote.put(doc2, function () {
-          db.sync(remote, function (err, result) {
-            result.pull.ok.should.equal(true);
-            result.pull.docs_read.should.equal(1);
-            result.pull.docs_written.should.equal(1);
-            result.pull.errors.should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('db.sync promise', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return db.sync(remote);
-      }).then(function (result) {
-        result.pull.ok.should.equal(true);
-        result.pull.docs_read.should.equal(1);
-        result.pull.docs_written.should.equal(1);
-        result.pull.errors.should.have.length(0);
-        done();
-      }, done);
-    });
-
-    it.skip('Test sync cancel', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var replications = db.sync(remote).on('complete', function () {
-        done();
-      });
-      should.exist(replications);
-      replications.cancel();
-    });
-
-    it.skip('Test sync cancel called twice', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var replications = db.sync(remote).on('complete', function () {
-        setTimeout(done); // let cancel() get called twice before finishing
-      });
-      should.exist(replications);
-      replications.cancel();
-      replications.cancel();
-    });
-
-    it('Test syncing two endpoints (issue 838)', function () {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      return db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          db.replicate.sync(remote).on('complete', resolve).on('error', reject);
-        });
-      }).then(function () {
-        // Replication isn't finished until onComplete has been called twice
-        return db.allDocs().then(function (res1) {
-          return remote.allDocs().then(function (res2) {
-            res1.total_rows.should.equal(res2.total_rows);
-          });
-        });
-      });
-    });
-
-    it.skip('3894 re-sync after immediate cancel', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.setMaxListeners(100);
-      remote.setMaxListeners(100);
-
-      var promise = PouchDB.utils.Promise.resolve();
-
-      function syncThenCancel() {
-        promise = promise.then(function () {
-          return new PouchDB.utils.Promise(function (resolve, reject) {
-            db = new PouchDB(dbs.name);
-            remote = new PouchDB(dbs.remote);
-            var sync = db.sync(remote)
-              .on('error', reject)
-              .on('complete', resolve);
-            sync.cancel();
-          }).then(function () {
-            return PouchDB.utils.Promise.all([
-              db.destroy(),
-              remote.destroy()
-            ]);
-          });
-        });
-      }
-
-      for (var i = 0; i < 5; i++) {
-        syncThenCancel();
-      }
-
-      return promise;
-    });
-
-    it('Syncing should stop if one replication fails (issue 838)',
-      function (done) {
-      var doc1 = {_id: 'adoc', foo: 'bar'};
-      var doc2 = {_id: 'anotherdoc', foo: 'baz'};
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var replications = db.sync(remote, {live: true});
-
-      replications.on('complete', function () {
-        remote.put(doc2, function () {
-          changes.should.equal(1);
-          done();
-        });
-      });
-
-      var changes = 0;
-      replications.on('change', function () {
-        changes++;
-        if (changes === 1) {
-          replications.pull.cancel();
-        }
-      });
-      db.put(doc1);
-    });
-
-    it('Push and pull changes both fire (issue 2555)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      var correct = false;
-      db.post({}).then(function () {
-        return remote.post({});
-      }).then(function () {
-        var numChanges = 0;
-        var lastChange;
-        var sync = db.sync(remote);
-        sync.on('change', function (change) {
-          ['push', 'pull'].should.contain(change.direction);
-          change.change.docs_read.should.equal(1);
-          change.change.docs_written.should.equal(1);
-          if (!lastChange) {
-            lastChange = change.direction;
-          } else {
-            lastChange.should.not.equal(change.direction);
-          }
-          if (++numChanges === 2) {
-            correct = true;
-            sync.cancel();
-          }
-        }).on('complete', function () {
-          correct.should.equal(true, 'things happened right');
-          done();
-        });
-      });
-    });
-
-    it('Remove an event listener', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{}, {}, {}]).then(function () {
-        return remote.bulkDocs([{}, {}, {}]);
-      }).then(function () {
-
-        function changesCallback() {
-          changeCalled = true;
-        }
-
-        var sync = db.replicate.to(remote);
-        var changeCalled = false;
-        sync.on('change', changesCallback);
-        sync.removeListener('change', changesCallback);
-        sync.on('error', function () {});
-        sync.on('complete', function () {
-          setTimeout(function () {
-            Object.keys(sync._events).should.have.length(0);
-            changeCalled.should.equal(false);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Remove an invalid event listener', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{}, {}, {}]).then(function () {
-        return remote.bulkDocs([{}, {}, {}]);
-      }).then(function () {
-        function otherCallback() {}
-        function realCallback() {
-          changeCalled = true;
-        }
-        var sync = db.replicate.to(remote);
-        var changeCalled = false;
-        sync.on('change', realCallback);
-        sync.removeListener('change', otherCallback);
-        sync.on('error', function () {});
-        sync.on('complete', function () {
-          setTimeout(function () {
-            Object.keys(sync._events).should.have.length(0);
-            changeCalled.should.equal(true);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Doesn\'t have a memory leak (push)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{}, {}, {}]).then(function () {
-        return remote.bulkDocs([{}, {}, {}]);
-      }).then(function () {
-        var sync = db.replicate.to(remote);
-        sync.on('change', function () {});
-        sync.on('error', function () {});
-        sync.on('complete', function () {
-          setTimeout(function () {
-            Object.keys(sync._events).should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Doesn\'t have a memory leak (pull)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{}, {}, {}]).then(function () {
-        return remote.bulkDocs([{}, {}, {}]);
-      }).then(function () {
-        var sync = db.replicate.from(remote);
-        sync.on('change', function () {});
-        sync.on('error', function () {});
-        sync.on('complete', function () {
-          setTimeout(function () {
-            Object.keys(sync._events).should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-
-    it('Doesn\'t have a memory leak (bi)', function (done) {
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{}, {}, {}]).then(function () {
-        return remote.bulkDocs([{}, {}, {}]);
-      }).then(function () {
-        var sync = db.sync(remote);
-        sync.on('change', function () {});
-        sync.on('error', function () {});
-        sync.on('complete', function () {
-          setTimeout(function () {
-            Object.keys(sync._events).should.have.length(0);
-            done();
-          });
-        });
-      });
-    });
-    it('PouchDB.sync with strings for dbs', function (done) {
-      var doc1 = {
-          _id: 'adoc',
-          foo: 'bar'
-        };
-      var doc2 = {
-          _id: 'anotherdoc',
-          foo: 'baz'
-        };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.put(doc1).then(function () {
-        return remote.put(doc2);
-      }).then(function () {
-        return PouchDB.sync(dbs.name, dbs.remote);
-      }).then(function (result) {
-        result.pull.ok.should.equal(true);
-        result.pull.docs_read.should.equal(1);
-        result.pull.docs_written.should.equal(1);
-        result.pull.errors.should.have.length(0);
-        done();
-      }, done);
-    });
-
-    it('#3270 triggers "denied" events',
-        function (done) {
-      testUtils.isCouchDB(function (isCouchDB) {
-        if (/*adapters[1] !== 'http' || */!isCouchDB) {
-          return done();
-        }
-        if (adapters[0] !== 'local' || adapters[1] !== 'http') {
-          return done();
-        }
-
-        var deniedErrors = [];
-        var ddoc = {
-          "_id": "_design/validate",
-          "validate_doc_update": function (newDoc) {
-            if (newDoc.foo) {
-              throw { unauthorized: 'go away, no picture' };
-            }
-          }.toString()
-        };
-
-        var remote = new PouchDB(dbs.remote);
-        var db = new PouchDB(dbs.name);
-
-        return remote.put(ddoc).then(function () {
-          var docs = [
-            {_id: 'foo1', foo: 'string'},
-            {_id: 'nofoo'},
-            {_id: 'foo2', foo: 'object'}
-          ];
-          return db.bulkDocs({docs: docs});
-        }).then(function () {
-          var sync = db.sync(dbs.remote);
-          sync.on('denied', function (error) {
-            deniedErrors.push(error);
-          });
-          return sync;
-        }).then(function () {
-          deniedErrors.length.should.equal(2);
-          deniedErrors[0].doc.name.should.equal('unauthorized');
-          deniedErrors[1].doc.name.should.equal('unauthorized');
-          deniedErrors[0].direction.should.equal('push');
-        })
-        .then(done, done);
-      });
-    });
-
-    it('#3270 triggers "denied" events, reverse direction',
-      function (done) {
-        testUtils.isCouchDB(function (isCouchDB) {
-          if (/*adapters[1] !== 'http' || */!isCouchDB) {
-            return done();
-          }
-          if (adapters[0] !== 'local' || adapters[1] !== 'http') {
-            return done();
-          }
-
-          var deniedErrors = [];
-          var ddoc = {
-            "_id": "_design/validate",
-            "validate_doc_update": function (newDoc) {
-              if (newDoc.foo) {
-                throw { unauthorized: 'go away, no picture' };
-              }
-            }.toString()
-          };
-
-          var remote = new PouchDB(dbs.remote);
-          var db = new PouchDB(dbs.name);
-
-          return remote.put(ddoc).then(function () {
-            var docs = [
-              {_id: 'foo1', foo: 'string'},
-              {_id: 'nofoo'},
-              {_id: 'foo2', foo: 'object'}
-            ];
-            return db.bulkDocs({docs: docs});
-          }).then(function () {
-            var sync = remote.sync(db);
-            sync.on('denied', function (error) {
-              deniedErrors.push(error);
-            });
-            return sync;
-          }).then(function () {
-            deniedErrors.length.should.equal(2);
-            deniedErrors[0].doc.name.should.equal('unauthorized');
-            deniedErrors[1].doc.name.should.equal('unauthorized');
-            deniedErrors[0].direction.should.equal('pull');
-          })
-            .then(done, done);
-        });
-      });
-
-    it('#3270 triggers "change" events with .docs property', function (done) {
-      var syncedDocs = [];
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {_id: '1'},
-        {_id: '2'},
-        {_id: '3'}
-      ];
-
-      db.bulkDocs({ docs: docs }, {}).then(function () {
-        var sync = db.sync(dbs.remote);
-        sync.on('change', function (change) {
-          syncedDocs = syncedDocs.concat(change.change.docs);
-        });
-        return sync;
-      })
-      .then(function () {
-        syncedDocs.sort(function (a, b) {
-          return a._id > b._id ? 1 : -1;
-        });
-
-        syncedDocs.length.should.equal(3);
-        syncedDocs[0]._id.should.equal('1');
-        syncedDocs[1]._id.should.equal('2');
-        syncedDocs[2]._id.should.equal('3');
-        done();
-      })
-      .catch(done);
-    });
-
-    it('4791 Single filter', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var localDocs = [{_id: '0'}, {_id: '1'}];
-      var remoteDocs = [{_id: 'a'}, {_id: 'b'}];
-
-      return remote.bulkDocs(remoteDocs).then(function () {
-        return db.bulkDocs(localDocs);
-      }).then(function () {
-        return db.sync(remote, {
-          filter: function (doc) { return doc._id !== '0' && doc._id !== 'a'; }
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-        return remote.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-      });
-    });
-
-
-    it('4791 Single filter, live/retry', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var localDocs = [{_id: '0'}, {_id: '1'}];
-      var remoteDocs = [{_id: 'a'}, {_id: 'b'}];
-
-      return remote.bulkDocs(remoteDocs).then(function () {
-        return db.bulkDocs(localDocs);
-      }).then(function () {
-        return new PouchDB.utils.Promise(function (resolve, reject) {
-          var filter = function (doc) {
-            return doc._id !== '0' && doc._id !== 'a';
-          };
-          var changes = 0;
-          var onChange = function (c) {
-            changes += c.change.docs.length;
-            if (changes === 2) {
-              sync.cancel();
-            }
-          };
-          var sync = db.sync(remote, {filter: filter, live: true, retry: true})
-            .on('error', reject)
-            .on('change', onChange)
-            .on('complete', resolve);
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-        return remote.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-      });
-    });
-
-    it('4289 Separate to / from filters', function () {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      var localDocs = [{_id: '0'}, {_id: '1'}];
-      var remoteDocs = [{_id: 'a'}, {_id: 'b'}];
-
-      return remote.bulkDocs(remoteDocs).then(function () {
-        return db.bulkDocs(localDocs);
-      }).then(function () {
-        return db.sync(remote, {
-          push: {filter: function (doc) { return doc._id === '0'; }},
-          pull: {filter: function (doc) { return doc._id === 'a'; }}
-        });
-      }).then(function () {
-        return db.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-        return remote.allDocs();
-      }).then(function (docs) {
-        docs.total_rows.should.equal(3);
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.sync_events.js b/tests/integration/test.sync_events.js
deleted file mode 100644
index db9abc4..0000000
--- a/tests/integration/test.sync_events.js
+++ /dev/null
@@ -1,72 +0,0 @@
-'use strict';
-
-var adapters = [
-  ['local', 'http'],
-  ['http', 'http'],
-  ['http', 'local'],
-  ['local', 'local']
-];
-
-if ('saucelabs' in testUtils.params()) {
-  adapters = [['local', 'http'], ['http', 'local']];
-}
-
-
-adapters.forEach(function (adapters) {
-  var title = 'test.sync_events.js-' + adapters[0] + '-' + adapters[1];
-  describe('suite2 ' + title, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    it('#4251 Should fire paused and active on sync', function (done) {
-
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-
-      db.bulkDocs([{_id: 'a'}, {_id: 'b'}]).then(function () {
-
-        var repl = db.sync(remote, {retry: true, live: true});
-        var counter = 0;
-
-        repl.on('complete', function () {
-          done();
-        });
-
-        repl.on('active', function () {
-          counter++;
-          if (counter === 1) {
-            // We are good, initial replication
-          } else if (counter === 3) {
-            remote.bulkDocs([{_id: 'e'}, {_id: 'f'}]);
-          }
-        });
-
-        repl.on('paused', function () {
-          counter++;
-          if (counter === 1) {
-            // Maybe a bug, if we have data should probably
-            // call active first
-            counter--;
-          } if (counter === 2) {
-            db.bulkDocs([{_id: 'c'}, {_id: 'd'}]);
-          } else if (counter === 4) {
-            repl.cancel();
-          }
-        });
-      });
-
-    });
-
-  });
-});
diff --git a/tests/integration/test.taskqueue.js b/tests/integration/test.taskqueue.js
deleted file mode 100644
index 88ea068..0000000
--- a/tests/integration/test.taskqueue.js
+++ /dev/null
@@ -1,74 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-adapters.forEach(function (adapter) {
-  describe('test.taskqueue.js-' + adapter, function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapter, 'testdb');
-      testUtils.cleanup([dbs.name], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name], done);
-    });
-
-
-    it('Add a doc', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ test: 'somestuff' }, function (err) {
-        done(err);
-      });
-    });
-
-    it('Query', function (done) {
-      // temp views are not supported in CouchDB 2.0
-      if (testUtils.isCouchMaster()) {
-        return done();
-      }
-
-      var db = new PouchDB(dbs.name);
-      var queryFun = {
-        map: function () {}
-      };
-      db.query(queryFun, { reduce: false }, function (_, res) {
-        res.rows.should.have.length(0);
-        done();
-      });
-    });
-
-    it('Bulk docs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { test: 'somestuff' },
-          { test: 'another' }
-        ]
-      }, function (err, infos) {
-        should.not.exist(infos[0].error);
-        should.not.exist(infos[1].error);
-        done();
-      });
-    });
-
-    it('Get', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.get('0', function (err) {
-        should.exist(err);
-        done();
-      });
-    });
-
-    it('Info', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.info(function (err, info) {
-        info.doc_count.should.equal(0);
-        done();
-      });
-    });
-
-  });
-});
diff --git a/tests/integration/test.uuids.js b/tests/integration/test.uuids.js
deleted file mode 100644
index e1fde4c..0000000
--- a/tests/integration/test.uuids.js
+++ /dev/null
@@ -1,68 +0,0 @@
-'use strict';
-/* jshint maxlen: false */
-var rfcRegexp = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
-
-function makeUuids(count, length, radix) {
-  count = count || 1;
-  var i = -1;
-  var out = [];
-  while (++i < count) {
-    out.push(PouchDB.utils.uuid(length, radix));
-  }
-  return out;
-}
-
-describe('test.uuid.js', function () {
-
-  it('UUID RFC4122 test', function () {
-    rfcRegexp.test(makeUuids()[0]).should
-      .equal(true, 'Single UUID complies with RFC4122.');
-    rfcRegexp.test(PouchDB.utils.uuid()).should
-      .equal(true,
-             'Single UUID through Pouch.utils.uuid complies with RFC4122.');
-  });
-
-  it('UUID generation uniqueness', function () {
-    var count = 1000;
-    var uuids = makeUuids(count);
-    testUtils.eliminateDuplicates(uuids).should.have
-      .length(count, 'Generated UUIDS are unique.');
-  });
-
-  it('Test small uuid uniqness', function () {
-    var length = 8;
-    var count = 2000;
-    var uuids = makeUuids(count, length);
-    testUtils.eliminateDuplicates(uuids).should.have
-      .length(count, 'Generated small UUIDS are unique.');
-  });
-
-  it('Test custom length', function () {
-    var length = 32;
-    var count = 10;
-    var uuids = makeUuids(count, length);
-    // Test single UUID wrapper
-    uuids.push(PouchDB.utils.uuid(length));
-    uuids.map(function (uuid) {
-      uuid.should.have.length(length, 'UUID length is correct.');
-    });
-  });
-
-  it('Test custom length, redix', function () {
-    var length = 32;
-    var count = 10;
-    var radix = 5;
-    var uuids = makeUuids(count, length, radix);
-    // Test single UUID wrapper
-    uuids.push(PouchDB.utils.uuid(length, radix));
-    uuids.map(function (uuid) {
-      var nums = uuid.split('').map(function (character) {
-          return parseInt(character, radix);
-        });
-      var max = Math.max.apply(Math, nums);
-      var min = Math.min.apply(Math, nums);
-      max.should.be.below(radix, 'Maximum character is less than radix');
-      min.should.be.at.least(0, 'Min character is greater than or equal to 0');
-    });
-  });
-});
diff --git a/tests/integration/utils.js b/tests/integration/utils.js
deleted file mode 100644
index dfa4fc9..0000000
--- a/tests/integration/utils.js
+++ /dev/null
@@ -1,340 +0,0 @@
-/* global PouchDB */
-/* jshint -W079 */
-'use strict';
-
-var testUtils = {};
-
-function uniq(list) {
-  var map = {};
-  list.forEach(function (item) {
-    map[item] = true;
-  });
-  return Object.keys(map);
-}
-
-testUtils.isCouchMaster = function () {
-  return 'SERVER' in testUtils.params() &&
-    testUtils.params().SERVER === 'couchdb-master';
-};
-
-testUtils.isSyncGateway = function () {
-  return 'SERVER' in testUtils.params() &&
-    testUtils.params().SERVER === 'sync-gateway';
-};
-
-testUtils.isExpressRouter = function () {
-  return 'SERVER' in testUtils.params() &&
-    testUtils.params().SERVER === 'pouchdb-express-router';
-};
-
-testUtils.params = function () {
-  if (typeof module !== 'undefined' && module.exports) {
-    return process.env;
-  }
-  var paramStr = document.location.search.slice(1);
-  return paramStr.split('&').reduce(function (acc, val) {
-    if (!val) {
-      return acc;
-    }
-    var tmp = val.split('=');
-    acc[tmp[0]] = decodeURIComponent(tmp[1]) || true;
-    return acc;
-  }, {});
-};
-
-testUtils.couchHost = function () {
-  if (typeof window !== 'undefined' && window.cordova) {
-    // magic route to localhost on android emulator
-    return 'http://10.0.2.2:5984';
-  }
-
-  if (typeof window !== 'undefined' && window.COUCH_HOST) {
-    return window.COUCH_HOST;
-  }
-
-  if (typeof process !== 'undefined' && process.env.COUCH_HOST) {
-    return process.env.COUCH_HOST;
-  }
-
-  if ('couchHost' in testUtils.params()) {
-    return testUtils.params().couchHost;
-  }
-
-  return 'http://localhost:5984';
-};
-
-// Abstracts constructing a Blob object, so it also works in older
-// browsers that don't support the native Blob constructor (e.g.
-// old QtWebKit versions, Android < 4.4).
-// Copied over from createBlob.js in PouchDB because we don't
-// want to have to export this function in utils
-function createBlob(parts, properties) {
-  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
-                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
-                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
-                  WebKitBlobBuilder;
-    var builder = new Builder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
-  }
-}
-
-testUtils.makeBlob = function (data, type) {
-  if (typeof module !== 'undefined' && module.exports) {
-    return new Buffer(data, 'binary');
-  } else {
-    return createBlob([data], {
-      type: (type || 'text/plain')
-    });
-  }
-};
-
-testUtils.binaryStringToBlob = function (bin, type) {
-  return PouchDB.utils.binaryStringToBlobOrBuffer(bin, type);
-};
-
-testUtils.btoa = function (arg) {
-  return PouchDB.utils.btoa(arg);
-};
-
-testUtils.atob = function (arg) {
-  return PouchDB.utils.atob(arg);
-};
-
-testUtils.readBlob = function (blob, callback) {
-  if (typeof module !== 'undefined' && module.exports) {
-    callback(blob.toString('binary'));
-  } else {
-    var reader = new FileReader();
-    reader.onloadend = function () {
-      
-      var binary = "";
-      var bytes = new Uint8Array(this.result || '');
-      var length = bytes.byteLength;
-      
-      for (var i = 0; i < length; i++) {
-        binary += String.fromCharCode(bytes[i]);
-      }
-      
-      callback(binary);
-    };
-    reader.readAsArrayBuffer(blob);
-  }
-};
-
-testUtils.readBlobPromise = function (blob) {
-  return new PouchDB.utils.Promise(function (resolve) {
-    testUtils.readBlob(blob, resolve);
-  });
-};
-
-testUtils.base64Blob = function (blob, callback) {
-  if (typeof module !== 'undefined' && module.exports) {
-    callback(blob.toString('base64'));
-  } else {
-    testUtils.readBlob(blob, function (binary) {
-      callback(PouchDB.utils.btoa(binary));
-    });
-  }
-};
-
-// Prefix http adapter database names with their host and
-// node adapter ones with a db location
-testUtils.adapterUrl = function (adapter, name) {
-  if (adapter === 'http') {
-    return testUtils.couchHost() + '/' + name;
-  }
-  return name;
-};
-
-// Delete specified databases
-testUtils.cleanup = function (dbs, done) {
-  dbs = uniq(dbs);
-  var num = dbs.length;
-  var finished = function () {
-    if (--num === 0) {
-      done();
-    }
-  };
-
-  dbs.forEach(function (db) {
-    new PouchDB(db).destroy(finished, finished);
-  });
-};
-
-// Put doc after prevRev (so that doc is a child of prevDoc
-// in rev_tree). Doc must have _rev. If prevRev is not specified
-// just insert doc with correct _rev (new_edits=false!)
-testUtils.putAfter = function (db, doc, prevRev, callback) {
-  var newDoc = PouchDB.utils.extend({}, doc);
-  if (!prevRev) {
-    db.put(newDoc, { new_edits: false }, callback);
-    return;
-  }
-  newDoc._revisions = {
-    start: +newDoc._rev.split('-')[0],
-    ids: [
-      newDoc._rev.split('-')[1],
-      prevRev.split('-')[1]
-    ]
-  };
-  db.put(newDoc, { new_edits: false }, callback);
-};
-
-// docs will be inserted one after another
-// starting from root
-testUtils.putBranch = function (db, docs, callback) {
-  function insert(i) {
-    var doc = docs[i];
-    var prev = i > 0 ? docs[i - 1]._rev : null;
-    function next() {
-      if (i < docs.length - 1) {
-        insert(i + 1);
-      } else {
-        callback();
-      }
-    }
-    db.get(doc._id, { rev: doc._rev }, function (err) {
-      if (err) {
-        testUtils.putAfter(db, docs[i], prev, function () {
-          next();
-        });
-      } else {
-        next();
-      }
-    });
-  }
-  insert(0);
-};
-
-testUtils.putTree = function (db, tree, callback) {
-  function insert(i) {
-    var branch = tree[i];
-    testUtils.putBranch(db, branch, function () {
-      if (i < tree.length - 1) {
-        insert(i + 1);
-      } else {
-        callback();
-      }
-    });
-  }
-  insert(0);
-};
-
-testUtils.isCouchDB = function (cb) {
-  PouchDB.ajax({url: testUtils.couchHost() + '/' }, function (err, res) {
-    cb('couchdb' in res);
-  });
-};
-
-testUtils.writeDocs = function (db, docs, callback, res) {
-  if (!res) {
-    res = [];
-  }
-  if (!docs.length) {
-    return callback(null, res);
-  }
-  var doc = docs.shift();
-  db.put(doc, function (err, info) {
-    res.push(info);
-    testUtils.writeDocs(db, docs, callback, res);
-  });
-};
-
-// Borrowed from: http://stackoverflow.com/a/840849
-testUtils.eliminateDuplicates = function (arr) {
-  var i, element, len = arr.length, out = [], obj = {};
-  for (i = 0; i < len; i++) {
-    obj[arr[i]] = 0;
-  }
-  for (element in obj) {
-    if (obj.hasOwnProperty(element)) {
-      out.push(element);
-    }
-  }
-  return out;
-};
-
-// Promise finally util similar to Q.finally
-testUtils.fin = function (promise, cb) {
-  return promise.then(function (res) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        return res;
-      });
-    }
-    return res;
-  }, function (reason) {
-    var promise2 = cb();
-    if (typeof promise2.then === 'function') {
-      return promise2.then(function () {
-        throw reason;
-      });
-    }
-    throw reason;
-  });
-};
-
-testUtils.promisify = function (fun, context) {
-  return function () {
-    var args = [];
-    for (var i = 0; i < arguments.length; i++) {
-      args[i] = arguments[i];
-    }
-    return new PouchDB.utils.Promise(function (resolve, reject) {
-      args.push(function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        return resolve(res);
-      });
-      fun.apply(context, args);
-    });
-  };
-};
-
-if (typeof module !== 'undefined' && module.exports) {
-  global.PouchDB = require('../../lib');
-  if (process.env.LEVEL_ADAPTER || process.env.LEVEL_PREFIX) {
-    var defaults = {};
-
-    if (process.env.LEVEL_ADAPTER) {
-      defaults.db = require(process.env.LEVEL_ADAPTER);
-      console.log('Using client-side leveldown adapter: ' +
-        process.env.LEVEL_ADAPTER);
-    }
-    if (process.env.LEVEL_PREFIX) {
-      defaults.prefix = process.env.LEVEL_PREFIX;
-      console.log('Using client-side leveldown prefix: ' + defaults.prefix);
-    }
-    global.PouchDB = global.PouchDB.defaults(defaults);
-  } else if (process.env.AUTO_COMPACTION) {
-    global.PouchDB = global.PouchDB.defaults({auto_compaction: true});
-  }
-  if (typeof process !== 'undefined') {
-    if (process.env.ADAPTER === 'websql') {
-      // test WebSQL in Node
-      require('../../extras/websql');
-      global.PouchDB.preferredAdapters = ['websql'];
-      global.PouchDB.prefix = './tmp/' + global.PouchDB.prefix;
-      require('mkdirp').sync('./tmp');
-    } else {
-      // test regular LevelDB in Node
-      global.PouchDB.prefix = './tmp/' + global.PouchDB.prefix;
-      global.PouchDB.adapters.leveldb.use_prefix = true;
-    }
-  }
-  module.exports = testUtils;
-}
diff --git a/tests/integration/webrunner.js b/tests/integration/webrunner.js
deleted file mode 100644
index 58c5963..0000000
--- a/tests/integration/webrunner.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* global mocha: true */
-
-'use strict';
-
-// use query parameter pluginFile if present,
-// eg: test.html?pluginFile=memory.pouchdb.js
-var preferredAdapters = window.location.search.match(/[?&]adapters=([^&]+)/);
-var pouchdbSrc = window.location.search.match(/[?&]src=([^&]+)/);
-if (pouchdbSrc) {
-  pouchdbSrc = decodeURIComponent(pouchdbSrc[1]);
-} else {
-  pouchdbSrc = '../../dist/pouchdb.js';
-}
-var scriptsToLoad = [pouchdbSrc];
-if (preferredAdapters) {
-  preferredAdapters = preferredAdapters[1].split(',');
-  preferredAdapters.forEach(function (adapter) {
-    if (adapter !== 'websql' && adapter !== 'idb') {
-      // load from plugin
-      scriptsToLoad.push('../../dist/pouchdb.' + adapter + '.js');
-    }
-  });
-}
-
-// Thanks to http://engineeredweb.com/blog/simple-async-javascript-loader/
-function asyncLoadScript(url, callback) {
-
-  // Create a new script and setup the basics.
-  var script = document.createElement("script"),
-  firstScript = document.getElementsByTagName('script')[0];
-
-  script.async = true;
-  script.src = url;
-
-  // Handle the case where an optional callback was passed in.
-  if ("function" === typeof (callback)) {
-    script.onload = function () {
-      callback();
-
-      // Clear it out to avoid getting called more than once or any 
-      // memory leaks.
-      script.onload = script.onreadystatechange = undefined;
-    };
-    script.onreadystatechange = function () {
-      if ("loaded" === script.readyState || "complete" === script.readyState) {
-        script.onload();
-      }
-    };
-  }
-
-  // Attach the script tag to the page (before the first script) so the
-  //magic can happen.
-  firstScript.parentNode.insertBefore(script, firstScript);
-}
-
-function modifyGlobals() {
-  if (preferredAdapters) {
-    window.PouchDB.preferredAdapters = preferredAdapters;
-  }
-  if (window.location.search.indexOf('autoCompaction') !== -1) {
-    window.PouchDB = window.PouchDB.defaults({auto_compaction: true});
-  }
-}
-
-function startTests() {
-
-  function loadNext() {
-    if (scriptsToLoad.length) {
-      var script = scriptsToLoad.shift();
-      asyncLoadScript(script, loadNext);
-    } else {
-      onReady();
-    }
-  }
-
-  function onReady() {
-    modifyGlobals();
-
-    var runner = mocha.run();
-
-    // Capture logs for selenium output
-    var logs = [];
-
-    (function (){
-
-      var oldLog = console.log;
-      console.log = function () {
-        var args = Array.prototype.slice.call(arguments);
-        args.unshift('log');
-        logs.push(args);
-        oldLog.apply(console, arguments);
-      };
-
-      var oldError = console.error;
-      console.error = function () {
-        var args = Array.prototype.slice.call(arguments);
-        args.unshift('error');
-        logs.push(args);
-        oldError.apply(console, arguments);
-      };
-
-    })();
-
-    window.results = {
-      browser: navigator.userAgent,
-      lastPassed: '',
-      passed: 0,
-      failed: 0,
-      failures: []
-    };
-
-    runner.on('pass', function (e) {
-      window.results.lastPassed = e.title;
-      window.results.passed++;
-    });
-
-    runner.on('fail', function (e) {
-      window.results.logs = logs;
-      window.results.failed++;
-      window.results.failures.push({
-        title: e.title,
-        message: e.err.message,
-        stack: e.err.stack
-      });
-    });
-
-    runner.on('end', function () {
-      window.results.logs = logs;
-      window.results.completed = true;
-      window.results.passed++;
-    });
-  }
-
-  loadNext();
-}
-
-if (window.cordova) {
-  var hasGrep = window.GREP &&
-      window.location.search.indexOf('grep=') === -1;
-  var hasAutoCompaction = window.AUTO_COMPACTION &&
-    window.location.search.indexOf('autoCompaction') === -1;
-  var hasAdapters = window.ADAPTERS &&
-    window.location.search.indexOf('adapters=') === -1;
-
-  if (hasGrep || hasAutoCompaction || hasAdapters) {
-    var params = [];
-    if (hasGrep) {
-      params.push('grep=' + encodeURIComponent(window.GREP));
-    }
-    if (hasAutoCompaction) {
-      params.push('autoCompaction=' +
-        encodeURIComponent(window.AUTO_COMPACTION));
-    }
-    if (hasAdapters) {
-      params.push('adapters=' + encodeURIComponent(window.ADAPTERS));
-    }
-    window.location.search += (window.location.search ? '&' : '?') +
-      params.join('&');
-  } else {
-    document.addEventListener("deviceready", startTests, false);
-  }
-} else {
-  startTests();
-}
-
-
diff --git a/tests/integration/worker.js b/tests/integration/worker.js
deleted file mode 100644
index 149176c..0000000
--- a/tests/integration/worker.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* jshint worker: true */
-'use strict';
-
-function onError(err) {
-  setTimeout(function () {
-    throw err; // can catch this in the worker's 'error' listener
-  }, 0);
-}
-
-function bigTest(name) {
-  var db = new PouchDB(name);
-  db.post({
-    _id: 'blablah',
-    key: 'lala'
-  }).then(function () {
-    return db.get('blablah');
-  }).then(function (doc) {
-    return db.destroy().then(function () {
-      self.postMessage(doc.key);
-    });
-  }).catch(onError);
-}
-
-function allDocs(name) {
-  var db = new PouchDB(name);
-  db.post({
-    _id: 'blah',
-    title: 'lalaa',
-    _attachments: {
-      'test': {
-        data: new Blob(),
-        content_type: ''
-      }
-    }
-  }).then(function () {
-    return db.get('blah');
-  }).then(function (doc) {
-    return db.destroy().then(function () {
-      self.postMessage(doc);
-    });
-  }).catch(onError);
-}
-
-function putAttachment(name, docId, attId, att, type) {
-  var db = new PouchDB(name);
-  db.putAttachment(docId, attId, att, type).then(function () {
-    return db.getAttachment(docId, attId);
-  }).then(function (fetchedAtt) {
-    return db.destroy().then(function () {
-      self.postMessage(fetchedAtt);
-    });
-  }).catch(onError);
-}
-
-self.addEventListener('message', function (e) {
-  if (Array.isArray(e.data) && e.data[0] === 'source') {
-    importScripts(e.data[1]);
-  } else if (e.data === 'ping') {
-    self.postMessage('pong');
-  } else if (e.data === 'version') {
-    self.postMessage(PouchDB.version);
-  } else if (Array.isArray(e.data) && e.data[0] === 'create') {
-    bigTest(e.data[1]);
-  } else if (Array.isArray(e.data) && e.data[0] === 'allDocs') {
-    allDocs(e.data[1]);
-  } else if (Array.isArray(e.data) && e.data[0] === 'putAttachment') {
-    putAttachment(e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
-  } else {
-    onError(new Error('unknown message: ' + JSON.stringify(e.data)));
-  }
-
-});
diff --git a/tests/mapreduce/index.html b/tests/mapreduce/index.html
deleted file mode 100644
index 8f8dfcf..0000000
--- a/tests/mapreduce/index.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Mocha</title>
-  <link rel="stylesheet" type="text/css" href="../../node_modules/mocha/mocha.css">
-</head>
-<body>
-<div id="mocha"></div>
-<script src="../../node_modules/mocha/mocha.js"></script>
-<script src="../../node_modules/chai/chai.js"></script>
-<script src="../../node_modules/chai-as-promised/lib/chai-as-promised.js"></script>
-<script>
-  mocha.setup({
-    timeout:100000,
-    ui: 'bdd'
-  });
-  var should = chai.should();
-</script>
-<script src='../integration/utils.js'></script>
-<script src="test.mapreduce.js"></script>
-<script src="test.persisted.js"></script>
-<script src='test.views.js'></script>
-<script type="text/javascript" src="../integration/webrunner.js"></script>
-</body>
-</html>
diff --git a/tests/mapreduce/test.mapreduce.js b/tests/mapreduce/test.mapreduce.js
deleted file mode 100644
index 683a827..0000000
--- a/tests/mapreduce/test.mapreduce.js
+++ /dev/null
@@ -1,3245 +0,0 @@
-/* global sum */
-'use strict';
-
-var adapters = ['local', 'http'];
-
-adapters.forEach(function (adapter) {
-
-  var viewTypes = ['persisted', 'temp'];
-  viewTypes.forEach(function (viewType) {
-    var suiteName = 'test.mapreduce.js-' + adapter + '-' + viewType;
-    var dbName = testUtils.adapterUrl(adapter, 'testdb');
-
-    tests(suiteName, dbName, adapter, viewType);
-  });
-});
-
-function tests(suiteName, dbName, dbType, viewType) {
-
-  describe(suiteName, function () {
-
-    var Promise;
-
-    var createView;
-    if (viewType === 'persisted') {
-      createView = function (db, viewObj) {
-        var storableViewObj = {
-          map : viewObj.map.toString()
-        };
-        if (viewObj.reduce) {
-          storableViewObj.reduce = viewObj.reduce.toString();
-        }
-        return new Promise(function (resolve, reject) {
-          db.put({
-            _id: '_design/theViewDoc',
-            views: {
-              'theView' : storableViewObj
-            }
-          }, function (err) {
-            if (err) {
-              reject(err);
-            } else {
-              resolve('theViewDoc/theView');
-            }
-          });
-        });
-      };
-    } else {
-      createView = function (db, viewObj) {
-        return new Promise(function (resolve) {
-          setTimeout(function () {
-            resolve(viewObj);
-          });
-        });
-      };
-    }
-
-    beforeEach(function () {
-      Promise = PouchDB.utils.Promise;
-      return new PouchDB(dbName).destroy();
-    });
-    afterEach(function () {
-      return new PouchDB(dbName).destroy();
-    });
-
-
-    it("Test basic view", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo, doc);
-          }
-        }).then(function (view) {
-          return db.bulkDocs({docs: [
-            {foo: 'bar'},
-            { _id: 'volatile', foo: 'baz' }
-          ]}).then(function () {
-            return db.get('volatile');
-          }).then(function (doc) {
-            return db.remove(doc);
-          }).then(function () {
-            return db.query(view, {include_docs: true, reduce: false});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Dont include deleted documents');
-            res.total_rows.should.equal(1, 'Include total_rows property.');
-            res.rows.forEach(function (x) {
-              should.exist(x.id);
-              should.exist(x.key);
-              should.exist(x.value);
-              should.exist(x.value._rev);
-              should.exist(x.doc);
-              should.exist(x.doc._rev);
-            });
-          });
-        });
-      });
-    });
-    it("Test basic view, no emitted value", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          }
-        }).then(function (view) {
-            return db.bulkDocs({docs: [
-              {foo: 'bar'},
-              { _id: 'volatile', foo: 'baz' }
-            ]}).then(function () {
-                return db.get('volatile');
-              }).then(function (doc) {
-                return db.remove(doc);
-              }).then(function () {
-                return db.query(view, {include_docs: true, reduce: false});
-              }).then(function (res) {
-                res.rows.should.have.length(1,
-                  'Dont include deleted documents');
-                res.total_rows.should.equal(1, 'Include total_rows property.');
-                res.rows.forEach(function (x) {
-                  should.exist(x.id);
-                  should.exist(x.key);
-                  should.equal(x.value, null);
-                  should.exist(x.doc);
-                  should.exist(x.doc._rev);
-                });
-              });
-          });
-      });
-    });
-
-    if (dbType === 'local' && viewType === 'temp') {
-      it("with a closure", function () {
-        return new PouchDB(dbName).then(function (db) {
-          return db.bulkDocs({docs: [
-            {foo: 'bar'},
-            { _id: 'volatile', foo: 'baz' }
-          ]}).then(function () {
-            var queryFun = (function (test) {
-              return function (doc, emit) {
-                if (doc._id === test) {
-                  emit(doc.foo);
-                }
-              };
-            }('volatile'));
-            return db.query(queryFun, {reduce: false});
-          });
-        }).should.become({
-          total_rows: 1,
-          offset: 0,
-          rows: [
-            {
-              id: 'volatile',
-              key: 'baz',
-              value: null
-            }
-          ]
-        });
-      });
-    }
-    if (viewType === 'temp') {
-
-      it('Test simultaneous temp views', function () {
-        return new PouchDB(dbName).then(function (db) {
-          return db.put({_id: '0', foo: 1, bar: 2, baz: 3}).then(function () {
-            return Promise.all(['foo', 'bar', 'baz'].map(function (key, i) {
-              var fun = 'function(doc){emit(doc.' + key + ');}';
-              return db.query({map: fun}).then(function (res) {
-                res.rows.should.deep.equal([{
-                  id: '0',
-                  key: i + 1,
-                  value: null
-                }]);
-              });
-            }));
-          });
-        });
-      });
-
-      it("Test passing just a function", function () {
-        return new PouchDB(dbName).then(function (db) {
-          return db.bulkDocs({docs: [
-            {foo: 'bar'},
-            { _id: 'volatile', foo: 'baz' }
-          ]}).then(function () {
-            return db.get('volatile');
-          }).then(function (doc) {
-            return db.remove(doc);
-          }).then(function () {
-            return db.query(function (doc) {
-              emit(doc.foo, doc);
-            }, {include_docs: true, reduce: false});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Dont include deleted documents');
-            res.rows.forEach(function (x) {
-              should.exist(x.id);
-              should.exist(x.key);
-              should.exist(x.value);
-              should.exist(x.value._rev);
-              should.exist(x.doc);
-              should.exist(x.doc._rev);
-            });
-          });
-        });
-      });
-    }
-
-    it("Test opts.startkey/opts.endkey", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [
-            {key: 'key1'},
-            {key: 'key2'},
-            {key: 'key3'},
-            {key: 'key4'},
-            {key: 'key5'}
-          ]}).then(function () {
-            return db.query(queryFun, {reduce: false, startkey: 'key2'});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'Startkey is inclusive');
-            return db.query(queryFun, {reduce: false, endkey: 'key3'});
-          }).then(function (res) {
-            res.rows.should.have.length(3, 'Endkey is inclusive');
-            return db.query(queryFun, {
-              reduce: false,
-              startkey: 'key2',
-              endkey: 'key3'
-            });
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Startkey and endkey together');
-            return db.query(queryFun, {
-              reduce: false,
-              startkey: 'key4',
-              endkey: 'key4'
-            });
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Startkey=endkey');
-          });
-        });
-      });
-    });
-
-    it("#4154 opts.start_key/opts.end_key are synonyms", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [
-            {key: 'key1'},
-            {key: 'key2'},
-            {key: 'key3'},
-            {key: 'key4'},
-            {key: 'key5'}
-          ]}).then(function () {
-            return db.query(queryFun, {reduce: false, start_key: 'key2'});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'Startkey is inclusive');
-            return db.query(queryFun, {reduce: false, end_key: 'key3'});
-          }).then(function (res) {
-            res.rows.should.have.length(3, 'Endkey is inclusive');
-            return db.query(queryFun, {
-              reduce: false,
-              start_key: 'key2',
-              end_key: 'key3'
-            });
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Startkey and endkey together');
-            return db.query(queryFun, {
-              reduce: false,
-              start_key: 'key4',
-              end_key: 'key4'
-            });
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Startkey=endkey');
-          });
-        });
-      });
-    });
-
-    //TODO: split this to their own tests within a describe block
-    it("Test opts.inclusive_end = false", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [
-            {key: 'key1'},
-            {key: 'key2'},
-            {key: 'key3'},
-            {key: 'key4'},
-            {key: 'key4'},
-            {key: 'key5'}
-          ]}).then(function () {
-            return db.query(queryFun, {
-              reduce: false,
-              endkey: 'key4',
-              inclusive_end: false
-            });
-          }).then(function (resp) {
-            resp.rows.should.have.length(3, 'endkey=key4 without ' +
-            'inclusive end');
-            resp.rows[0].key.should.equal('key1');
-            resp.rows[2].key.should.equal('key3');
-          })
-          .then(function () {
-            return db.query(queryFun, {
-              reduce: false,
-              startkey: 'key3',
-              endkey: 'key4',
-              inclusive_end: false
-            });
-          }).then(function (resp) {
-            resp.rows.should.have.length(1, 'startkey=key3, endkey=key4 ' +
-            'without inclusive end');
-            resp.rows[0].key.should.equal('key3');
-          }).then(function () {
-            return db.query(queryFun, {
-              reduce: false,
-              startkey: 'key4',
-              endkey: 'key1',
-              descending: true,
-              inclusive_end: false
-            });
-          }).then(function (resp) {
-            resp.rows.should
-              .have.length(4, 'startkey=key4, endkey=key1 descending without ' +
-              'inclusive end');
-            resp.rows[0].key.should.equal('key4');
-          });
-        });
-      });
-    });
-
-    it("Test opts.key", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [
-            {key: 'key1'},
-            {key: 'key2'},
-            {key: 'key3'},
-            {key: 'key3'}
-          ]}).then(function () {
-            return db.query(queryFun, {reduce: false, key: 'key2'});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Doc with key');
-            return db.query(queryFun, {reduce: false, key: 'key3'});
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Multiple docs with key');
-          });
-        });
-      });
-    });
-
-    it("Test basic view collation", function () {
-
-      var values = [];
-
-      // special values sort before all other types
-      values.push(null);
-      values.push(false);
-      values.push(true);
-
-      // then numbers
-      values.push(1);
-      values.push(2);
-      values.push(3.0);
-      values.push(4);
-
-      // then text, case sensitive
-      // currently chrome uses ascii ordering and so wont handle caps properly
-      values.push("a");
-      //values.push("A");
-      values.push("aa");
-      values.push("b");
-      //values.push("B");
-      values.push("ba");
-      values.push("bb");
-
-      // then arrays. compared element by element until different.
-      // Longer arrays sort after their prefixes
-      values.push(["a"]);
-      values.push(["b"]);
-      values.push(["b", "c"]);
-      values.push(["b", "c", "a"]);
-      values.push(["b", "d"]);
-      values.push(["b", "d", "e"]);
-
-      // then object, compares each key value in the list until different.
-      // larger objects sort after their subset objects.
-      values.push({a: 1});
-      values.push({a: 2});
-      values.push({b: 1});
-      values.push({b: 2});
-      values.push({b: 2, a: 1}); // Member order does matter for collation.
-      // CouchDB preserves member order
-      // but doesn't require that clients will.
-      // (this test might fail if used with a js engine
-      // that doesn't preserve order)
-      values.push({b: 2, c: 2});
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          }
-        }).then(function (queryFun) {
-
-          var docs = values.map(function (x, i) {
-            return {_id: (i).toString(), foo: x};
-          });
-          return db.bulkDocs({docs: docs}).then(function () {
-            return db.query(queryFun, {reduce: false});
-          }).then(function (res) {
-            res.rows.forEach(function (x, i) {
-              JSON.stringify(x.key).should.equal(JSON.stringify(values[i]),
-                'keys collate');
-            });
-            return db.query(queryFun, {descending: true, reduce: false});
-          }).then(function (res) {
-            res.rows.forEach(function (x, i) {
-              JSON.stringify(x.key).should.equal(JSON.stringify(
-                  values[values.length - 1 - i]),
-                'keys collate descending');
-            });
-          });
-        });
-      });
-    });
-
-    it("Test joins", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            if (doc.doc_id) {
-              emit(doc._id, {_id: doc.doc_id});
-            }
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [
-            {_id: 'mydoc', foo: 'bar'},
-            { doc_id: 'mydoc' }
-          ]}).then(function () {
-            return db.query(queryFun, {include_docs: true, reduce: false});
-          }).then(function (res) {
-            should.exist(res.rows[0].doc);
-            return res.rows[0].doc._id;
-          });
-        }).should.become('mydoc', 'mydoc included');
-      });
-    });
-
-    it("No reduce function", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function () {
-            emit('key', 'val');
-          }
-        }).then(function (queryFun) {
-          return db.post({foo: 'bar'}).then(function () {
-            return db.query(queryFun);
-          });
-        });
-      }).should.be.fulfilled;
-    });
-
-    it("Query after db.close", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo, 'val');
-          }
-        }).then(function (queryFun) {
-          return db.put({_id: 'doc', foo: 'bar'}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.should.deep.equal([
-              {
-                id: 'doc',
-                key: 'bar',
-                value: 'val'
-              }
-            ]);
-            return db.close();
-          }).then(function () {
-            db = new PouchDB(dbName);
-            return db.query(queryFun).then(function (res) {
-              res.rows.should.deep.equal([
-                {
-                  id: 'doc',
-                  key: 'bar',
-                  value: 'val'
-                }
-              ]);
-            });
-          });
-        });
-      });
-    });
-
-    it("Built in _sum reduce function", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.val, 1);
-          },
-          reduce: "_sum"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: 'bar' },
-              { val: 'bar' },
-              { val: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group_level: 999});
-          }).then(function (resp) {
-            return resp.rows.map(function (row) {
-              return row.value;
-            });
-          });
-        });
-      }).should.become([2, 1]);
-    });
-
-    it("Built in _count reduce function", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.val, doc.val);
-          },
-          reduce: "_count"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: 'bar' },
-              { val: 'bar' },
-              { val: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group_level: 999});
-          }).then(function (resp) {
-            return resp.rows.map(function (row) {
-              return row.value;
-            });
-          });
-        });
-      }).should.become([2, 1]);
-    });
-
-    it("Built in _stats reduce function", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){emit(doc.val, 1);}",
-          reduce: "_stats"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: 'bar' },
-              { val: 'bar' },
-              { val: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group_level: 999});
-          }).then(function (res) {
-            return res.rows[0].value;
-          });
-        });
-      }).should.become({
-        sum: 2,
-        count: 2,
-        min: 1,
-        max: 1,
-        sumsqr: 2
-      });
-    });
-
-    it("Built in _stats reduce function should throw an error with a promise",
-      function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){emit(doc.val, 'lala');}",
-          reduce: "_stats"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: 'bar' },
-              { val: 'bar' },
-              { val: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group_level: 999});
-          });
-        });
-      }).should.be.rejected;
-    });
-
-    it("Built in _sum reduce function should throw an error with a promise",
-      function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){emit(null, doc.val);}",
-          reduce: "_sum"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: 1 },
-              { val: 2 },
-              { val: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group: true});
-          });
-        });
-      }).should.be.rejected;
-    });
-
-    it("Built in _sum reduce function with num arrays should throw an error",
-      function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){emit(null, doc.val);}",
-          reduce: "_sum"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { val: [1, 2, 3] },
-              { val: 2 },
-              { val: ['baz']}
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group: true});
-          });
-        });
-      }).should.be.rejected;
-    });
-
-    it("Built in _sum can be used with lists of numbers", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){emit(null, doc.val);}",
-          reduce: "_sum"
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { _id: '1', val: 2 },
-              { _id: '2', val: [1, 2, 3, 4] },
-              { _id: '3', val: [3, 4] },
-              { _id: '4', val: 1 }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {reduce: true, group: true});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [{
-              key : null,
-              value : [7, 6, 3, 4]
-            }]});
-          });
-        });
-      });
-    });
-
-    if (viewType === 'temp') {
-      it("No reduce function, passing just a function", function () {
-        return new PouchDB(dbName).then(function (db) {
-          return db.post({foo: 'bar'}).then(function () {
-            var queryFun = function () {
-              emit('key', 'val');
-            };
-            return db.query(queryFun);
-          });
-        }).should.be.fulfilled;
-      });
-    }
-
-    it('Query result should include _conflicts', function () {
-      var db2name = 'test2b' + Math.random();
-      var cleanup = function () {
-        return new PouchDB(db2name).destroy();
-      };
-      var doc1 = {_id: '1', foo: 'bar'};
-      var doc2 = {_id: '1', foo: 'baz'};
-      return testUtils.fin(new PouchDB(dbName).then(function (db) {
-        return new PouchDB(db2name).then(function (remote) {
-          var replicate = testUtils.promisify(db.replicate.from, db.replicate);
-          return db.post(doc1).then(function () {
-            return remote.post(doc2);
-          }).then(function () {
-            return replicate(remote);
-          }).then(function () {
-            return db.query(function (doc) {
-              if (doc._conflicts) {
-                emit(doc._conflicts, null);
-              }
-            }, {include_docs : true, conflicts: true});
-          }).then(function (res) {
-            should.exist(res.rows[0].doc._conflicts);
-            return db.get(res.rows[0].doc._id, {conflicts: true});
-          }).then(function (res) {
-            should.exist(res._conflicts);
-          });
-        });
-      }), cleanup);
-    });
-
-    /* jshint maxlen:false */
-    var icons = [
-      "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"
-    ];
-
-    /* jshint maxlen:100 */
-
-    var iconDigests = [
-      "md5-Mf8m9ehZnCXC717bPkqkCA==",
-      "md5-fdEZBYtnvr+nozYVDzzxpA==",
-      "md5-ImDARszfC+GA3Cv9TVW4HA==",
-      "md5-hBsgoz3ujHM4ioa72btwow==",
-      "md5-jDUyV6ySnTVANn2qq3332g=="
-    ];
-
-    var iconLengths = [1047, 789, 967, 527, 1108];
-
-    it('#190 Query works with attachments=true', function () {
-
-      var db = new PouchDB(dbName);
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc._id);
-          }
-        });
-      }).then(function (queryFun) {
-        return db.query(queryFun, {
-          include_docs: true,
-          attachments: true
-        }).then(function (res) {
-          var attachments = res.rows.map(function (row) {
-            var doc = row.doc;
-            delete doc._attachments['foo.png'].revpos;
-            return doc._attachments;
-          });
-          attachments.should.deep.equal(icons.map(function (icon, i) {
-            return {
-              "foo.png": {
-                "content_type": "image/png",
-                "data": icon,
-                "digest": iconDigests[i]
-              }
-            };
-          }), 'works with attachments=true');
-          return db.query(queryFun, {include_docs: true});
-        }).then(function (res) {
-          var attachments = res.rows.map(function (row) {
-            var doc = row.doc;
-            delete doc._attachments['foo.png'].revpos;
-            return doc._attachments['foo.png'];
-          });
-          attachments.should.deep.equal(icons.map(function (icon, i) {
-            return {
-              "content_type": "image/png",
-              stub: true,
-              "digest": iconDigests[i],
-              length: iconLengths[i]
-            };
-          }), 'works with attachments=false');
-
-          return db.query(queryFun, {attachments: true});
-        }).then(function (res) {
-          res.rows.should.have.length(5);
-          res.rows.forEach(function (row) {
-            should.not.exist(row.doc, 'ignored if include_docs=false');
-          });
-        });
-      });
-    });
-
-    it('#2858 Query works with attachments=true, binary=true 1', function () {
-
-      // Need to avoid the cache to workaround
-      // https://issues.apache.org/jira/browse/COUCHDB-2880
-      var db = new PouchDB(dbName, {ajax: {cache: false}});
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString(),
-          _attachments: {
-            'foo.png': {
-              data: icons[i],
-              content_type: 'image/png'
-            }
-          }
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc._id);
-          }
-        });
-      }).then(function (queryFun) {
-        return db.query(queryFun, {
-          include_docs: true,
-          attachments: true,
-          binary: true
-        }).then(function (res) {
-          res.rows.forEach(function (row) {
-            var doc = row.doc;
-            Object.keys(doc._attachments).forEach(function (attName) {
-              var att = doc._attachments[attName];
-              should.not.exist(att.stub);
-              att.data.should.not.be.a('string');
-            });
-          });
-        });
-      });
-    });
-
-    it('#2858 Query works with attachments=true, binary=true 2', function () {
-
-      // Need to avoid the cache to workaround
-      // https://issues.apache.org/jira/browse/COUCHDB-2880
-      var db = new PouchDB(dbName, {ajax: {cache: false}});
-      var docs = [];
-      for (var i = 0; i < 5; i++) {
-        docs.push({
-          _id: i.toString()
-        });
-      }
-      return db.bulkDocs(docs).then(function () {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc._id);
-          }
-        });
-      }).then(function (queryFun) {
-        return db.query(queryFun, {
-          include_docs: true,
-          attachments: true,
-          binary: true
-        }).then(function (res) {
-          res.rows.forEach(function (row) {
-            var doc = row.doc;
-            should.not.exist(doc._attachments);
-          });
-        });
-      });
-    });
-
-    it('#242 conflicts at the root level', function () {
-      var db = new PouchDB(dbName);
-
-      return db.bulkDocs([
-        {
-          foo: '1',
-          _id: 'foo',
-          _rev: '1-w',
-          _revisions: {start: 1, ids: ['w']}
-        }
-      ], {new_edits: false}).then(function () {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          }
-        }).then(function (queryFun) {
-          return db.query(queryFun).then(function (res) {
-            res.rows[0].key.should.equal('1');
-            return db.bulkDocs([
-              {
-                foo: '2',
-                _id: 'foo',
-                _rev: '1-x',
-                _revisions: {start: 1, ids: ['x']}
-              }
-            ], {new_edits: false}).then(function () {
-              return db.query(queryFun);
-            }).then(function (res) {
-              res.rows[0].key.should.equal('2');
-              return db.bulkDocs([
-                {
-                  foo: '3',
-                  _id: 'foo',
-                  _rev: '1-y',
-                  _deleted: true,
-                  _revisions: {start: 1, ids: ['y']}
-                }
-              ], {new_edits: false});
-            }).then(function () {
-              return db.query(queryFun);
-            }).then(function (res) {
-              res.rows[0].key.should.equal('2');
-            });
-          });
-        });
-      });
-    });
-
-    it('#242 conflicts at the root+1 level', function () {
-      var db = new PouchDB(dbName);
-
-      return db.bulkDocs([
-        {
-          foo: '2',
-          _id: 'foo',
-          _rev: '1-x',
-          _revisions: {start: 1, ids: ['x']}
-        },
-        {
-          foo: '3',
-          _id: 'foo',
-          _rev: '2-y',
-          _deleted: true,
-          _revisions: {start: 2, ids: ['y', 'x']}
-        }
-
-      ], {new_edits: false}).then(function () {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          }
-        }).then(function (queryFun) {
-          return db.query(queryFun).then(function (res) {
-            res.rows.length.should.equal(0);
-            return db.bulkDocs([
-              {
-                foo: '1',
-                _id: 'foo',
-                _rev: '1-w',
-                _revisions: {start: 1, ids: ['w']}
-              }
-            ], {new_edits: false}).then(function () {
-              return db.query(queryFun);
-            }).then(function (res) {
-              res.rows[0].key.should.equal('1');
-              return db.bulkDocs([
-                {
-                  foo: '4',
-                  _id: 'foo',
-                  _rev: '1-z',
-                  _revisions: {start: 1, ids: ['z']}
-                }
-              ], {new_edits: false});
-            }).then(function () {
-              return db.query(queryFun);
-            }).then(function (res) {
-              res.rows[0].key.should.equal('4');
-            });
-          });
-        });
-      });
-    });
-
-    it('Views should include _conflicts', function () {
-      var db2name = 'test2' + Math.random();
-      var cleanup = function () {
-        return new PouchDB(db2name).destroy();
-      };
-      var doc1 = {_id: '1', foo: 'bar'};
-      var doc2 = {_id: '1', foo: 'baz'};
-      return testUtils.fin(new PouchDB(dbName).then(function (db) {
-        return new PouchDB(db2name).then(function (remote) {
-          return createView(db, {
-            map : function (doc) {
-              emit(doc._id, !!doc._conflicts);
-            }
-          }).then(function (queryFun) {
-            var replicate = testUtils.promisify(db.replicate.from, db.replicate);
-            return db.post(doc1).then(function () {
-              return remote.post(doc2);
-            }).then(function () {
-              return replicate(remote);
-            }).then(function () {
-              return db.get(doc1._id, {conflicts: true});
-            }).then(function (res) {
-              should.exist(res._conflicts);
-              return db.query(queryFun);
-            }).then(function (res) {
-              res.rows[0].value.should.equal(true);
-            });
-          });
-        });
-      }), cleanup);
-    });
-
-    it("Test view querying with limit option", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            if (doc.foo === 'bar') {
-              emit(doc.foo);
-            }
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'bar' },
-              { foo: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { limit: 1 });
-          }).then(function (res) {
-            res.total_rows.should.equal(2, 'Correctly returns total rows');
-            res.rows.should.have.length(1, 'Correctly limits returned rows');
-          });
-        });
-      });
-    });
-
-    it("Test view querying with custom reduce function", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: function (keys) {
-            return keys.map(function (keyId) {
-              var key = keyId[0];
-              // var id = keyId[1];
-              return key.join('');
-            });
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: ['foo', 'bar'] },
-              { foo: ['foo', 'bar'] },
-              { foo: ['foo', 'bar', 'baz'] },
-              { foo: ['baz'] },
-              { foo: ['baz', 'bar'] }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { reduce: true });
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Correctly reduced returned rows');
-            should.not.exist(res.rows[0].key, 'Correct, non-existing key');
-            res.rows[0].value.should.have.length(5);
-            res.rows[0].value.should.include('foobarbaz');
-            res.rows[0].value.should.include('foobar'); // twice
-            res.rows[0].value.should.include('bazbar');
-            res.rows[0].value.should.include('baz');
-            return db.query(queryFun, { group_level: 1, reduce: true });
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Correctly group reduced rows');
-            res.rows[0].key.should.deep.equal(['baz']);
-            res.rows[0].value.should.have.length(2);
-            res.rows[0].value.should.include('bazbar');
-            res.rows[0].value.should.include('baz');
-            res.rows[1].key.should.deep.equal(['foo']);
-            res.rows[1].value.should.have.length(3);
-            res.rows[1].value.should.include('foobarbaz');
-            res.rows[1].value.should.include('foobar'); // twice
-          });
-        });
-      });
-    });
-
-    it("Test view querying with group_level option and reduce", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: ['foo', 'bar'] },
-              { foo: ['foo', 'bar'] },
-              { foo: ['foo', 'bar', 'baz'] },
-              { foo: ['baz'] },
-              { foo: ['baz', 'bar'] }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { group_level: 1, reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Correctly group returned rows');
-            res.rows[0].key.should.deep.equal(['baz']);
-            res.rows[0].value.should.equal(2);
-            res.rows[1].key.should.deep.equal(['foo']);
-            res.rows[1].value.should.equal(3);
-            return db.query(queryFun, { group_level: 999, reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'Correctly group returned rows');
-            res.rows[2].key.should.deep.equal(['foo', 'bar']);
-            res.rows[2].value.should.equal(2);
-            return db.query(queryFun, { group_level: '999', reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'Correctly group returned rows');
-            res.rows[2].key.should.deep.equal(['foo', 'bar']);
-            res.rows[2].value.should.equal(2);
-            return db.query(queryFun, { group_level: 0, reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Correctly group returned rows');
-            res.rows[0].value.should.equal(5);
-          });
-        });
-      });
-    });
-
-    it("Test view querying with invalid group_level options", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          return db.query(queryFun, { group_level: -1, reduce: true
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-            return db.query(queryFun, { group_level: 'exact', reduce: true});
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-          });
-        });
-      });
-    });
-
-    it("Test view querying with limit option and reduce", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'bar' },
-              { foo: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { limit: 1, group: true, reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Correctly limits returned rows');
-            res.rows[0].key.should.equal('bar');
-            res.rows[0].value.should.equal(2);
-          }).then(function () {
-            return db.query(queryFun, { limit: '1', group: true, reduce: true});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'Correctly limits returned rows');
-            res.rows[0].key.should.equal('bar');
-            res.rows[0].value.should.equal(2);
-          });
-        });
-      });
-    });
-
-    it("Test view querying with invalid limit option and reduce", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'bar' },
-              { foo: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { limit: -1, group: true, reduce: true});
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-            return db.query(queryFun, { limit: '1a', group: true, reduce: true});
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-          });
-        });
-      });
-    });
-
-    it('Test unsafe object usage (#244)', function () {
-      var db = new PouchDB(dbName);
-      return db.bulkDocs([
-        {_id: 'constructor'}
-      ]).then(function (res) {
-        var rev = res[0].rev;
-        return createView(db, {
-          map: function (doc) {
-            emit(doc._id);
-          }
-        }).then(function (queryFun) {
-          return db.query(queryFun, {include_docs: true}).then(function (res) {
-            res.rows.should.deep.equal([
-              {
-                "key": "constructor",
-                "id": "constructor",
-                "value": null,
-                "doc": {
-                  "_id": "constructor",
-                  "_rev": rev
-                }
-              }
-            ]);
-            return db.bulkDocs([
-              {_id: 'constructor', _rev: rev}
-            ]);
-          }).then(function (res) {
-            rev = res[0].rev;
-            return db.query(queryFun, {include_docs: true});
-          }).then(function (res) {
-            res.rows.should.deep.equal([
-              {
-                "key": "constructor",
-                "id": "constructor",
-                "value": null,
-                "doc": {
-                  "_id": "constructor",
-                  "_rev": rev
-                }
-              }
-            ]);
-            return db.bulkDocs([
-              {_id: 'constructor', _rev: rev, _deleted: true}
-            ]);
-          }).then(function (res) {
-            rev = res[0].rev;
-            return db.query(queryFun, {include_docs: true});
-          }).then(function (res) {
-            res.rows.should.deep.equal([]);
-          });
-        });
-      });
-    });
-
-    it("Test view querying with a skip option and reduce", function () {
-      var qf;
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          qf = queryFun;
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'bar' },
-              { foo: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {skip: 1, group: true, reduce: true});
-          });
-        }).then(function (res) {
-          res.rows.should.have.length(1, 'Correctly limits returned rows');
-          res.rows[0].key.should.equal('baz');
-          res.rows[0].value.should.equal(1);
-        }).then(function () {
-          return db.query(qf, {skip: '1', group: true, reduce: true});
-        }).then(function (res) {
-          res.rows.should.have.length(1, 'Correctly limits returned rows');
-          res.rows[0].key.should.equal('baz');
-          res.rows[0].value.should.equal(1);
-        });
-      });
-    });
-
-    it("Test view querying with invalid skip option and reduce", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: '_count'
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'bar' },
-              { foo: 'baz' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { skip: -1, group: true, reduce: true});
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-            return db.query(queryFun, { skip: '1a', group: true, reduce: true});
-          }).then(function (res) {
-            res.should.not.exist('expected error on invalid group_level');
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            err.message.should.be.a('string');
-          });
-        });
-      });
-    });
-
-    it("Special document member _doc_id_rev should never leak outside",
-      function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            if (doc.foo === 'bar') {
-              emit(doc.foo);
-            }
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, { include_docs: true });
-          }).then(function (res) {
-            should.not.exist(res.rows[0].doc._doc_id_rev, '_doc_id_rev is leaking but should not');
-          });
-        });
-      });
-    });
-
-    it('multiple view creations and cleanups', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var map = function (doc) {
-          emit(doc.num);
-        };
-        function createView(name) {
-          var storableViewObj = {
-            map: map.toString()
-          };
-          return  db.put({
-            _id: '_design/' + name,
-            views: {
-              theView: storableViewObj
-            }
-          });
-        }
-        return db.bulkDocs({
-          docs: [
-            {_id: 'test1'}
-          ]
-        }).then(function () {
-          function sequence(name) {
-            return createView(name).then(function () {
-              return db.query(name + '/theView').then(function () {
-                return db.viewCleanup();
-              });
-            });
-          }
-          var attempts = [];
-          var numAttempts = 10;
-          for (var i = 0; i < numAttempts; i++) {
-            attempts.push(sequence('test' + i));
-          }
-          return Promise.all(attempts).then(function () {
-            var keys = [];
-            for (var i = 0; i < numAttempts; i++) {
-              keys.push('_design/test' + i);
-            }
-            return db.allDocs({keys : keys, include_docs : true});
-          }).then(function (res) {
-            var docs = res.rows.map(function (row) {
-              row.doc._deleted = true;
-              return row.doc;
-            });
-            return db.bulkDocs({docs : docs});
-          }).then(function () {
-            return db.viewCleanup();
-          }).then(function (res) {
-            res.ok.should.equal(true);
-          });
-        });
-      });
-    });
-
-    it('If reduce function returns 0, resulting value should not be null', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: function () {
-            return 0;
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' }
-            ]
-          }).then(function () {
-            return db.query(queryFun).then(function (data) {
-              should.exist(data.rows[0].value);
-            });
-          });
-        });
-      });
-    });
-
-    it('Testing skip with a view', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.foo);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({
-            docs: [
-              { foo: 'bar' },
-              { foo: 'baz' },
-              { foo: 'baf' }
-            ]
-          }).then(function () {
-            return db.query(queryFun, {skip: 1});
-          }).then(function (data) {
-            data.rows.should.have.length(2);
-            data.offset.should.equal(1);
-            data.total_rows.should.equal(3);
-          });
-        });
-      });
-    });
-
-    it('Map documents on 0/null/undefined/empty string', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.num);
-          }
-        }).then(function (mapFunction) {
-          var docs = [
-            {_id: '0', num: 0},
-            {_id: '1', num: 1},
-            {_id: 'undef' /* num is undefined */},
-            {_id: 'null', num: null},
-            {_id: 'empty', num: ''},
-            {_id: 'nan', num: NaN},
-            {_id: 'inf', num: Infinity},
-            {_id: 'neginf', num: -Infinity}
-          ];
-          return db.bulkDocs({docs: docs}).then(function () {
-            return db.query(mapFunction, {key: 0});
-          }).then(function (data) {
-            data.rows.should.have.length(1);
-            data.rows[0].id.should.equal('0');
-
-            return db.query(mapFunction, {key: ''});
-          }).then(function (data) {
-            data.rows.should.have.length(1);
-            data.rows[0].id.should.equal('empty');
-
-            return db.query(mapFunction, {key: undefined});
-          }).then(function (data) {
-            data.rows.should.have.length(8); // everything
-
-            // keys that should all resolve to null
-            var emptyKeys = [null, NaN, Infinity, -Infinity];
-            return Promise.all(emptyKeys.map(function (emptyKey) {
-              return db.query(mapFunction, {key: emptyKey}).then(function (data) {
-                data.rows.map(function (row) {
-                  return row.id;
-                }).should.deep.equal(['inf', 'nan', 'neginf', 'null', 'undef']);
-              });
-            }));
-          });
-        });
-      });
-    });
-
-    it('Testing query with keys', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.field);
-          }
-        }).then(function (queryFun) {
-          var opts = {include_docs: true};
-          return db.bulkDocs({
-            docs: [
-              {_id: 'doc_0', field: 0},
-              {_id: 'doc_1', field: 1},
-              {_id: 'doc_2', field: 2},
-              {_id: 'doc_empty', field: ''},
-              {_id: 'doc_null', field: null},
-              {_id: 'doc_undefined' /* field undefined */},
-              {_id: 'doc_foo', field: 'foo'}
-            ]
-          }).then(function () {
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(7, 'returns all docs');
-            opts.keys = [];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(0, 'returns 0 docs');
-
-            opts.keys = [0];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(1, 'returns one doc');
-            data.rows[0].doc._id.should.equal('doc_0');
-
-            opts.keys = [2, 'foo', 1, 0, null, ''];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            // check that the returned ordering fits opts.keys
-            data.rows.should.have.length(7, 'returns 7 docs in correct order');
-            data.rows[0].doc._id.should.equal('doc_2');
-            data.rows[1].doc._id.should.equal('doc_foo');
-            data.rows[2].doc._id.should.equal('doc_1');
-            data.rows[3].doc._id.should.equal('doc_0');
-            data.rows[4].doc._id.should.equal('doc_null');
-            data.rows[5].doc._id.should.equal('doc_undefined');
-            data.rows[6].doc._id.should.equal('doc_empty');
-
-            opts.keys = [3, 1, 4, 2];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            // nonexistent keys just give us holes in the list
-            data.rows.should.have.length(2, 'returns 2 non-empty docs');
-            data.rows[0].key.should.equal(1);
-            data.rows[0].doc._id.should.equal('doc_1');
-            data.rows[1].key.should.equal(2);
-            data.rows[1].doc._id.should.equal('doc_2');
-
-            opts.keys = [2, 1, 2, 0, 2, 1];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            // with duplicates, we return multiple docs
-            data.rows.should.have.length(6, 'returns 6 docs with duplicates');
-            data.rows[0].doc._id.should.equal('doc_2');
-            data.rows[1].doc._id.should.equal('doc_1');
-            data.rows[2].doc._id.should.equal('doc_2');
-            data.rows[3].doc._id.should.equal('doc_0');
-            data.rows[4].doc._id.should.equal('doc_2');
-            data.rows[5].doc._id.should.equal('doc_1');
-
-            opts.keys = [2, 1, 2, 3, 2];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            // duplicates and unknowns at the same time, for maximum weirdness
-            data.rows.should.have.length(4, 'returns 2 docs with duplicates/unknowns');
-            data.rows[0].doc._id.should.equal('doc_2');
-            data.rows[1].doc._id.should.equal('doc_1');
-            data.rows[2].doc._id.should.equal('doc_2');
-            data.rows[3].doc._id.should.equal('doc_2');
-
-            opts.keys = [3];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(0, 'returns 0 doc due to unknown key');
-
-            opts.include_docs = false;
-            opts.keys = [3, 2];
-            return db.query(queryFun, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(1, 'returns 1 doc due to unknown key');
-            data.rows[0].id.should.equal('doc_2');
-            should.not.exist(data.rows[0].doc, 'no doc, since include_docs=false');
-          });
-        });
-      });
-    });
-
-    it('Testing query with multiple keys, multiple docs', function () {
-      function ids(row) {
-        return row.id;
-      }
-      var opts = {keys: [0, 1, 2]};
-      var spec;
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.field1);
-            emit(doc.field2);
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: '0', field1: 0},
-              {_id: '1a', field1: 1},
-              {_id: '1b', field1: 1},
-              {_id: '1c', field1: 1},
-              {_id: '2+3', field1: 2, field2: 3},
-              {_id: '4+5', field1: 4, field2: 5},
-              {_id: '3+5', field1: 3, field2: 5},
-              {_id: '3+4', field1: 3, field2: 4}
-            ]
-          }).then(function () {
-            spec = ['0', '1a', '1b', '1c', '2+3'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts.keys = [3, 5, 4, 3];
-            spec = ['2+3', '3+4', '3+5', '3+5', '4+5', '3+4', '4+5', '2+3', '3+4', '3+5'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-          });
-        });
-      });
-    });
-    it('Testing multiple emissions (issue #14)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.foo);
-            emit(doc.bar);
-            emit(doc.foo);
-            emit(doc.bar, 'multiple values!');
-            emit(doc.bar, 'crayon!');
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: 'doc1', foo : 'foo', bar : 'bar'},
-              {_id: 'doc2', foo : 'foo', bar : 'bar'}
-            ]
-          }).then(function () {
-            var opts = {keys: ['foo', 'bar']};
-
-            return db.query(mapFunction, opts);
-          });
-        }).then(function (data) {
-          data.rows.should.have.length(10);
-
-          data.rows[0].key.should.equal('foo');
-          data.rows[0].id.should.equal('doc1');
-          data.rows[1].key.should.equal('foo');
-          data.rows[1].id.should.equal('doc1');
-
-          data.rows[2].key.should.equal('foo');
-          data.rows[2].id.should.equal('doc2');
-          data.rows[3].key.should.equal('foo');
-          data.rows[3].id.should.equal('doc2');
-
-          data.rows[4].key.should.equal('bar');
-          data.rows[4].id.should.equal('doc1');
-          should.not.exist(data.rows[4].value);
-          data.rows[5].key.should.equal('bar');
-          data.rows[5].id.should.equal('doc1');
-          data.rows[5].value.should.equal('crayon!');
-          data.rows[6].key.should.equal('bar');
-          data.rows[6].id.should.equal('doc1');
-          data.rows[6].value.should.equal('multiple values!');
-
-          data.rows[7].key.should.equal('bar');
-          data.rows[7].id.should.equal('doc2');
-          should.not.exist(data.rows[7].value);
-          data.rows[8].key.should.equal('bar');
-          data.rows[8].id.should.equal('doc2');
-          data.rows[8].value.should.equal('crayon!');
-          data.rows[9].key.should.equal('bar');
-          data.rows[9].id.should.equal('doc2');
-          data.rows[9].value.should.equal('multiple values!');
-        });
-      });
-    });
-    it('Testing multiple emissions (complex keys)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function () {
-            emit(['a'], 1);
-            emit(['b'], 3);
-            emit(['a'], 2);
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: 'doc1', foo: 'foo', bar: 'bar'}
-            ]
-          }).then(function () {
-            return db.query(mapFunction);
-          });
-        }).then(function (data) {
-          data.rows.should.have.length(3);
-          data.rows[0].key.should.eql(['a']);
-          data.rows[0].value.should.equal(1);
-          data.rows[1].key.should.eql(['a']);
-          data.rows[1].value.should.equal(2);
-          data.rows[2].key.should.eql(['b']);
-          data.rows[2].value.should.equal(3);
-        });
-      });
-    });
-    it('Testing empty startkeys and endkeys', function () {
-      var opts = {startkey: null, endkey: ''};
-      function ids(row) {
-        return row.id;
-      }
-      var spec;
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.field);
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: 'doc_empty', field: ''},
-              {_id: 'doc_null', field: null},
-              {_id: 'doc_undefined' /* field undefined */},
-              {_id: 'doc_foo', field: 'foo'}
-            ]
-          }).then(function () {
-            spec = ['doc_null', 'doc_undefined', 'doc_empty'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts = {startkey: '', endkey: 'foo'};
-            spec = ['doc_empty', 'doc_foo'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts = {startkey: null, endkey: null};
-            spec = ['doc_null', 'doc_undefined'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts.descending = true;
-            spec.reverse();
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-          });
-        });
-      });
-    });
-
-    it('#238 later non-winning revisions', function () {
-      var db = new PouchDB(dbName);
-
-      return createView(db, {
-        map: function (doc) {
-          emit(doc.name);
-        }
-      }).then(function (mapFun) {
-        return db.bulkDocs([{
-          _id: 'doc',
-          name: 'zoot',
-          _rev: '2-x',
-          _revisions: {
-            start: 2,
-            ids: ['x', 'y']
-          }
-        }], {new_edits: false}).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zoot');
-          return db.bulkDocs([{
-            _id: 'doc',
-            name: 'suit',
-            _rev: '2-w',
-            _revisions: {
-              start: 2,
-              ids: ['w', 'y']
-            }
-          }], {new_edits: false});
-        }).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zoot');
-        });
-      });
-    });
-
-    it('#238 later non-winning deleted revisions', function () {
-      var db = new PouchDB(dbName);
-
-      return createView(db, {
-        map: function (doc) {
-          emit(doc.name);
-        }
-      }).then(function (mapFun) {
-        return db.bulkDocs([{
-          _id: 'doc',
-          name: 'zoot',
-          _rev: '2-x',
-          _revisions: {
-            start: 2,
-            ids: ['x', 'y']
-          }
-        }], {new_edits: false}).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zoot');
-          return db.bulkDocs([{
-            _id: 'doc',
-            name: 'suit',
-            _deleted: true,
-            _rev: '2-z',
-            _revisions: {
-              start: 2,
-              ids: ['z', 'y']
-            }
-          }], {new_edits: false});
-        }).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zoot');
-        });
-      });
-    });
-
-    it('#238 query with conflicts', function () {
-      var db = new PouchDB(dbName);
-
-      return createView(db, {
-        map: function (doc) {
-          emit(doc.name);
-        }
-      }).then(function (mapFun) {
-        return db.bulkDocs([
-
-          {
-            _id: 'doc',
-            name: 'zab',
-            _rev: '2-y',
-            _revisions: {
-              start: 1,
-              ids: ['y']
-            }
-          }, {
-            _id: 'doc',
-            name: 'zoot',
-            _rev: '2-x',
-            _revisions: {
-              start: 2,
-              ids: ['x', 'y']
-            }
-          }
-        ], {new_edits: false}).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zoot');
-          return db.bulkDocs([
-            {
-              _id: 'doc',
-              name: 'suit',
-              _rev: '2-w',
-              _revisions: {
-                start: 2,
-                ids: ['w', 'y']
-              }
-            }, {
-              _id: 'doc',
-              name: 'zorb',
-              _rev: '2-z',
-              _revisions: {
-                start: 2,
-                ids: ['z', 'y']
-              }
-            }
-          ], {new_edits: false});
-        }).then(function () {
-          return db.query(mapFun);
-        }).then(function (res) {
-          res.rows.should.have.length(1);
-          res.rows[0].id.should.equal('doc');
-          res.rows[0].key.should.equal('zorb');
-        });
-      });
-    });
-
-    it('Testing ordering with startkey/endkey/key', function () {
-      var opts = {startkey: '1', endkey: '4'};
-      function ids(row) {
-        return row.id;
-      }
-      var spec;
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.field, null);
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: 'h', field: '4'},
-              {_id: 'a', field: '1'},
-              {_id: 'e', field: '2'},
-              {_id: 'c', field: '1'},
-              {_id: 'f', field: '3'},
-              {_id: 'g', field: '4'},
-              {_id: 'd', field: '2'},
-              {_id: 'b', field: '1'}
-            ]
-          }).then(function () {
-            spec = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts = {key: '1'};
-            spec = ['a', 'b', 'c'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts = {key: '2'};
-            spec = ['d', 'e'];
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec);
-
-            opts.descending = true;
-            spec.reverse();
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(spec, 'reverse order');
-          });
-        });
-      });
-    });
-
-    it('opts.keys should work with complex keys', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.foo, doc.foo);
-          }
-        }).then(function (mapFunction) {
-          var keys = [
-            {key: 'missing'},
-            ['test', 1],
-            {key1: 'value1'},
-            ['missing'],
-            [0, 0]
-          ];
-          return db.bulkDocs({
-            docs: [
-              {foo: {key2: 'value2'}},
-              {foo: {key1: 'value1'}},
-              {foo: [0, 0]},
-              {foo: ['test', 1]},
-              {foo: [0, false]}
-            ]
-          }).then(function () {
-            var opts = {keys: keys};
-            return db.query(mapFunction, opts);
-          }).then(function (data) {
-            data.rows.should.have.length(3);
-            data.rows[0].value.should.deep.equal(keys[1]);
-            data.rows[1].value.should.deep.equal(keys[2]);
-            data.rows[2].value.should.deep.equal(keys[4]);
-          });
-        });
-      });
-    });
-
-    it('Testing ordering with dates', function () {
-      function ids(row) {
-        return row.id;
-      }
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.date, null);
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: '1969', date: '1969 was when Space Oddity hit'},
-              {_id: '1971', date : new Date('1971-12-17T00:00:00.000Z')}, // Hunky Dory was released
-              {_id: '1972', date: '1972 was when Ziggy landed on Earth'},
-              {_id: '1977', date: new Date('1977-01-14T00:00:00.000Z')}, // Low was released
-              {_id: '1985', date: '1985+ is better left unmentioned'}
-            ]
-          }).then(function () {
-            return db.query(mapFunction);
-          }).then(function (data) {
-            data.rows.map(ids).should.deep.equal(['1969', '1971', '1972', '1977', '1985']);
-          });
-        });
-      });
-    });
-
-    it('should work with a joined doc', function () {
-      function change(row) {
-        return [row.key, row.doc._id, row.doc.val];
-      }
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            if (doc.join) {
-              emit(doc.color, {_id : doc.join});
-            }
-          }
-        }).then(function (mapFunction) {
-          return db.bulkDocs({
-            docs: [
-              {_id: 'a', join: 'b', color: 'green'},
-              {_id: 'b', val: 'c'},
-              {_id: 'd', join: 'f', color: 'red'}
-            ]
-          }).then(function () {
-            return db.query(mapFunction, {include_docs: true});
-          }).then(function (resp) {
-            return change(resp.rows[0]).should.deep.equal(['green', 'b', 'c']);
-          });
-        });
-      });
-    });
-
-    it('should query correctly with a variety of criteria', function () {
-      return new PouchDB(dbName).then(function (db) {
-
-        return createView(db, {
-          map : function (doc) {
-            emit(doc._id);
-          }
-        }).then(function (mapFun) {
-
-          var docs = [
-            {_id : '0'},
-            {_id : '1'},
-            {_id : '2'},
-            {_id : '3'},
-            {_id : '4'},
-            {_id : '5'},
-            {_id : '6'},
-            {_id : '7'},
-            {_id : '8'},
-            {_id : '9'}
-          ];
-          return db.bulkDocs({docs : docs}).then(function (res) {
-            docs[3]._deleted = true;
-            docs[7]._deleted = true;
-            docs[3]._rev = res[3].rev;
-            docs[7]._rev = res[7].rev;
-            return db.remove(docs[3]);
-          }).then(function () {
-            return db.remove(docs[7]);
-          }).then(function () {
-            return db.query(mapFun, {});
-          }).then(function (res) {
-            res.rows.should.have.length(8, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5'});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5', skip : 2, limit : 10});
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5', descending : true, skip : 1});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5', endkey : 'z'});
-          }).then(function (res) {
-            res.rows.should.have.length(4, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5', endkey : '5'});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '5', endkey : '4', descending : true});
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '3', endkey : '7', descending : false});
-          }).then(function (res) {
-            res.rows.should.have.length(3, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '7', endkey : '3', descending : true});
-          }).then(function (res) {
-            res.rows.should.have.length(3, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {startkey : '', endkey : '0'});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {keys : ['0', '1', '3']});
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {keys : ['0', '1', '0', '2', '1', '1']});
-          }).then(function (res) {
-            res.rows.should.have.length(6, 'correctly return rows');
-            res.rows.map(function (row) { return row.key; }).should.deep.equal(
-              ['0', '1', '0', '2', '1', '1']);
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {keys : []});
-          }).then(function (res) {
-            res.rows.should.have.length(0, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {keys : ['7']});
-          }).then(function (res) {
-            res.rows.should.have.length(0, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {key : '3'});
-          }).then(function (res) {
-            res.rows.should.have.length(0, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {key : '2'});
-          }).then(function (res) {
-            res.rows.should.have.length(1, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-            return db.query(mapFun, {key : 'z'});
-          }).then(function (res) {
-            res.rows.should.have.length(0, 'correctly return rows');
-            res.total_rows.should.equal(8, 'correctly return total_rows');
-
-            return db.query(mapFun, {startkey : '5', endkey : '4'}).then(function (res) {
-              res.should.not.exist('expected error on reversed start/endkey');
-            }).catch(function (err) {
-              err.status.should.equal(400);
-              err.message.should.be.a('string');
-            });
-          });
-        });
-      });
-    });
-
-    it('should query correctly with skip/limit and multiple keys/values', function () {
-      var db = new PouchDB(dbName);
-      var docs = {
-        docs: [
-          {_id: 'doc1', foo : 'foo', bar : 'bar'},
-          {_id: 'doc2', foo : 'foo', bar : 'bar'}
-        ]
-      };
-      var getValues = function (res) {
-        return res.value;
-      };
-      var getIds = function (res) {
-        return res.id;
-      };
-
-      return createView(db, {
-        map : function (doc) {
-          emit(doc.foo, 'fooValue');
-          emit(doc.foo);
-          emit(doc.bar);
-          emit(doc.bar, 'crayon!');
-          emit(doc.bar, 'multiple values!');
-          emit(doc.bar, 'crayon!');
-        }
-      }).then(function (mapFun) {
-
-        return db.bulkDocs(docs).then(function () {
-          return db.query(mapFun, {});
-        }).then(function (res) {
-          res.rows.should.have.length(12, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          res.rows.map(getValues).should.deep.equal(
-            [null, 'crayon!', 'crayon!', 'multiple values!',
-              null, 'crayon!', 'crayon!', 'multiple values!',
-              null, 'fooValue', null, 'fooValue']);
-          res.rows.map(getIds).should.deep.equal(
-            ['doc1', 'doc1', 'doc1', 'doc1',
-              'doc2', 'doc2', 'doc2', 'doc2',
-              'doc1', 'doc1', 'doc2', 'doc2']);
-          return db.query(mapFun, {startkey : 'foo'});
-        }).then(function (res) {
-          res.rows.should.have.length(4, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          res.rows.map(getValues).should.deep.equal(
-            [null, 'fooValue', null, 'fooValue']);
-          res.rows.map(getIds).should.deep.equal(
-            ['doc1', 'doc1', 'doc2', 'doc2']);
-          return db.query(mapFun, {startkey : 'foo', endkey : 'foo'});
-        }).then(function (res) {
-          res.rows.should.have.length(4, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'bar', endkey : 'bar'});
-        }).then(function (res) {
-          res.rows.should.have.length(8, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'foo', limit : 1});
-        }).then(function (res) {
-          res.rows.should.have.length(1, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          res.rows.map(getValues).should.deep.equal([null]);
-          res.rows.map(getIds).should.deep.equal(['doc1']);
-          return db.query(mapFun, {startkey : 'foo', limit : 2});
-        }).then(function (res) {
-          res.rows.should.have.length(2, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'foo', limit : 1000});
-        }).then(function (res) {
-          res.rows.should.have.length(4, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'foo', skip : 1});
-        }).then(function (res) {
-          res.rows.should.have.length(3, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'foo', skip : 3, limit : 0});
-        }).then(function (res) {
-          res.rows.should.have.length(0, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'foo', skip : 3, limit : 1});
-        }).then(function (res) {
-          res.rows.should.have.length(1, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          res.rows.map(getValues).should.deep.equal(['fooValue']);
-          res.rows.map(getIds).should.deep.equal(['doc2']);
-          return db.query(mapFun, {startkey : 'quux', skip : 3, limit : 1});
-        }).then(function (res) {
-          res.rows.should.have.length(0, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-          return db.query(mapFun, {startkey : 'bar', limit : 2});
-        }).then(function (res) {
-          res.rows.should.have.length(2, 'correctly return rows');
-          res.total_rows.should.equal(12, 'correctly return total_rows');
-        });
-      });
-    });
-
-    it('should query correctly with undefined key/values', function () {
-      var db = new PouchDB(dbName);
-      var docs = {
-        docs: [
-          {_id: 'doc1'},
-          {_id: 'doc2'}
-        ]
-      };
-      return createView(db, {
-        map : function () {
-          emit();
-        }
-      }).then(function (mapFun) {
-        return db.bulkDocs(docs).then(function () {
-          return db.query(mapFun, {});
-        }).then(function (res) {
-          res.total_rows.should.equal(2, 'correctly return total_rows');
-          res.rows.should.deep.equal([
-            {
-              key : null,
-              value : null,
-              id : 'doc1'
-            },
-            {
-              key : null,
-              value : null,
-              id : 'doc2'
-            }
-          ]);
-        });
-      });
-    });
-    it('should query correctly with no docs', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function () {
-            emit();
-          }
-        }).then(function (queryFun) {
-          return db.query(queryFun).then(function (res) {
-            res.total_rows.should.equal(0, 'total_rows');
-            res.offset.should.equal(0);
-            res.rows.should.deep.equal([]);
-          });
-        });
-      });
-    });
-    it('should query correctly with no emits', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function () {
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs : [
-            {_id : 'foo'},
-            {_id : 'bar'}
-          ]}).then(function () {
-            return db.query(queryFun).then(function (res) {
-              res.total_rows.should.equal(0, 'total_rows');
-              res.offset.should.equal(0);
-              res.rows.should.deep.equal([]);
-            });
-          });
-        });
-      });
-    });
-    it('should correctly return results when reducing or not reducing', function () {
-
-      function keyValues(row) {
-        return { key: row.key, value: row.value };
-      }
-      function keys(row) {
-        return row.key;
-      }
-      function values(row) {
-        return row.value;
-      }
-      function docIds(row) {
-        return row.doc._id;
-      }
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          },
-          reduce : '_count'
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs : [
-            {name : 'foo', _id : '1'},
-            {name : 'bar', _id : '2'},
-            {name : 'foo', _id : '3'},
-            {name : 'quux', _id : '4'},
-            {name : 'foo', _id : '5'},
-            {name : 'foo', _id : '6'},
-            {name : 'foo', _id : '7'}
-
-          ]}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            Object.keys(res.rows[0]).sort().should.deep.equal(['key', 'value'],
-              'object only have 2 keys');
-            should.not.exist(res.total_rows, 'no total_rows1');
-            should.not.exist(res.offset, 'no offset1');
-            res.rows.map(keyValues).should.deep.equal([
-              {
-                key   : null,
-                value : 7
-              }
-            ]);
-            return db.query(queryFun, {group : true});
-          }).then(function (res) {
-            Object.keys(res.rows[0]).sort().should.deep.equal(['key', 'value'],
-              'object only have 2 keys');
-            should.not.exist(res.total_rows, 'no total_rows2');
-            should.not.exist(res.offset, 'no offset2');
-            res.rows.map(keyValues).should.deep.equal([
-              {
-                key : 'bar',
-                value : 1
-              },
-              {
-                key : 'foo',
-                value : 5
-              },
-              {
-                key : 'quux',
-                value : 1
-              }
-            ]);
-            return db.query(queryFun, {reduce : false});
-          }).then(function (res) {
-            Object.keys(res.rows[0]).sort().should.deep.equal(['id', 'key', 'value'],
-              'object only have 3 keys');
-            res.total_rows.should.equal(7, 'total_rows1');
-            res.offset.should.equal(0, 'offset1');
-            res.rows.map(keys).should.deep.equal([
-              'bar', 'foo', 'foo', 'foo', 'foo', 'foo', 'quux'
-            ]);
-            res.rows.map(values).should.deep.equal([
-              null, null, null, null, null, null, null
-            ]);
-            return db.query(queryFun, {reduce : false, skip : 3});
-          }).then(function (res) {
-            Object.keys(res.rows[0]).sort().should.deep.equal(['id', 'key', 'value'],
-              'object only have 3 keys');
-            res.total_rows.should.equal(7, 'total_rows2');
-            res.offset.should.equal(3, 'offset2');
-            res.rows.map(keys).should.deep.equal([
-              'foo', 'foo', 'foo', 'quux'
-            ]);
-            return db.query(queryFun, {reduce : false, include_docs : true});
-          }).then(function (res) {
-            Object.keys(res.rows[0]).sort().should.deep.equal(['doc', 'id', 'key', 'value'],
-              'object only have 4 keys');
-            res.total_rows.should.equal(7, 'total_rows3');
-            res.offset.should.equal(0, 'offset3');
-            res.rows.map(keys).should.deep.equal([
-              'bar', 'foo', 'foo', 'foo', 'foo', 'foo', 'quux'
-            ]);
-            res.rows.map(values).should.deep.equal([
-              null, null, null, null, null, null, null
-            ]);
-            res.rows.map(docIds).should.deep.equal([
-              '2', '1', '3', '5', '6', '7', '4'
-            ]);
-            return db.query(queryFun, {include_docs : true}).then(function (res) {
-              should.not.exist(res);
-            }).catch(function (err) {
-              err.status.should.equal(400);
-              err.message.should.be.a('string');
-              // include_docs is invalid for reduce
-            });
-          });
-        });
-      });
-    });
-
-    it('should query correctly after replicating and other ddoc', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: [{name: 'foobar'}]}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.map(function (x) {return x.key; }).should.deep.equal([
-              'foobar'
-            ], 'test db before replicating');
-            return new PouchDB('local-other').then(function (db2) {
-              return db.replicate.to(db2).then(function () {
-                return db.query(queryFun);
-              }).then(function (res) {
-                res.rows.map(function (x) {return x.key; }).should.deep.equal([
-                  'foobar'
-                ], 'test db after replicating');
-                return db.put({_id: '_design/other_ddoc', views: {
-                  map: "function(doc) { emit(doc._id); }"
-                }});
-              }).then(function () {
-                  // the random ddoc adds a single change that we don't
-                  // care about. testing this increases our coverage
-                return db.query(queryFun);
-              }).then(function (res) {
-                res.rows.map(function (x) {return x.key; }).should.deep.equal([
-                  'foobar'
-                ], 'test db after adding random ddoc');
-                return db2.query(queryFun);
-              }).then(function (res) {
-                res.rows.map(function (x) {return x.key; }).should.deep.equal([
-                  'foobar'
-                ], 'test db2');
-              }).catch(function (err) {
-                return new PouchDB('local-other').destroy().then(function () {
-                  throw err;
-                });
-              }).then(function () {
-                return new PouchDB('local-other').destroy();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should query correctly after many edits', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name, doc.likes);
-          }
-        }).then(function (queryFun) {
-          var docs = [
-            { _id: '1', name: 'leonardo' },
-            { _id: '2', name: 'michelangelo' },
-            { _id: '3', name: 'donatello' },
-            { _id: '4', name: 'rafael' },
-            { _id: '5', name: 'april o\'neil' },
-            { _id: '6', name: 'splinter' },
-            { _id: '7', name: 'shredder' },
-            { _id: '8', name: 'krang' },
-            { _id: '9', name: 'rocksteady' },
-            { _id: 'a', name: 'bebop' },
-            { _id: 'b', name: 'casey jones' },
-            { _id: 'c', name: 'casey jones' },
-            { _id: 'd', name: 'baxter stockman' },
-            { _id: 'e', name: 'general chaos' },
-            { _id: 'f', name: 'rahzar' },
-            { _id: 'g', name: 'tokka' },
-            { _id: 'h', name: 'usagi yojimbo' },
-            { _id: 'i', name: 'rat king' },
-            { _id: 'j', name: 'metalhead' },
-            { _id: 'k', name: 'slash' },
-            { _id: 'l', name: 'ace duck' }
-          ];
-
-          for (var i = 0; i < 100; i++) {
-            docs.push({
-              _id: 'z-' + (i + 1000), // for correct string ordering
-              name: 'random foot soldier #' + i
-            });
-          }
-
-          function update(res, docFun) {
-            for (var i  = 0; i < res.length; i++) {
-              docs[i]._rev = res[i].rev;
-              docFun(docs[i]);
-            }
-            return db.bulkDocs({docs : docs});
-          }
-          return db.bulkDocs({docs : docs}).then(function (res) {
-            return update(res, function (doc) { doc.likes = 'pizza'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.knows = 'kung fu'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.likes = 'fighting'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc._deleted = true; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc._deleted = false; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.name = doc.name + '1'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.name = doc.name + '2'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.name = 'nameless'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc._deleted = true; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.likes = 'turtles'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc._deleted = false; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.whatever = 'quux'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.stuff = 'baz'; });
-          }).then(function (res) {
-            return update(res, function (doc) { doc.things = 'foo'; });
-          }).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.total_rows.should.equal(docs.length, 'expected total_rows');
-            res.rows.map(function (row) {
-              return [row.id, row.key, row.value];
-            }).should.deep.equal(docs.map(function (doc) {
-              return [doc._id, 'nameless', 'turtles'];
-            }), 'key values match');
-          });
-        });
-      });
-    });
-
-    it('should query correctly with staggered seqs', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          var docs = [];
-
-          for (var i = 0; i < 200; i++) {
-            docs.push({
-              _id: 'doc-' + (i + 1000), // for correct string ordering
-              name: 'gen1'
-            });
-          }
-          return db.bulkDocs({docs: docs}).then(function (infos) {
-            docs.forEach(function (doc, i) {
-              doc._rev = infos[i].rev;
-              doc.name = 'gen2';
-            });
-            docs.reverse();
-            return db.bulkDocs({docs: docs});
-          }).then(function (infos) {
-            docs.forEach(function (doc, i) {
-              doc._rev = infos[i].rev;
-              doc.name = 'gen-3';
-            });
-            docs.reverse();
-            return db.bulkDocs({docs: docs});
-          }).then(function (infos) {
-            docs.forEach(function (doc, i) {
-              doc._rev = infos[i].rev;
-              doc.name = 'gen-4-odd';
-            });
-            var docsToUpdate = docs.filter(function (doc, i) {
-              return i % 2 === 1;
-            });
-            docsToUpdate.reverse();
-            return db.bulkDocs({docs: docsToUpdate});
-          }).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            var expected = docs.map(function (doc, i) {
-              var key = i % 2 === 1 ? 'gen-4-odd' : 'gen-3';
-              return {key: key, id: doc._id, value: null};
-            });
-            expected.sort(function (a, b) {
-              if (a.key !== b.key) {
-                return a.key < b.key ? -1 : 1;
-              }
-              return a.id < b.id ? -1 : 1;
-            });
-            res.rows.should.deep.equal(expected);
-          });
-        });
-      });
-    });
-
-    it('should handle removes/undeletes/updates', function () {
-      var theDoc = {name : 'bar', _id : '1'};
-
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.put(theDoc).then(function (info) {
-            theDoc._rev = info.rev;
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.length.should.equal(1);
-            theDoc._deleted = true;
-            return db.post(theDoc);
-          }).then(function (info) {
-            theDoc._rev = info.rev;
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.length.should.equal(0);
-            theDoc._deleted = false;
-            return db.post(theDoc);
-          }).then(function (info) {
-            theDoc._rev = info.rev;
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.length.should.equal(1);
-            theDoc.name = 'foo';
-            return db.post(theDoc);
-          }).then(function (info) {
-            theDoc._rev = info.rev;
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.length.should.equal(1);
-            res.rows[0].key.should.equal('foo');
-            theDoc._deleted = true;
-            return db.post(theDoc);
-          }).then(function (info) {
-            theDoc._rev = info.rev;
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.length.should.equal(0);
-          });
-        });
-      });
-    });
-
-    it('should return error when multi-key fetch & group=false', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) { emit(doc._id); },
-          reduce: '_sum'
-        }).then(function (queryFun) {
-          var keys = ['1', '2'];
-          var opts = {
-            keys: keys,
-            group: false
-          };
-          return db.query(queryFun, opts).then(function (res) {
-            should.not.exist(res);
-          }).catch(function (err) {
-            err.status.should.equal(400);
-            opts = {keys: keys};
-            return db.query(queryFun, opts).then(function (res) {
-              should.not.exist(res);
-            }).catch(function (err) {
-              err.status.should.equal(400);
-              opts = {keys: keys, reduce : false};
-              return db.query(queryFun, opts).then(function () {
-                opts = {keys: keys, group: true};
-                return db.query(queryFun, opts);
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should handle user errors in map functions', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var err;
-        db.on('error', function (e) { err = e; });
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.nonexistent.foo);
-          }
-        }).then(function (queryFun) {
-          return db.put({name : 'bar', _id : '1'}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.should.have.length(0);
-            if (dbType === 'local') {
-              should.exist(err);
-            }
-          });
-        });
-      });
-    });
-    it('should handle user errors in reduce functions', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var err;
-        db.on('error', function (e) { err = e; });
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          },
-          reduce : function (keys) {
-            return keys[0].foo.bar;
-          }
-        }).then(function (queryFun) {
-          return db.put({name : 'bar', _id : '1'}).then(function () {
-            return db.query(queryFun, {group: true});
-          }).then(function (res) {
-            res.rows.map(function (row) {return row.key; }).should.deep.equal(['bar']);
-            return db.query(queryFun, {reduce: false});
-          }).then(function (res) {
-            res.rows.map(function (row) {return row.key; }).should.deep.equal(['bar']);
-            if (dbType === 'local') {
-              should.exist(err);
-            }
-          });
-        });
-      });
-    });
-    it('should handle reduce returning undefined', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var err;
-        db.on('error', function (e) { err = e; });
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          },
-          reduce : function () {
-          }
-        }).then(function (queryFun) {
-          return db.put({name : 'bar', _id : '1'}).then(function () {
-            return db.query(queryFun, {group: true});
-          }).then(function (res) {
-            res.rows.map(function (row) {return row.key; }).should.deep.equal(['bar']);
-            return db.query(queryFun, {reduce: false});
-          }).then(function (res) {
-            res.rows.map(function (row) {return row.key; }).should.deep.equal(['bar']);
-            should.not.exist(err);
-          });
-        });
-      });
-    });
-    it('should properly query custom reduce functions', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name, doc.count);
-          },
-          reduce : function (keys, values, rereduce) {
-            // calculate the average count per name
-            if (!rereduce) {
-              var result = {
-                sum : sum(values),
-                count : values.length
-              };
-              result.average = result.sum / result.count;
-              return result;
-            } else {
-              var thisSum = sum(values.map(function (value) {return value.sum; }));
-              var thisCount = sum(values.map(function (value) {return value.count; }));
-              return {
-                sum : thisSum,
-                count : thisCount,
-                average : (thisSum / thisCount)
-              };
-            }
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs : [
-            {name : 'foo', count : 1},
-            {name : 'bar', count : 7},
-            {name : 'foo', count : 3},
-            {name : 'quux', count : 3},
-            {name : 'foo', count : 3},
-            {name : 'foo', count : 0},
-            {name : 'foo', count : 4},
-            {name : 'baz', count : 3},
-            {name : 'baz', count : 0},
-            {name : 'baz', count : 2}
-          ]}).then(function () {
-            return db.query(queryFun, {group : true});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              },
-              {
-                key : 'baz',
-                value : { sum: 5, count: 3, average: (5 / 3) }
-              },
-              {
-                key : 'foo',
-                value : { sum: 11, count: 5, average: (11 / 5) }
-              },
-              {
-                key : 'quux',
-                value : { sum: 3, count: 1, average: 3 }
-              }
-            ]}, 'all');
-            return db.query(queryFun, {group : false});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : null,
-                value : { sum: 26, count: 10, average: 2.6 }
-              }
-            ]}, 'group=false');
-            return db.query(queryFun, {group : true, startkey : 'bar', endkey : 'baz', skip : 1});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'baz',
-                value : { sum: 5, count: 3, average: (5 / 3) }
-              }
-            ]}, 'bar-baz skip 1');
-            return db.query(queryFun, {group : true, endkey : 'baz'});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              },
-              {
-                key : 'baz',
-                value : { sum: 5, count: 3, average: (5 / 3) }
-              }
-            ]}, '-baz');
-            return db.query(queryFun, {group : true, startkey : 'foo'});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'foo',
-                value : { sum: 11, count: 5, average: (11 / 5) }
-              },
-              {
-                key : 'quux',
-                value : { sum: 3, count: 1, average: 3 }
-              }
-            ]}, 'foo-');
-            return db.query(queryFun, {group : true, startkey : 'foo', descending : true});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'foo',
-                value : { sum: 11, count: 5, average: (11 / 5) }
-              },
-              {
-                key : 'baz',
-                value : { sum: 5, count: 3, average: (5 / 3) }
-              },
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              }
-            ]}, 'foo- descending=true');
-            return db.query(queryFun, {group : true, startkey : 'quux', skip : 1});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'quux skip 1');
-            return db.query(queryFun, {group : true, startkey : 'quux', limit : 0});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'quux limit 0');
-            return db.query(queryFun, {group : true, startkey : 'bar', endkey : 'baz'});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              },
-              {
-                key : 'baz',
-                value : { sum: 5, count: 3, average: (5 / 3) }
-              }
-            ]}, 'bar-baz');
-            return db.query(queryFun, {group : true, keys : ['bar', 'baz'], limit : 1});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              }
-            ]}, 'bar & baz');
-            return db.query(queryFun, {group : true, keys : ['bar', 'baz'], limit : 0});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'bar & baz limit 0');
-            return db.query(queryFun, {group : true, key : 'bar', limit : 0});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'key=bar limit 0');
-            return db.query(queryFun, {group : true, key : 'bar'});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-              {
-                key : 'bar',
-                value : { sum: 7, count: 1, average : 7}
-              }
-            ]}, 'key=bar');
-            return db.query(queryFun, {group : true, key : 'zork'});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'zork');
-            return db.query(queryFun, {group : true, keys : []});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'keys=[]');
-            return db.query(queryFun, {group : true, key : null});
-          }).then(function (res) {
-            res.should.deep.equal({rows : [
-            ]}, 'key=null');
-          });
-        });
-      });
-    });
-
-    it('should handle many doc changes', function () {
-
-      var docs = [{_id: '0'}, {_id : '1'}, {_id: '2'}];
-
-      var keySets = [
-        [1],
-        [2, 3],
-        [4],
-        [5],
-        [6, 7, 3],
-        [],
-        [2, 3],
-        [1, 2],
-        [],
-        [9],
-        [9, 3, 2, 1]
-      ];
-
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            doc.keys.forEach(function (key) {
-              emit(key);
-            });
-          }
-        }).then(function (mapFun) {
-          return db.bulkDocs({docs : docs}).then(function () {
-            var tasks = keySets.map(function (keys, i) {
-              return function () {
-                var expectedResponseKeys = [];
-                return db.allDocs({
-                  keys : ['0', '1', '2'],
-                  include_docs: true
-                }).then(function (res) {
-                  docs = res.rows.map(function (x) { return x.doc; });
-                  docs.forEach(function (doc, j) {
-                    doc.keys = keySets[(i + j) % keySets.length];
-                    doc.keys.forEach(function (key) {
-                      expectedResponseKeys.push(key);
-                    });
-                  });
-                  expectedResponseKeys.sort();
-                  return db.bulkDocs({docs: docs});
-                }).then(function () {
-                  return db.query(mapFun);
-                }).then(function (res) {
-                  var actualKeys = res.rows.map(function (x) {
-                    return x.key;
-                  });
-                  actualKeys.should.deep.equal(expectedResponseKeys);
-                });
-              };
-            });
-            var chain = tasks.shift()();
-            function getNext() {
-              var task = tasks.shift();
-              return task && function () {
-                return task().then(getNext());
-              };
-            }
-            return chain.then(getNext());
-          });
-        });
-      });
-    });
-
-    it('should handle many doc changes', function () {
-
-      var docs = [{_id: '0'}, {_id : '1'}, {_id: '2'}];
-
-      var keySets = [
-        [1],
-        [2, 3],
-        [4],
-        [5],
-        [6, 7, 3],
-        [],
-        [2, 3],
-        [1, 2],
-        [],
-        [9],
-        [9, 3, 2, 1]
-      ];
-
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            doc.keys.forEach(function (key) {
-              emit(key);
-            });
-          }
-        }).then(function (mapFun) {
-          return db.bulkDocs({docs : docs}).then(function () {
-            var tasks = keySets.map(function (keys, i) {
-              return function () {
-                var expectedResponseKeys = [];
-                return db.allDocs({
-                  keys : ['0', '1', '2'],
-                  include_docs: true
-                }).then(function (res) {
-                  docs = res.rows.map(function (x) { return x.doc; });
-                  docs.forEach(function (doc, j) {
-                    doc.keys = keySets[(i + j) % keySets.length];
-                    doc.keys.forEach(function (key) {
-                      expectedResponseKeys.push(key);
-                    });
-                  });
-                  expectedResponseKeys.sort(function (a, b) {
-                    return a - b;
-                  });
-                  return db.bulkDocs({docs: docs});
-                }).then(function () {
-                  return db.query(mapFun);
-                }).then(function (res) {
-                  var actualKeys = res.rows.map(function (x) {
-                    return x.key;
-                  });
-                  actualKeys.should.deep.equal(expectedResponseKeys);
-                });
-              };
-            });
-            function getNext() {
-              var task = tasks.shift();
-              if (task) {
-                return task().then(getNext);
-              }
-            }
-            return getNext();
-          });
-        });
-      });
-    });
-
-    it('should work with post', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) { emit(doc._id); }.toString()
-        }).then(function (mapFun) {
-          return db.bulkDocs({docs: [{_id : 'bazbazbazb'}]}).then(function () {
-            var i = 300;
-            var keys = [];
-            while (i--) {
-              keys.push('bazbazbazb');
-            }
-            return db.query(mapFun, {keys: keys}).then(function (resp) {
-              resp.total_rows.should.equal(1);
-              resp.rows.should.have.length(300);
-              return resp.rows.every(function (row) {
-                return row.id === 'bazbazbazb' && row.key === 'bazbazbazb';
-              });
-            });
-          }).should.become(true);
-        });
-      });
-    });
-
-    it("should accept trailing ';' in a map definition (#178)", function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: "function(doc){};\n"
-        }).then(function (queryFun) {
-          return db.query(queryFun);
-        }).should.become({
-          offset: 0,
-          rows: [],
-          total_rows: 0
-        });
-      });
-    });
-
-    it('should throw a 404 when no funcs found in ddoc (#181)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return db.put({
-          _id: '_design/test'
-        }).then(function () {
-          return db.query('test/unexisting');
-        }).then(function () {
-          //shouldn't happen
-          true.should.equal(false);
-        }).catch(function (err) {
-          err.status.should.equal(404);
-        });
-      });
-    });
-
-    it('should continue indexing when map eval fails (#214)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var err;
-        db.on('error', function (e) {
-          err = e;
-        });
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo.bar, doc);
-          }
-        }).then(function (view) {
-          return db.bulkDocs({docs: [
-            {
-              foo: {
-                bar: "foobar"
-              }
-            },
-            { notfoo: "thisWillThrow" },
-            {
-              foo: {
-                bar: "otherFoobar"
-              }
-            }
-          ]}).then(function () {
-            return db.query(view);
-          }).then(function (res) {
-            if (dbType === 'local') {
-              should.exist(err);
-            }
-            res.rows.should.have.length(2, 'Ignore the wrongly formatted doc');
-            return db.query(view);
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Ignore the wrongly formatted doc');
-          });
-
-        });
-      });
-    });
-
-    it('should continue indexing when map eval fails, ' +
-        'even without a listener (#214)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map: function (doc) {
-            emit(doc.foo.bar, doc);
-          }
-        }).then(function (view) {
-          return db.bulkDocs({docs: [
-            {
-              foo: {
-                bar: "foobar"
-              }
-            },
-            { notfoo: "thisWillThrow" },
-            {
-              foo: {
-                bar: "otherFoobar"
-              }
-            }
-          ]}).then(function () {
-            return db.query(view);
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Ignore the wrongly formatted doc');
-            return db.query(view);
-          }).then(function (res) {
-            res.rows.should.have.length(2, 'Ignore the wrongly formatted doc');
-          });
-
-        });
-      });
-    });
-
-    it('should update the emitted value', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var docs = [];
-        for (var i = 0; i < 300; i++) {
-          docs.push({
-            _id: i.toString(),
-            name: 'foo',
-            count: 1
-          });
-        }
-
-        return createView(db, {
-          map: "function(doc){emit(doc.name, doc.count);};\n"
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs: docs}).then(function (res) {
-            for (var i = 0; i < res.length; i++) {
-              docs[i]._rev = res[i].rev;
-            }
-            return db.query(queryFun);
-          }).then(function (res) {
-            var values = res.rows.map(function (x) { return x.value; });
-            values.should.have.length(docs.length);
-            values[0].should.equal(1);
-            docs.forEach(function (doc) {
-              doc.count = 2;
-            });
-            return db.bulkDocs({docs: docs});
-          }).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            var values = res.rows.map(function (x) { return x.value; });
-            values.should.have.length(docs.length);
-            values[0].should.equal(2);
-          });
-        });
-      });
-    });
-  });
-}
diff --git a/tests/mapreduce/test.persisted.js b/tests/mapreduce/test.persisted.js
deleted file mode 100644
index ec9fa76..0000000
--- a/tests/mapreduce/test.persisted.js
+++ /dev/null
@@ -1,674 +0,0 @@
-'use strict';
-
-var adapters = ['local', 'http'];
-
-adapters.forEach(function (adapter) {
-
-  var suiteName = 'test.persisted.js-' + adapter;
-  var dbName = testUtils.adapterUrl(adapter, 'testdb');
-
-  tests(suiteName, dbName, adapter);
-});
-
-function tests(suiteName, dbName, dbType) {
-
-  describe(suiteName, function () {
-
-    var Promise;
-
-    function setTimeoutPromise(time) {
-      return new Promise(function (resolve) {
-        setTimeout(function () { resolve(true); }, time);
-      });
-    }
-
-    function createView(db, viewObj) {
-      var storableViewObj = {
-        map : viewObj.map.toString()
-      };
-      if (viewObj.reduce) {
-        storableViewObj.reduce = viewObj.reduce.toString();
-      }
-      return new Promise(function (resolve, reject) {
-        db.put({
-          _id: '_design/theViewDoc',
-          views: {
-            'theView' : storableViewObj
-          }
-        }, function (err) {
-          if (err) {
-            reject(err);
-          } else {
-            resolve('theViewDoc/theView');
-          }
-        });
-      });
-    }
-
-    beforeEach(function () {
-      Promise = PouchDB.utils.Promise;
-      return new PouchDB(dbName).destroy();
-    });
-    afterEach(function () {
-      return new PouchDB(dbName).destroy();
-    });
-
-    it('Test destroyed event on auxiliary db', function () {
-      var db = new PouchDB(dbName);
-      var rev;
-      return db.put({
-        _id: '_design/name',
-        views: {
-          name: {
-            map: function (doc) {
-              emit(doc.name);
-            }.toString()
-          }
-        }
-      }).then(function (res) {
-        rev = res.rev;
-        return db.bulkDocs([
-          {_id: 'foo', name: 'foo', title: 'yo'},
-          {_id: 'baz', name: 'bar', title: 'hey'},
-          {_id: 'bar', name: 'baz', title: 'wuzzup'}
-        ]);
-      }).then(function () {
-        return db.query('name');
-      }).then(function () {
-        return db.remove('_design/name', rev);
-      }).then(function () {
-        return db.viewCleanup();
-      }).then(function () {
-        return db.put({
-          _id: '_design/title',
-          views: {
-            title: {
-              map: function (doc) {
-                emit(doc.title);
-              }.toString()
-            }
-          }
-        });
-      }).then(function (res) {
-        rev = res.rev;
-      }).then(function () {
-        return db.query('title');
-      }).then(function () {
-        return db.remove('_design/title', rev);
-      }).then(function () {
-        return db.viewCleanup();
-      }).then(function () {
-        var views = ['name', 'title'];
-        return PouchDB.utils.Promise.all(views.map(function (view) {
-          return db.query(view).then(function () {
-            throw new Error('expected an error');
-          }, function (err) {
-            should.exist(err);
-          });
-        }));
-      }).then(function () {
-        return db.put({
-          _id: '_design/name',
-          views: {
-            name: {
-              map: function (doc) {
-                emit(doc.name);
-              }.toString()
-            }
-          }
-        }).then(function (res) {
-          rev = res.rev;
-          return db.query('name');
-        }).then(function (res) {
-          res.rows.map(function (row) {
-            return [row.id, row.key];
-          }).should.deep.equal([
-              ['baz', 'bar'],
-              ['bar', 'baz'],
-              ['foo', 'foo']
-            ]);
-        });
-      });
-    });
-
-    it('Returns ok for viewCleanup on empty db', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return db.viewCleanup().then(function (res) {
-          res.ok.should.equal(true);
-        });
-      });
-    });
-
-    it('Returns ok for viewCleanup on empty db, callback style', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return new Promise(function (resolve, reject) {
-          db.viewCleanup(function (err, res) {
-            if (err) {
-              return reject(err);
-            }
-            resolve(res);
-          });
-        }).then(function (res) {
-            res.ok.should.equal(true);
-          });
-      });
-    });
-
-    it('Returns ok for viewCleanup after modifying view', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var ddoc = {
-          _id: '_design/myview',
-          views: {
-            myview: {
-              map: function (doc) {
-                emit(doc.firstName);
-              }.toString()
-            }
-          }
-        };
-        var doc = {
-          _id: 'foo',
-          firstName: 'Foobar',
-          lastName: 'Bazman'
-        };
-        return db.bulkDocs({docs: [ddoc, doc]}).then(function (info) {
-          ddoc._rev = info[0].rev;
-          return db.query('myview');
-        }).then(function (res) {
-          res.rows.should.deep.equal([
-            {id: 'foo', key: 'Foobar', value: null}
-          ]);
-          ddoc.views.myview.map = function (doc) {
-            emit(doc.lastName);
-          }.toString();
-          return db.put(ddoc);
-        }).then(function () {
-          return db.query('myview');
-        }).then(function (res) {
-          res.rows.should.deep.equal([
-            {id: 'foo', key: 'Bazman', value: null}
-          ]);
-          return db.viewCleanup();
-        });
-      });
-    });
-
-    it('Return ok for viewCleanup after modding view, old format', function () {
-      return new PouchDB(dbName).then(function (db) {
-        var ddoc = {
-          _id: '_design/myddoc',
-          views: {
-            myview: {
-              map: function (doc) {
-                emit(doc.firstName);
-              }.toString()
-            }
-          }
-        };
-        var doc = {
-          _id: 'foo',
-          firstName: 'Foobar',
-          lastName: 'Bazman'
-        };
-        return db.bulkDocs({docs: [ddoc, doc]}).then(function (info) {
-          ddoc._rev = info[0].rev;
-          return db.query('myddoc/myview');
-        }).then(function (res) {
-          res.rows.should.deep.equal([
-            {id: 'foo', key: 'Foobar', value: null}
-          ]);
-          ddoc.views.myview.map = function (doc) {
-            emit(doc.lastName);
-          }.toString();
-          return db.put(ddoc);
-        }).then(function () {
-          return db.query('myddoc/myview');
-        }).then(function (res) {
-          res.rows.should.deep.equal([
-            {id: 'foo', key: 'Bazman', value: null}
-          ]);
-          return db.viewCleanup();
-        });
-      });
-    });
-
-    it("Query non existing view returns error", function () {
-      return new PouchDB(dbName).then(function (db) {
-        var doc = {
-          _id: '_design/barbar',
-          views: {
-            scores: {
-              map: 'function(doc) { if (doc.score) { emit(null, doc.score); } }'
-            }
-          }
-        };
-        return db.post(doc).then(function () {
-          return db.query('barbar/dontExist', {key: 'bar'});
-        });
-      }).should.be.rejected;
-    });
-
-    it('many simultaneous persisted views', function () {
-      this.timeout(120000);
-      var db = new PouchDB(dbName);
-
-      var views = [];
-      var doc = {_id: 'foo'};
-      for (var i = 0; i < 20; i++) {
-        views.push('foo_' + i);
-        doc['foo_' + i] = 'bar_' + i;
-      }
-
-      return db.put(doc).then(function () {
-        return Promise.all(views.map(function (_, i) {
-          var fun = "function (doc) { emit(doc.foo_" + i + ");}";
-
-          var ddocId = 'theViewDoc_' + i;
-          var ddoc = {
-            _id: '_design/' + ddocId,
-            views: {
-              theView : {map: fun}
-            }
-          };
-
-          return db.put(ddoc).then(function (res) {
-            ddoc._rev = res.rev;
-            return db.query(ddocId + '/theView');
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows[0].key.should.equal('bar_' + i);
-            res.rows[0].id.should.equal('foo');
-            return db.remove(ddoc);
-          }).then(function () {
-            return db.viewCleanup();
-          }).then(function () {
-            return db.query(ddocId + '/theView').then(function () {
-              throw new Error('view should have been deleted');
-            }, function (err) {
-              should.exist(err);
-            });
-          });
-        }));
-      });
-    });
-
-    it('should error with a callback', function (done) {
-      new PouchDB(dbName, function (err, db) {
-        db.query('fake/thing', function (err) {
-          should.exist(err);
-          done();
-        });
-      });
-    });
-
-    it('should query correctly when stale', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs : [
-            {name : 'bar', _id : '1'},
-            {name : 'foo', _id : '2'}
-          ]}).then(function () {
-            return db.query(queryFun, {stale : 'ok'});
-          }).then(function (res) {
-            res.total_rows.should.be.within(0, 2);
-            res.offset.should.equal(0);
-            res.rows.length.should.be.within(0, 2);
-            return db.query(queryFun, {stale : 'update_after'});
-          }).then(function (res) {
-            res.total_rows.should.be.within(0, 2);
-            res.rows.length.should.be.within(0, 2);
-            return setTimeoutPromise(5);
-          }).then(function () {
-            return db.query(queryFun, {stale : 'ok'});
-          }).then(function (res) {
-            res.total_rows.should.equal(2);
-            res.rows.length.should.equal(2);
-            return db.get('2');
-          }).then(function (doc2) {
-            return db.remove(doc2);
-          }).then(function () {
-            return db.query(queryFun, {stale : 'ok', include_docs : true});
-          }).then(function (res) {
-            res.total_rows.should.be.within(1, 2);
-            res.rows.length.should.be.within(1, 2);
-            if (res.rows.length === 2) {
-              res.rows[1].key.should.equal('foo');
-              should.not.exist(res.rows[1].doc,
-                'should not throw if doc removed');
-            }
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.total_rows.should.equal(1, 'equals1-1');
-            res.rows.length.should.equal(1, 'equals1-2');
-            return db.get('1');
-          }).then(function (doc1) {
-            doc1.name = 'baz';
-            return db.post(doc1);
-          }).then(function () {
-            return db.query(queryFun, {stale : 'update_after'});
-          }).then(function (res) {
-            res.rows.length.should.equal(1);
-            ['baz', 'bar'].indexOf(res.rows[0].key).should.be.above(-1,
-              'key might be stale, thats ok');
-            return setTimeoutPromise(1000);
-          }).then(function () {
-            return db.query(queryFun, {stale : 'ok'});
-          }).then(function (res) {
-            res.rows.length.should.equal(1);
-            res.rows[0].key.should.equal('baz');
-          });
-        });
-      });
-    });
-
-    it('should query correctly with stale update_after', function () {
-      var pouch = new PouchDB(dbName);
-
-      return createView(pouch, {map: function (doc) {
-        emit(doc.foo);
-      }}).then(function (queryFun) {
-        var docs = [];
-
-        for (var i = 0; i < 10; i++) {
-          docs.push({foo: 'bar'});
-        }
-
-        return pouch.bulkDocs(docs).then(function () {
-          return pouch.query(queryFun, {stale: 'update_after'});
-        }).then(function (res) {
-          res.rows.should.have.length(0, 'query() returned immediately');
-          return setTimeoutPromise(1000);
-        }).then(function () {
-          return pouch.query(queryFun, {stale: 'ok'});
-        }).then(function (res) {
-          res.rows.should.have.length(10, 'index was built in background');
-        });
-      });
-    });
-
-    it('should delete duplicate indexes', function () {
-      var docs = [];
-      for (var i = 0; i < 10; i++) {
-        docs.push(
-          {
-            _id : '_design/view' + i,
-            views : {
-              view : {
-                map : "function(doc){emit('foo');}"
-              }
-            }
-          }
-        );
-      }
-      return new PouchDB(dbName).then(function (db) {
-        return db.bulkDocs({docs : docs}).then(function (responses) {
-          var promise = Promise.resolve();
-          for (var i = 0; i < docs.length; i++) {
-            /* jshint loopfunc:true */
-            docs[i]._rev = responses[i].rev;
-            promise = promise.then(db.query('view' + i + '/view'));
-          }
-          return promise;
-        }).then(function () {
-          docs.forEach(function (doc) {
-            doc._deleted = true;
-          });
-          return db.bulkDocs({docs : docs});
-        }).then(function () {
-          return db.viewCleanup();
-        });
-      });
-    });
-
-    it('should handle user errors in design doc names', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return db.put({
-          _id : '_design/theViewDoc'
-        }).then(function () {
-          return db.query('foo/bar');
-        }).then(function (res) {
-          should.not.exist(res);
-        }).catch(function (err) {
-          err.status.should.equal(404);
-          return db.put(
-            {_id : '_design/void', views : {1 : null}}
-          ).then(function () {
-              return db.query('void/1');
-            }).then(function (res) {
-              should.not.exist(res);
-            }).catch(function (err) {
-              err.status.should.be.a('number');
-              // this might throw due to erroneous ddoc, but that's ok
-              return db.viewCleanup().catch(function (err) {
-                err.status.should.equal(500);
-              });
-            });
-        });
-      });
-    });
-
-    it('should allow the user to create many design docs', function () {
-      function getKey(row) {
-        return row.key;
-      }
-      return new PouchDB(dbName).then(function (db) {
-        return db.put({
-          _id : '_design/foo',
-          views : {
-            byId : { map : function (doc) { emit(doc._id); }.toString()},
-            byField : { map : function (doc) { emit(doc.field); }.toString()}
-          }
-        }).then(function () {
-          return db.put({_id : 'myDoc', field : 'myField'});
-        }).then(function () {
-          return db.query('foo/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-          return db.put({
-            _id : '_design/bar',
-            views : {
-              byId : {map : function (doc) { emit(doc._id); }.toString()}
-            }
-          });
-        }).then(function () {
-          return db.query('bar/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-        }).then(function () {
-          return db.viewCleanup();
-        }).then(function () {
-          return db.query('foo/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-          return db.query('foo/byField');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myField']);
-          return db.query('bar/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-          return db.get('_design/bar');
-        }).then(function (barDoc) {
-          return db.remove(barDoc);
-        }).then(function () {
-          return db.get('_design/foo');
-        }).then(function (fooDoc) {
-          delete fooDoc.views.byField;
-          return db.put(fooDoc);
-        }).then(function () {
-          return db.query('foo/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-          return db.viewCleanup();
-        }).then(function () {
-          return db.query('foo/byId');
-        }).then(function (res) {
-          res.rows.map(getKey).should.deep.equal(['myDoc']);
-          return db.query('foo/byField').then(function (res) {
-            should.not.exist(res);
-          }).catch(function (err) {
-            err.status.should.equal(404);
-            return db.query('bar/byId').then(function (res) {
-              should.not.exist(res);
-            }).catch(function (err) {
-              err.status.should.equal(404);
-              return db.get('_design/foo').then(function (fooDoc) {
-                return db.remove(fooDoc).then(function () {
-                  return db.viewCleanup();
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('should allow view names without slashes', function () {
-      var ddocRev;
-      return new PouchDB(dbName).then(function (db) {
-        return db.put({
-          _id : '_design/foo',
-          views : {
-            foo : { map : function (doc) { emit(doc._id); }.toString()}
-          }
-        }).then(function (info) {
-          ddocRev = info.rev;
-          return db.bulkDocs({docs : [{_id : 'baz'}, {_id : 'bar'}]});
-        }).then(function () {
-          return db.query('foo');
-        }).then(function (res) {
-          res.rows[0].key.should.equal('bar');
-          res.rows[1].key.should.equal('baz');
-          return db.remove({_id : '_design/foo', _rev : ddocRev});
-        });
-      });
-    });
-    it('test 304s in Safari (issue 69)', function () {
-      return new PouchDB(dbName).then(function (db) {
-        return createView(db, {
-          map : function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.bulkDocs({docs : [
-            {name : 'foo'}
-          ]}).then(function () {
-            return db.query(queryFun, {keys : ['foo']});
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            return db.query(queryFun, {keys : ['foo']});
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            return db.query(queryFun, {keys : ['foo']});
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-          });
-        });
-      });
-    });
-
-    var isNode = typeof window === 'undefined';
-    if (dbType === 'local' && isNode) {
-      it('#239 test memdown db', function () {
-        var destroyedDBs = [];
-        PouchDB.on('destroyed', function (db) {
-          destroyedDBs.push(db);
-        });
-
-        // make sure prefixed DBs are tied to regular DBs
-        var db = new PouchDB(dbName, {db: require('memdown')});
-        return testUtils.fin(createView(db, {
-          map: function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.post({name: 'foo'}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows[0].key.should.equal('foo');
-            var ddocId = '_design/' + queryFun.split('/')[0];
-            return db.get(ddocId);
-          }).then(function (ddoc) {
-            return db.remove(ddoc);
-          }).then(function () {
-            return db.viewCleanup();
-          });
-        }), function () {
-          return db.destroy().then(function () {
-            var chain = Promise.resolve();
-            // for each of the supposedly destroyed DBs,
-            // check that there isn't a normal DB hanging around
-            destroyedDBs.forEach(function (dbName) {
-              chain = chain.then(function () {
-                var db = new PouchDB(dbName);
-                var promise = db.info().then(function (info) {
-                  info.update_seq.should.equal(0);
-                });
-                return testUtils.fin(promise, function () {
-                  return db.destroy();
-                });
-              });
-            });
-            return chain;
-          }).then(function () {
-            PouchDB.removeAllListeners('destroyed');
-          });
-        });
-      });
-
-      it('#239 test prefixed db', function () {
-        var destroyedDBs = [];
-        PouchDB.on('destroyed', function (db) {
-          destroyedDBs.push(db);
-        });
-
-        // make sure prefixed DBs are tied to regular DBs
-        require('mkdirp').sync('./myprefix_./tmp/'); // TODO: bit hacky
-        var db = new PouchDB(dbName, {prefix: './myprefix_'});
-        return testUtils.fin(createView(db, {
-          map: function (doc) {
-            emit(doc.name);
-          }
-        }).then(function (queryFun) {
-          return db.post({name: 'foo'}).then(function () {
-            return db.query(queryFun);
-          }).then(function (res) {
-            res.rows.should.have.length(1);
-            res.rows[0].key.should.equal('foo');
-            var ddocId = '_design/' + queryFun.split('/')[0];
-            return db.get(ddocId);
-          }).then(function (ddoc) {
-            return db.remove(ddoc);
-          }).then(function () {
-            return db.viewCleanup();
-          });
-        }), function () {
-          return db.destroy().then(function () {
-            var chain = Promise.resolve();
-            // for each of the supposedly destroyed DBs,
-            // check that there isn't a normal DB hanging around
-            destroyedDBs.forEach(function (dbName) {
-              chain = chain.then(function () {
-                var db = new PouchDB(dbName);
-                var promise = db.info().then(function (info) {
-                  info.update_seq.should.equal(0);
-                });
-                return testUtils.fin(promise, function () {
-                  return db.destroy();
-                });
-              });
-            });
-            return chain;
-          }).then(function () {
-            PouchDB.removeAllListeners('destroyed');
-          });
-        });
-      });
-    }
-
-  });
-}
diff --git a/tests/mapreduce/test.views.js b/tests/mapreduce/test.views.js
deleted file mode 100644
index 3788a6c..0000000
--- a/tests/mapreduce/test.views.js
+++ /dev/null
@@ -1,700 +0,0 @@
-/*jshint expr:true */
-'use strict';
-
-var adapters = [
-  ['local', 'http']
-];
-
-adapters.forEach(function (adapters) {
-  describe('test.views.js-' + adapters[0] + '-' + adapters[1], function () {
-
-    var dbs = {};
-
-    beforeEach(function (done) {
-      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
-      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-    after(function (done) {
-      testUtils.cleanup([dbs.name, dbs.remote], done);
-    });
-
-
-    it('Test basic view', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { foo: 'bar' },
-          {
-            _id: 'volatile',
-            foo: 'baz'
-          }
-        ]
-      }, {}, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.foo, doc);
-          }
-        };
-        db.get('volatile', function (_, doc) {
-          db.remove(doc, function () {
-            db.query(queryFun, {
-              include_docs: true,
-              reduce: false
-            }, function (_, res) {
-              res.rows.should.have.length(1, 'Dont include deleted documents');
-              res.total_rows.should.equal(1, 'Include total_rows property.');
-              res.rows.forEach(function (x) {
-                should.exist(x.id);
-                should.exist(x.key);
-                should.exist(x.value._rev);
-                should.exist(x.doc._rev);
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test passing just a function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { foo: 'bar' },
-          {
-            _id: 'volatile',
-            foo: 'baz'
-          }
-        ]
-      }, {}, function () {
-        var queryFun = function (doc) {
-          emit(doc.foo, doc);
-        };
-        db.get('volatile', function (_, doc) {
-          db.remove(doc, function () {
-            db.query(queryFun, {
-              include_docs: true,
-              reduce: false
-            }, function (_, res) {
-              res.rows.should.have.length(1, 'Dont include deleted documents');
-              res.rows.forEach(function (x) {
-                should.exist(x.id);
-                should.exist(x.key);
-                should.exist(x.value._rev);
-                should.exist(x.doc._rev);
-              });
-              done();
-            });
-          });
-        });
-      });
-    });
-
-    it('Test opts.startkey/opts.endkey', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { key: 'key1' },
-          { key: 'key2' },
-          { key: 'key3' },
-          { key: 'key4' },
-          { key: 'key5' }
-        ]
-      }, {}, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        };
-        db.query(queryFun, {
-          reduce: false,
-          startkey: 'key2'
-        }, function (_, res) {
-          res.rows.should.have.length(4, 'Startkey is inclusive');
-          db.query(queryFun, {
-            reduce: false,
-            endkey: 'key3'
-          }, function (_, res) {
-            res.rows.should.have.length(3, 'Endkey is inclusive');
-            db.query(queryFun, {
-              reduce: false,
-              startkey: 'key2',
-              endkey: 'key3'
-            }, function (_, res) {
-              res.rows.should.have.length(2, 'Startkey and endkey together');
-              db.query(queryFun, {
-                reduce: false,
-                startkey: 'key4',
-                endkey: 'key4'
-              }, function (_, res) {
-                res.rows.should.have.length(1, 'Startkey=endkey');
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test opts.key', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { key: 'key1' },
-          { key: 'key2' },
-          { key: 'key3' },
-          { key: 'key3' }
-        ]
-      }, {}, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.key, doc);
-          }
-        };
-        db.query(queryFun, {
-          reduce: false,
-          key: 'key2'
-        }, function (_, res) {
-          res.rows.should.have.length(1, 'Doc with key');
-          db.query(queryFun, {
-            reduce: false,
-            key: 'key3'
-          }, function (_, res) {
-            res.rows.should.have.length(2, 'Multiple docs with key');
-            done();
-          });
-        });
-      });
-    });
-
-    it.skip('Test basic view collation', function (done) {
-      var values = [];
-      // special values sort before all other types
-      values.push(null);
-      values.push(false);
-      values.push(true);
-      // then numbers
-      values.push(1);
-      values.push(2);
-      values.push(3);
-      values.push(4);
-      // then text, case sensitive
-      // currently chrome uses ascii ordering and so wont handle 
-      // capitals properly
-      values.push('a');
-      //values.push("A");
-      values.push('aa');
-      values.push('b');
-      //values.push("B");
-      values.push('ba');
-      values.push('bb');
-      // then arrays. compared element by element until different.
-      // Longer arrays sort after their prefixes
-      values.push(['a']);
-      values.push(['b']);
-      values.push([
-        'b',
-        'c'
-      ]);
-      values.push([
-        'b',
-        'c',
-        'a'
-      ]);
-      values.push([
-        'b',
-        'd'
-      ]);
-      values.push([
-        'b',
-        'd',
-        'e'
-      ]);
-      // then object, compares each key value in the list until different.
-      // larger objects sort after their subset objects.
-      values.push({ a: 1 });
-      values.push({ a: 2 });
-      values.push({ b: 1 });
-      values.push({ b: 2 });
-      values.push({
-        b: 2,
-        a: 1
-      });
-      // Member order does matter for collation.
-      // CouchDB preserves member order
-      // but doesn't require that clients will.
-      // (this test might fail if used with a js engine
-      // that doesn't preserve order)
-      values.push({
-        b: 2,
-        c: 2
-      });
-      var db = new PouchDB(dbs.name);
-      var docs = values.map(function (x, i) {
-        return {
-          _id: i.toString(),
-          foo: x
-        };
-      });
-      db.bulkDocs({ docs: docs }, {}, function (err) {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.foo, null);
-          }
-        };
-        if (err) {
-          done(err);
-        }
-        db.query(queryFun, { reduce: false }, function (err, res) {
-          if (err) {
-            done(err);
-          }
-          res.rows.forEach(function (x, i) {
-            x.key.should.deep.equal(values[i], 'keys collate');
-          });
-          db.query(queryFun, {
-            descending: true,
-            reduce: false
-          }, function (err, res) {
-            if (err) {
-              done(err);
-            }
-            res.rows.forEach(function (x, i) {
-              x.key.should.deep
-                .equal(values[values.length - 1 - i],
-                       'keys collate descending');
-            });
-            done();
-          });
-        });
-      });
-    });
-
-    it('Test joins', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          {
-            _id: 'mydoc',
-            foo: 'bar'
-          },
-          { doc_id: 'mydoc' }
-        ]
-      }, {}, function () {
-        var queryFun = {
-          map: function (doc) {
-            if (doc.doc_id) {
-              emit(doc._id, { _id: doc.doc_id });
-            }
-          }
-        };
-        db.query(queryFun, {
-          include_docs: true,
-          reduce: false
-        }, function (_, res) {
-          should.exist(res.rows[0].doc);
-          res.rows[0].doc._id.should.equal('mydoc', 'mydoc included');
-          done();
-        });
-      });
-    });
-
-    it('No reduce function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ foo: 'bar' }, function () {
-        var queryFun = {
-          map: function () {
-            emit('key', 'val');
-          }
-        };
-        db.query(queryFun, function () {
-          done();
-        });
-      });
-    });
-
-    it('Built in _sum reduce function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { val: 'bar' },
-          { val: 'bar' },
-          { val: 'baz' }
-        ]
-      }, null, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.val, 1);
-          },
-          reduce: '_sum'
-        };
-        db.query(queryFun, {
-          reduce: true,
-          group_level: 999
-        }, function (err, res) {
-          res.rows.should.have.length(2);
-          res.rows[0].value.should.equal(2);
-          res.rows[1].value.should.equal(1);
-          done();
-        });
-      });
-    });
-
-    it('Built in _count reduce function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { val: 'bar' },
-          { val: 'bar' },
-          { val: 'baz' }
-        ]
-      }, null, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.val, doc.val);
-          },
-          reduce: '_count'
-        };
-        db.query(queryFun, {
-          reduce: true,
-          group_level: 999
-        }, function (err, res) {
-          res.rows.should.have.length(2);
-          res.rows[0].value.should.equal(2);
-          res.rows[1].value.should.equal(1);
-          done();
-        });
-      });
-    });
-
-    it('Built in _stats reduce function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { val: 'bar' },
-          { val: 'bar' },
-          { val: 'baz' }
-        ]
-      }, null, function () {
-        var queryFun = {
-          map: function (doc) {
-            emit(doc.val, 1);
-          },
-          reduce: '_stats'
-        };
-        db.query(queryFun, {
-          reduce: true,
-          group_level: 999
-        }, function (err, res) {
-          var stats = res.rows[0].value;
-          stats.sum.should.equal(2);
-          stats.count.should.equal(2);
-          stats.min.should.equal(1);
-          stats.max.should.equal(1);
-          stats.sumsqr.should.equal(2);
-          done();
-        });
-      });
-    });
-
-    it('No reduce function, passing just a  function', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.post({ foo: 'bar' }, function () {
-        var queryFun = function () {
-          emit('key', 'val');
-        };
-        db.query(queryFun, function () {
-          done();
-        });
-      });
-    });
-
-    it('Views should include _conflicts', function (done) {
-      var doc1 = {
-        _id: '1',
-        foo: 'bar'
-      };
-      var doc2 = {
-        _id: '1',
-        foo: 'baz'
-      };
-      var queryFun = function (doc) {
-        emit(doc._id, !!doc._conflicts);
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.post(doc1, function () {
-        remote.post(doc2, function () {
-          db.replicate.from(remote, function () {
-            db.get(doc1._id, { conflicts: true }, function (err, res) {
-              should.exist(res._conflicts);
-              db.query(queryFun, function (err, res) {
-                should.exist(res.rows[0].value);
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Map only documents with _conflicts (#1000)', function (done) {
-      var docs1 = [
-        {
-          _id: '1',
-          foo: 'bar'
-        },
-        {
-          _id: '2',
-          name: 'two'
-        }
-      ];
-      var doc2 = {
-        _id: '1',
-        foo: 'baz'
-      };
-      var queryFun = function (doc) {
-        if (doc._conflicts) {
-          emit(doc._id, doc._conflicts);
-        }
-      };
-      var db = new PouchDB(dbs.name);
-      var remote = new PouchDB(dbs.remote);
-      db.bulkDocs({ docs: docs1 }, function (err, res) {
-        var revId1 = res[0].rev;
-        remote.post(doc2, function (err, res) {
-          var revId2 = res.rev;
-          db.replicate.from(remote, function () {
-            db.get(docs1[0]._id, { conflicts: true }, function (err, res) {
-              var winner = res._rev;
-              var looser = winner === revId1 ? revId2 : revId1;
-              should.exist(res._conflicts);
-              db.query(queryFun, function (err, res) {
-                res.rows.should.have.length(1, 'One doc with conflicts');
-                res.rows[0].key.should
-                  .equal('1', 'Correct document with conflicts.');
-                res.rows[0].value.should.deep
-                  .equal([looser], 'Correct conflicts included.');
-                done();
-              });
-            });
-          });
-        });
-      });
-    });
-
-    it('Test view querying with limit option', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { foo: 'bar' },
-          { foo: 'bar' },
-          { foo: 'baz' }
-        ]
-      }, null, function () {
-        db.query(function (doc) {
-          if (doc.foo === 'bar') {
-            emit(doc.foo);
-          }
-        }, { limit: 1 }, function (err, res) {
-          res.total_rows.should.equal(2, 'Correctly returns total rows');
-          res.rows.should.have.length(1, 'Correctly limits returned rows');
-          done();
-        });
-      });
-    });
-
-    it('Query non existing view returns error', function (done) {
-      var db = new PouchDB(dbs.name);
-      var doc = {
-        _id: '_design/barbar',
-        views:
-          { scores:
-            { map: 'function (doc) { if (doc.score) ' +
-                   '{ emit(null, doc.score); } }' } }
-      };
-      db.post(doc, function () {
-        db.query('barbar/dontExist', { key: 'bar' }, function (err) {
-          if (!err.name) {
-            err.name = err.error;
-            err.message = err.reason;
-          }
-          err.name.should.be.a('string');
-          err.message.should.be.a('string');
-          done();
-        });
-      });
-    });
-
-    it('Special document member _doc_id_rev', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: [{ foo: 'bar' }] }, null, function () {
-        db.query(function (doc) {
-          if (doc.foo === 'bar') {
-            emit(doc.foo);
-          }
-        }, { include_docs: true }, function (err, res) {
-          should.not.exist(res.rows[0].doc._doc_id_rev);
-          done();
-        });
-      });
-    });
-
-    it('If reduce function returns 0', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({ docs: [{ foo: 'bar' }] }, null, function () {
-        db.query({
-          map: function (doc) {
-            emit(doc.foo);
-          },
-          reduce: function () {
-            return 0;
-          }
-        }, function (err, data) {
-          should.not.equal(data.rows[0].value, null, 'value is null');
-          done();
-        });
-      });
-    });
-
-    it('Testing skip with a view', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { foo: 'bar' },
-          { foo: 'baz' },
-          { foo: 'baf' }
-        ]
-      }, null, function () {
-        db.query(function (doc) {
-          emit(doc.foo, null);
-        }, { skip: 1 }, function (err, data) {
-          should.not.exist(err);
-          data.rows.should.have.length(2);
-          done();
-        });
-      });
-    });
-
-    it('Testing skip with allDocs', function (done) {
-      var db = new PouchDB(dbs.name);
-      db.bulkDocs({
-        docs: [
-          { foo: 'bar' },
-          { foo: 'baz' },
-          { foo: 'baf' }
-        ]
-      }, null, function () {
-        db.allDocs({ skip: 1 }, function (err, data) {
-          should.not.exist(err);
-          data.rows.should.have.length(2);
-          done();
-        });
-      });
-    });
-
-    it('Destroy view when db created with {name: foo}', function () {
-      var db = new PouchDB({name: dbs.name});
-      var doc = {
-        _id: '_design/index',
-        views: {
-          index:
-          { map: 'function (doc) { emit(doc._id); }' }
-        }
-      };
-      return db.put(doc).then(function () {
-        return db.query('index');
-      }).then(function () {
-        return db.destroy();
-      });
-    });
-
-    it('Map documents on 0/null/undefined/empty string', function (done) {
-      var db = new PouchDB(dbs.name);
-      var docs = [
-        {
-          _id: 'doc0',
-          num: 0
-        },
-        {
-          _id: 'doc1',
-          num: 1
-        },
-        { _id: 'doc2' },
-        {
-          _id: 'doc3',
-          num: null
-        },
-        {
-          _id: 'doc4',
-          num: ''
-        }
-      ];
-      db.bulkDocs({ docs: docs }, function () {
-        var mapFunction = function (doc) {
-          emit(doc.num, null);
-        };
-        db.query(mapFunction, {
-          key: 0,
-          include_docs: true
-        }, function (err, data) {
-          data.rows.should.have.length(1);
-          data.rows[0].doc._id.should.equal('doc0');
-        });
-        db.query(mapFunction, {
-          key: null,
-          include_docs: true
-        }, function (err, data) {
-          data.rows.should.have.length(2);
-          data.rows[0].doc._id.should.equal('doc2');
-          data.rows[1].doc._id.should.equal('doc3');
-        });
-        db.query(mapFunction, {
-          key: '',
-          include_docs: true
-        }, function (err, data) {
-          data.rows.should.have.length(1);
-          data.rows[0].doc._id.should.equal('doc4');
-        });
-        db.query(mapFunction, {
-          key: undefined,
-          include_docs: true
-        }, function (err, data) {
-          data.rows.should.have.length(5);
-          // everything
-          done();
-        });
-      });
-    });
-    if (typeof window === 'undefined' && !process.browser) {
-      var fs = require('fs');
-      it("destroy using prototype", function () {
-        return new PouchDB(dbs.name + 1).then(function (db) {
-          var doc = {
-            _id: '_design/barbar',
-            views: {
-              scores: {
-                map: function (doc) {
-                  if (doc.score) {
-                    emit(null, doc.score);
-                  }
-                }.toString(),
-                reduce: '_sum'
-              }
-            }
-          };
-          return db.bulkDocs([doc, {score: 3}, {score: 5}]).then(function () {
-            return db.query('barbar/scores');
-          }).then(function (a) {
-            a.rows[0].value.should.equal(8);
-            return db.destroy();
-          }).then(function () {
-            fs.readdirSync('./tmp').should.have.length(0);
-          });
-        });
-      });
-    }
-  });
-});
diff --git a/tests/misc/express-pouchdb-minimum-for-pouchdb.js b/tests/misc/express-pouchdb-minimum-for-pouchdb.js
deleted file mode 100644
index ed7d17f..0000000
--- a/tests/misc/express-pouchdb-minimum-for-pouchdb.js
+++ /dev/null
@@ -1,8 +0,0 @@
-'use strict';
-
-var PouchDB = require('../../');
-
-var app = require('express-pouchdb')(PouchDB, {
-  mode: 'minimumForPouchDB'
-});
-app.listen(3000);
diff --git a/tests/misc/pouchdb-express-router.js b/tests/misc/pouchdb-express-router.js
deleted file mode 100644
index 5923b7d..0000000
--- a/tests/misc/pouchdb-express-router.js
+++ /dev/null
@@ -1,9 +0,0 @@
-'use strict';
-
-var express = require('express');
-var app = express();
-var PouchDB = require('../../');
-
-app.use(require('pouchdb-express-router')(PouchDB));
-
-app.listen(3000);
diff --git a/tests/misc/sync-gateway-config-server.js b/tests/misc/sync-gateway-config-server.js
deleted file mode 100644
index 85df9bf..0000000
--- a/tests/misc/sync-gateway-config-server.js
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var http = require('http');
-
-function createSyncGatewayConfigServer() {
-  if (process.env.SERVER !== 'sync-gateway') {
-    console.log("not launching SG config server");
-    return;
-  }
-  console.log("launching SG config server for", process.env.COUCH_HOST);
-  // Sync Gateway should be launched with tests/misc/sync-gateway-config.json
-  // which causes it to query this port for database-level config.
-  var SG_CONFIG_PORT = 8001;
-  var sgDBConfig = {
-      "server": "walrus:",
-      "users": {
-        "GUEST": {"disabled": false, "admin_channels": ["*"] }
-      }
-    };
-  function sgConfig(req, res) {
-    res.writeHead(200, {'Content-Type': 'application/json'});
-    res.end(JSON.stringify(sgDBConfig));
-  }
-  http.createServer(sgConfig).listen(SG_CONFIG_PORT);
-}
-
-if (require.main === module) {
-  createSyncGatewayConfigServer();
-} else {
-  module.exports.start = createSyncGatewayConfigServer;
-}
diff --git a/tests/misc/sync-gateway-config.json b/tests/misc/sync-gateway-config.json
deleted file mode 100644
index 2a904ae..0000000
--- a/tests/misc/sync-gateway-config.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "log" : ["HTTP+"],
-  "configServer" : "http://localhost:8001/"
-}
diff --git a/tests/performance/index.html b/tests/performance/index.html
deleted file mode 100644
index 8a233ee..0000000
--- a/tests/performance/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8">
-  </head>
-  <body>
-    <pre style="width: 100%; height: 100%;" id="output"></pre>
-    <script src="/dist/pouchdb.js"></script>
-    <script src="/dist/pouchdb.localstorage.js"></script>
-    <script src="/dist/pouchdb.idb-alt.js"></script>
-    <script src="/dist/pouchdb.memory.js"></script>
-    <script src="../performance-bundle.js"></script>
-  </body>
-</html>
diff --git a/tests/performance/index.js b/tests/performance/index.js
deleted file mode 100644
index 385a4ba..0000000
--- a/tests/performance/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-
-'use strict';
-
-var opts = {};
-
-var levelAdapter = typeof process !== 'undefined' && process.env &&
-    process.env.LEVEL_ADAPTER;
-
-function runTestSuites(PouchDB) {
-  var reporter = require('./perf.reporter');
-  reporter.log('Testing PouchDB version ' + PouchDB.version +
-    ((opts.adapter || levelAdapter) ?
-      (', using adapter: ' + (opts.adapter || levelAdapter)) : '') +
-    '\n\n');
-
-  require('./perf.basics')(PouchDB, opts);
-  require('./perf.views')(PouchDB, opts);
-  require('./perf.attachments')(PouchDB, opts);
-}
-var startNow = true;
-if (global.window && global.window.location && global.window.location.search) {
-
-  var fragment = global.window.location.search.replace(/^\??/, '').split('&');
-  var params = {};
-  fragment.forEach(function (param) {
-    var keyValue = param.split('=');
-    params[keyValue[0]] = decodeURIComponent(keyValue[1]);
-  });
-
-  if ('adapter' in params) {
-    opts.adapter = params.adapter;
-  }
-
-  if ('src' in params) {
-
-    var script = global.document.createElement('script');
-    script.src = params.src;
-    script.onreadystatechange = function () {
-      if ("loaded" === script.readyState || "complete" === script.readyState) {
-        runTestSuites(global.window.PouchDB);
-      }
-    };
-
-    global.document.getElementsByTagName('body')[0].appendChild(script);
-    startNow = false;
-  }
-}
-if (startNow) {
-  var PouchDB = process.browser ? window.PouchDB : require('../..');
-  runTestSuites(PouchDB);
-}
diff --git a/tests/performance/perf.attachments.js b/tests/performance/perf.attachments.js
deleted file mode 100644
index b00c229..0000000
--- a/tests/performance/perf.attachments.js
+++ /dev/null
@@ -1,58 +0,0 @@
-'use strict';
-
-function randomBrowserBlob(size) {
-  var buff = new ArrayBuffer(size);
-  var arr = new Uint8Array(buff);
-  for (var i = 0; i < size; i++) {
-    arr[i] = Math.floor(65535 * Math.random());
-  }
-  return new Blob([buff], {type: 'application/octet-stream'});
-}
-
-function randomBuffer(size) {
-  var buff = new Buffer(size);
-  for (var i = 0; i < size; i++) {
-    buff.write(
-      String.fromCharCode(Math.floor(65535 * Math.random())),
-      i, 1, 'binary');
-  }
-  return buff;
-}
-
-
-function randomBlob(size) {
-  if (process.browser) {
-    return randomBrowserBlob(size);
-  } else { // node
-    return randomBuffer(size);
-  }
-}
-
-module.exports = function (PouchDB, opts) {
-
-  require('lie');
-  var utils = require('./utils');
-
-  var testCases = [
-    {
-      name: 'basic-attachments',
-      assertions: 1,
-      iterations: 1000,
-      setup: function (db, callback) {
-
-        var blob = randomBlob(50000);
-        db._blob = blob;
-        callback();
-      },
-      test: function (db, itr, doc, done) {
-        db.putAttachment(Math.random().toString(), 'foo.txt', db._blob,
-          'application/octet-stream').then(function () {
-          done();
-        }, done);
-      }
-    }
-  ];
-
-  utils.runTests(PouchDB, 'views', testCases, opts);
-
-};
diff --git a/tests/performance/perf.basics.js b/tests/performance/perf.basics.js
deleted file mode 100644
index 9019b05..0000000
--- a/tests/performance/perf.basics.js
+++ /dev/null
@@ -1,215 +0,0 @@
-'use strict';
-
-module.exports = function (PouchDB, opts) {
-
-  var Promise = require('lie');
-  var utils = require('./utils');
-  var commonUtils = require('../common-utils.js');
-
-  var RepTest = require('./replication-test.js')(PouchDB, Promise);
-  var oneGen = new RepTest();
-  var twoGen = new RepTest();
-
-  var testCases = [
-    {
-      name: 'basic-inserts',
-      assertions: 1,
-      iterations: 1000,
-      setup: function (db, callback) {
-        callback(null, {'yo': 'dawg'});
-      },
-      test: function (db, itr, doc, done) {
-        db.post(doc, done);
-      }
-    }, {
-      name: 'bulk-inserts',
-      assertions: 1,
-      iterations: 100,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 100; i++) {
-          docs.push({much : 'docs', very : 'bulk'});
-        }
-        callback(null, {docs : docs});
-      },
-      test: function (db, itr, docs, done) {
-        db.bulkDocs(docs, done);
-      }
-    }, {
-      name: 'basic-updates',
-      assertions: 1,
-      iterations: 100,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 100; i++) {
-          docs.push({});
-        }
-        db.bulkDocs(docs, callback);
-      },
-      test: function (db, itr, _, done) {
-        db.allDocs({include_docs: true}, function (err, res) {
-          if (err) {
-            return done(err);
-          }
-          var docs = res.rows.map(function (x) { return x.doc; });
-          db.bulkDocs(docs, done);
-        });
-      }
-    }, {
-      name: 'basic-gets',
-      assertions: 1,
-      iterations: 10000,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 10000; i++) {
-          docs.push({_id : commonUtils.createDocId(i),
-            foo : 'bar', baz : 'quux'});
-        }
-        db.bulkDocs({docs : docs}, callback);
-      },
-      test: function (db, itr, docs, done) {
-        db.get(commonUtils.createDocId(itr), done);
-      }
-    }, {
-      name: 'all-docs-skip-limit',
-      assertions: 1,
-      iterations: 50,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 1000; i++) {
-          docs.push({_id : commonUtils.createDocId(i),
-            foo : 'bar', baz : 'quux'});
-        }
-        db.bulkDocs({docs : docs}, callback);
-      },
-      test: function (db, itr, docs, done) {
-        var tasks = [];
-        for (var i = 0; i < 10; i++) {
-          tasks.push(i);
-        }
-        Promise.all(tasks.map(function (doc, i) {
-          return db.allDocs({skip : i * 100, limit : 10});
-        })).then(function () {
-          done();
-        }, done);
-      }
-    }, {
-      name: 'all-docs-startkey-endkey',
-      assertions: 1,
-      iterations: 50,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 1000; i++) {
-          docs.push({
-            _id: commonUtils.createDocId(i),
-            foo: 'bar',
-            baz: 'quux'
-          });
-        }
-        db.bulkDocs({docs: docs}, callback);
-      },
-      test: function (db, itr, docs, done) {
-        var tasks = [];
-        for (var i = 0; i < 10; i++) {
-          tasks.push(i);
-        }
-        Promise.all(tasks.map(function (doc, i) {
-          return db.allDocs({
-            startkey: commonUtils.createDocId(i * 100),
-            endkey: commonUtils.createDocId((i * 100) + 10)
-          });
-        })).then(function () {
-          done();
-        }, done);
-      }
-    }, {
-      name: 'all-docs-include-docs',
-      assertions: 1,
-      iterations: 100,
-      setup: function (db, callback) {
-        var docs = [];
-        for (var i = 0; i < 1000; i++) {
-          docs.push({
-            _id: commonUtils.createDocId(i),
-            foo: 'bar',
-            baz: 'quux',
-            _deleted: i % 2 === 1
-          });
-        }
-        db.bulkDocs({docs: docs}, callback);
-      },
-      test: function (db, itr, docs, done) {
-        return db.allDocs({
-          include_docs: true,
-          limit: 100
-        }).then(function () {
-          return db.post({}); // to invalidate the doc count
-        }).then(function () {
-          done();
-        }, done);
-      }
-    },
-    {
-      name: 'pull-replication-perf-skimdb',
-      assertions: 1,
-      iterations: 0,
-      setup: function (localDB, callback) {
-        var remoteCouchUrl = "http://skimdb.iriscouch.com/registry";
-        var remoteDB = new PouchDB(remoteCouchUrl, {
-          ajax: {pool: {maxSockets: 15}}
-        });
-        var localPouches = [];
-
-        for (var i = 0; i < this.iterations; ++i) {
-          localPouches[i] = new PouchDB(commonUtils.safeRandomDBName());
-        }
-
-        return callback(null, {
-          localPouches: localPouches,
-          remoteDB: remoteDB
-        });
-      },
-      test: function (ignoreDB, itr, testContext, done) {
-        var localDB = testContext.localPouches[itr];
-        var remoteDB = testContext.remoteDB;
-
-        var replication = PouchDB.replicate(remoteDB, localDB, {
-          live: false,
-          batch_size: 100
-        });
-        replication.on('change', function (info) {
-          if (info.docs_written >= 200) {
-            replication.cancel();
-            done();
-          }
-        }).on('error', done);
-      },
-      tearDown: function (ignoreDB, testContext) {
-        if (testContext && testContext.localPouches) {
-          return Promise.all(
-            testContext.localPouches.map(function (localPouch) {
-              return localPouch.destroy();
-            }));
-        }
-      }
-    },
-    {
-      name: 'pull-replication-one-generation',
-      assertions: 1,
-      iterations: 1,
-      setup: oneGen.setup(1, 1),
-      test: oneGen.test(),
-      tearDown: oneGen.tearDown()
-    },
-    {
-      name: 'pull-replication-two-generation',
-      assertions: 1,
-      iterations: 1,
-      setup: twoGen.setup(1, 2),
-      test: twoGen.test(),
-      tearDown: twoGen.tearDown()
-    }
-  ];
-
-  utils.runTests(PouchDB, 'basics', testCases, opts);
-};
diff --git a/tests/performance/perf.reporter.js b/tests/performance/perf.reporter.js
deleted file mode 100644
index ce7b414..0000000
--- a/tests/performance/perf.reporter.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict';
-var isNode = process && !process.browser;
-var UAParser = require('ua-parser-js');
-var ua = !isNode && new UAParser(navigator.userAgent);
-global.results = {};
-
-var pre = !isNode && global.document.getElementById('output');
-
-function log(msg) {
-  if (pre) {
-    pre.innerHTML = pre.innerHTML + msg;
-  } else {
-    console.log(msg);
-  }
-}
-
-exports.log = log;
-
-exports.startSuite = function (suiteName) {
-  log('Starting suite: ' + suiteName + '\n\n');
-};
-
-exports.start = function (testCase) {
-  var key = testCase.name;
-  log('Starting test: ' + key + ' with ' + testCase.assertions +
-    ' assertions and ' + testCase.iterations + ' iterations... ');
-  global.results[key] = {
-    start: Date.now()
-  };
-};
-
-exports.end = function (testCase) {
-  var key = testCase.name;
-  var obj = global.results[key];
-  obj.end = Date.now();
-  obj.duration = obj.end - obj.start;
-  log('done in ' + obj.duration + 'ms\n');
-};
-
-exports.complete = function () {
-  global.results.completed = true;
-  if (isNode) {
-    global.results.client = {node: process.version};
-  } else {
-    global.results.client = {
-      browser: ua.getBrowser(),
-      device: ua.getDevice(),
-      engine: ua.getEngine(),
-      cpu: ua.getCPU(),
-      os : ua.getOS(),
-      userAgent: navigator.userAgent
-    };
-  }
-  console.log(global.results);
-  log('\nTests Complete!\n\n');
-};
-
diff --git a/tests/performance/perf.views.js b/tests/performance/perf.views.js
deleted file mode 100644
index 425d5b5..0000000
--- a/tests/performance/perf.views.js
+++ /dev/null
@@ -1,148 +0,0 @@
-'use strict';
-
-module.exports = function (PouchDB, opts) {
-
-  var Promise = require('lie');
-  var utils = require('./utils');
-
-  function makeTestDocs() {
-    return [
-      {key: null},
-      {key: true},
-      {key: false},
-      {key: -1},
-      {key: 0},
-      {key: 1},
-      {key: 2},
-      {key: 3},
-      {key: Math.random()},
-      {key: 'bar' + Math.random()},
-      {key: 'foo' + Math.random()},
-      {key: 'foobar' + Math.random()}
-    ];
-  }
-
-  var testCases = [
-    {
-      name: 'temp-views',
-      assertions: 1,
-      iterations: 1,
-      setup: function (db, callback) {
-        var tasks = [];
-        for (var i = 0; i < 100; i++) {
-          tasks.push(i);
-        }
-        Promise.all(tasks.map(function () {
-          return db.bulkDocs({docs : makeTestDocs()});
-        })).then(function () {
-          callback();
-        }, callback);
-      },
-      test: function (db, itr, doc, done) {
-        var tasks = [
-          {startkey: 'foo', limit: 5},
-          {startkey: 'foobar', limit: 5},
-          {startkey: 'foo', limit: 5},
-          {startkey: -1, limit: 5},
-          {startkey: null, limit: 5}
-        ];
-        Promise.all(tasks.map(function (task) {
-          return db.query(function (doc) {
-            emit(doc.key);
-          }, task);
-        })).then(function () {
-          done();
-        }, done);
-      }
-    },
-    {
-      name: 'persisted-views',
-      assertions: 1,
-      iterations: 10,
-      setup: function (db, callback) {
-        var tasks = [];
-        for (var i = 0; i < 100; i++) {
-          tasks.push(i);
-        }
-        Promise.all(tasks.map(function () {
-          return db.bulkDocs({docs : makeTestDocs()});
-        })).then(function () {
-          return db.put({
-            _id : '_design/myview',
-            views : {
-              myview : {
-                map : function (doc) {
-                  emit(doc.key);
-                }.toString()
-              }
-            }
-          });
-        }).then(function () {
-          return db.query('myview/myview');
-        }).then(function () {
-          callback();
-        }, callback);
-      },
-      test: function (db, itr, doc, done) {
-        var tasks = [
-          {startkey: 'foo', limit: 5},
-          {startkey: 'foobar', limit: 5},
-          {startkey: 'foo', limit: 5},
-          {startkey: -1, limit: 5},
-          {startkey: null, limit: 5}
-        ];
-        Promise.all(tasks.map(function (task) {
-            return db.query('myview/myview', task);
-          })).then(function () {
-            done();
-          }, done);
-      }
-    },
-    {
-      name: 'persisted-views-stale-ok',
-      assertions: 1,
-      iterations: 10,
-      setup: function (db, callback) {
-        var tasks = [];
-        for (var i = 0; i < 100; i++) {
-          tasks.push(i);
-        }
-        Promise.all(tasks.map(function () {
-            return db.bulkDocs({docs : makeTestDocs()});
-          })).then(function () {
-            return db.put({
-              _id : '_design/myview',
-              views : {
-                myview : {
-                  map : function (doc) {
-                    emit(doc.key);
-                  }.toString()
-                }
-              }
-            });
-          }).then(function () {
-            return db.query('myview/myview');
-          }).then(function () {
-            callback();
-          }, callback);
-      },
-      test: function (db, itr, doc, done) {
-        var tasks = [
-          {startkey: 'foo', limit: 5, stale : 'ok'},
-          {startkey: 'foobar', limit: 5, stale : 'ok'},
-          {startkey: 'foo', limit: 5, stale : 'ok'},
-          {startkey: -1, limit: 5, stale : 'ok'},
-          {startkey: null, limit: 5, stale : 'ok'}
-        ];
-        Promise.all(tasks.map(function (task) {
-            return db.query('myview/myview', task);
-          })).then(function () {
-            done();
-          }, done);
-      }
-    }
-  ];
-
-  utils.runTests(PouchDB, 'views', testCases, opts);
-
-};
diff --git a/tests/performance/replication-test.js b/tests/performance/replication-test.js
deleted file mode 100644
index a1186b2..0000000
--- a/tests/performance/replication-test.js
+++ /dev/null
@@ -1,97 +0,0 @@
-'use strict';
-
-module.exports = function (PouchDB, Promise) {
-
-  var NUM_DOCS = 1000;
-  var MAX_SOCKETS = 15;
-  var BATCH_SIZE = 100;
-
-  var commonUtils = require('../common-utils.js');
-  var log = require('debug')('pouchdb:tests:performance');
-
-  var PullRequestTestObject = function () {
-    this.localPouches = [];
-  };
-
-  PullRequestTestObject.prototype.setup = function (itr, gens) {
-    var self = this;
-    return function (localDB, callback) {
-      var remoteDBOpts = {ajax: {pool: {maxSockets: MAX_SOCKETS}}};
-      var remoteCouchUrl = commonUtils.couchHost() + "/" +
-        commonUtils.safeRandomDBName();
-
-      self.remoteDB = new PouchDB(remoteCouchUrl, remoteDBOpts);
-
-      var i;
-      var docs = [];
-      var localOpts = {ajax: {timeout: 60 * 1000}};
-
-      for (i = 0; i < itr; ++i) {
-        self.localPouches[i] = new PouchDB(commonUtils.safeRandomDBName());
-      }
-
-      for (i = 0; i < NUM_DOCS; i++) {
-        docs.push({
-          _id: commonUtils.createDocId(i),
-          foo: Math.random(),
-          bar: Math.random()
-        });
-      }
-
-      var addGeneration = function (generationCount, docs) {
-        return self.remoteDB.bulkDocs({docs: docs}, localOpts)
-          .then(function (bulkDocsResponse) {
-            --generationCount;
-            if (generationCount <= 0) {
-              return {};
-            }
-            var updatedDocs = bulkDocsResponse.map(function (doc) {
-              return {
-                _id: doc.id,
-                _rev: doc.rev,
-                foo: Math.random(),
-                bar: Math.random()
-              };
-            });
-            return addGeneration(generationCount, updatedDocs);
-          });
-      };
-
-      return addGeneration(gens, docs).then(callback);
-    };
-  };
-
-  PullRequestTestObject.prototype.test = function () {
-    var self = this;
-    return function (ignoreDB, itr, ignoreContext, done) {
-      var localDB = self.localPouches[itr];
-      PouchDB.replicate(self.remoteDB, localDB,
-        {live: false, batch_size: BATCH_SIZE})
-      .on('change', function (info) {
-        log("replication - info - " + JSON.stringify(info));
-      })
-      .on('complete', function (info) {
-        log("replication - complete - " + JSON.stringify(info));
-        done();
-      })
-      .on('error', function (err) {
-        log("replication - error - " + JSON.stringify(err));
-        throw err;
-      });
-    };
-  };
-
-  PullRequestTestObject.prototype.tearDown = function () {
-    var self = this;
-    return function () {
-      return self.remoteDB.destroy().then(function () {
-        return Promise.all(
-          self.localPouches.map(function (localPouch) {
-            return localPouch.destroy();
-          }));
-      });
-    };
-  };
-
-  return PullRequestTestObject;
-};
diff --git a/tests/performance/utils.js b/tests/performance/utils.js
deleted file mode 100644
index 8859268..0000000
--- a/tests/performance/utils.js
+++ /dev/null
@@ -1,92 +0,0 @@
-'use strict';
-
-var reporter = require('./perf.reporter');
-var test = require('tape');
-var commonUtils = require('../common-utils.js');
-var Promise = require('lie');
-
-var grep;
-if (global.window && global.window.location && global.window.location.search) {
-  grep = global.window.location.search.match(/[&?]grep=([^&]+)/);
-  grep = grep && grep[1];
-} else if (process && process.env) {
-  grep = process.env.GREP;
-}
-
-var levelAdapter = typeof process !== 'undefined' && process.env &&
-    process.env.LEVEL_ADAPTER;
-
-exports.runTests = function (PouchDB, suiteName, testCases, opts) {
-  testCases.forEach(function (testCase, i) {
-    if (grep && suiteName.indexOf(grep) === -1 &&
-        testCase.name.indexOf(grep) === -1) {
-      return;
-    }
-
-    if (testCase.iterations === 0) {
-      return;
-    }
-
-    test('benchmarking', function (t) {
-
-      var db;
-      var setupObj;
-
-      var localDbName = commonUtils.safeRandomDBName();
-
-      t.test('setup', function (t) {
-        opts.size = 3000;
-        if (levelAdapter) {
-          opts.db = require(levelAdapter);
-        }
-        db = new PouchDB(localDbName, opts);
-        testCase.setup(db, function (err, res) {
-          setupObj = res;
-          if (i === 0) {
-            reporter.startSuite(suiteName);
-          }
-          reporter.start(testCase);
-          t.end();
-        });
-      });
-
-      t.test(testCase.name, function (t) {
-        t.plan(testCase.assertions);
-        var num = 0;
-        function after(err) {
-          if (err) {
-            t.error(err);
-            reporter.log(testCase.name + ' errored: ' + err.message + '\n');
-          }
-          if (++num < testCase.iterations) {
-            process.nextTick(function () {
-              testCase.test(db, num, setupObj, after);
-            });
-          } else {
-            t.ok(testCase.name + ' completed');
-          }
-        }
-        testCase.test(db, num, setupObj, after);
-      });
-      t.test('teardown', function (t) {
-        var testCaseTeardown = testCase.tearDown ?
-          testCase.tearDown(db, setupObj) :
-          Promise.resolve();
-
-        testCaseTeardown.then(function () {
-          reporter.end(testCase);
-          var opts = {adapter : db.adapter};
-          if (levelAdapter) {
-            opts.db = require(levelAdapter);
-          }
-          return new PouchDB(localDbName, opts).destroy();
-        }).then(function () {
-          t.end();
-          if (i === testCases.length - 1) {
-            reporter.complete(suiteName);
-          }
-        });
-      });
-    });
-  });
-};
diff --git a/tests/stress/websql_storage_limit.html b/tests/stress/websql_storage_limit.html
deleted file mode 100644
index f3e6fbe..0000000
--- a/tests/stress/websql_storage_limit.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!doctype html>
-<html>
-<body>
-<h1>WebSQL storage limit stress test</h1>
-
-<form action='#' id="myform" onsubmit="runTest();return false;">
-    <h3>Choose size in MB:</h3>
-    <input type="radio" id="5" name="size" value="5"/>
-    <label for="5">5</label>
-    <input type="radio" id="10" name="size" value="10" checked="checked"/>
-    <label for="5">10</label>
-    <input type="radio" id="50" name="size" value="50"/>
-    <label for="5">50</label>
-    <input type="radio" id="100" name="size" value="100"/>
-    <label for="5">100</label>
-    <input type="radio" id="500" name="size" value="500"/>
-    <label for="5">500</label>
-    <input type="radio" id="1000" name="size" value="1000"/>
-    <label for="5">1000</label>
-    <p/>
-    <button>Run test</button>
-</form>
-<p/>
-<pre id="log"> </pre>
-<script src="../../dist/pouchdb.js"></script>
-<script>
-
-    function getRadioValue() {
-        var inputs = document.getElementsByName("size");
-        for (var i = 0; i < inputs.length; i++) {
-            if (inputs[i].checked) {
-                return inputs[i].value;
-            }
-        }
-    }
-
-    function log(text) {
-        document.getElementById('log').appendChild(document.createTextNode(text + '\n'));
-    }
-
-    log('this is a load test designed to reproduce the 10MB size limit bug on Safari/iOS 7');
-    log("if all's well, you should see a success message, else an error");
-    log("you can use Safari's 'reset Safari' option to try again\n");
-
-    function runTest() {
-
-        log('starting...');
-
-        var BATCH_SIZE = 1000;
-        var ITERATIONS = 1000;
-        var pouch = new PouchDB('websql_stress', {adapter: 'websql', size: getRadioValue()});
-        var promise = PouchDB.utils.Promise.resolve();
-
-        function addDocs(i) {
-            promise = promise.then(function () {
-                var docs = [];
-                for (var j = 0; j < BATCH_SIZE; j++) {
-                    docs.push({});
-                }
-                return pouch.bulkDocs({docs: docs}).then(function () {
-                    var numDone = (i + 1) * BATCH_SIZE;
-                    var total = BATCH_SIZE * ITERATIONS;
-                    var percent = (Math.round((numDone / total) * 10000) / 100).toFixed(2);
-                    log('Added ' + numDone + '/' + total + ' (' + percent + '%) docs so far...');
-                });
-            });
-        }
-
-        for (var i = 0; i < ITERATIONS; i++) {
-            addDocs(i);
-        }
-        promise.then(function () {
-            log('Success!');
-        }, function (err) {
-            log('Failure!');
-            log(err);
-        });
-
-        return false;
-    }
-</script>
-</body>
-</html>
diff --git a/tests/unit/test.ajax.js b/tests/unit/test.ajax.js
deleted file mode 100644
index 8a4ae70..0000000
--- a/tests/unit/test.ajax.js
+++ /dev/null
@@ -1,77 +0,0 @@
-'use strict';
-
-var should = require('chai').should();
-var mockery = require('mockery');
-
-describe('test.ajax.js', function () {
-  var cb;
-  var ajax;
-
-  beforeEach(function () {
-    mockery.enable({
-      warnOnReplace: false,
-      warnOnUnregistered: false,
-      useCleanCache: true
-    });
-
-    function requestStub(callOpts, callCB) {
-      cb = callCB;
-    }
-
-    mockery.registerMock('request', requestStub);
-    ajax = require('../../lib/deps/ajax/ajaxCore');
-  });
-
-  after(function () {
-    mockery.disable();
-  });
-
-  it('should exist', function () {
-    should.exist(ajax);
-    ajax.should.be.a('function');
-  });
-
-  it('detects error on an interrupted binary file', function (done) {
-    ajax({
-      method: 'GET',
-      binary: true,
-      url: 'http://test.db/dbname/docid/filename.jpg'
-    }, function (err, res) {
-      // here's the test, we should get an 'err' response
-      should.exist(err);
-      should.not.exist(res);
-      done();
-    });
-
-    // Simulates an interrupted network request
-    setTimeout(function () {
-      cb(null, {
-        statusCode: 0
-      },
-      "");
-    }, 4);
-  });
-
-  it('should work on a working binary file', function (done) {
-    ajax({
-      method: 'GET',
-      binary: true,
-      url: 'http://test.db/dbname/docid/filename.jpg'
-    }, function (err, res) {
-      should.not.exist(err);
-      should.exist(res);
-      done();
-    });
-
-    setTimeout(function () {
-      cb(null, {
-        statusCode: 200,
-        headers: {
-          'Content-Type': 'image/jpeg'
-        }
-      }, new Buffer('sure this is binary data'));
-    }, 4);
-  });
-
-});
-
diff --git a/tests/unit/test.gen-replication-id.js b/tests/unit/test.gen-replication-id.js
deleted file mode 100644
index fc25e36..0000000
--- a/tests/unit/test.gen-replication-id.js
+++ /dev/null
@@ -1,164 +0,0 @@
-'use strict';
-
-var memdown = require('memdown');
-var PouchDB = require('../../lib/index');
-var sourceDb = new PouchDB({name: 'local_db', db: memdown});
-var targetDb = new PouchDB({name: 'target_db', db: memdown});
-var genReplicationId =
-  require('../../lib/replicate/generateReplicationId');
-
-require('chai').should();
-
-describe('test.gen-replication-id.js', function () {
-  it('is different with different `doc_ids` option', function () {
-    var opts2 = {doc_ids: ["1"]};
-    var opts1 = {doc_ids: ["2"]};
-
-    return genReplicationId(sourceDb, targetDb, opts1).then(
-      function (replicationId1) {
-        return genReplicationId(sourceDb, targetDb, opts2).then(
-          function (replicationId2) {
-            replicationId2.should.not.eql(replicationId1);
-          }
-        );
-      }
-    );
-  });
-
-  it('ignores the order of array elements in the `doc_ids` option',
-    function () {
-      var opts1 = {doc_ids: ["1", "2", "3"]};
-      var opts2 = {doc_ids: ["3", "2", "1"]};
-
-      return genReplicationId(sourceDb, targetDb, opts1).then(
-        function (replicationId1) {
-          return genReplicationId(sourceDb, targetDb, opts2).then(
-            function (replicationId2) {
-              replicationId2.should.eql(replicationId1);
-            }
-          );
-        }
-      );
-    }
-  );
-
-  it('is different with different `filter` option', function () {
-    var opts1 = {filter: 'ddoc/filter'};
-    var opts2 = {filter: 'ddoc/other_filter'};
-
-    return genReplicationId(sourceDb, targetDb, opts1).then(
-      function (replicationId1) {
-        return genReplicationId(sourceDb, targetDb, opts2).then(
-          function (replicationId2) {
-            replicationId2.should.not.eql(replicationId1);
-          }
-        );
-      }
-    );
-  });
-
-  it('ignores the `query_params` option if there\'s no `filter` option',
-    function () {
-      var opts1 = {query_params: {foo: 'bar'}};
-      var opts2 = {query_params: {bar: 'baz'}};
-
-      return genReplicationId(sourceDb, targetDb, opts1).then(
-        function (replicationId1) {
-          return genReplicationId(sourceDb, targetDb, opts2).then(
-            function (replicationId2) {
-              replicationId2.should.eql(replicationId1);
-            }
-          );
-        }
-      );
-    }
-  );
-
-  it('is different with same `filter` but different `query_params` option',
-    function () {
-      var opts1 = {filter: 'ddoc/filter', query_params: {foo: 'bar'}};
-      var opts2 = {filter: 'ddoc/other_filter'};
-
-      return genReplicationId(sourceDb, targetDb, opts1).then(
-        function (replicationId1) {
-          return genReplicationId(sourceDb, targetDb, opts2).then(
-            function (replicationId2) {
-              replicationId2.should.not.eql(replicationId1);
-            }
-          );
-        }
-      );
-    }
-  );
-
-  it('ignores the order of object properties in the `query_params` option',
-    function () {
-      var opts1 = {
-        filter: 'ddoc/filter',
-        query_params: {foo: 'bar', bar: 'baz'}
-      };
-      var opts2 = {
-        filter: 'ddoc/filter',
-        query_params: {bar: 'baz', foo: 'bar'}
-      };
-
-      return genReplicationId(sourceDb, targetDb, opts1).then(
-        function (replicationId1) {
-          return genReplicationId(sourceDb, targetDb, opts2).then(
-            function (replicationId2) {
-              replicationId2.should.eql(replicationId1);
-            }
-          );
-        }
-      );
-    }
-  );
-
-  it('it ignores the `view` option unless the `filter` option value ' +
-     'is `_view`',
-    function () {
-      var opts1 = {view: 'ddoc/view'};
-      var opts2 = {view: 'ddoc/other_view'};
-      var opts3 = {filter: 'ddoc/view', view: 'ddoc/view'};
-      var opts4 = {filter: 'ddoc/view', view: 'ddoc/other_view'};
-      var opts5 = {filter: '_view', view: 'ddoc/other_view'};
-      var opts6 = {filter: '_view', view: 'ddoc/view'};
-
-      return genReplicationId(sourceDb, targetDb, opts1).then(
-        function (replicationId1) {
-          return genReplicationId(sourceDb, targetDb, opts2).then(
-            function (replicationId2) {
-              replicationId2.should.eql(replicationId1);
-              return replicationId2;
-            }
-          );
-        }
-      ).then(function (replicationId2) {
-        return genReplicationId(sourceDb, targetDb, opts3).then(
-          function (replicationId3) {
-            replicationId3.should.not.eql(replicationId2);
-
-            return genReplicationId(sourceDb, targetDb, opts4).then(
-              function (replicationId4) {
-                replicationId4.should.eql(replicationId3);
-                return replicationId4;
-              }
-            );
-          }
-        );
-      }).then(function (replicationId4) {
-        return genReplicationId(sourceDb, targetDb, opts5).then(
-          function (replicationId5) {
-            replicationId5.should.not.eql(replicationId4);
-
-            return genReplicationId(sourceDb, targetDb, opts6).then(
-              function (replicationId6) {
-                replicationId6.should.not.eql(replicationId5);
-              }
-            );
-          }
-        );
-      });
-    }
-  );
-});
diff --git a/tests/unit/test.mapreduce.js b/tests/unit/test.mapreduce.js
deleted file mode 100644
index 99c8665..0000000
--- a/tests/unit/test.mapreduce.js
+++ /dev/null
@@ -1,65 +0,0 @@
-'use strict';
-
-var should = require('chai').should();
-var upsert = require('../../lib/deps/upsert');
-var utils = require('../../lib/mapreduce/utils');
-var Promise = require('../../lib/deps/promise');
-
-describe('test.mapreduce.js-upsert', function () {
-  it('should throw an error with no doc id', function () {
-    return upsert().should.be.rejected;
-  });
-  it('should throw an error if the doc errors', function () {
-    return upsert({
-      get: function (foo, cb) {
-        cb(new Error('a fake error!'));
-      }
-    }, 'foo').should.be.rejected;
-  });
-  it('should fulfill if the diff returns false', function () {
-    return upsert({
-      get: function (foo, cb) {
-        cb(null, 'lalala');
-      }
-    }, 'foo', function () {
-      return false;
-    }).should.be.fulfilled;
-  });
-  it('should error if it can\'t put', function () {
-    return upsert({
-      get: function (foo, cb) {
-        cb(null, 'lalala');
-      },
-      put: function () {
-        return Promise.reject(new Error('falala'));
-      }
-    }, 'foo', function () {
-      return true;
-    }).should.be.rejected;
-  });
-});
-
-describe('test.mapreduce.js-utils', function () {
-  it('callbackify should work with a callback', function (done) {
-    function fromPromise() {
-      return Promise.resolve(true);
-    }
-    utils.callbackify(fromPromise)(function (err, resp) {
-      should.not.exist(err);
-      should.exist(resp);
-      done();
-    });
-  });
-  it('fin should work without returning a function and it resolves',
-    function () {
-    return utils.fin(Promise.resolve(), function () {
-      return {};
-    }).should.be.fullfilled;
-  });
-  it('fin should work without returning a function and it rejects',
-    function () {
-    return utils.fin(Promise.reject(), function () {
-      return {};
-    }).should.be.rejected;
-  });
-});
diff --git a/tests/unit/test.merge.js b/tests/unit/test.merge.js
deleted file mode 100644
index 0146a5f..0000000
--- a/tests/unit/test.merge.js
+++ /dev/null
@@ -1,417 +0,0 @@
-'use strict';
-
-// Porting tests from Apache CouchDB
-// https://github.com/davisp/couchdb/blob/local_doc_revs/test/
-// etap/060-kt-merging.t
-
-var merge = require('../../lib/deps/merge');
-var winningRev = require('../../lib/deps/merge/winningRev');
-
-describe('test.merge.js', function () {
-
-  var simple;
-  var two0;
-  var two1;
-  var newleaf;
-  var withnewleaf;
-  var newbranch;
-  var newdeepbranch;
-  var stemmededit;
-  var stemmedconflicts;
-  var newbranchleaf;
-  var newbranchleafbranch;
-  var stemmed2;
-  var stemmed3;
-  var partialrecover;
-
-  /*
-   * Our merge() function actually mutates the input object, because it's
-   * more performant than deep cloning the object every time it's passed
-   * into merge(). So in order for these tests to pass, we need to redefine
-   * these objects every time.
-   */
-  beforeEach(function () {
-    simple = {pos: 1, ids: ['1', {}, []]};
-    two0 = {pos: 1, ids: ['1', {}, [['2_0', {}, []]]]};
-    two1 = {pos: 1, ids: ['1', {}, [['2_1', {}, []]]]};
-    newleaf = {pos: 2, ids: ['2_0', {}, [['3', {}, []]]]};
-    withnewleaf = {pos: 1, ids: ['1', {}, [['2_0', {}, [['3', {}, []]]]]]};
-    newbranch = {pos: 1, ids: ['1', {}, [['2_0', {}, []], ['2_1', {}, []]]]};
-    newdeepbranch = {pos: 2, ids: ['2_0', {}, [['3_1', {}, []]]]};
-
-    stemmededit = {pos: 3, ids: ['3', {}, []]};
-    stemmedconflicts = [simple, stemmededit];
-
-    newbranchleaf = {
-      pos: 1,
-      ids: ['1', {}, [['2_0', {}, [['3', {}, []]]], ['2_1', {}, []]]]
-    };
-
-    newbranchleafbranch = {
-      pos: 1,
-      ids: ['1', {}, [
-        ['2_0', {}, [['3', {}, []], ['3_1', {}, []]]], ['2_1', {}, []]
-      ]]
-    };
-
-    stemmed2 = [
-      {pos: 1, ids: ['1', {}, [['2_1', {}, []]]]},
-      {pos: 2, ids: ['2_0', {}, [['3', {}, []], ['3_1', {}, []]]]}
-    ];
-
-    stemmed3 = [
-      {pos: 2, ids: ['2_1', {}, []]},
-      {pos: 3, ids: ['3', {}, []]},
-      {pos: 3, ids: ['3_1', {}, []]}
-    ];
-
-    partialrecover = [
-      {pos: 1, ids: ['1', {}, [['2_0', {}, [['3', {}, []]]]]]},
-      {pos: 2, ids: ['2_1', {}, []]},
-      {pos: 3, ids: ['3_1', {}, []]}
-    ];
-  });
-
-  it('Merging a path into an empty tree is the path', function () {
-    merge([], simple, 10).should.deep.equal({
-      tree: [simple],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Remerge path into path is reflexive', function () {
-    merge([simple], simple, 10).should.deep.equal({
-      tree: [simple],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merging a path with multiple entries is the path', function () {
-    merge([], two0, 10).should.deep.equal({
-      tree: [two0],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Merging a path with multiple entries is reflexive', function () {
-    merge([two0], two0, 10).should.deep.equal({
-      tree: [two0],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merging a subpath into a path results in the path', function () {
-    merge([two0], simple, 10).should.deep.equal({
-      tree: [two0],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merging a new leaf gives us a new leaf', function () {
-    merge([two0], newleaf, 10).should.deep.equal({
-      tree: [withnewleaf],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Merging a new branch returns a proper tree', function () {
-    merge([two0], two1, 10).should.deep.equal({
-      tree: [newbranch],
-      stemmedRevs: [],
-      conflicts: 'new_branch'
-    });
-  });
-
-  it('Order of merging does not affect the resulting tree', function () {
-    merge([two1], two0, 10).should.deep.equal({
-      tree: [newbranch],
-      stemmedRevs: [],
-      conflicts: 'new_branch'
-    });
-  });
-
-  it('Merging a new_leaf doesnt return new_branch when branches exist',
-     function () {
-    merge([newbranch], newleaf, 10).should.deep.equal({
-      tree: [newbranchleaf],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Merging a deep branch with branches works', function () {
-    merge([newbranchleaf], newdeepbranch, 10).should.deep.equal({
-      tree: [newbranchleafbranch],
-      stemmedRevs: [],
-      conflicts: 'new_branch'
-    });
-  });
-
-  it('New information reconnects steming induced conflicts', function () {
-    merge(stemmedconflicts, withnewleaf, 10).should.deep.equal({
-      tree: [withnewleaf],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Simple stemming works', function () {
-    merge([two0], newleaf, 2).should.deep.equal({
-      tree: [newleaf],
-      stemmedRevs: ['1-1'],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Merge with stemming works correctly for branches', function () {
-    merge([newbranchleafbranch], simple, 2).should.deep.equal({
-      tree: stemmed2,
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merge with stemming to leaves works fine', function () {
-    merge([newbranchleafbranch], simple, 1).should.deep.equal({
-      tree: stemmed3,
-      stemmedRevs: ['1-1', '2-2_0'],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merging unstemmed recovers as much as possible without losing info',
-     function () {
-    merge(stemmed3, withnewleaf, 10).should.deep.equal({
-      tree: partialrecover,
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('winningRev returns the longest leaf', function () {
-    var tree = [
-      {"pos": 1, "ids": [
-        "bfe70372c90ded1087239e5191984f76", {}, [
-          ["44d71a718b90e4696c06a90e08912c8f", {}, []],
-          ["56e657612d55ab1a402dcb281c874f2a", {}, [
-            ["93c3db16462f656f7172ccabd3cf6cd6", {}, []]
-          ]]
-        ]
-      ]}
-    ];
-    winningRev({rev_tree: tree})
-      .should.equal("3-93c3db16462f656f7172ccabd3cf6cd6");
-  });
-
-  it('winningRev returns the longest leaf again', function () {
-    // this one is from issue #293
-    var tree = [
-      {"pos": 1, "ids": [
-        "203db1a1810a838895d561f67b224b5d", {}, [
-          ["bf5e08a4f9fa6d33a53f4a00ae3ea399", {}, [
-            ["28cd77a3ca30f79e1cfffcd6a41ca308", {}, []]
-          ]]
-        ]
-      ]},
-      {"pos": 1, "ids": [
-        "c6d5cce35bcfbef90b20f140d723cbdb", {}, [
-          ["1b8dfbb1267e213328920bae43f2f597", {}, []],
-          ["59ed830b84b276ab776c3c51aaf93a16", {}, [
-            ["64a9842c6aea50bf24660378e496e853", {}, []]
-          ]]
-        ]
-      ]}
-    ];
-    winningRev({rev_tree: tree})
-      .should.equal("3-64a9842c6aea50bf24660378e496e853");
-  });
-
-  // ///// These are tests from CouchDB's kt-merging.erl test suite
-
-  var one = {pos: 1, ids: ['1', {}, []]};
-  it('The empty tree is the identity for merge.', function () {
-    merge([], one, 10).should.deep.equal({
-      tree: [one],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  it('Merging is reflexive', function () {
-    merge([one], one, 10).should.deep.equal({
-      tree: [one],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var two = {pos: 1, ids: ['2', {}, []]};
-  var twoSibs = [one, two];
-  it('Merging a prefix of a tree with the tree yields the tree.', function () {
-    merge(twoSibs, one, 10).should.deep.equal({
-      tree: twoSibs,
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var three = {pos: 1, ids: ['3', {}, []]};
-  var threeSibs = [one, two, three];
-  it('Merging a third unrelated branch leads to a conflict.', function () {
-    merge(twoSibs, three, 10).should.deep.equal({
-      tree: threeSibs,
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var twoChild = {pos: 1, ids: ['1', {}, [
-    ['1a', {}, [
-      ['1aa', {}, []]
-    ]]
-  ]]};
-  it('Merging two children is still reflexive.', function () {
-    merge([twoChild], twoChild, 10).should.deep.equal({
-      tree: [twoChild],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var twoChildSibs = {pos: 1, ids: ['1', {}, [
-    ['1a', {}, []],
-    ['1b', {}, []]
-  ]]};
-  it('Merging a tree to itself is itself.', function () {
-    merge([twoChildSibs], twoChildSibs, 10).should.deep.equal({
-      tree: [twoChildSibs],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var twoChildPlusSibs = {pos: 1, ids: ['1', {}, [
-    ['1a', {}, [
-      ['1aa', {}, []]
-    ]],
-    ['1b', {}, []]
-  ]]};
-  it('Merging tree of uneven length at node 2.', function () {
-    merge([twoChild], twoChildSibs, 10).should.deep.equal({
-      tree: [twoChildPlusSibs],
-      stemmedRevs: [],
-      conflicts: 'new_branch'
-    });
-  });
-
-  var stemmed1b = {pos: 2, ids: ['1a', {}, []]};
-  it('Merging a tree with a stem.', function () {
-    merge([twoChildSibs], stemmed1b, 10).should.deep.equal({
-      tree: [twoChildSibs],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var twoChildPlusSibs2 = {pos: 1, ids: ['1', {}, [
-    ['1a', {}, []],
-    ['1b', {}, [
-      ['1bb', {}, []]
-    ]]
-  ]]};
-  var stemmed1bb = {pos: 3, ids: ['1bb', {}, []]};
-  it('Merging a stem at a deeper level.', function () {
-    merge([twoChildPlusSibs2], stemmed1bb, 10).should.deep.equal({
-      tree: [twoChildPlusSibs2],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var stemmedTwoChildSibs2 = [
-    {pos: 2, ids: ['1a', {}, []]},
-    {pos: 2, ids: ['1b', {}, [['1bb', {}, []]]]}
-  ];
-  it('Merging a stem at a deeper level against paths at deeper levels.',
-     function () {
-    merge(stemmedTwoChildSibs2, stemmed1bb, 10).should.deep.equal({
-      tree: stemmedTwoChildSibs2,
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var stemmed1aa = {pos: 3, ids: ['1aa', {}, []]};
-  it("Merging a single tree with a deeper stem.", function () {
-    merge([twoChild], stemmed1aa, 10).should.deep.equal({
-      tree: [twoChild],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var stemmed1a = {pos: 2, ids: ['1a', {}, [['1aa', {}, []]]]};
-  it('Merging a larger stem.', function () {
-    merge([twoChild], stemmed1a, 10).should.deep.equal({
-      tree: [twoChild],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('More merging.', function () {
-    merge([stemmed1a], stemmed1aa, 10).should.deep.equal({
-      tree: [stemmed1a],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  var oneChild = {pos: 1, ids: ['1', {}, [['1a', {}, []]]]};
-  it('Merging should create conflicts.', function () {
-    merge([oneChild], stemmed1aa, 10).should.deep.equal({
-      tree: [oneChild, stemmed1aa],
-      stemmedRevs: [],
-      conflicts: 'internal_node'
-    });
-  });
-
-  it('Merging should have no conflicts.', function () {
-    merge([oneChild, stemmed1aa], twoChild, 10).should.deep.equal({
-      tree: [twoChild],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-  var foo = {pos: 1, ids: ['foo', {}, [
-    ['foo2', {}, []],
-    ['foo3', {}, []]
-  ]]};
-  var bar = {pos: 1, ids: ['foo', {}, [
-    ['foo3', {}, [
-      ['foo4', {}, []]
-    ]]
-  ]]};
-  var fooBar = {pos: 1, ids: ['foo', {}, [
-    ['foo2', {}, []],
-    ['foo3', {}, [
-      ['foo4', {}, []]
-    ]]
-  ]]};
-
-  it('Merging trees with conflicts ought to behave.', function () {
-    merge([foo], bar, 10).should.deep.equal({
-      tree: [fooBar],
-      stemmedRevs: [],
-      conflicts: 'new_leaf'
-    });
-  });
-
-});
diff --git a/tests/unit/test.once.js b/tests/unit/test.once.js
deleted file mode 100644
index 2d8de62..0000000
--- a/tests/unit/test.once.js
+++ /dev/null
@@ -1,27 +0,0 @@
-
-'use strict';
-
-var should = require('chai').should();
-var once = require('../../lib/deps/once');
-var toPromise = require('../../lib/deps/toPromise');
-
-describe('test.once.js', function () {
-
-  it('Only call once ... once', function () {
-    var myFun = once(function () { });
-    myFun();
-    should.throw(myFun);
-  });
-
-  it('Once wrapped in a promise', function (done) {
-    var callback = function () {};
-    var myFun = toPromise(function (callback) {
-      setTimeout(function () {
-        callback();
-        should.throw(callback);
-        done();
-      });
-    });
-    myFun(callback);
-  });
-});
diff --git a/tests/unit/test.parse-uri.js b/tests/unit/test.parse-uri.js
deleted file mode 100644
index 8aeb09e..0000000
--- a/tests/unit/test.parse-uri.js
+++ /dev/null
@@ -1,35 +0,0 @@
-'use strict';
-
-require('chai').should();
-var parseUri = require('../../lib/deps/parseUri');
-
-describe('test.parse-uri.js', function () {
-
-  it('parses a basic uri', function () {
-    var parsed = parseUri('http://foobar.com');
-    parsed.host.should.equal('foobar.com');
-    parsed.protocol.should.equal('http');
-  });
-
-  it('parses a complex uri', function () {
-    var parsed = parseUri('http://user:pass@foo.com/baz/bar/index.html?hey=yo');
-    parsed.should.deep.equal({
-        anchor: '',
-      query: 'hey=yo',
-      file: 'index.html',
-      directory: '/baz/bar/',
-      path: '/baz/bar/index.html',
-      relative: '/baz/bar/index.html?hey=yo',
-      port: '',
-      host: 'foo.com',
-      password: 'pass',
-      user: 'user',
-      userInfo: 'user:pass',
-      authority: 'user:pass@foo.com',
-      protocol: 'http',
-      source: 'http://user:pass@foo.com/baz/bar/index.html?hey=yo',
-      queryKey: { hey: 'yo' } }
-    );
-  });
-
-});
\ No newline at end of file
diff --git a/tests/unit/test.utils.js b/tests/unit/test.utils.js
deleted file mode 100644
index 720f3f4..0000000
--- a/tests/unit/test.utils.js
+++ /dev/null
@@ -1,34 +0,0 @@
-
-'use strict';
-
-var should = require('chai').should();
-var normalizeDdocFunctionName =
-  require('../../lib/deps/docs/normalizeDdocFunctionName');
-var parseDdocFunctionName =
-  require('../../lib/deps/docs/parseDdocFunctionName');
-
-describe('test.utils.js', function () {
-  describe('the design doc function name normalizer', function () {
-    it('normalizes foo to foo/foo', function () {
-      normalizeDdocFunctionName('foo').should.be.eql('foo/foo');
-    });
-    it('normalizes foo/bar to foo/bar', function () {
-      normalizeDdocFunctionName('foo/bar').should.be.eql('foo/bar');
-    });
-    it('normalizes null to a non existing value', function () {
-      should.not.exist(normalizeDdocFunctionName(null));
-    });
-  });
-  describe('ddoc function name parser', function () {
-    it('parses foo/bar as [foo,bar]', function () {
-      parseDdocFunctionName('foo/bar').should.be.eql(['foo', 'bar']);
-    });
-    it('parses foo as [foo,foo]', function () {
-      parseDdocFunctionName('foo').should.be.eql(['foo', 'foo']);
-    });
-    it('throws if it can\'t parse the function name', function () {
-      should.not.exist(parseDdocFunctionName(null));
-      should.not.exist(parseDdocFunctionName('foo/bar/baz'));
-    });
-  });
-});