[SCM] groovebasin/master: drop not needed patches

andrewrk-guest at users.alioth.debian.org andrewrk-guest at users.alioth.debian.org
Sat Oct 4 00:38:54 UTC 2014


The following commit has been merged in the master branch:
commit 292b1f9aa11a7f4e63f135fcc982b1818a12860a
Author: Andrew Kelley <superjoe30 at gmail.com>
Date:   Fri Oct 3 20:38:07 2014 +0000

    drop not needed patches

diff --git a/debian/patches/bundle_node_modules.patch b/debian/patches/bundle_node_modules.patch
deleted file mode 100644
index cb0b066..0000000
--- a/debian/patches/bundle_node_modules.patch
+++ /dev/null
@@ -1,68734 +0,0 @@
-Description: bundle lastfm and archiver
- Still working on getting these properly packaged up. In the mean time they
- are bundled here. This is not acceptable Debian practice; this package is a
- work in progress.
-Author: Andrew Kelley <superjoe30 at gmail.com>
-Forwarded: no
-Last-Update: 2014-07-04
-
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/LICENSE-MIT
-@@ -0,0 +1,22 @@
-+Copyright (c) 2012-2014 Chris Talkington, 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.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/README.md
-@@ -0,0 +1,163 @@
-+# Archiver v0.10.1 [![Build Status](https://travis-ci.org/ctalkington/node-archiver.svg?branch=master)](https://travis-ci.org/ctalkington/node-archiver)
-+
-+a streaming interface for archive generation
-+
-+[![NPM](https://nodei.co/npm/archiver.png)](https://nodei.co/npm/archiver/)
-+
-+## Install
-+
-+```bash
-+npm install archiver --save
-+```
-+
-+You can also use `npm install https://github.com/ctalkington/node-archiver/archive/master.tar.gz` to test upcoming versions.
-+
-+## Archiver
-+
-+#### create(format, options)
-+
-+Creates an Archiver instance based on the format (zip, tar, etc) passed. Parameters can be passed directly to `Archiver` constructor for convenience.
-+
-+#### registerFormat(format, module)
-+
-+Registers an archive format. Format modules are essentially transform streams with a few required methods. They will be further documented once a formal spec is in place.
-+
-+### Instance Methods
-+
-+Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) methods.
-+
-+#### append(input, data)
-+
-+Appends an input source (text string, buffer, or stream) to the instance. When the instance has received, processed, and emitted the input, the `entry` event is fired.
-+
-+Replaced `#addFile` in v0.5.
-+
-+```js
-+archive.append('string', { name:'string.txt' });
-+archive.append(new Buffer('string'), { name:'buffer.txt' });
-+archive.append(fs.createReadStream('mydir/file.txt'), { name:'stream.txt' });
-+archive.append(null, { name:'dir/' });
-+```
-+
-+#### bulk(mappings)
-+
-+Appends multiple entries from passed array of src-dest mappings. A lazystream wrapper is used to prevent issues with open file limits.
-+
-+Globbing patterns are supported through use of the [file-utils](https://github.com/SBoudrias/file-utils) package. Please note that multiple src files to single dest file (ie concat) is not supported.
-+
-+The `data` property can be set (per src-dest mapping) to define data for matched entries.
-+
-+```js
-+archive.bulk([
-+  { src: ['mydir/**'], data: { date: new Date() } },
-+  { expand: true, cwd: 'mydir', src: ['**'], dest: 'newdir' }
-+]);
-+```
-+
-+For more detail on this feature, please see [BULK.md](https://github.com/ctalkington/node-archiver/blob/master/BULK.md).
-+
-+#### file(filepath, data)
-+
-+Appends a file given its filepath using a lazystream wrapper to prevent issues with open file limits. When the instance has received, processed, and emitted the file, the `entry` event is fired.
-+
-+```js
-+archive.file('mydir/file.txt', { name:'file.txt' });
-+```
-+
-+#### finalize()
-+
-+Finalizes the instance. You should listen for the `end`/`close`/`finish` of the destination stream to properly detect completion.
-+
-+#### pointer()
-+
-+Returns the current byte length emitted by archiver. Use this in your end callback to log generated size.
-+
-+## Events
-+
-+Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) events.
-+
-+#### entry
-+
-+Fired when the input has been received, processed, and emitted. Passes entry data as first argument.
-+
-+## Zip
-+
-+### Options
-+
-+#### comment `string`
-+
-+Sets the zip comment.
-+
-+#### forceUTC `boolean`
-+
-+If true, forces the entry date to UTC. Helps with testing across timezones.
-+
-+#### store `boolean`
-+
-+If true, all entry contents will be archived without compression by default.
-+
-+#### zlib `object`
-+
-+Passed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.
-+
-+### Entry Data
-+
-+#### name `string` `required`
-+
-+Sets the entry name including internal path.
-+
-+#### date `string|Date`
-+
-+Sets the entry date. This can be any valid date string or instance. Defaults to current time in locale.
-+
-+#### store `boolean`
-+
-+If true, entry contents will be archived without compression.
-+
-+#### comment `string`
-+
-+Sets the entry comment.
-+
-+#### mode `number`
-+
-+Sets the entry permissions. Defaults to octal 0755 (directory) or 0644 (file).
-+
-+## Tar
-+
-+### Options
-+
-+#### gzip `boolean`
-+
-+Compresses the tar archive using gzip, default is false.
-+
-+#### gzipOptions `object`
-+
-+Passed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.
-+
-+### Entry Data
-+
-+#### name `string` `required`
-+
-+Sets the entry name including internal path.
-+
-+#### date `string|Date`
-+
-+Sets the entry date. This can be any valid date string or instance. Defaults to current time in locale.
-+
-+#### mode `number`
-+
-+Sets the entry permissions. Defaults to octal 0755 (directory) or 0644 (file).
-+
-+## Libraries
-+
-+Archiver makes use of several libraries/modules to avoid duplication of efforts.
-+
-+- [zip-stream](https://npmjs.org/package/zip-stream)
-+- [tar-stream](https://npmjs.org/package/tar-stream)
-+
-+## Things of Interest
-+
-+- [Examples](https://github.com/ctalkington/node-archiver/blob/master/examples)
-+- [Changelog](https://github.com/ctalkington/node-archiver/releases)
-+- [Contributing](https://github.com/ctalkington/node-archiver/blob/master/CONTRIBUTING.md)
-+- [MIT License](https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT)
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/archiver.js
-@@ -0,0 +1,42 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var ArchiverCore = require('./modules/core');
-+var formatModules = {};
-+
-+var archiver = module.exports = function(format, options) {
-+  return archiver.create(format, options);
-+};
-+
-+archiver.create = function(format, options) {
-+  if (formatModules[format]) {
-+    var inst = new ArchiverCore(options);
-+    inst.setModule(new formatModules[format](options));
-+
-+    return inst;
-+  } else {
-+    throw new Error('unknown format: ' + format);
-+  }
-+};
-+
-+archiver.registerFormat = function(format, module) {
-+  if (module && typeof module === 'function' && typeof module.prototype.append === 'function') {
-+    formatModules[format] = module;
-+
-+    // backwards compat
-+    var compatName = 'create' + format.charAt(0).toUpperCase() + format.slice(1);
-+    archiver[compatName] = function(options) {
-+      return archiver.create(format, options);
-+    };
-+  } else {
-+    throw new Error('format module invalid: ' + format);
-+  }
-+};
-+
-+archiver.registerFormat('zip', require('./modules/zip'));
-+archiver.registerFormat('tar', require('./modules/tar'));
-+archiver.registerFormat('json', require('./modules/json'));
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/modules/core/index.js
-@@ -0,0 +1,263 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var Transform = require('readable-stream').Transform;
-+
-+var util = require('../../util');
-+var Queue = require('./queue');
-+
-+var Archiver = module.exports = function(options) {
-+  options = this.options = util.defaults(options, {
-+    highWaterMark: 1024 * 1024
-+  });
-+
-+  Transform.call(this, options);
-+
-+  this._moduleOutputPiped = false;
-+
-+  this._pointer = 0;
-+  this._files = [];
-+  this._module = false;
-+
-+  this._queue = new Queue();
-+  this._queue.on('error', this._onQueueError.bind(this));
-+  this._queue.on('entry', this._onQueueEntry.bind(this));
-+  this._queue.once('end', this._onQueueEnd.bind(this));
-+};
-+
-+inherits(Archiver, Transform);
-+
-+Archiver.prototype._moduleSupports = function(key) {
-+  this._module.supports = util.defaults(this._module.supports, {
-+    directory: false
-+  });
-+
-+  return this._module.supports[key];
-+};
-+
-+Archiver.prototype._normalizeFileData = function(data) {
-+  data = util.defaults(data, {
-+    type: 'file',
-+    name: null,
-+    date: null,
-+    mode: null,
-+    sourcePath: null
-+  });
-+
-+  var isDir = data.type === 'directory';
-+
-+  if (data.name) {
-+    data.name = util.sanitizePath(data.name);
-+
-+    if (data.name.slice(-1) === '/') {
-+      isDir = true;
-+      data.type = 'directory';
-+    } else if (isDir) {
-+      data.name += '/';
-+    }
-+  }
-+
-+  if (typeof data.mode === 'number') {
-+    data.mode &= 0777;
-+  } else {
-+    data.mode = isDir ? 0755 : 0644;
-+  }
-+
-+  data.date = util.dateify(data.date);
-+
-+  return data;
-+};
-+
-+Archiver.prototype._onModuleError = function(err) {
-+  this.emit('error', err);
-+};
-+
-+Archiver.prototype._onQueueEnd = function() {
-+  if (typeof this._module.finalize === 'function') {
-+    this._module.finalize();
-+  } else if (typeof this._module.end === 'function') {
-+    this._module.end();
-+  } else {
-+    this.emit('error', new Error('format module missing finalize and end method'));
-+  }
-+};
-+
-+Archiver.prototype._onQueueEntry = function(entry) {
-+  var nextCallback = function(err, file) {
-+    if (err) {
-+      this.emit('error', err);
-+      return;
-+    }
-+
-+    file = file || entry.data;
-+
-+    this.emit('entry', file);
-+    this._files.push(file);
-+    this._queue.next();
-+  }.bind(this);
-+
-+  this._module.append(entry.source, entry.data, nextCallback);
-+};
-+
-+Archiver.prototype._onQueueError = function(err) {
-+  this.emit('error', err);
-+};
-+
-+Archiver.prototype._pipeModuleOutput = function() {
-+  this._module.on('error', this._onModuleError.bind(this));
-+  this._module.pipe(this);
-+
-+  this._moduleOutputPiped = true;
-+};
-+
-+Archiver.prototype._processFile = function(source, data, callback) {
-+  this.emit('error', new Error('method not implemented'));
-+};
-+
-+Archiver.prototype._transform = function(chunk, encoding, callback) {
-+  if (chunk) {
-+    this._pointer += chunk.length;
-+  }
-+
-+  callback(null, chunk);
-+};
-+
-+Archiver.prototype.append = function(source, data) {
-+  data = this._normalizeFileData(data);
-+
-+  if (typeof data.name !== 'string' || data.name.length === 0) {
-+    this.emit('error', new Error('entry name must be a non-empty string value'));
-+    return this;
-+  }
-+
-+  if (data.type === 'directory' && !this._moduleSupports('directory')) {
-+    this.emit('error', new Error('entries of "' + data.type + '" type not currently supported by this module'));
-+    return;
-+  }
-+
-+  source = util.normalizeInputSource(source);
-+
-+  if (Buffer.isBuffer(source)) {
-+    data.sourceType = 'buffer';
-+  } else if (util.isStream(source)) {
-+    data.sourceType = 'stream';
-+  } else {
-+    this.emit('error', new Error('input source must be valid Stream or Buffer instance'));
-+    return this;
-+  }
-+
-+  this._queue.add({
-+    data: data,
-+    source: source
-+  });
-+
-+  return this;
-+};
-+
-+Archiver.prototype.bulk = function(mappings) {
-+  if (!Array.isArray(mappings)) {
-+    mappings = [mappings];
-+  }
-+
-+  var self = this;
-+  var files = util.normalizeFilesArray(mappings);
-+
-+  files.forEach(function(file){
-+    var isExpandedPair = file.orig.expand || false;
-+    var fileData = file.data || {};
-+
-+    file.src.forEach(function(filepath) {
-+      var data = util._.extend({}, fileData);
-+      var name = isExpandedPair ? file.dest : util.unixifyPath(file.dest || '', filepath);
-+
-+      if (name === '.') {
-+        return;
-+      }
-+
-+      var stat = util.stat(filepath);
-+      var source;
-+
-+      if (!stat) {
-+        return;
-+      }
-+
-+      data.name = util.sanitizePath(name);
-+      data.sourcePath = filepath;
-+
-+      if (stat.isFile()) {
-+        data.type = 'file';
-+        data.sourceType = 'stream';
-+
-+        source = util.lazyReadStream(filepath);
-+      } else if (stat.isDirectory() && self._moduleSupports('directory')) {
-+        data.name = util.trailingSlashIt(data.name);
-+        data.type = 'directory';
-+        data.sourcePath = util.trailingSlashIt(data.sourcePath);
-+        data.sourceType = 'buffer';
-+
-+        source = new Buffer(0);
-+      } else {
-+        return;
-+      }
-+
-+      self._queue.add({
-+        data: data,
-+        source: source
-+      });
-+    });
-+  });
-+
-+  return this;
-+};
-+
-+Archiver.prototype.file = function(filepath, data) {
-+  data = this._normalizeFileData(data);
-+
-+  if (typeof filepath !== 'string' || filepath.length === 0) {
-+    this.emit('error', new Error('filepath must be a non-empty string value'));
-+    return this;
-+  }
-+
-+  if (util.file.isFile(filepath)) {
-+    if (typeof data.name !== 'string' || data.name.length === 0) {
-+      data.name = util.sanitizePath(filepath);
-+    }
-+
-+    data.sourcePath = filepath;
-+    data.sourceType = 'stream';
-+
-+    this._queue.add({
-+      data: data,
-+      source: util.lazyReadStream(filepath)
-+    });
-+  } else {
-+    this.emit('error', new Error('invalid file: ' + filepath));
-+  }
-+
-+  return this;
-+};
-+
-+Archiver.prototype.finalize = function(callback) {
-+  this._queue.close();
-+
-+  return this;
-+};
-+
-+Archiver.prototype.setModule = function(module) {
-+  if (this._moduleOutputPiped) {
-+    this.emit('error', new Error('format module already set'));
-+    return;
-+  }
-+
-+  this._module = module;
-+  this._pipeModuleOutput();
-+};
-+
-+Archiver.prototype.pointer = function() {
-+  return this._pointer;
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/modules/core/queue.js
-@@ -0,0 +1,58 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var EventEmitter = require('events').EventEmitter;
-+
-+var Queue = module.exports = function() {
-+  EventEmitter.call(this);
-+
-+  this.closed = false;
-+  this.ended = false;
-+  this.waiting = false;
-+
-+  this.entries = [];
-+};
-+
-+inherits(Queue, EventEmitter);
-+
-+Queue.prototype.add = function(obj) {
-+  if (this.closed) {
-+    this.emit('error', new Error('can\'t add queue entry after close'));
-+  } else {
-+    this.entries.push(obj);
-+    this.run();
-+  }
-+};
-+
-+Queue.prototype.close = function() {
-+  this.closed = true;
-+  this.run();
-+};
-+
-+Queue.prototype.next = function() {
-+  this.waiting = false;
-+  this.run();
-+};
-+
-+Queue.prototype.run = function() {
-+  if (this.waiting || (this.closed && this.ended)) {
-+    return;
-+  }
-+
-+  if (this.entries.length === 0) {
-+    if (this.closed) {
-+      this.emit('end');
-+      this.ended = true;
-+    }
-+
-+    return;
-+  }
-+
-+  this.waiting = true;
-+  this.emit('entry', this.entries.shift());
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/modules/json/index.js
-@@ -0,0 +1,71 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var Transform = require('readable-stream').Transform;
-+
-+var crc32 = require('buffer-crc32');
-+var util = require('../../util');
-+
-+var Json = module.exports = function(options) {
-+  options = this.options = util.defaults(options, {});
-+
-+  Transform.call(this, options);
-+
-+  this.supports = {
-+    directory: true
-+  };
-+
-+  this.files = [];
-+};
-+
-+inherits(Json, Transform);
-+
-+Json.prototype._transform = function(chunk, encoding, callback) {
-+  callback(null, chunk);
-+};
-+
-+Json.prototype._writeStringified = function() {
-+  var fileString = JSON.stringify(this.files);
-+  this.write(fileString);
-+};
-+
-+Json.prototype.append = function(source, data, callback) {
-+  var self = this;
-+
-+  data.crc32 = 0;
-+
-+  function onend(err, sourceBuffer) {
-+    if (err) {
-+      callback(err);
-+      return;
-+    }
-+
-+    data.size = sourceBuffer.length || 0;
-+    data.crc32 = crc32.unsigned(sourceBuffer);
-+
-+    self.files.push(data);
-+
-+    callback(null, data);
-+  }
-+
-+  if (data.sourceType === 'buffer') {
-+    onend(null, source);
-+  } else if (data.sourceType === 'stream') {
-+    util.collectStream(source, onend);
-+  }
-+};
-+
-+Json.prototype.finalize = function(callback) {
-+  callback = callback || function() {};
-+
-+  this._writeStringified();
-+
-+  this.end();
-+
-+  callback();
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/modules/tar/index.js
-@@ -0,0 +1,76 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var zlib = require('zlib');
-+
-+var engine = require('tar-stream');
-+var util = require('../../util');
-+
-+var Tar = module.exports = function(options) {
-+  options = this.options = util.defaults(options, {
-+    gzip: false
-+  });
-+
-+  if (typeof options.gzipOptions !== 'object') {
-+    options.gzipOptions = {};
-+  }
-+
-+  this.supports = {
-+    directory: true
-+  };
-+
-+  this.engine = engine.pack(options);
-+  this.compressor = false;
-+
-+  if (options.gzip) {
-+    this.compressor = zlib.createGzip(options.gzipOptions);
-+    this.compressor.on('error', this._onCompressorError.bind(this));
-+  }
-+};
-+
-+Tar.prototype._onCompressorError = function(err) {
-+  this.engine.emit('error', err);
-+};
-+
-+Tar.prototype.append = function(source, data, callback) {
-+  var self = this;
-+
-+  data.mtime = data.date;
-+
-+  function append(err, sourceBuffer) {
-+    if (err) {
-+      callback(err);
-+      return;
-+    }
-+
-+    self.engine.entry(data, sourceBuffer, function(err) {
-+      callback(err, data);
-+    });
-+  }
-+
-+  if (data.sourceType === 'buffer') {
-+    append(null, source);
-+  } else if (data.sourceType === 'stream') {
-+    util.collectStream(source, append);
-+  }
-+};
-+
-+Tar.prototype.finalize = function() {
-+  this.engine.finalize();
-+};
-+
-+Tar.prototype.on = function() {
-+  return this.engine.on.apply(this.engine, arguments);
-+};
-+
-+Tar.prototype.pipe = function(destination, options) {
-+  if (this.compressor) {
-+    return this.engine.pipe.apply(this.engine, [this.compressor]).pipe(destination, options);
-+  } else {
-+    return this.engine.pipe.apply(this.engine, arguments);
-+  }
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/modules/zip/index.js
-@@ -0,0 +1,39 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var engine = require('zip-stream');
-+var util = require('../../util');
-+
-+var Zip = module.exports = function(options) {
-+  options = this.options = util.defaults(options, {
-+    comment: '',
-+    forceUTC: false,
-+    store: false
-+  });
-+
-+  this.supports = {
-+    directory: true
-+  };
-+
-+  this.engine = new engine(options);
-+};
-+
-+Zip.prototype.append = function(source, data, callback) {
-+  this.engine.entry(source, data, callback);
-+};
-+
-+Zip.prototype.finalize = function() {
-+  this.engine.finalize();
-+};
-+
-+Zip.prototype.on = function() {
-+  return this.engine.on.apply(this.engine, arguments);
-+};
-+
-+Zip.prototype.pipe = function() {
-+  return this.engine.pipe.apply(this.engine, arguments);
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/lib/util/index.js
-@@ -0,0 +1,193 @@
-+/**
-+ * node-archiver
-+ *
-+ * Copyright (c) 2012-2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT
-+ */
-+var fs = require('fs');
-+var path = require('path');
-+
-+var Stream = require('stream').Stream;
-+var PassThrough = require('readable-stream').PassThrough;
-+
-+var util = module.exports = {};
-+
-+util._ = require('lodash');
-+util.lazystream = require('lazystream');
-+util.file = require('file-utils');
-+
-+util.collectStream = function(source, callback) {
-+  var collection = [];
-+  var size = 0;
-+
-+  source.on('error', callback);
-+
-+  source.on('data', function(chunk) {
-+    collection.push(chunk);
-+    size += chunk.length;
-+  });
-+
-+  source.on('end', function() {
-+    var buf = new Buffer(size, 'utf8');
-+    var offset = 0;
-+
-+    collection.forEach(function(data) {
-+      data.copy(buf, offset);
-+      offset += data.length;
-+    });
-+
-+    callback(null, buf);
-+  });
-+};
-+
-+util.dateify = function(dateish) {
-+  dateish = dateish || new Date();
-+
-+  if (dateish instanceof Date) {
-+    dateish = dateish;
-+  } else if (typeof dateish === 'string') {
-+    dateish = new Date(dateish);
-+  } else {
-+    dateish = new Date();
-+  }
-+
-+  return dateish;
-+};
-+
-+// this is slightly different from lodash version
-+util.defaults = function(object, source, guard) {
-+  var args = arguments;
-+  args[0] = args[0] || {};
-+
-+  return util._.defaults.apply(util._, args);
-+};
-+
-+util.isStream = function(source) {
-+  return source instanceof Stream;
-+};
-+
-+util.lazyReadStream = function(filepath) {
-+  return new util.lazystream.Readable(function() {
-+    return fs.createReadStream(filepath);
-+  });
-+};
-+
-+// reusing bits of grunt's multi-task source normalization
-+util.normalizeFilesArray = function(data) {
-+  var files = [];
-+
-+  data.forEach(function(obj) {
-+    var prop;
-+    if ('src' in obj || 'dest' in obj) {
-+      files.push(obj);
-+    }
-+  });
-+
-+  if (files.length === 0) {
-+    return [];
-+  }
-+
-+  files = util._(files).chain().forEach(function(obj) {
-+    if (!('src' in obj) || !obj.src) { return; }
-+    // Normalize .src properties to flattened array.
-+    if (Array.isArray(obj.src)) {
-+      obj.src = util._.flatten(obj.src);
-+    } else {
-+      obj.src = [obj.src];
-+    }
-+  }).map(function(obj) {
-+    // Build options object, removing unwanted properties.
-+    var expandOptions = util._.extend({}, obj);
-+    delete expandOptions.src;
-+    delete expandOptions.dest;
-+
-+    // Expand file mappings.
-+    if (obj.expand) {
-+      return util.file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) {
-+        // Copy obj properties to result.
-+        var result = util._.extend({}, obj);
-+        // Make a clone of the orig obj available.
-+        result.orig = util._.extend({}, obj);
-+        // Set .src and .dest, processing both as templates.
-+        result.src = mapObj.src;
-+        result.dest = mapObj.dest;
-+        // Remove unwanted properties.
-+        ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) {
-+          delete result[prop];
-+        });
-+        return result;
-+      });
-+    }
-+
-+    // Copy obj properties to result, adding an .orig property.
-+    var result = util._.extend({}, obj);
-+    // Make a clone of the orig obj available.
-+    result.orig = util._.extend({}, obj);
-+
-+    if ('src' in result) {
-+      // Expose an expand-on-demand getter method as .src.
-+      Object.defineProperty(result, 'src', {
-+        enumerable: true,
-+        get: function fn() {
-+          var src;
-+          if (!('result' in fn)) {
-+            src = obj.src;
-+            // If src is an array, flatten it. Otherwise, make it into an array.
-+            src = Array.isArray(src) ? util._.flatten(src) : [src];
-+            // Expand src files, memoizing result.
-+            fn.result = util.file.expand(expandOptions, src);
-+          }
-+          return fn.result;
-+        }
-+      });
-+    }
-+
-+    if ('dest' in result) {
-+      result.dest = obj.dest;
-+    }
-+
-+    return result;
-+  }).flatten().value();
-+
-+  return files;
-+};
-+
-+util.normalizeInputSource = function(source) {
-+  if (source === null) {
-+    return new Buffer(0);
-+  } else if (typeof source === 'string') {
-+    return new Buffer(source);
-+  } else if (util.isStream(source) && !source._readableState) {
-+    var normalized = new PassThrough();
-+    source.pipe(normalized);
-+
-+    return normalized;
-+  }
-+
-+  return source;
-+};
-+
-+util.sanitizePath = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return filepath.replace(/\\/g, '/').replace(/:/g, '').replace(/^\/+/, '');
-+};
-+
-+util.stat = function() {
-+  var filepath = path.join.apply(path, arguments);
-+
-+  if (!util.file.exists(filepath)) {
-+    return false;
-+  }
-+
-+  return fs.statSync(filepath);
-+};
-+
-+util.trailingSlashIt = function(str) {
-+  return str.slice(-1) !== '/' ? str + '/' : str;
-+};
-+
-+util.unixifyPath = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return filepath.replace(/\\/g, '/');
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/.npmignore
-@@ -0,0 +1 @@
-+node_modules
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/.travis.yml
-@@ -0,0 +1,8 @@
-+language: node_js
-+node_js:
-+  - 0.6
-+  - 0.8
-+notifications:
-+  email:
-+    recipients:
-+      - brianloveswords at gmail.com
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/LICENSE
-@@ -0,0 +1,17 @@
-+Copyright (c) 2013 Brian J. Brennan
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/README.md
-@@ -0,0 +1,47 @@
-+# buffer-crc32
-+
-+[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)
-+
-+crc32 that works with binary data and fancy character sets, outputs
-+buffer, signed or unsigned data and has tests.
-+
-+Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix
-+
-+# install
-+```
-+npm install buffer-crc32
-+```
-+
-+# example
-+```js
-+var crc32 = require('buffer-crc32');
-+// works with buffers
-+var buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])
-+crc32(buf) // -> <Buffer 94 5a ab 4a>
-+
-+// has convenience methods for getting signed or unsigned ints
-+crc32.signed(buf) // -> -1805997238
-+crc32.unsigned(buf) // -> 2488970058
-+
-+// will cast to buffer if given a string, so you can
-+// directly use foreign characters safely
-+crc32('自動販売機') // -> <Buffer cb 03 1a c5>
-+
-+// and works in append mode too
-+var partialCrc = crc32('hey');
-+var partialCrc = crc32(' ', partialCrc);
-+var partialCrc = crc32('sup', partialCrc);
-+var partialCrc = crc32(' ', partialCrc);
-+var finalCrc = crc32('bros', partialCrc); // -> <Buffer 47 fa 55 70>
-+```
-+
-+# tests
-+This was tested against the output of zlib's crc32 method. You can run
-+the tests with`npm test` (requires tap)
-+
-+# see also
-+https://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also
-+supports buffer inputs and return unsigned ints (thanks @tjholowaychuk).
-+
-+# license
-+MIT/X11
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/index.js
-@@ -0,0 +1,91 @@
-+var Buffer = require('buffer').Buffer;
-+
-+var CRC_TABLE = [
-+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
-+  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
-+  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
-+  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-+  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
-+  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
-+  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
-+  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-+  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
-+  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
-+  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
-+  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
-+  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
-+  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
-+  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-+  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
-+  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
-+  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
-+  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-+  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
-+  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
-+  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
-+  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
-+  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
-+  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
-+  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-+  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
-+  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
-+  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
-+  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-+  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
-+  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
-+  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
-+  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
-+  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
-+  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
-+  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-+  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
-+  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
-+  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
-+  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-+  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
-+  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
-+  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
-+  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
-+  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
-+  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
-+  0x2d02ef8d
-+];
-+
-+if (typeof Int32Array !== 'undefined')
-+  CRC_TABLE = new Int32Array(CRC_TABLE);
-+
-+function bufferizeInt(num) {
-+  var tmp = Buffer(4);
-+  tmp.writeInt32BE(num, 0);
-+  return tmp;
-+}
-+
-+function _crc32(buf, previous) {
-+  if (!Buffer.isBuffer(buf)) {
-+    buf = Buffer(buf);
-+  }
-+  if (Buffer.isBuffer(previous)) {
-+    previous = previous.readUInt32BE(0);
-+  }
-+  var crc = ~~previous ^ -1;
-+  for (var n = 0; n < buf.length; n++) {
-+    crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);
-+  }
-+  return (crc ^ -1);
-+}
-+
-+function crc32() {
-+  return bufferizeInt(_crc32.apply(null, arguments));
-+}
-+crc32.signed = function () {
-+  return _crc32.apply(null, arguments);
-+};
-+crc32.unsigned = function () {
-+  return _crc32.apply(null, arguments) >>> 0;
-+};
-+
-+module.exports = crc32;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/package.json
-@@ -0,0 +1,39 @@
-+{
-+  "author": {
-+    "name": "Brian J. Brennan",
-+    "email": "brianloveswords at gmail.com",
-+    "url": "http://bjb.io"
-+  },
-+  "name": "buffer-crc32",
-+  "description": "A pure javascript CRC32 algorithm that plays nice with binary data",
-+  "version": "0.2.3",
-+  "contributors": [
-+    {
-+      "name": "Vladimir Kuznetsov"
-+    }
-+  ],
-+  "homepage": "https://github.com/brianloveswords/buffer-crc32",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/brianloveswords/buffer-crc32.git"
-+  },
-+  "main": "index.js",
-+  "scripts": {
-+    "test": "./node_modules/.bin/tap tests/*.test.js"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "~0.2.5"
-+  },
-+  "optionalDependencies": {},
-+  "engines": {
-+    "node": "*"
-+  },
-+  "readme": "# buffer-crc32\n\n[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)\n\ncrc32 that works with binary data and fancy character sets, outputs\nbuffer, signed or unsigned data and has tests.\n\nDerived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix\n\n# install\n```\nnpm install buffer-crc32\n```\n\n# example\n```js\nvar crc32 = require('buffer-crc32');\n// works with buffers\nvar buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])\ncrc32(buf) // -> <Buffer 94 5a ab 4a>\n\n// has convenience methods for getting signed or unsigned ints\ncrc32.signed(buf) // -> -1805997238\ncrc32.unsigned(buf) // -> 2488970058\n\n// will cast to buffer if given a string, so you can\n// directly use foreign characters safely\ncrc32('自動販売機') // -> <Buffer cb 03 1a c5>\n\n// and works in append mode too\nvar partialCrc = crc32('hey');\nvar partialCrc = crc32(' ', partialCrc);\nvar partialCrc = crc32('sup', partialCrc);\nvar partialCrc = crc32(' ', partialCrc);\nvar finalCrc = crc32('bros', partialCrc); // -> <Buffer 47 fa 55 70>\n```\n\n# tests\nThis was tested against the output of zlib's crc32 method. You can run\nthe tests with`npm test` (requires tap)\n\n# see also\nhttps://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also\nsupports buffer inputs and return unsigned ints (thanks @tjholowaychuk).\n\n# license\nMIT/X11\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/brianloveswords/buffer-crc32/issues"
-+  },
-+  "_id": "buffer-crc32 at 0.2.3",
-+  "_from": "buffer-crc32@~0.2.1"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/buffer-crc32/tests/crc.test.js
-@@ -0,0 +1,89 @@
-+var crc32 = require('..');
-+var test = require('tap').test;
-+
-+test('simple crc32 is no problem', function (t) {
-+  var input = Buffer('hey sup bros');
-+  var expected = Buffer([0x47, 0xfa, 0x55, 0x70]);
-+  t.same(crc32(input), expected);
-+  t.end();
-+});
-+
-+test('another simple one', function (t) {
-+  var input = Buffer('IEND');
-+  var expected = Buffer([0xae, 0x42, 0x60, 0x82]);
-+  t.same(crc32(input), expected);
-+  t.end();
-+});
-+
-+test('slightly more complex', function (t) {
-+  var input = Buffer([0x00, 0x00, 0x00]);
-+  var expected = Buffer([0xff, 0x41, 0xd9, 0x12]);
-+  t.same(crc32(input), expected);
-+  t.end();
-+});
-+
-+test('complex crc32 gets calculated like a champ', function (t) {
-+  var input = Buffer('शीर्षक');
-+  var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]);
-+  t.same(crc32(input), expected);
-+  t.end();
-+});
-+
-+test('casts to buffer if necessary', function (t) {
-+  var input = 'शीर्षक';
-+  var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]);
-+  t.same(crc32(input), expected);
-+  t.end();
-+});
-+
-+test('can do signed', function (t) {
-+  var input = 'ham sandwich';
-+  var expected = -1891873021;
-+  t.same(crc32.signed(input), expected);
-+  t.end();
-+});
-+
-+test('can do unsigned', function (t) {
-+  var input = 'bear sandwich';
-+  var expected = 3711466352;
-+  t.same(crc32.unsigned(input), expected);
-+  t.end();
-+});
-+
-+
-+test('simple crc32 in append mode', function (t) {
-+  var input = [Buffer('hey'), Buffer(' '), Buffer('sup'), Buffer(' '), Buffer('bros')];
-+  var expected = Buffer([0x47, 0xfa, 0x55, 0x70]);
-+  for (var crc = 0, i = 0; i < input.length; i++) {
-+    crc = crc32(input[i], crc);
-+  }
-+  t.same(crc, expected);
-+  t.end();
-+});
-+
-+
-+test('can do signed in append mode', function (t) {
-+  var input1 = 'ham';
-+  var input2 = ' ';
-+  var input3 = 'sandwich';
-+  var expected = -1891873021;
-+
-+  var crc = crc32.signed(input1);
-+  crc = crc32.signed(input2, crc);
-+  crc = crc32.signed(input3, crc);
-+
-+  t.same(crc, expected);
-+  t.end();
-+});
-+
-+test('can do unsigned in append mode', function (t) {
-+  var input1 = 'bear san';
-+  var input2 = 'dwich';
-+  var expected = 3711466352;
-+
-+  var crc = crc32.unsigned(input1);
-+  crc = crc32.unsigned(input2, crc);
-+  t.same(crc, expected);
-+  t.end();
-+});
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/.editorconfig
-@@ -0,0 +1,12 @@
-+# http://editorconfig.org
-+root = true
-+
-+[*]
-+indent_style = space
-+indent_size = 2
-+charset = utf-8
-+trim_trailing_whitespace = true
-+insert_final_newline = true
-+
-+[*.md]
-+trim_trailing_whitespace = false
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/.jshintrc
-@@ -0,0 +1,43 @@
-+{
-+  "node"      : true,
-+  "bitwise"   : true,
-+  "boss"      : true,
-+  "browser"   : true,
-+  "camelcase" : true,
-+  "debug"     : true,
-+  "eqeqeq"    : true,
-+  "eqnull"    : true,
-+  "expr"      : true,
-+  "immed"     : true,
-+  "iterator"  : true,
-+  "lastsemic" : true,
-+  "laxbreak"  : true,
-+  "laxcomma"  : true,
-+  "loopfunc"  : true,
-+  "maxlen"    : 120,
-+  "multistr"  : true,
-+  "newcap"    : true,
-+  "noarg"     : true,
-+  "onecase"   : true,
-+  "onevar"    : false,
-+  "plusplus"  : false,
-+  "proto"     : true,
-+  "quotmark"  : "single",
-+  "regexdash" : true,
-+  "regexp"    : true,
-+  "scripturl" : true,
-+  "shadow"    : true,
-+  "smarttabs" : true,
-+  "strict"    : false,
-+  "sub"       : true,
-+  "supernew"  : true,
-+  "undef"     : true,
-+  "validthis" : true,
-+  "withstmt"  : true,
-+  "globals": {
-+    "describe": true,
-+    "it": true,
-+    "beforeEach": true,
-+    "afterEach": true
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/.npmignore
-@@ -0,0 +1,3 @@
-+node_modules
-+.npm-debug.log
-+tmp
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/.travis.yml
-@@ -0,0 +1,11 @@
-+language: node_js
-+node_js:
-+  - "0.10"
-+  - "0.11"
-+
-+before_install:
-+  - npm install -gq grunt-cli
-+
-+matrix:
-+  allow_failures:
-+    - node_js: "0.11"
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/Gruntfile.js
-@@ -0,0 +1,56 @@
-+/*
-+ * grunt
-+ * http://gruntjs.com/
-+ *
-+ * Copyright (c) 2013 "Cowboy" Ben Alman
-+ * Licensed under the MIT license.
-+ * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
-+ */
-+
-+'use strict';
-+
-+module.exports = function(grunt) {
-+
-+  // Project configuration.
-+  grunt.initConfig({
-+    nodeunit: {
-+      all: [ 'tests/**.js', '!tests/fixtures/**', '!tests/helpers/**' ]
-+    },
-+    jshint: {
-+      lib: ['lib/**/*.js'],
-+      options: {
-+        curly: true,
-+        eqeqeq: true,
-+        immed: true,
-+        latedef: 'nofunc',
-+        newcap: true,
-+        noarg: true,
-+        sub: true,
-+        undef: true,
-+        unused: true,
-+        boss: true,
-+        eqnull: true,
-+        node: true,
-+      }
-+    },
-+    watch: {
-+      tests: {
-+        files: [ '**/*' ],
-+        tasks: [ 'test' ]
-+      }
-+    }
-+  });
-+
-+  // These plugins provide necessary tasks.
-+  grunt.loadNpmTasks('grunt-contrib-jshint');
-+  grunt.loadNpmTasks('grunt-contrib-nodeunit');
-+  grunt.loadNpmTasks('grunt-contrib-watch');
-+  grunt.loadNpmTasks('grunt-release');
-+
-+  // "npm test" runs these tasks
-+  grunt.registerTask('test', ['jshint', 'nodeunit']);
-+
-+  // Default task.
-+  grunt.registerTask('default', ['test']);
-+
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/LICENSE
-@@ -0,0 +1,20 @@
-+The MIT License (MIT)
-+
-+Copyright (c) 2013 Simon Boudrias
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/README.md
-@@ -0,0 +1,149 @@
-+file-utils [![](https://travis-ci.org/SBoudrias/file-utils.png)](https://travis-ci.org/SBoudrias/file-utils)
-+==========
-+
-+This is a Grunt.file forks to allow the creation of scoped file utilities and the ability to add write filters.
-+
-+Same as Grunt.file, this is a set of _synchronous_ utility. As so, it should **never** be used on a Node.js server. This is meant for users/command line utilities.
-+
-+
-+File API
-+=========
-+
-+Upcoming. Meanwhile, check [Grunt.file documentation](http://gruntjs.com/api/grunt.file) as the same methods are available.
-+
-+#### Setting options - `file.option( name, [ value ])`
-+
-+```
-+// Set option
-+file.option('write', false);
-+
-+// Get option
-+file.option('write');
-+```
-+
-+**Available Options**
-+- `write` (Boolean): If write is set to `false`, then no file will be written or deleted. Useful for test run without side effets.
-+- `logger` (Logger object): Used internally to log information to the console. **API still work in progress**
-+- `encoding` (String): Defaults `utf8`. Set the default encoding used for reading/writing. Note most methods allow you to overwridde it for a single run.
-+- `force` (Boolean): `force: true` Force the deletion of folders and file outside the utility scope (or CWD if no scope).
-+
-+
-+ENV scope and filters
-+=========
-+
-+### Creating an Env - file#createEnv([ options ]);
-+
-+```javascript
-+var file = require('file-utils');
-+
-+var env = file.createEnv({
-+  base: 'my/scoped/path',
-+  dest: 'destination/path' // optionnal
-+});
-+
-+// Alternatively, they can be functions returning a path:
-+
-+var env = file.createEnv({
-+  base: function() {
-+    return 'my/scoped/path';
-+  },
-+  dest: function() { // optionnal
-+    return 'destination/path';
-+  }
-+});
-+```
-+
-+The `base` directory will prefix any paths passed to `mkdir`, `recurse`, `read`, `readJSON`, `write`, `delete`, `exists`, `isLink`, `isDir` and `isFile` methods.
-+
-+The `dest` directory will prefix the `destination` path provided in the `copy` method. Note that this option is optionnal and will default to the current working directory.
-+
-+If [options (`logger`, `write`, etc)](#setting-options---fileoption-name--value-) are not passed, each `Env` instance inherit those of its parent.
-+
-+Write Filters
-+---------
-+
-+Write filters are applied on `env.write` and `env.copy`.
-+
-+They're used to modifiy the content or the filepath of a file.
-+
-+#### Add a write filter - `env.registerWriteFilter( name, filter )`
-+
-+**options**
-+- `name` (String): The name under which registering the filter
-+- `filter` (Function): The filter function
-+
-+The filter function take a file object as parameter. This file object is a hash containing a `path` and a `contents` property. You can modify these two property as you like and returning the modified object.
-+
-+```javascript
-+env.registerWriteFilter( 'coffee', function( file ) {
-+  if (!path.extname(file) !== '.js') return file;
-+
-+  file.path = file.path.replace(/(\.js)$/, '.coffee');
-+  file.content = convertJsToCoffee( file.contents );
-+
-+  return file;
-+});
-+```
-+
-+#### Remove a write filter - `env.removeWriteFilter( name )`
-+
-+```javascript
-+env.removeWriteFilter('coffee');
-+```
-+
-+#### Async filter
-+
-+The filter can also be asynchronous. This is done by calling `this.async()` and passing the return value to the callback provided.
-+
-+```javascript
-+env.registerWriteFilter( 'coffee', function( file ) {
-+  var done = this.async();
-+
-+  // some process
-+  setTimeout(function() {
-+    done({ path: '/newfile', contents: 'filtered content' });
-+  }, 1000);
-+});
-+```
-+
-+**Caution:** Using an asynchronous filter will change the way write and copy method are called to. This will make both of those method to run asynchronously too.
-+
-+Validation Filters
-+----------
-+
-+Validation filters are applied on `env.write` and `env.copy`.
-+
-+They're used to allow or disallow the write action.
-+
-+#### Add a validation filter - `env.registerValidationFilter( name, filter )`
-+
-+**options**
-+- `name` (String): The name under which registering the filter
-+- `filter` (Function): The filter function
-+
-+The filter function take a file object as parameter. This file object is a hash containing a `path` (String) and a `contents` (String if text file, Buffer otherwise) property.
-+
-+Return `true` to allow the file to be written. Return `false` or an error message `String` to disallow the write action.
-+
-+```javascript
-+env.registerValidationFilter( 'checkConflicts', function( toOutput ) {
-+  if ( file.exists(toOutput.path) ) {
-+    return 'file is already present';
-+  }
-+  return true;
-+});
-+```
-+
-+Just like the write filters, [this filter can be asynchronous](#async-filter).
-+
-+#### Remove a validation filter - `env.removeValidationFilter( name )`
-+
-+```javascript
-+env.removeValidationFilter('checkConflicts');
-+```
-+
-+
-+Todos
-+=========
-+
-+- Real Logging system
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/file-utils.sublime-project
-@@ -0,0 +1,9 @@
-+{
-+	"folders":
-+	[
-+		{
-+			"follow_symlinks": true,
-+			"path": "."
-+		}
-+	]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/file-utils.sublime-workspace
-@@ -0,0 +1,778 @@
-+{
-+	"auto_complete":
-+	{
-+		"selected_items":
-+		[
-+			[
-+				"create",
-+				"createDummyGenerator"
-+			],
-+			[
-+				"append",
-+				"appendDefaultPaths  (function)"
-+			],
-+			[
-+				"forceSav",
-+				"forceSaveSpy"
-+			],
-+			[
-+				"Phantom",
-+				"PhantomjsRunner"
-+			],
-+			[
-+				"partner",
-+				"partners-zone"
-+			],
-+			[
-+				"get",
-+				"getNextCampaign  (function)"
-+			],
-+			[
-+				"Campaign",
-+				"Campaign_model"
-+			]
-+		]
-+	},
-+	"buffers":
-+	[
-+	],
-+	"build_system": "",
-+	"command_palette":
-+	{
-+		"height": 58.0,
-+		"selected_items":
-+		[
-+			[
-+				"json",
-+				"Set Syntax: JSON"
-+			],
-+			[
-+				"facade",
-+				"Laravel Facade: DB"
-+			],
-+			[
-+				"pack ins",
-+				"Package Control: Install Package"
-+			],
-+			[
-+				"lis pack",
-+				"Package Control: List Packages"
-+			],
-+			[
-+				"ss js",
-+				"Set Syntax: JavaScript"
-+			],
-+			[
-+				"ss rub",
-+				"Set Syntax: Ruby"
-+			],
-+			[
-+				"ss rubn",
-+				"Set Syntax: Ruby on Rails"
-+			],
-+			[
-+				"ss html",
-+				"Set Syntax: HTML"
-+			],
-+			[
-+				"html",
-+				"HTML: Encode Special Characters"
-+			],
-+			[
-+				"ss asp",
-+				"Set Syntax: ASP"
-+			]
-+		],
-+		"width": 528.0
-+	},
-+	"console":
-+	{
-+		"height": 125.0,
-+		"history":
-+		[
-+			"import urllib.request,os; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); open(os.path.join(ipp, pf), 'wb').write(urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ','%20')).read())"
-+		]
-+	},
-+	"distraction_free":
-+	{
-+		"menu_visible": true,
-+		"show_minimap": false,
-+		"show_open_files": false,
-+		"show_tabs": false,
-+		"side_bar_visible": false,
-+		"status_bar_visible": false
-+	},
-+	"file_history":
-+	[
-+		"/E/github/generator/lib/env/index.js",
-+		"/E/github/generator/lib/env/resolver.js",
-+		"/E/github/generator/test/env.js",
-+		"/E/github/generator/lib/test/assert.js",
-+		"/E/github/generator/lib/base.js",
-+		"/E/github/generator/test/base.js",
-+		"/E/github/generator/test/fallbacks.js",
-+		"/E/test/temp/app/js/component/pagination.js",
-+		"/E/github/generator/readme.md",
-+		"/E/github/generator/lib/actions/invoke.js",
-+		"/E/github/generator/package.json",
-+		"/E/github/generator/test/mocha.opts",
-+		"/E/github/generator/benchmark/module.js",
-+		"/E/github/generator/main.js",
-+		"/E/github/generator/lib/test/helpers.js",
-+		"/E/github/generator/test/helpers.js",
-+		"/E/github/generator/coverage/lcov-report/generator/lib/env/adapter.js.html",
-+		"/E/github/generator/coverage/lcov-report/generator/lib/env/resolver.js.html",
-+		"/E/github/generator/.git/config",
-+		"/E/github/generator/.git/HEAD",
-+		"/E/github/generator/test/env.resolver.js",
-+		"/E/github/generator/lib/env/run-loop.js",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 3/Packages/SideBarEnhancements/CHANGELOG",
-+		"/E/github/generator/lib/actions/fetch.js",
-+		"/E/github/generator/lib/util/log.js",
-+		"/E/github/generator/test/fetch.js",
-+		"/E/github/generator/lib/actions/install.js",
-+		"/E/github/generator/test/conflicter.js",
-+		"/E/github/generator/test/storage.js",
-+		"/E/github/generator/test/legacy.js",
-+		"/E/github/generator/.jscs.json",
-+		"/E/github/generator/test/actions.js",
-+		"/E/github/generator/test/adapter.js",
-+		"/E/github/generator/test/fixtures/template-setting.xml",
-+		"/E/github/generator/test/fixtures/template-tags.jst",
-+		"/E/github/generator/lib/util/engines.js",
-+		"/E/github/generator/doc/engines.md",
-+		"/E/github/generator/benchmark/env.js",
-+		"/E/github/generator/.git/info/exclude",
-+		"/E/github/generator/.git/refs/remotes/jdespatis/file-utils-for-remote",
-+		"/E/github/generator/.git/refs/remotes/mine/255-unit-test",
-+		"/E/github/generator/doc/user.md",
-+		"/E/github/generator/lib/env/store.js",
-+		"/E/github/generator/lib/util/storage.js",
-+		"/E/github/generator/lib/actions/spawn_command.js",
-+		"/E/github/generator/lib/actions/actions.js",
-+		"/E/github/generator/lib/actions/user.js",
-+		"/E/github/generator/lib/actions/prompt.js",
-+		"/E/github/generator/test/generators.js",
-+		"/E/github/generator/test/fixtures/custom-generator-extend/support/index.js",
-+		"/E/github/generator/lib/actions/wiring.js",
-+		"/E/github/generator/lib/actions/file.js",
-+		"/E/github/generator/lib/actions/string.js",
-+		"/E/github/generator/lib/env/adapter.js",
-+		"/E/github/generator/lib/util/common.js",
-+		"/E/github/generator/jsdoc.json",
-+		"/E/github/generator/.gitmodules",
-+		"/E/github/generator/doc.js",
-+		"/E/github/generator/lib/named-base.js",
-+		"/E/github/generator/test/user.js",
-+		"/E/github/generator/doc/fetch.md",
-+		"/E/github/generator/doc/common.md",
-+		"/E/github/generator/test/.jshintrc",
-+		"/E/github/generator/gulpfile.js",
-+		"/E/github/generator/.travis.yml",
-+		"/E/github/generator/doc/base.md",
-+		"/E/github/generator/test/fixtures/mocha-generator/main.js",
-+		"/E/github/generator/lib/util/conflicter.js",
-+		"/C/Program Files/nodejs/node_modules/npm/npmrc",
-+		"/C/Users/Simon.Boudrias/.npmrc",
-+		"/C/Program Files/nodejs/npm.cmd",
-+		"/C/Program Files/nodejs/npm",
-+		"/C/Program Files/nodejs/node_modules/npm/bin/npm-cli.js",
-+		"/E/github/generator/test/remote.js",
-+		"/E/github/generator/doc/spawn_command.md",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/npm/yo.cmd",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/npm/yo",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/User/Package Control.sublime-settings",
-+		"/E/github/generator/doc/storage.md",
-+		"/E/github/generator/test/namespaces.js",
-+		"/E/github/generator/test/wiring.js",
-+		"/E/github/generator/test/fixtures/custom-generator-extend/index.js",
-+		"/E/github/generator/test/fixtures/file-conflict.txt",
-+		"/E/github/generator/test/fixtures/lookup-project/package.json",
-+		"/E/github/generator/test/fixtures/lookup-projet/package.json",
-+		"/E/github/generator/test/env/main.js",
-+		"/E/github/generator/test/env/store.js",
-+		"/E/github/generator/test/fixtures/dummy-package",
-+		"/E/github/generator/test/fixtures/dummy-package/index.js",
-+		"/E/github/generator/test/fixtures/dummy-package/package.json",
-+		"/E/github/generator/lib/env.js",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby/collect-{-e-..-}-(col).sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/JavaScript/function-(fun).sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby/do-obj-..-end-(doo).sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby/def-end.sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby on Rails snippets/def-post-request.sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby on Rails snippets/def-create-resource.sublime-snippet",
-+		"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby on Rails snippets/def-get-request.sublime-snippet",
-+		"/E/github/generator/test/fixtures/help.txt",
-+		"/E/github/generator/test/fixtures/generator-dummy/main.js",
-+		"/E/test/generator-bbb/.jshintrc",
-+		"/E/test/generator-bbb/app/templates/_component.json",
-+		"/E/test/generator-bbb/.git/config",
-+		"/E/test/generator/package.json",
-+		"/E/test/bb-gen/package.json",
-+		"/E/github/grunt-mocha/example/test/js/mocha.js",
-+		"/E/github/grunt-mocha/phantomjs/main.js",
-+		"/E/github/grunt-mocha/Gruntfile.js",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/home/widgets/lexique/index.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/home/widgets/glossary/index.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/models/widget_model.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/home/home.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/models/experience_model.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/controllers/experience.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/experience/experience.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/layouts/_header.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/models/partner_model.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/public/css/style.css",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/partner/partner.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/views/layouts/main.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/controllers/home.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/controllers/base.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/models/campaign_model.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/models/season_model.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/language/fr/content_lang.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/language/en/content_lang.php",
-+		"/E/Projets/MTO/QuebecOriginal/quebecoriginal.com/branches/summer/application/errors/error_404.php",
-+		"/E/test/generator/app/index.js"
-+	],
-+	"find":
-+	{
-+		"height": 38.0
-+	},
-+	"find_in_files":
-+	{
-+		"height": 102.0,
-+		"where_history":
-+		[
-+			"",
-+			"test/**",
-+			"",
-+			"test/",
-+			"",
-+			"test/",
-+			""
-+		]
-+	},
-+	"find_state":
-+	{
-+		"case_sensitive": false,
-+		"find_history":
-+		[
-+			"this",
-+			"bbb",
-+			"alias(",
-+			"alias",
-+			"env",
-+			"this.options =",
-+			"options =",
-+			".generator",
-+			".generators",
-+			"fallbacks",
-+			"resolve",
-+			"generateName",
-+			"consoleà",
-+			"console",
-+			"fallbacks",
-+			"defaultFor",
-+			"self",
-+			"invoke",
-+			"env",
-+			"Env",
-+			"env",
-+			"adapter",
-+			"enforce",
-+			"error",
-+			"this.error",
-+			"Stub",
-+			"stub",
-+			"invoke =",
-+			"invoke",
-+			"shouldRun",
-+			"this.shouldRun",
-+			"method",
-+			"run",
-+			"generators",
-+			" help /",
-+			"}}",
-+			"{{",
-+			"maven",
-+			"%>",
-+			"<%",
-+			"#template",
-+			"template",
-+			"templateSettings",
-+			"'write/to/from-foo-template-maven-vars.xml'",
-+			"'foo-template-maven-vars.xml'",
-+			"@memberof yeoman-generator",
-+			"exports.",
-+			"self",
-+			"fallbacks",
-+			"assert.",
-+			"exports.",
-+			"findGeneratorsIn",
-+			"exports",
-+			"this.paths",
-+			"lookups",
-+			"paths",
-+			"this.env.paths",
-+			"default",
-+			"this.appendPath",
-+			"exports.",
-+			"fetch",
-+			"exports.",
-+			" * @memberof env/resolver",
-+			"exports.",
-+			"username",
-+			"wiring.",
-+			"user.",
-+			"install.",
-+			"file.",
-+			"fetch.",
-+			"actions.",
-+			"helpers",
-+			"assert.",
-+			"//",
-+			"// ",
-+			"exports",
-+			"actions",
-+			"_setStor",
-+			"\"",
-+			"appendPath",
-+			"defaultPath",
-+			"appendDefault",
-+			"alias",
-+			"globalTest",
-+			"\"",
-+			"resolved",
-+			"runHooks",
-+			"ember:all",
-+			"hook4",
-+			"');\n",
-+			"hook4",
-+			"hook4:ember:all",
-+			"console",
-+			"resolved",
-+			"invoke =",
-+			"runHooks",
-+			"hookFor",
-+			"resolvePath",
-+			"files",
-+			"dir",
-+			"_getNpmGenerators",
-+			"match",
-+			"Generator",
-+			"generator",
-+			"defaultPa",
-+			"findup",
-+			"[type]",
-+			"#register",
-+			"store",
-+			"generator",
-+			"appendDef",
-+			"arguments",
-+			"cwd",
-+			"alias",
-+			"aliases",
-+			"isBinaryFile",
-+			"log",
-+			"shell",
-+			"remote",
-+			"(source, destination)",
-+			"describe('remote.",
-+			"src",
-+			"remote",
-+			"TestGen",
-+			"testGen",
-+			"TestGen",
-+			"testGen",
-+			"Generator"
-+		],
-+		"highlight": true,
-+		"in_selection": false,
-+		"preserve_case": false,
-+		"regex": false,
-+		"replace_history":
-+		[
-+		],
-+		"reverse": false,
-+		"show_context": true,
-+		"use_buffer2": true,
-+		"whole_word": false,
-+		"wrap": true
-+	},
-+	"groups":
-+	[
-+		{
-+			"sheets":
-+			[
-+			]
-+		}
-+	],
-+	"incremental_find":
-+	{
-+		"height": 0.0
-+	},
-+	"input":
-+	{
-+		"height": 38.0
-+	},
-+	"layout":
-+	{
-+		"cells":
-+		[
-+			[
-+				0,
-+				0,
-+				1,
-+				1
-+			]
-+		],
-+		"cols":
-+		[
-+			0.0,
-+			1.0
-+		],
-+		"rows":
-+		[
-+			0.0,
-+			1.0
-+		]
-+	},
-+	"menu_visible": true,
-+	"output.exec":
-+	{
-+		"height": 154.0
-+	},
-+	"output.find_results":
-+	{
-+		"height": 0.0
-+	},
-+	"project": "file-utils.sublime-project",
-+	"replace":
-+	{
-+		"height": 0.0
-+	},
-+	"save_all_on_build": true,
-+	"select_file":
-+	{
-+		"height": 0.0,
-+		"selected_items":
-+		[
-+			[
-+				"bae",
-+				"lib\\base.js"
-+			],
-+			[
-+				"mochaopt",
-+				"test\\mocha.opts"
-+			],
-+			[
-+				"helpers",
-+				"lib\\test\\helpers.js"
-+			],
-+			[
-+				"helper",
-+				"test\\helpers.js"
-+			],
-+			[
-+				"base",
-+				"lib\\base.js"
-+			],
-+			[
-+				"engine",
-+				"lib\\util\\engines.js"
-+			],
-+			[
-+				"envresol",
-+				"test/env.resolver.js"
-+			],
-+			[
-+				"store",
-+				"lib/env/store.js"
-+			],
-+			[
-+				"testbase",
-+				"test/base.js"
-+			],
-+			[
-+				"storejs",
-+				"lib/env/store.js"
-+			],
-+			[
-+				"testenvresolv",
-+				"test/env.resolver.js"
-+			],
-+			[
-+				"spawn",
-+				"lib/actions/spawn_command.js"
-+			],
-+			[
-+				"actio",
-+				"lib/actions/actions.js"
-+			],
-+			[
-+				"envind",
-+				"lib/env/index.js"
-+			],
-+			[
-+				"testenv",
-+				"test/env.js"
-+			],
-+			[
-+				"testremote",
-+				"test/remote.js"
-+			],
-+			[
-+				"spa",
-+				"doc/spawn_command.md"
-+			],
-+			[
-+				"actions",
-+				"lib/actions/actions.js"
-+			],
-+			[
-+				"test/base",
-+				"test/base.js"
-+			],
-+			[
-+				"libenv",
-+				"lib/env/index.js"
-+			],
-+			[
-+				"pack",
-+				"package.json"
-+			],
-+			[
-+				"feth",
-+				"lib/actions/fetch.js"
-+			],
-+			[
-+				"ssruby",
-+				"/C/Users/Simon.Boudrias/AppData/Roaming/Sublime Text 2/Packages/Ruby/do-obj-..-end-(doo).sublime-snippet"
-+			],
-+			[
-+				"jshin",
-+				"generator-bbb/.jshintrc"
-+			],
-+			[
-+				"widget",
-+				"application/models/widget_model.php"
-+			],
-+			[
-+				"viewpart",
-+				"application/views/partner/partner.php"
-+			],
-+			[
-+				"style",
-+				"public/css/style.css"
-+			],
-+			[
-+				"modelpart",
-+				"application/models/partner_model.php"
-+			],
-+			[
-+				"modelexpre",
-+				"application/models/experience_model.php"
-+			],
-+			[
-+				"404",
-+				"application/errors/error_404.php"
-+			],
-+			[
-+				"season",
-+				"application/models/season_model.php"
-+			],
-+			[
-+				"campa",
-+				"application/models/campaign_model.php"
-+			],
-+			[
-+				"controll",
-+				"application/controllers/base.php"
-+			],
-+			[
-+				"header",
-+				"application/views/layouts/_header.php"
-+			],
-+			[
-+				"viewhome",
-+				"application/views/home/home.php"
-+			],
-+			[
-+				"partner",
-+				"application/controllers/partner.php"
-+			],
-+			[
-+				"heaer",
-+				"application/views/layouts/_header.php"
-+			],
-+			[
-+				"footer",
-+				"application/views/layouts/_footer.php"
-+			],
-+			[
-+				"_footer",
-+				"application/views/layouts/_footer.php"
-+			],
-+			[
-+				"styl",
-+				"public/css/style.css"
-+			],
-+			[
-+				"controllebase",
-+				"application/controllers/base.php"
-+			],
-+			[
-+				"controlbase",
-+				"application/controllers/base.php"
-+			],
-+			[
-+				"wordscss",
-+				"public/widgets/expressions/css/words.css"
-+			],
-+			[
-+				"js",
-+				"public/widgets/expressions/js/words.js"
-+			],
-+			[
-+				"handle",
-+				"example/vendor/handlebars.js"
-+			],
-+			[
-+				"config",
-+				"example/app/config.js"
-+			],
-+			[
-+				"inter",
-+				"example/app/views/interface.js"
-+			],
-+			[
-+				"hbs",
-+				"example/vendor/hbs.js"
-+			],
-+			[
-+				"emails",
-+				"trunk/public/emails/share/email_en.html"
-+			],
-+			[
-+				"applcon",
-+				"application/config/config.php"
-+			]
-+		],
-+		"width": 0.0
-+	},
-+	"select_project":
-+	{
-+		"height": 500.0,
-+		"selected_items":
-+		[
-+			[
-+				"mint",
-+				"E:\\Projets\\Monnaie Royale Canadienne\\MintChip\\MintChip - monnaie royale.sublime-project"
-+			],
-+			[
-+				"",
-+				"E:\\Projets\\Monnaie Royale Canadienne\\MintChip\\MintChip - monnaie royale.sublime-project"
-+			],
-+			[
-+				"bdc",
-+				"E:\\Projets\\BDC\\YoungEntrepreneurAward\\trunk\\BDC - entrepreneur award.sublime-project"
-+			],
-+			[
-+				"inquir",
-+				"/E/github/Inquirer.js/Inquirerjs.sublime-project"
-+			],
-+			[
-+				"presse",
-+				"/E/Projets/LaPresse/Noël 2013/trunk/presseplus-noel.sublime-project"
-+			],
-+			[
-+				"yo",
-+				"/E/github/yo/yo.sublime-project"
-+			],
-+			[
-+				"ski",
-+				"/E/Projets/MTO/Microsite-ski/trunk/mto-ski.sublime-project"
-+			],
-+			[
-+				"telu",
-+				"/E/Projets/Telus/Holidays/telus_holidays.sublime-project"
-+			],
-+			[
-+				"distin",
-+				"/E/Projets/Aeroplan has changed/aeroplan-distinction.sublime-project"
-+			],
-+			[
-+				"mto",
-+				"/E/Projets/MTO/Microsite-ski/trunk/mto-ski.sublime-project"
-+			],
-+			[
-+				"dund",
-+				"/E/Projets/Aeroplan_Dundas/trunk/aeroplan_dundas.sublime-project"
-+			],
-+			[
-+				"inqui",
-+				"/E/github/Inquirer.js/Inquirerjs.sublime-project"
-+			],
-+			[
-+				"airt",
-+				"/E/Projets/air-transat/trunk/Welcome.web/air-transat.sublime-project"
-+			],
-+			[
-+				"aer",
-+				"/E/Projets/Aeroplan Distinction/aeroplan-distinction.sublime-project"
-+			],
-+			[
-+				"aeropl",
-+				"/E/Projets/Aeroplan Milestone/aeroplan_milestone.sublime-project"
-+			],
-+			[
-+				"form",
-+				"/E/formations/JavaScript MVC (Backbone)/formation-backbone.sublime-project"
-+			],
-+			[
-+				"layout",
-+				"/E/github/backbone.layoutmanager/backbone.LayoutManager.sublime-project"
-+			],
-+			[
-+				"airtr",
-+				"/E/Projets/air-transat/trunk/Welcome.web/air-transat.sublime-project"
-+			],
-+			[
-+				"air",
-+				"/E/Projets/air-transat/trunk/Welcome.web/air-transat.sublime-project"
-+			],
-+			[
-+				"air tr",
-+				"/E/Projets/air-transat/trunk/Welcome.web/air-transat.sublime-project"
-+			],
-+			[
-+				"gm",
-+				"/E/Projets/GMX/Bannieres PressePlus/GM_bannieres.sublime-project"
-+			],
-+			[
-+				"conf",
-+				"/C/Users/Simon.Boudrias/pc_config.sublime-project"
-+			]
-+		],
-+		"width": 380.0
-+	},
-+	"select_symbol":
-+	{
-+		"height": 0.0,
-+		"selected_items":
-+		[
-+		],
-+		"width": 0.0
-+	},
-+	"settings":
-+	{
-+	},
-+	"show_minimap": true,
-+	"show_open_files": true,
-+	"show_tabs": true,
-+	"side_bar_visible": true,
-+	"side_bar_width": 232.0,
-+	"status_bar_visible": true,
-+	"template_settings":
-+	{
-+	}
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/index.js
-@@ -0,0 +1,11 @@
-+var _ = require('lodash');
-+var File = require('./lib/file');
-+var Env = require('./lib/env');
-+
-+var file = new File();
-+
-+file.createEnv = function(opt) {
-+  return new Env(_.extend({}, this._options, opt));
-+};
-+
-+module.exports = file;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/lib/env.js
-@@ -0,0 +1,163 @@
-+var path = require('path');
-+var util = require('util');
-+var _ = require('lodash');
-+var File = require('./file');
-+
-+module.exports = Env;
-+
-+function Env(opt) {
-+  File.apply(this, arguments);
-+
-+  this._base = opt.base || '';
-+  this._destBase = opt.dest || '';
-+  this._writeFilters = {};
-+  this._validationFilters = {};
-+
-+  var methodsToPrefix = [ 'mkdir', 'recurse', 'read', 'readJSON', 'write', 'delete',
-+  'exists', 'isLink', 'isDir', 'isFile' ];
-+
-+  // Prefix path arguments with this environment root dir
-+  methodsToPrefix.forEach(function(methodName) {
-+    this[methodName] = function() {
-+      var args = _.toArray(arguments);
-+      args[0] = this.fromBase(args[0]);
-+      return File.prototype[methodName].apply(this, args);
-+    };
-+  }.bind(this));
-+
-+  this.copy = function() {
-+    var args = _.toArray(arguments);
-+    args[0] = this.fromBase(args[0]);
-+    args[1] = this.fromDestBase(args[1]);
-+    return File.prototype.copy.apply(this, args);
-+  };
-+
-+  this._actualWrite = this.write;
-+  this.write = function(filepath, contents, options) {
-+    return this.applyWriteFilters({
-+      path: filepath,
-+      contents: contents
-+    }, this.applyValidationFilters, options);
-+  };
-+}
-+
-+util.inherits(Env, File);
-+
-+Env.prototype.setBase = function(filepath) {
-+  this._base = filepath;
-+};
-+
-+// Return a path prefixed by the base (if not absolute)
-+Env.prototype.fromBase = function(filepath) {
-+  if (this.isPathAbsolute(filepath)) {
-+    return filepath;
-+  }
-+  return path.join(_.isFunction(this._base) ? this._base() : this._base, filepath);
-+};
-+
-+Env.prototype.setDestBase = function(filepath) {
-+  this._destBase = filepath;
-+};
-+
-+// Return a path prefixed by the destination base (if not absolute)
-+Env.prototype.fromDestBase = function(filepath) {
-+  if (this.isPathAbsolute(filepath)) {
-+    return filepath;
-+  }
-+  return path.join(_.isFunction(this._destBase) ? this._destBase() : this._destBase, filepath);
-+};
-+
-+Env.prototype.registerWriteFilter = function(name, filter) {
-+  this._writeFilters[name] = filter;
-+};
-+
-+Env.prototype.removeWriteFilter = function(name) {
-+  delete this._writeFilters[name];
-+};
-+
-+Env.prototype.registerValidationFilter = function(name, filter) {
-+  this._validationFilters[name] = filter;
-+};
-+
-+Env.prototype.removeValidationFilter = function(name) {
-+  delete this._validationFilters[name];
-+};
-+
-+
-+Env.prototype.applyWriteFilters = function(file, validate, options) {
-+  var writeFilters = _.reduce(this._writeFilters, function(m, v) { m.push(v); return m; }, []);
-+  if (!writeFilters.length) {
-+    return validate.call(this, file, options);
-+  }
-+
-+  var i = 0;
-+  var output;
-+  var recurse = function(file) {
-+    i++;
-+    if (writeFilters[i]) {
-+      runAsync(writeFilters[i], recurse, file);
-+    } else {
-+      output = validate.call(this, file, options);
-+    }
-+  }.bind(this);
-+
-+  runAsync(writeFilters[i], recurse, file);
-+
-+  return output;
-+};
-+
-+Env.prototype.applyValidationFilters = function( file, options ) {
-+  var validationFilters = _.reduce(this._validationFilters, function(m, v) { m.push(v); return m; }, []);
-+  if (!validationFilters.length) {
-+    return this._actualWrite.call(this, file.path, file.contents, options);
-+  }
-+
-+  var i = 0;
-+  var output;
-+  var recurse = function(validated) {
-+    if ( validated !== true ) {
-+      return this.log.write(validated || 'Not actually writing to '+ file.path +' haven\'t pass validation' );
-+    }
-+    i++;
-+    if (validationFilters[i]) {
-+      runAsync(validationFilters[i], recurse, file);
-+    } else {
-+      output = this._actualWrite.call(this, file.path, file.contents, options);
-+    }
-+  }.bind(this);
-+
-+  runAsync(validationFilters[i], recurse, file);
-+
-+  return output;
-+};
-+
-+
-+/**
-+ * Allow a function to be run async by using `this.async()`. If not, then the function is
-+ * runned synchronously.
-+ * @param  {Function} func  The function to run
-+ * @param  {Function} cb    Callback to be provided even if the function is run sync
-+ * @param  {...rest}        Arguments passed to `func`
-+ * @return {null}
-+ */
-+function runAsync( func, cb ) {
-+  var rest = [];
-+  var len = 1;
-+
-+  while ( len++ < arguments.length ) {
-+    rest.push( arguments[len] );
-+  }
-+
-+  var async = false;
-+  var returnValue = func.apply({
-+    async: function() {
-+      async = true;
-+      return _.once(cb);
-+    }
-+  }, rest );
-+
-+  // Note: Call the callback synchronously to keep the sync flow by default
-+  if ( !async ) {
-+    cb(returnValue);
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/lib/file.js
-@@ -0,0 +1,367 @@
-+/*
-+ * grunt
-+ * http://gruntjs.com/
-+ *
-+ * Copyright (c) 2013 "Cowboy" Ben Alman
-+ * Licensed under the MIT license.
-+ * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
-+ */
-+
-+// Nodejs libs.
-+var fs = require('fs');
-+var path = require('path');
-+
-+// The module to be exported.
-+module.exports = File;
-+
-+// External libs.
-+var rimraf = require('rimraf');
-+var iconv = require('iconv-lite');
-+var glob = require('glob');
-+var minimatch = require('minimatch');
-+var isBinaryFile = require('isbinaryfile');
-+var _ = require('lodash');
-+
-+var fquery = require('./query');
-+var defaultLogger = require('./logger');
-+
-+// Windows?
-+var win32 = process.platform === 'win32';
-+
-+// Normalize \\ paths to / paths.
-+var unixifyPath = function(filepath) {
-+  if (win32) {
-+    return filepath.replace(/\\/g, '/');
-+  } else {
-+    return filepath;
-+  }
-+};
-+
-+function File(opt) {
-+  if (!opt) {
-+    opt = {};
-+  }
-+
-+  this._options = _.defaults(opt, {
-+    write: true,
-+    encoding: 'utf8',
-+    logger: defaultLogger
-+  });
-+
-+  Object.defineProperty(this, 'log', {
-+    get: function() {
-+      return this.option('logger');
-+    }
-+  });
-+}
-+
-+// Get or set options
-+File.prototype.option = function( key, val ) {
-+  if (arguments.length < 2) {
-+    return this._options[key];
-+  } else {
-+    return this._options[key] = val;
-+  }
-+};
-+
-+// Process specified wildcard glob patterns or filenames against a
-+// callback, excluding and uniquing files in the result set.
-+var processPatterns = function(patterns, fn) {
-+  // Filepaths to return.
-+  var result = [];
-+  // Iterate over flattened patterns array.
-+  _.flatten(patterns).forEach(function(pattern) {
-+    // If the first character is ! it should be omitted
-+    var exclusion = pattern.indexOf('!') === 0;
-+    // If the pattern is an exclusion, remove the !
-+    if (exclusion) { pattern = pattern.slice(1); }
-+    // Find all matching files for this pattern.
-+    var matches = fn(pattern);
-+    if (exclusion) {
-+      // If an exclusion, remove matching files.
-+      result = _.difference(result, matches);
-+    } else {
-+      // Otherwise add matching files.
-+      result = _.union(result, matches);
-+    }
-+  });
-+  return result;
-+};
-+
-+// Match a filepath or filepaths against one or more wildcard patterns. Returns
-+// all matching filepaths.
-+File.prototype.match = function(options, patterns, filepaths) {
-+  if (!_.isPlainObject(options)) {
-+    filepaths = patterns;
-+    patterns = options;
-+    options = {};
-+  }
-+
-+  // Return empty set if either patterns or filepaths was omitted.
-+  if (patterns == null || filepaths == null) { return []; }
-+  // Normalize patterns and filepaths to arrays.
-+  if (!Array.isArray(patterns)) { patterns = [patterns]; }
-+  if (!Array.isArray(filepaths)) { filepaths = [filepaths]; }
-+  // Return empty set if there are no patterns or filepaths.
-+  if (patterns.length === 0 || filepaths.length === 0) { return []; }
-+  // Return all matching filepaths.
-+  return processPatterns(patterns, function(pattern) {
-+    return minimatch.match(filepaths, pattern, options);
-+  }.bind(this));
-+};
-+
-+// Match a filepath or filepaths against one or more wildcard patterns. Returns
-+// true if any of the patterns match.
-+File.prototype.isMatch = function() {
-+  return this.match.apply(this, arguments).length > 0;
-+};
-+
-+// Return an array of all file paths that match the given wildcard patterns.
-+File.prototype.expand = function() {
-+  var args = _.toArray(arguments);
-+  // If the first argument is an options object, save those options to pass
-+  // into the File.prototype.glob.sync method.
-+  var options = _.isPlainObject(args[0]) ? args.shift() : {};
-+  // Use the first argument if it's an Array, otherwise convert the arguments
-+  // object to an array and use that.
-+  var patterns = Array.isArray(args[0]) ? args[0] : args;
-+  // Return empty set if there are no patterns or filepaths.
-+  if (patterns.length === 0) { return []; }
-+  // Return all matching filepaths.
-+  var matches = processPatterns(patterns, function(pattern) {
-+    // Find all matching files for this pattern.
-+    return glob.sync(pattern, options);
-+  }.bind(this));
-+  // Filter result set?
-+  if (options.filter) {
-+    matches = matches.filter(function(filepath) {
-+      filepath = path.join(options.cwd || '', filepath);
-+      try {
-+        if (typeof options.filter === 'function') {
-+          return options.filter(filepath);
-+        } else {
-+          // If the file is of the right type and exists, this should work.
-+          return fs.statSync(filepath)[options.filter]();
-+        }
-+      } catch(e) {
-+        // Otherwise, it's probably not the right type.
-+        return false;
-+      }
-+    });
-+  }
-+  return matches;
-+};
-+
-+var pathSeparatorRe = /[\/\\]/g;
-+
-+// Build a multi task "files" object dynamically.
-+File.prototype.expandMapping = function(patterns, destBase, options) {
-+  options = _.defaults({}, options, {
-+    rename: function(destBase, destPath) {
-+      return path.join(destBase || '', destPath);
-+    }
-+  });
-+  var files = [];
-+  var fileByDest = {};
-+  // Find all files matching pattern, using passed-in options.
-+  this.expand(options, patterns).forEach(function(src) {
-+    var destPath = src;
-+    // Flatten?
-+    if (options.flatten) {
-+      destPath = path.basename(destPath);
-+    }
-+    // Change the extension?
-+    if (options.ext) {
-+      destPath = destPath.replace(/(\.[^\/]*)?$/, options.ext);
-+    }
-+    // Generate destination filename.
-+    var dest = options.rename(destBase, destPath, options);
-+    // Prepend cwd to src path if necessary.
-+    if (options.cwd) { src = path.join(options.cwd, src); }
-+    // Normalize filepaths to be unix-style.
-+    dest = dest.replace(pathSeparatorRe, '/');
-+    src = src.replace(pathSeparatorRe, '/');
-+    // Map correct src path to dest path.
-+    if (fileByDest[dest]) {
-+      // If dest already exists, push this src onto that dest's src array.
-+      fileByDest[dest].src.push(src);
-+    } else {
-+      // Otherwise create a new src-dest file mapping object.
-+      files.push({
-+        src: [src],
-+        dest: dest,
-+      });
-+      // And store a reference for later use.
-+      fileByDest[dest] = files[files.length - 1];
-+    }
-+  });
-+  return files;
-+};
-+
-+// Like mkdir -p. Create a directory and any intermediary directories.
-+File.prototype.mkdir = function(dirpath, mode) {
-+  if (!this.option('write')) { return; }
-+  // Set directory mode in a strict-mode-friendly way.
-+  if (mode == null) {
-+    mode = parseInt('0777', 8) & (~process.umask());
-+  }
-+  dirpath.split(pathSeparatorRe).reduce(function(parts, part) {
-+    parts += part + '/';
-+    var subpath = path.resolve(parts);
-+    if (!File.prototype.exists.call(null, subpath)) {
-+      try {
-+        fs.mkdirSync(subpath, mode);
-+      } catch(e) {
-+        throw new Error('Unable to create directory "' + subpath + '" (Error code: ' + e.code + ').', e);
-+      }
-+    }
-+    return parts;
-+  }.bind(this), '');
-+};
-+
-+// Recurse into a directory, executing callback for each file.
-+File.prototype.recurse = function(rootdir, callback, subdir) {
-+  var abspath = subdir ? path.join(rootdir, subdir) : rootdir;
-+  fs.readdirSync(abspath).forEach(function(filename) {
-+    var filepath = path.join(abspath, filename);
-+    if (fs.statSync(filepath).isDirectory()) {
-+      this.recurse(rootdir, callback, unixifyPath(path.join(subdir || '', filename || '')));
-+    } else {
-+      callback(unixifyPath(filepath), rootdir, subdir, filename);
-+    }
-+  }.bind(this));
-+};
-+
-+// Read a file, return its contents.
-+File.prototype.read = function(filepath, options) {
-+  if (!options) { options = {}; }
-+  var contents;
-+  try {
-+    contents = fs.readFileSync(filepath);
-+    // If encoding is not explicitly null, convert from encoded buffer to a
-+    // string. If no encoding was specified, use the default.
-+    if (options.encoding !== null) {
-+      contents = iconv.decode(contents, options.encoding || this.option('encoding'));
-+      // Strip any BOM that might exist.
-+      if (contents.charCodeAt(0) === 0xFEFF) {
-+        contents = contents.substring(1);
-+      }
-+    }
-+    return contents;
-+  } catch(e) {
-+    throw new Error('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e);
-+  }
-+};
-+
-+// Read a file, parse its contents, return an object.
-+File.prototype.readJSON = function(filepath, options) {
-+  var src = this.read(filepath, options);
-+  var result;
-+  try {
-+    result = JSON.parse(src);
-+    return result;
-+  } catch(e) {
-+    throw new Error('Unable to parse "' + filepath + '" file (' + e.message + ').', e);
-+  }
-+};
-+
-+// Write a file.
-+File.prototype.write = function(filepath, contents, options) {
-+  if (!options) { options = {}; }
-+  var nowrite = !this.option('write');
-+  this.log.write((nowrite ? 'Not actually writing ' : 'Writing ') + filepath + '...');
-+  // Create path, if necessary.
-+  this.mkdir(path.dirname(filepath));
-+  try {
-+    // If contents is already a Buffer, don't try to encode it. If no encoding
-+    // was specified, use the default.
-+    if (!Buffer.isBuffer(contents)) {
-+      contents = iconv.encode(contents, options.encoding || this.option('encoding'));
-+    }
-+    // Actually write file.
-+    if (!nowrite) {
-+      fs.writeFileSync(filepath, contents, { mode: options.mode });
-+    }
-+    return true;
-+  } catch(e) {
-+    throw new Error('Unable to write "' + filepath + '" file (Error code: ' + e.code + ').', e);
-+  }
-+};
-+
-+// Read a file, optionally processing its content, then write the output.
-+File.prototype.copy = function(srcpath, destpath, options) {
-+  if (!options) { options = {}; }
-+  // If a process function was specified, and noProcess isn't true or doesn't
-+  // match the srcpath, process the file's source.
-+  var process = options.process && options.noProcess !== true &&
-+    !(options.noProcess && this.isMatch(options.noProcess, srcpath));
-+  // If the file will be processed, use the encoding as-specified. Otherwise,
-+  // use an encoding of null to force the file to be read/written as a Buffer.
-+  if (options.encoding === undefined && !isBinaryFile(srcpath)) {
-+    options.encoding = this.option('encoding');
-+  }
-+  var readWriteOptions = process ? options : _.extend({
-+    encoding: null,
-+    mode: fs.statSync(srcpath).mode
-+  }, options);
-+  // Actually read the file.
-+  var contents = this.read(srcpath, readWriteOptions);
-+  if (process) {
-+    this.log.write('Processing source...');
-+    try {
-+      contents = options.process(contents, srcpath);
-+    } catch(e) {
-+      throw new Error('Error while processing "' + srcpath + '" file.', e);
-+    }
-+  }
-+
-+  // Abort copy if the process function returns false.
-+  if (contents === false) {
-+    this.log.write('Write aborted.');
-+  } else {
-+    this.write(destpath, contents, readWriteOptions);
-+  }
-+};
-+
-+// Delete folders and files recursively
-+File.prototype.delete = function(filepath, options) {
-+  var nowrite = !this.option('write');
-+  if (!options) {
-+    options = {force: this.option('force') || false};
-+  }
-+
-+  this.log.write((nowrite ? 'Not actually deleting ' : 'Deleting ') + filepath + '...');
-+
-+  if (!File.prototype.exists.call(null, filepath)) {
-+    this.log.warn('Cannot delete nonexistent file.');
-+    return false;
-+  }
-+
-+  // Only delete cwd or outside cwd if --force enabled. Be careful, people!
-+  if (!options.force) {
-+    var base = path.resolve(this._base || '');
-+    if (fquery.isPathCwd(filepath)) {
-+      this.log.warn('Cannot delete the current working directory.');
-+      return false;
-+    } else if (!fquery.doesPathContain(base, filepath)) {
-+      this.log.warn('Cannot delete files outside the current working directory.');
-+      return false;
-+    }
-+  }
-+
-+  try {
-+    // Actually delete. Or not.
-+    if (!nowrite) {
-+      rimraf.sync(filepath);
-+    }
-+    return true;
-+  } catch(e) {
-+    throw new Error('Unable to delete "' + filepath + '" file (' + e.message + ').', e);
-+  }
-+};
-+
-+// Extend dependencies
-+File.prototype.glob = require('glob');
-+File.prototype.minimatch = require('minimatch');
-+File.prototype.findup = require('findup-sync');
-+_.extend(File.prototype, fquery);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/lib/logger.js
-@@ -0,0 +1,8 @@
-+module.exports = {
-+  warn: function(msg) {
-+    console.log('WARN: ' + msg);
-+  },
-+  write: function(msg) {
-+    console.log(msg);
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/lib/query.js
-@@ -0,0 +1,82 @@
-+/**
-+ * File/Path comparison and queries
-+ */
-+
-+var path = require('path');
-+var fs = require('fs');
-+
-+// True if the file path exists.
-+exports.exists = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return fs.existsSync(filepath);
-+};
-+
-+// True if the file is a symbolic link.
-+exports.isLink = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return this.exists(filepath) && fs.lstatSync(filepath).isSymbolicLink();
-+};
-+
-+// True if the path is a directory.
-+exports.isDir = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return this.exists(filepath) && fs.statSync(filepath).isDirectory();
-+};
-+
-+// True if the path is a file.
-+exports.isFile = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return this.exists(filepath) && fs.statSync(filepath).isFile();
-+};
-+
-+exports.isExecutable = function(filepath) {
-+  var stats = fs.statSync(filepath);
-+  return !!(1 & parseFloat((stats.mode & parseInt(777, 8)).toString(8)[0]));
-+};
-+
-+// Is a given file path absolute?
-+exports.isPathAbsolute = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return path.resolve(filepath) === filepath.replace(/[\/\\]+$/, '');
-+};
-+
-+// Do all the specified paths refer to the same path?
-+exports.arePathsEquivalent = function(first) {
-+  first = path.resolve(first);
-+  for (var i = 1; i < arguments.length; i++) {
-+    if (first !== path.resolve(arguments[i])) { return false; }
-+  }
-+  return true;
-+};
-+
-+// Are descendant path(s) contained within ancestor path? Note: does not test
-+// if paths actually exist.
-+exports.doesPathContain = function(ancestor) {
-+  ancestor = path.resolve(ancestor);
-+  var relative;
-+  for (var i = 1; i < arguments.length; i++) {
-+    relative = path.relative(path.resolve(arguments[i]), ancestor);
-+    if (relative === '' || /\w+/.test(relative)) { return false; }
-+  }
-+  return true;
-+};
-+
-+// Test to see if a filepath is the CWD.
-+exports.isPathCwd = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  try {
-+    return this.arePathsEquivalent(process.cwd(), fs.realpathSync(filepath));
-+  } catch(e) {
-+    return false;
-+  }
-+};
-+
-+// Test to see if a filepath is contained within the CWD.
-+exports.isPathInCwd = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  try {
-+    return this.doesPathContain(process.cwd(), fs.realpathSync(filepath));
-+  } catch(e) {
-+    return false;
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/.jshintrc
-@@ -0,0 +1,15 @@
-+{
-+  "loopfunc": true,
-+  "curly": true,
-+  "eqeqeq": true,
-+  "immed": true,
-+  "latedef": true,
-+  "newcap": true,
-+  "noarg": true,
-+  "sub": true,
-+  "undef": true,
-+  "unused": true,
-+  "boss": true,
-+  "eqnull": true,
-+  "node": true
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/.travis.yml
-@@ -0,0 +1,5 @@
-+language: node_js
-+node_js:
-+  - 0.8
-+before_script:
-+  - npm install -g grunt-cli
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/Gruntfile.js
-@@ -0,0 +1,25 @@
-+'use strict';
-+
-+module.exports = function(grunt) {
-+
-+  // Project configuration.
-+  grunt.initConfig({
-+    nodeunit: {
-+      files: ['test/**/*_test.js'],
-+    },
-+    jshint: {
-+      options: {
-+        jshintrc: '.jshintrc'
-+      },
-+      all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']
-+    }
-+  });
-+
-+  // Load plugins.
-+  grunt.loadNpmTasks('grunt-contrib-jshint');
-+  grunt.loadNpmTasks('grunt-contrib-nodeunit');
-+
-+  // Default task.
-+  grunt.registerTask('default', ['jshint', 'nodeunit']);
-+
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/LICENSE-MIT
-@@ -0,0 +1,22 @@
-+Copyright (c) 2013 "Cowboy" Ben Alman
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/README.md
-@@ -0,0 +1,45 @@
-+# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync)
-+
-+Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
-+
-+## Getting Started
-+Install the module with: `npm install findup-sync`
-+
-+```js
-+var findup = require('findup-sync');
-+
-+// Start looking in the CWD.
-+var filepath1 = findup('{a,b}*.txt');
-+
-+// Start looking somewhere else, and ignore case (probably a good idea).
-+var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true});
-+```
-+
-+## Usage
-+
-+```js
-+findup(patternOrPatterns [, minimatchOptions])
-+```
-+
-+### patternOrPatterns
-+Type: `String` or `Array`  
-+Default: none
-+
-+One or more wildcard glob patterns. Or just filenames.
-+
-+### minimatchOptions
-+Type: `Object`  
-+Default: `{}`
-+
-+Options to be passed to [minimatch](https://github.com/isaacs/minimatch).
-+
-+Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here.
-+
-+## Contributing
-+In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
-+
-+## Release History
-+2014-03-14 - v0.1.3 - Updated dependencies.  
-+2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform.  
-+2012-11-15 - v0.1.1 - Now works without an options object.  
-+2012-11-01 - v0.1.0 - Initial release.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/lib/findup-sync.js
-@@ -0,0 +1,46 @@
-+/*
-+ * findup-sync
-+ * https://github.com/cowboy/node-findup-sync
-+ *
-+ * Copyright (c) 2013 "Cowboy" Ben Alman
-+ * Licensed under the MIT license.
-+ */
-+
-+'use strict';
-+
-+// Nodejs libs.
-+var path = require('path');
-+
-+// External libs.
-+var glob = require('glob');
-+var _ = require('lodash');
-+
-+// Search for a filename in the given directory or all parent directories.
-+module.exports = function(patterns, options) {
-+  // Normalize patterns to an array.
-+  if (!Array.isArray(patterns)) { patterns = [patterns]; }
-+  // Create globOptions so that it can be modified without mutating the
-+  // original object.
-+  var globOptions = Object.create(options || {});
-+  globOptions.maxDepth = 1;
-+  globOptions.cwd = path.resolve(globOptions.cwd || '.');
-+
-+  var files, lastpath;
-+  do {
-+    // Search for files matching patterns.
-+    files = _(patterns).map(function(pattern) {
-+      return glob.sync(pattern, globOptions);
-+    }).flatten().uniq().value();
-+    // Return file if found.
-+    if (files.length > 0) {
-+      return path.resolve(path.join(globOptions.cwd, files[0]));
-+    }
-+    // Go up a directory.
-+    lastpath = globOptions.cwd;
-+    globOptions.cwd = path.resolve(globOptions.cwd, '..');
-+  // If parentpath is the same as basedir, we can't go any higher.
-+  } while (globOptions.cwd !== lastpath);
-+
-+  // No files were found!
-+  return null;
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/package.json
-@@ -0,0 +1,48 @@
-+{
-+  "name": "findup-sync",
-+  "description": "Find the first file matching a given pattern in the current directory or the nearest ancestor directory.",
-+  "version": "0.1.3",
-+  "homepage": "https://github.com/cowboy/node-findup-sync",
-+  "author": {
-+    "name": "\"Cowboy\" Ben Alman",
-+    "url": "http://benalman.com/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/cowboy/node-findup-sync.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/cowboy/node-findup-sync/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/cowboy/node-findup-sync/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/findup-sync",
-+  "engines": {
-+    "node": ">= 0.6.0"
-+  },
-+  "scripts": {
-+    "test": "grunt nodeunit"
-+  },
-+  "dependencies": {
-+    "glob": "~3.2.9",
-+    "lodash": "~2.4.1"
-+  },
-+  "devDependencies": {
-+    "grunt": "~0.4.4",
-+    "grunt-contrib-jshint": "~0.9.2",
-+    "grunt-contrib-nodeunit": "~0.3.3"
-+  },
-+  "keywords": [
-+    "find",
-+    "glob",
-+    "file"
-+  ],
-+  "readme": "# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync)\n\nFind the first file matching a given pattern in the current directory or the nearest ancestor directory.\n\n## Getting Started\nInstall the module with: `npm install findup-sync`\n\n```js\nvar findup = require('findup-sync');\n\n// Start looking in the CWD.\nvar filepath1 = findup('{a,b}*.txt');\n\n// Start looking somewhere else, and ignore case (probably a good idea).\nvar filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true});\n```\n\n## Usage\n\n```js\nfindup(patternOrPatterns [, minimatchOptions])\n```\n\n### patternOrPatterns\nType: `String` or `Array`  \nDefault: none\n\nOne or more wildcard glob patterns. Or just filenames.\n\n### minimatchOptions\nType: `Object`  \nDefault: `{}`\n\nOptions to be passed to [minimatch](https://github.com/isaacs/minimatch).\n\nNote that if you want to start in a different directory than the current working directory, specify a `cwd` property here.\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2014-03-14 - v0.1.3 - Updated dependencies.  \n2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform.  \n2012-11-15 - v0.1.1 - Now works without an options object.  \n2012-11-01 - v0.1.0 - Initial release.\n",
-+  "readmeFilename": "README.md",
-+  "_id": "findup-sync at 0.1.3",
-+  "_from": "findup-sync@~0.1.2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/findup-sync/test/findup-sync_test.js
-@@ -0,0 +1,48 @@
-+'use strict';
-+
-+// Nodejs lib.
-+var path = require('path');
-+
-+var findup = require('../lib/findup-sync.js');
-+
-+// Get a relative path.
-+var rel = function(abspath) {
-+  return typeof abspath === 'string' ? path.relative('.', abspath) : abspath;
-+};
-+
-+exports['findup'] = {
-+  setUp: function(done) {
-+    this.cwd = process.cwd();
-+    done();
-+  },
-+  tearDown: function(done) {
-+    process.chdir(this.cwd);
-+    done();
-+  },
-+  'simple': function(test) {
-+    test.expect(8);
-+    var opts = {cwd: 'test/fixtures/a/b'};
-+    test.equal(rel(findup('foo.txt', opts)), path.normalize('test/fixtures/a/foo.txt'), 'should find files');
-+    test.equal(rel(findup('bar.txt', opts)), path.normalize('test/fixtures/a/b/bar.txt'), 'should find files');
-+    test.equal(rel(findup('a.txt', opts)), path.normalize('test/fixtures/a.txt'), 'should find files');
-+    test.equal(rel(findup('?.txt', opts)), path.normalize('test/fixtures/a.txt'), 'should support glob patterns');
-+    test.equal(rel(findup('*.txt', opts)), path.normalize('test/fixtures/a/b/bar.txt'), 'should find the first thing that matches the glob pattern');
-+    test.equal(rel(findup(['b*.txt', 'f*.txt'], opts)), path.normalize('test/fixtures/a/b/bar.txt'), 'should find the first thing that matches any of the glob patterns');
-+    test.equal(rel(findup(['f*.txt', 'b*.txt'], opts)), path.normalize('test/fixtures/a/b/bar.txt'), 'should find the first thing that matches any of the glob patterns');
-+    test.equal(findup('not-gonna-exist-i-hope.txt', opts), null, 'should returning null if no files found');
-+    test.done();
-+  },
-+  'cwd': function(test) {
-+    test.expect(8);
-+    process.chdir('test/fixtures/a/b');
-+    test.equal(rel(findup('foo.txt')), path.normalize('../foo.txt'), 'should find files');
-+    test.equal(rel(findup('bar.txt')), 'bar.txt', 'should find files');
-+    test.equal(rel(findup('a.txt')), path.normalize('../../a.txt'), 'should find files');
-+    test.equal(rel(findup('?.txt')), path.normalize('../../a.txt'), 'should support glob patterns');
-+    test.equal(rel(findup('*.txt')), 'bar.txt', 'should find the first thing that matches the glob pattern');
-+    test.equal(rel(findup(['b*.txt', 'f*.txt'])), 'bar.txt', 'should find the first thing that matches any of the glob patterns');
-+    test.equal(rel(findup(['f*.txt', 'b*.txt'])), 'bar.txt', 'should find the first thing that matches any of the glob patterns');
-+    test.equal(findup('not-gonna-exist-i-hope.txt'), null, 'should returning null if no files found');
-+    test.done();
-+  },
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/.npmignore
-@@ -0,0 +1,2 @@
-+.*.swp
-+test/a/
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/.travis.yml
-@@ -0,0 +1,3 @@
-+language: node_js
-+node_js:
-+  - 0.8
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/LICENSE
-@@ -0,0 +1,27 @@
-+Copyright (c) Isaac Z. Schlueter ("Author")
-+All rights reserved.
-+
-+The BSD License
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+1. Redistributions of source code must retain the above copyright
-+   notice, this list of conditions and the following disclaimer.
-+
-+2. Redistributions in binary form must reproduce the above copyright
-+   notice, this list of conditions and the following disclaimer in the
-+   documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/README.md
-@@ -0,0 +1,250 @@
-+# Glob
-+
-+Match files using the patterns the shell uses, like stars and stuff.
-+
-+This is a glob implementation in JavaScript.  It uses the `minimatch`
-+library to do its matching.
-+
-+## Attention: node-glob users!
-+
-+The API has changed dramatically between 2.x and 3.x. This library is
-+now 100% JavaScript, and the integer flags have been replaced with an
-+options object.
-+
-+Also, there's an event emitter class, proper tests, and all the other
-+things you've come to expect from node modules.
-+
-+And best of all, no compilation!
-+
-+## Usage
-+
-+```javascript
-+var glob = require("glob")
-+
-+// options is optional
-+glob("**/*.js", options, function (er, files) {
-+  // files is an array of filenames.
-+  // If the `nonull` option is set, and nothing
-+  // was found, then files is ["**/*.js"]
-+  // er is an error object or null.
-+})
-+```
-+
-+## Features
-+
-+Please see the [minimatch
-+documentation](https://github.com/isaacs/minimatch) for more details.
-+
-+Supports these glob features:
-+
-+* Brace Expansion
-+* Extended glob matching
-+* "Globstar" `**` matching
-+
-+See:
-+
-+* `man sh`
-+* `man bash`
-+* `man 3 fnmatch`
-+* `man 5 gitignore`
-+* [minimatch documentation](https://github.com/isaacs/minimatch)
-+
-+## glob(pattern, [options], cb)
-+
-+* `pattern` {String} Pattern to be matched
-+* `options` {Object}
-+* `cb` {Function}
-+  * `err` {Error | null}
-+  * `matches` {Array<String>} filenames found matching the pattern
-+
-+Perform an asynchronous glob search.
-+
-+## glob.sync(pattern, [options])
-+
-+* `pattern` {String} Pattern to be matched
-+* `options` {Object}
-+* return: {Array<String>} filenames found matching the pattern
-+
-+Perform a synchronous glob search.
-+
-+## Class: glob.Glob
-+
-+Create a Glob object by instanting the `glob.Glob` class.
-+
-+```javascript
-+var Glob = require("glob").Glob
-+var mg = new Glob(pattern, options, cb)
-+```
-+
-+It's an EventEmitter, and starts walking the filesystem to find matches
-+immediately.
-+
-+### new glob.Glob(pattern, [options], [cb])
-+
-+* `pattern` {String} pattern to search for
-+* `options` {Object}
-+* `cb` {Function} Called when an error occurs, or matches are found
-+  * `err` {Error | null}
-+  * `matches` {Array<String>} filenames found matching the pattern
-+
-+Note that if the `sync` flag is set in the options, then matches will
-+be immediately available on the `g.found` member.
-+
-+### Properties
-+
-+* `minimatch` The minimatch object that the glob uses.
-+* `options` The options object passed in.
-+* `error` The error encountered.  When an error is encountered, the
-+  glob object is in an undefined state, and should be discarded.
-+* `aborted` Boolean which is set to true when calling `abort()`.  There
-+  is no way at this time to continue a glob search after aborting, but
-+  you can re-use the statCache to avoid having to duplicate syscalls.
-+* `statCache` Collection of all the stat results the glob search
-+  performed.
-+* `cache` Convenience object.  Each field has the following possible
-+  values:
-+  * `false` - Path does not exist
-+  * `true` - Path exists
-+  * `1` - Path exists, and is not a directory
-+  * `2` - Path exists, and is a directory
-+  * `[file, entries, ...]` - Path exists, is a directory, and the
-+    array value is the results of `fs.readdir`
-+
-+### Events
-+
-+* `end` When the matching is finished, this is emitted with all the
-+  matches found.  If the `nonull` option is set, and no match was found,
-+  then the `matches` list contains the original pattern.  The matches
-+  are sorted, unless the `nosort` flag is set.
-+* `match` Every time a match is found, this is emitted with the matched.
-+* `error` Emitted when an unexpected error is encountered, or whenever
-+  any fs error occurs if `options.strict` is set.
-+* `abort` When `abort()` is called, this event is raised.
-+
-+### Methods
-+
-+* `abort` Stop the search.
-+
-+### Options
-+
-+All the options that can be passed to Minimatch can also be passed to
-+Glob to change pattern matching behavior.  Also, some have been added,
-+or have glob-specific ramifications.
-+
-+All options are false by default, unless otherwise noted.
-+
-+All options are added to the glob object, as well.
-+
-+* `cwd` The current working directory in which to search.  Defaults
-+  to `process.cwd()`.
-+* `root` The place where patterns starting with `/` will be mounted
-+  onto.  Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
-+  systems, and `C:\` or some such on Windows.)
-+* `dot` Include `.dot` files in normal matches and `globstar` matches.
-+  Note that an explicit dot in a portion of the pattern will always
-+  match dot files.
-+* `nomount` By default, a pattern starting with a forward-slash will be
-+  "mounted" onto the root setting, so that a valid filesystem path is
-+  returned.  Set this flag to disable that behavior.
-+* `mark` Add a `/` character to directory matches.  Note that this
-+  requires additional stat calls.
-+* `nosort` Don't sort the results.
-+* `stat` Set to true to stat *all* results.  This reduces performance
-+  somewhat, and is completely unnecessary, unless `readdir` is presumed
-+  to be an untrustworthy indicator of file existence.  It will cause
-+  ELOOP to be triggered one level sooner in the case of cyclical
-+  symbolic links.
-+* `silent` When an unusual error is encountered
-+  when attempting to read a directory, a warning will be printed to
-+  stderr.  Set the `silent` option to true to suppress these warnings.
-+* `strict` When an unusual error is encountered
-+  when attempting to read a directory, the process will just continue on
-+  in search of other matches.  Set the `strict` option to raise an error
-+  in these cases.
-+* `cache` See `cache` property above.  Pass in a previously generated
-+  cache object to save some fs calls.
-+* `statCache` A cache of results of filesystem information, to prevent
-+  unnecessary stat calls.  While it should not normally be necessary to
-+  set this, you may pass the statCache from one glob() call to the
-+  options object of another, if you know that the filesystem will not
-+  change between calls.  (See "Race Conditions" below.)
-+* `sync` Perform a synchronous glob search.
-+* `nounique` In some cases, brace-expanded patterns can result in the
-+  same file showing up multiple times in the result set.  By default,
-+  this implementation prevents duplicates in the result set.
-+  Set this flag to disable that behavior.
-+* `nonull` Set to never return an empty set, instead returning a set
-+  containing the pattern itself.  This is the default in glob(3).
-+* `nocase` Perform a case-insensitive match.  Note that case-insensitive
-+  filesystems will sometimes result in glob returning results that are
-+  case-insensitively matched anyway, since readdir and stat will not
-+  raise an error.
-+* `debug` Set to enable debug logging in minimatch and glob.
-+* `globDebug` Set to enable debug logging in glob, but not minimatch.
-+
-+## Comparisons to other fnmatch/glob implementations
-+
-+While strict compliance with the existing standards is a worthwhile
-+goal, some discrepancies exist between node-glob and other
-+implementations, and are intentional.
-+
-+If the pattern starts with a `!` character, then it is negated.  Set the
-+`nonegate` flag to suppress this behavior, and treat leading `!`
-+characters normally.  This is perhaps relevant if you wish to start the
-+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
-+characters at the start of a pattern will negate the pattern multiple
-+times.
-+
-+If a pattern starts with `#`, then it is treated as a comment, and
-+will not match anything.  Use `\#` to match a literal `#` at the
-+start of a line, or set the `nocomment` flag to suppress this behavior.
-+
-+The double-star character `**` is supported by default, unless the
-+`noglobstar` flag is set.  This is supported in the manner of bsdglob
-+and bash 4.1, where `**` only has special significance if it is the only
-+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
-+`a/**b` will not.
-+
-+If an escaped pattern has no matches, and the `nonull` flag is set,
-+then glob returns the pattern as-provided, rather than
-+interpreting the character escapes.  For example,
-+`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
-+that it does not resolve escaped pattern characters.
-+
-+If brace expansion is not disabled, then it is performed before any
-+other interpretation of the glob pattern.  Thus, a pattern like
-+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-+checked for validity.  Since those two are valid, matching proceeds.
-+
-+## Windows
-+
-+**Please only use forward-slashes in glob expressions.**
-+
-+Though windows uses either `/` or `\` as its path separator, only `/`
-+characters are used by this glob implementation.  You must use
-+forward-slashes **only** in glob expressions.  Back-slashes will always
-+be interpreted as escape characters, not path separators.
-+
-+Results from absolute patterns such as `/foo/*` are mounted onto the
-+root setting using `path.join`.  On windows, this will by default result
-+in `/foo/*` matching `C:\foo\bar.txt`.
-+
-+## Race Conditions
-+
-+Glob searching, by its very nature, is susceptible to race conditions,
-+since it relies on directory walking and such.
-+
-+As a result, it is possible that a file that exists when glob looks for
-+it may have been deleted or modified by the time it returns the result.
-+
-+As part of its internal implementation, this program caches all stat
-+and readdir calls that it makes, in order to cut down on system
-+overhead.  However, this also makes it even more susceptible to races,
-+especially if the cache or statCache objects are reused between glob
-+calls.
-+
-+Users are thus advised not to use a glob result as a guarantee of
-+filesystem state in the face of rapid changes.  For the vast majority
-+of operations, this is never a problem.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/examples/g.js
-@@ -0,0 +1,9 @@
-+var Glob = require("../").Glob
-+
-+var pattern = "test/a/**/[cg]/../[cg]"
-+console.log(pattern)
-+
-+var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
-+  console.log("matches", matches)
-+})
-+console.log("after")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/examples/usr-local.js
-@@ -0,0 +1,9 @@
-+var Glob = require("../").Glob
-+
-+var pattern = "{./*/*,/*,/usr/local/*}"
-+console.log(pattern)
-+
-+var mg = new Glob(pattern, {mark: true}, function (er, matches) {
-+  console.log("matches", matches)
-+})
-+console.log("after")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/glob.js
-@@ -0,0 +1,728 @@
-+// Approach:
-+//
-+// 1. Get the minimatch set
-+// 2. For each pattern in the set, PROCESS(pattern)
-+// 3. Store matches per-set, then uniq them
-+//
-+// PROCESS(pattern)
-+// Get the first [n] items from pattern that are all strings
-+// Join these together.  This is PREFIX.
-+//   If there is no more remaining, then stat(PREFIX) and
-+//   add to matches if it succeeds.  END.
-+// readdir(PREFIX) as ENTRIES
-+//   If fails, END
-+//   If pattern[n] is GLOBSTAR
-+//     // handle the case where the globstar match is empty
-+//     // by pruning it out, and testing the resulting pattern
-+//     PROCESS(pattern[0..n] + pattern[n+1 .. $])
-+//     // handle other cases.
-+//     for ENTRY in ENTRIES (not dotfiles)
-+//       // attach globstar + tail onto the entry
-+//       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
-+//
-+//   else // not globstar
-+//     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
-+//       Test ENTRY against pattern[n]
-+//       If fails, continue
-+//       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
-+//
-+// Caveat:
-+//   Cache all stats and readdirs results to minimize syscall.  Since all
-+//   we ever care about is existence and directory-ness, we can just keep
-+//   `true` for files, and [children,...] for directories, or `false` for
-+//   things that don't exist.
-+
-+
-+
-+module.exports = glob
-+
-+var fs = require("fs")
-+, minimatch = require("minimatch")
-+, Minimatch = minimatch.Minimatch
-+, inherits = require("inherits")
-+, EE = require("events").EventEmitter
-+, path = require("path")
-+, isDir = {}
-+, assert = require("assert").ok
-+
-+function glob (pattern, options, cb) {
-+  if (typeof options === "function") cb = options, options = {}
-+  if (!options) options = {}
-+
-+  if (typeof options === "number") {
-+    deprecated()
-+    return
-+  }
-+
-+  var g = new Glob(pattern, options, cb)
-+  return g.sync ? g.found : g
-+}
-+
-+glob.fnmatch = deprecated
-+
-+function deprecated () {
-+  throw new Error("glob's interface has changed. Please see the docs.")
-+}
-+
-+glob.sync = globSync
-+function globSync (pattern, options) {
-+  if (typeof options === "number") {
-+    deprecated()
-+    return
-+  }
-+
-+  options = options || {}
-+  options.sync = true
-+  return glob(pattern, options)
-+}
-+
-+this._processingEmitQueue = false
-+
-+glob.Glob = Glob
-+inherits(Glob, EE)
-+function Glob (pattern, options, cb) {
-+  if (!(this instanceof Glob)) {
-+    return new Glob(pattern, options, cb)
-+  }
-+
-+  if (typeof options === "function") {
-+    cb = options
-+    options = null
-+  }
-+
-+  if (typeof cb === "function") {
-+    this.on("error", cb)
-+    this.on("end", function (matches) {
-+      cb(null, matches)
-+    })
-+  }
-+
-+  options = options || {}
-+
-+  this._endEmitted = false
-+  this.EOF = {}
-+  this._emitQueue = []
-+
-+  this.paused = false
-+  this._processingEmitQueue = false
-+
-+  this.maxDepth = options.maxDepth || 1000
-+  this.maxLength = options.maxLength || Infinity
-+  this.cache = options.cache || {}
-+  this.statCache = options.statCache || {}
-+
-+  this.changedCwd = false
-+  var cwd = process.cwd()
-+  if (!options.hasOwnProperty("cwd")) this.cwd = cwd
-+  else {
-+    this.cwd = options.cwd
-+    this.changedCwd = path.resolve(options.cwd) !== cwd
-+  }
-+
-+  this.root = options.root || path.resolve(this.cwd, "/")
-+  this.root = path.resolve(this.root)
-+  if (process.platform === "win32")
-+    this.root = this.root.replace(/\\/g, "/")
-+
-+  this.nomount = !!options.nomount
-+
-+  if (!pattern) {
-+    throw new Error("must provide pattern")
-+  }
-+
-+  // base-matching: just use globstar for that.
-+  if (options.matchBase && -1 === pattern.indexOf("/")) {
-+    if (options.noglobstar) {
-+      throw new Error("base matching requires globstar")
-+    }
-+    pattern = "**/" + pattern
-+  }
-+
-+  this.strict = options.strict !== false
-+  this.dot = !!options.dot
-+  this.mark = !!options.mark
-+  this.sync = !!options.sync
-+  this.nounique = !!options.nounique
-+  this.nonull = !!options.nonull
-+  this.nosort = !!options.nosort
-+  this.nocase = !!options.nocase
-+  this.stat = !!options.stat
-+
-+  this.debug = !!options.debug || !!options.globDebug
-+  if (this.debug)
-+    this.log = console.error
-+
-+  this.silent = !!options.silent
-+
-+  var mm = this.minimatch = new Minimatch(pattern, options)
-+  this.options = mm.options
-+  pattern = this.pattern = mm.pattern
-+
-+  this.error = null
-+  this.aborted = false
-+
-+  // list of all the patterns that ** has resolved do, so
-+  // we can avoid visiting multiple times.
-+  this._globstars = {}
-+
-+  EE.call(this)
-+
-+  // process each pattern in the minimatch set
-+  var n = this.minimatch.set.length
-+
-+  // The matches are stored as {<filename>: true,...} so that
-+  // duplicates are automagically pruned.
-+  // Later, we do an Object.keys() on these.
-+  // Keep them as a list so we can fill in when nonull is set.
-+  this.matches = new Array(n)
-+
-+  this.minimatch.set.forEach(iterator.bind(this))
-+  function iterator (pattern, i, set) {
-+    this._process(pattern, 0, i, function (er) {
-+      if (er) this.emit("error", er)
-+      if (-- n <= 0) this._finish()
-+    })
-+  }
-+}
-+
-+Glob.prototype.log = function () {}
-+
-+Glob.prototype._finish = function () {
-+  assert(this instanceof Glob)
-+
-+  var nou = this.nounique
-+  , all = nou ? [] : {}
-+
-+  for (var i = 0, l = this.matches.length; i < l; i ++) {
-+    var matches = this.matches[i]
-+    this.log("matches[%d] =", i, matches)
-+    // do like the shell, and spit out the literal glob
-+    if (!matches) {
-+      if (this.nonull) {
-+        var literal = this.minimatch.globSet[i]
-+        if (nou) all.push(literal)
-+        else all[literal] = true
-+      }
-+    } else {
-+      // had matches
-+      var m = Object.keys(matches)
-+      if (nou) all.push.apply(all, m)
-+      else m.forEach(function (m) {
-+        all[m] = true
-+      })
-+    }
-+  }
-+
-+  if (!nou) all = Object.keys(all)
-+
-+  if (!this.nosort) {
-+    all = all.sort(this.nocase ? alphasorti : alphasort)
-+  }
-+
-+  if (this.mark) {
-+    // at *some* point we statted all of these
-+    all = all.map(this._mark, this)
-+  }
-+
-+  this.log("emitting end", all)
-+
-+  this.EOF = this.found = all
-+  this.emitMatch(this.EOF)
-+}
-+
-+function alphasorti (a, b) {
-+  a = a.toLowerCase()
-+  b = b.toLowerCase()
-+  return alphasort(a, b)
-+}
-+
-+function alphasort (a, b) {
-+  return a > b ? 1 : a < b ? -1 : 0
-+}
-+
-+Glob.prototype._mark = function (p) {
-+  var c = this.cache[p]
-+  var m = p
-+  if (c) {
-+    var isDir = c === 2 || Array.isArray(c)
-+    var slash = p.slice(-1) === '/'
-+
-+    if (isDir && !slash)
-+      m += '/'
-+    else if (!isDir && slash)
-+      m = m.slice(0, -1)
-+
-+    if (m !== p) {
-+      this.statCache[m] = this.statCache[p]
-+      this.cache[m] = this.cache[p]
-+    }
-+  }
-+
-+  return m
-+}
-+
-+Glob.prototype.abort = function () {
-+  this.aborted = true
-+  this.emit("abort")
-+}
-+
-+Glob.prototype.pause = function () {
-+  if (this.paused) return
-+  if (this.sync)
-+    this.emit("error", new Error("Can't pause/resume sync glob"))
-+  this.paused = true
-+  this.emit("pause")
-+}
-+
-+Glob.prototype.resume = function () {
-+  if (!this.paused) return
-+  if (this.sync)
-+    this.emit("error", new Error("Can't pause/resume sync glob"))
-+  this.paused = false
-+  this.emit("resume")
-+  this._processEmitQueue()
-+  //process.nextTick(this.emit.bind(this, "resume"))
-+}
-+
-+Glob.prototype.emitMatch = function (m) {
-+  this.log('emitMatch', m)
-+  this._emitQueue.push(m)
-+  this._processEmitQueue()
-+}
-+
-+Glob.prototype._processEmitQueue = function (m) {
-+  this.log("pEQ paused=%j processing=%j m=%j", this.paused,
-+           this._processingEmitQueue, m)
-+  var done = false
-+  while (!this._processingEmitQueue &&
-+         !this.paused) {
-+    this._processingEmitQueue = true
-+    var m = this._emitQueue.shift()
-+    this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m)
-+    if (!m) {
-+      this.log(">processEmitQueue, falsey m")
-+      this._processingEmitQueue = false
-+      break
-+    }
-+
-+    if (m === this.EOF || !(this.mark && !this.stat)) {
-+      this.log("peq: unmarked, or eof")
-+      next.call(this, 0, false)
-+    } else if (this.statCache[m]) {
-+      var sc = this.statCache[m]
-+      var exists
-+      if (sc)
-+        exists = sc.isDirectory() ? 2 : 1
-+      this.log("peq: stat cached")
-+      next.call(this, exists, exists === 2)
-+    } else {
-+      this.log("peq: _stat, then next")
-+      this._stat(m, next)
-+    }
-+
-+    function next(exists, isDir) {
-+      this.log("next", m, exists, isDir)
-+      var ev = m === this.EOF ? "end" : "match"
-+
-+      // "end" can only happen once.
-+      assert(!this._endEmitted)
-+      if (ev === "end")
-+        this._endEmitted = true
-+
-+      if (exists) {
-+        // Doesn't mean it necessarily doesn't exist, it's possible
-+        // we just didn't check because we don't care that much, or
-+        // this is EOF anyway.
-+        if (isDir && !m.match(/\/$/)) {
-+          m = m + "/"
-+        } else if (!isDir && m.match(/\/$/)) {
-+          m = m.replace(/\/+$/, "")
-+        }
-+      }
-+      this.log("emit", ev, m)
-+      this.emit(ev, m)
-+      this._processingEmitQueue = false
-+      if (done && m !== this.EOF && !this.paused)
-+        this._processEmitQueue()
-+    }
-+  }
-+  done = true
-+}
-+
-+Glob.prototype._process = function (pattern, depth, index, cb_) {
-+  assert(this instanceof Glob)
-+
-+  var cb = function cb (er, res) {
-+    assert(this instanceof Glob)
-+    if (this.paused) {
-+      if (!this._processQueue) {
-+        this._processQueue = []
-+        this.once("resume", function () {
-+          var q = this._processQueue
-+          this._processQueue = null
-+          q.forEach(function (cb) { cb() })
-+        })
-+      }
-+      this._processQueue.push(cb_.bind(this, er, res))
-+    } else {
-+      cb_.call(this, er, res)
-+    }
-+  }.bind(this)
-+
-+  if (this.aborted) return cb()
-+
-+  if (depth > this.maxDepth) return cb()
-+
-+  // Get the first [n] parts of pattern that are all strings.
-+  var n = 0
-+  while (typeof pattern[n] === "string") {
-+    n ++
-+  }
-+  // now n is the index of the first one that is *not* a string.
-+
-+  // see if there's anything else
-+  var prefix
-+  switch (n) {
-+    // if not, then this is rather simple
-+    case pattern.length:
-+      prefix = pattern.join("/")
-+      this._stat(prefix, function (exists, isDir) {
-+        // either it's there, or it isn't.
-+        // nothing more to do, either way.
-+        if (exists) {
-+          if (prefix && isAbsolute(prefix) && !this.nomount) {
-+            if (prefix.charAt(0) === "/") {
-+              prefix = path.join(this.root, prefix)
-+            } else {
-+              prefix = path.resolve(this.root, prefix)
-+            }
-+          }
-+
-+          if (process.platform === "win32")
-+            prefix = prefix.replace(/\\/g, "/")
-+
-+          this.matches[index] = this.matches[index] || {}
-+          this.matches[index][prefix] = true
-+          this.emitMatch(prefix)
-+        }
-+        return cb()
-+      })
-+      return
-+
-+    case 0:
-+      // pattern *starts* with some non-trivial item.
-+      // going to readdir(cwd), but not include the prefix in matches.
-+      prefix = null
-+      break
-+
-+    default:
-+      // pattern has some string bits in the front.
-+      // whatever it starts with, whether that's "absolute" like /foo/bar,
-+      // or "relative" like "../baz"
-+      prefix = pattern.slice(0, n)
-+      prefix = prefix.join("/")
-+      break
-+  }
-+
-+  // get the list of entries.
-+  var read
-+  if (prefix === null) read = "."
-+  else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
-+    if (!prefix || !isAbsolute(prefix)) {
-+      prefix = path.join("/", prefix)
-+    }
-+    read = prefix = path.resolve(prefix)
-+
-+    // if (process.platform === "win32")
-+    //   read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
-+
-+    this.log('absolute: ', prefix, this.root, pattern, read)
-+  } else {
-+    read = prefix
-+  }
-+
-+  this.log('readdir(%j)', read, this.cwd, this.root)
-+
-+  return this._readdir(read, function (er, entries) {
-+    if (er) {
-+      // not a directory!
-+      // this means that, whatever else comes after this, it can never match
-+      return cb()
-+    }
-+
-+    // globstar is special
-+    if (pattern[n] === minimatch.GLOBSTAR) {
-+      // test without the globstar, and with every child both below
-+      // and replacing the globstar.
-+      var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
-+      entries.forEach(function (e) {
-+        if (e.charAt(0) === "." && !this.dot) return
-+        // instead of the globstar
-+        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
-+        // below the globstar
-+        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
-+      }, this)
-+
-+      s = s.filter(function (pattern) {
-+        var key = gsKey(pattern)
-+        var seen = !this._globstars[key]
-+        this._globstars[key] = true
-+        return seen
-+      }, this)
-+
-+      if (!s.length)
-+        return cb()
-+
-+      // now asyncForEach over this
-+      var l = s.length
-+      , errState = null
-+      s.forEach(function (gsPattern) {
-+        this._process(gsPattern, depth + 1, index, function (er) {
-+          if (errState) return
-+          if (er) return cb(errState = er)
-+          if (--l <= 0) return cb()
-+        })
-+      }, this)
-+
-+      return
-+    }
-+
-+    // not a globstar
-+    // It will only match dot entries if it starts with a dot, or if
-+    // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
-+    var pn = pattern[n]
-+    var rawGlob = pattern[n]._glob
-+    , dotOk = this.dot || rawGlob.charAt(0) === "."
-+
-+    entries = entries.filter(function (e) {
-+      return (e.charAt(0) !== "." || dotOk) &&
-+             e.match(pattern[n])
-+    })
-+
-+    // If n === pattern.length - 1, then there's no need for the extra stat
-+    // *unless* the user has specified "mark" or "stat" explicitly.
-+    // We know that they exist, since the readdir returned them.
-+    if (n === pattern.length - 1 &&
-+        !this.mark &&
-+        !this.stat) {
-+      entries.forEach(function (e) {
-+        if (prefix) {
-+          if (prefix !== "/") e = prefix + "/" + e
-+          else e = prefix + e
-+        }
-+        if (e.charAt(0) === "/" && !this.nomount) {
-+          e = path.join(this.root, e)
-+        }
-+
-+        if (process.platform === "win32")
-+          e = e.replace(/\\/g, "/")
-+
-+        this.matches[index] = this.matches[index] || {}
-+        this.matches[index][e] = true
-+        this.emitMatch(e)
-+      }, this)
-+      return cb.call(this)
-+    }
-+
-+
-+    // now test all the remaining entries as stand-ins for that part
-+    // of the pattern.
-+    var l = entries.length
-+    , errState = null
-+    if (l === 0) return cb() // no matches possible
-+    entries.forEach(function (e) {
-+      var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
-+      this._process(p, depth + 1, index, function (er) {
-+        if (errState) return
-+        if (er) return cb(errState = er)
-+        if (--l === 0) return cb.call(this)
-+      })
-+    }, this)
-+  })
-+
-+}
-+
-+function gsKey (pattern) {
-+  return '**' + pattern.map(function (p) {
-+    return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
-+  }).join('/')
-+}
-+
-+Glob.prototype._stat = function (f, cb) {
-+  assert(this instanceof Glob)
-+  var abs = f
-+  if (f.charAt(0) === "/") {
-+    abs = path.join(this.root, f)
-+  } else if (this.changedCwd) {
-+    abs = path.resolve(this.cwd, f)
-+  }
-+
-+  if (f.length > this.maxLength) {
-+    var er = new Error("Path name too long")
-+    er.code = "ENAMETOOLONG"
-+    er.path = f
-+    return this._afterStat(f, abs, cb, er)
-+  }
-+
-+  this.log('stat', [this.cwd, f, '=', abs])
-+
-+  if (!this.stat && this.cache.hasOwnProperty(f)) {
-+    var exists = this.cache[f]
-+    , isDir = exists && (Array.isArray(exists) || exists === 2)
-+    if (this.sync) return cb.call(this, !!exists, isDir)
-+    return process.nextTick(cb.bind(this, !!exists, isDir))
-+  }
-+
-+  var stat = this.statCache[abs]
-+  if (this.sync || stat) {
-+    var er
-+    try {
-+      stat = fs.statSync(abs)
-+    } catch (e) {
-+      er = e
-+    }
-+    this._afterStat(f, abs, cb, er, stat)
-+  } else {
-+    fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
-+  }
-+}
-+
-+Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
-+  var exists
-+  assert(this instanceof Glob)
-+
-+  if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
-+    this.log("should be ENOTDIR, fake it")
-+
-+    er = new Error("ENOTDIR, not a directory '" + abs + "'")
-+    er.path = abs
-+    er.code = "ENOTDIR"
-+    stat = null
-+  }
-+
-+  var emit = !this.statCache[abs]
-+  this.statCache[abs] = stat
-+
-+  if (er || !stat) {
-+    exists = false
-+  } else {
-+    exists = stat.isDirectory() ? 2 : 1
-+    if (emit)
-+      this.emit('stat', f, stat)
-+  }
-+  this.cache[f] = this.cache[f] || exists
-+  cb.call(this, !!exists, exists === 2)
-+}
-+
-+Glob.prototype._readdir = function (f, cb) {
-+  assert(this instanceof Glob)
-+  var abs = f
-+  if (f.charAt(0) === "/") {
-+    abs = path.join(this.root, f)
-+  } else if (isAbsolute(f)) {
-+    abs = f
-+  } else if (this.changedCwd) {
-+    abs = path.resolve(this.cwd, f)
-+  }
-+
-+  if (f.length > this.maxLength) {
-+    var er = new Error("Path name too long")
-+    er.code = "ENAMETOOLONG"
-+    er.path = f
-+    return this._afterReaddir(f, abs, cb, er)
-+  }
-+
-+  this.log('readdir', [this.cwd, f, abs])
-+  if (this.cache.hasOwnProperty(f)) {
-+    var c = this.cache[f]
-+    if (Array.isArray(c)) {
-+      if (this.sync) return cb.call(this, null, c)
-+      return process.nextTick(cb.bind(this, null, c))
-+    }
-+
-+    if (!c || c === 1) {
-+      // either ENOENT or ENOTDIR
-+      var code = c ? "ENOTDIR" : "ENOENT"
-+      , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
-+      er.path = f
-+      er.code = code
-+      this.log(f, er)
-+      if (this.sync) return cb.call(this, er)
-+      return process.nextTick(cb.bind(this, er))
-+    }
-+
-+    // at this point, c === 2, meaning it's a dir, but we haven't
-+    // had to read it yet, or c === true, meaning it's *something*
-+    // but we don't have any idea what.  Need to read it, either way.
-+  }
-+
-+  if (this.sync) {
-+    var er, entries
-+    try {
-+      entries = fs.readdirSync(abs)
-+    } catch (e) {
-+      er = e
-+    }
-+    return this._afterReaddir(f, abs, cb, er, entries)
-+  }
-+
-+  fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
-+}
-+
-+Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
-+  assert(this instanceof Glob)
-+  if (entries && !er) {
-+    this.cache[f] = entries
-+    // if we haven't asked to stat everything for suresies, then just
-+    // assume that everything in there exists, so we can avoid
-+    // having to stat it a second time.  This also gets us one step
-+    // further into ELOOP territory.
-+    if (!this.mark && !this.stat) {
-+      entries.forEach(function (e) {
-+        if (f === "/") e = f + e
-+        else e = f + "/" + e
-+        this.cache[e] = true
-+      }, this)
-+    }
-+
-+    return cb.call(this, er, entries)
-+  }
-+
-+  // now handle errors, and cache the information
-+  if (er) switch (er.code) {
-+    case "ENOTDIR": // totally normal. means it *does* exist.
-+      this.cache[f] = 1
-+      return cb.call(this, er)
-+    case "ENOENT": // not terribly unusual
-+    case "ELOOP":
-+    case "ENAMETOOLONG":
-+    case "UNKNOWN":
-+      this.cache[f] = false
-+      return cb.call(this, er)
-+    default: // some unusual error.  Treat as failure.
-+      this.cache[f] = false
-+      if (this.strict) this.emit("error", er)
-+      if (!this.silent) console.error("glob error", er)
-+      return cb.call(this, er)
-+  }
-+}
-+
-+var isAbsolute = process.platform === "win32" ? absWin : absUnix
-+
-+function absWin (p) {
-+  if (absUnix(p)) return true
-+  // pull off the device/UNC bit from a windows path.
-+  // from node's lib/path.js
-+  var splitDeviceRe =
-+      /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
-+    , result = splitDeviceRe.exec(p)
-+    , device = result[1] || ''
-+    , isUnc = device && device.charAt(1) !== ':'
-+    , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
-+
-+  return isAbsolute
-+}
-+
-+function absUnix (p) {
-+  return p.charAt(0) === "/" || p === ""
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/LICENSE
-@@ -0,0 +1,16 @@
-+The ISC License
-+
-+Copyright (c) Isaac Z. Schlueter
-+
-+Permission to use, copy, modify, and/or distribute this software for any
-+purpose with or without fee is hereby granted, provided that the above
-+copyright notice and this permission notice appear in all copies.
-+
-+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+PERFORMANCE OF THIS SOFTWARE.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/README.md
-@@ -0,0 +1,42 @@
-+Browser-friendly inheritance fully compatible with standard node.js
-+[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
-+
-+This package exports standard `inherits` from node.js `util` module in
-+node environment, but also provides alternative browser-friendly
-+implementation through [browser
-+field](https://gist.github.com/shtylman/4339901). Alternative
-+implementation is a literal copy of standard one located in standalone
-+module to avoid requiring of `util`. It also has a shim for old
-+browsers with no `Object.create` support.
-+
-+While keeping you sure you are using standard `inherits`
-+implementation in node.js environment, it allows bundlers such as
-+[browserify](https://github.com/substack/node-browserify) to not
-+include full `util` package to your client code if all you need is
-+just `inherits` function. It worth, because browser shim for `util`
-+package is large and `inherits` is often the single function you need
-+from it.
-+
-+It's recommended to use this package instead of
-+`require('util').inherits` for any code that has chances to be used
-+not only in node.js but in browser too.
-+
-+## usage
-+
-+```js
-+var inherits = require('inherits');
-+// then use exactly as the standard one
-+```
-+
-+## note on version ~1.0
-+
-+Version ~1.0 had completely different motivation and is not compatible
-+neither with 2.0 nor with standard node.js `inherits`.
-+
-+If you are using version ~1.0 and planning to switch to ~2.0, be
-+careful:
-+
-+* new version uses `super_` instead of `super` for referencing
-+  superclass
-+* new version overwrites current prototype while old one preserves any
-+  existing fields on it
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/inherits.js
-@@ -0,0 +1 @@
-+module.exports = require('util').inherits
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/inherits_browser.js
-@@ -0,0 +1,23 @@
-+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
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "inherits",
-+  "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
-+  "version": "2.0.1",
-+  "keywords": [
-+    "inheritance",
-+    "class",
-+    "klass",
-+    "oop",
-+    "object-oriented",
-+    "inherits",
-+    "browser",
-+    "browserify"
-+  ],
-+  "main": "./inherits.js",
-+  "browser": "./inherits_browser.js",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/inherits"
-+  },
-+  "license": "ISC",
-+  "scripts": {
-+    "test": "node test"
-+  },
-+  "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n  superclass\n* new version overwrites current prototype while old one preserves any\n  existing fields on it\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/inherits/issues"
-+  },
-+  "_id": "inherits at 2.0.1",
-+  "_from": "inherits at 2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/inherits/test.js
-@@ -0,0 +1,25 @@
-+var inherits = require('./inherits.js')
-+var assert = require('assert')
-+
-+function test(c) {
-+  assert(c.constructor === Child)
-+  assert(c.constructor.super_ === Parent)
-+  assert(Object.getPrototypeOf(c) === Child.prototype)
-+  assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
-+  assert(c instanceof Child)
-+  assert(c instanceof Parent)
-+}
-+
-+function Child() {
-+  Parent.call(this)
-+  test(this)
-+}
-+
-+function Parent() {}
-+
-+inherits(Child, Parent)
-+
-+var c = new Child
-+test(c)
-+
-+console.log('ok')
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/.npmignore
-@@ -0,0 +1 @@
-+node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-+All rights reserved.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/README.md
-@@ -0,0 +1,218 @@
-+# minimatch
-+
-+A minimal matching utility.
-+
-+[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
-+
-+
-+This is the matching library used internally by npm.
-+
-+Eventually, it will replace the C binding in node-glob.
-+
-+It works by converting glob expressions into JavaScript `RegExp`
-+objects.
-+
-+## Usage
-+
-+```javascript
-+var minimatch = require("minimatch")
-+
-+minimatch("bar.foo", "*.foo") // true!
-+minimatch("bar.foo", "*.bar") // false!
-+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
-+```
-+
-+## Features
-+
-+Supports these glob features:
-+
-+* Brace Expansion
-+* Extended glob matching
-+* "Globstar" `**` matching
-+
-+See:
-+
-+* `man sh`
-+* `man bash`
-+* `man 3 fnmatch`
-+* `man 5 gitignore`
-+
-+## Minimatch Class
-+
-+Create a minimatch object by instanting the `minimatch.Minimatch` class.
-+
-+```javascript
-+var Minimatch = require("minimatch").Minimatch
-+var mm = new Minimatch(pattern, options)
-+```
-+
-+### Properties
-+
-+* `pattern` The original pattern the minimatch object represents.
-+* `options` The options supplied to the constructor.
-+* `set` A 2-dimensional array of regexp or string expressions.
-+  Each row in the
-+  array corresponds to a brace-expanded pattern.  Each item in the row
-+  corresponds to a single path-part.  For example, the pattern
-+  `{a,b/c}/d` would expand to a set of patterns like:
-+
-+        [ [ a, d ]
-+        , [ b, c, d ] ]
-+
-+    If a portion of the pattern doesn't have any "magic" in it
-+    (that is, it's something like `"foo"` rather than `fo*o?`), then it
-+    will be left as a string rather than converted to a regular
-+    expression.
-+
-+* `regexp` Created by the `makeRe` method.  A single regular expression
-+  expressing the entire pattern.  This is useful in cases where you wish
-+  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
-+* `negate` True if the pattern is negated.
-+* `comment` True if the pattern is a comment.
-+* `empty` True if the pattern is `""`.
-+
-+### Methods
-+
-+* `makeRe` Generate the `regexp` member if necessary, and return it.
-+  Will return `false` if the pattern is invalid.
-+* `match(fname)` Return true if the filename matches the pattern, or
-+  false otherwise.
-+* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
-+  filename, and match it against a single row in the `regExpSet`.  This
-+  method is mainly for internal use, but is exposed so that it can be
-+  used by a glob-walker that needs to avoid excessive filesystem calls.
-+
-+All other methods are internal, and will be called as necessary.
-+
-+## Functions
-+
-+The top-level exported function has a `cache` property, which is an LRU
-+cache set to store 100 items.  So, calling these methods repeatedly
-+with the same pattern and options will use the same Minimatch object,
-+saving the cost of parsing it multiple times.
-+
-+### minimatch(path, pattern, options)
-+
-+Main export.  Tests a path against the pattern using the options.
-+
-+```javascript
-+var isJS = minimatch(file, "*.js", { matchBase: true })
-+```
-+
-+### minimatch.filter(pattern, options)
-+
-+Returns a function that tests its
-+supplied argument, suitable for use with `Array.filter`.  Example:
-+
-+```javascript
-+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
-+```
-+
-+### minimatch.match(list, pattern, options)
-+
-+Match against the list of
-+files, in the style of fnmatch or glob.  If nothing is matched, and
-+options.nonull is set, then return a list containing the pattern itself.
-+
-+```javascript
-+var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
-+```
-+
-+### minimatch.makeRe(pattern, options)
-+
-+Make a regular expression object from the pattern.
-+
-+## Options
-+
-+All options are `false` by default.
-+
-+### debug
-+
-+Dump a ton of stuff to stderr.
-+
-+### nobrace
-+
-+Do not expand `{a,b}` and `{1..3}` brace sets.
-+
-+### noglobstar
-+
-+Disable `**` matching against multiple folder names.
-+
-+### dot
-+
-+Allow patterns to match filenames starting with a period, even if
-+the pattern does not explicitly have a period in that spot.
-+
-+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
-+is set.
-+
-+### noext
-+
-+Disable "extglob" style patterns like `+(a|b)`.
-+
-+### nocase
-+
-+Perform a case-insensitive match.
-+
-+### nonull
-+
-+When a match is not found by `minimatch.match`, return a list containing
-+the pattern itself if this option is set.  When not set, an empty list
-+is returned if there are no matches.
-+
-+### matchBase
-+
-+If set, then patterns without slashes will be matched
-+against the basename of the path if it contains slashes.  For example,
-+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-+
-+### nocomment
-+
-+Suppress the behavior of treating `#` at the start of a pattern as a
-+comment.
-+
-+### nonegate
-+
-+Suppress the behavior of treating a leading `!` character as negation.
-+
-+### flipNegate
-+
-+Returns from negate expressions the same as if they were not negated.
-+(Ie, true on a hit, false on a miss.)
-+
-+
-+## Comparisons to other fnmatch/glob implementations
-+
-+While strict compliance with the existing standards is a worthwhile
-+goal, some discrepancies exist between minimatch and other
-+implementations, and are intentional.
-+
-+If the pattern starts with a `!` character, then it is negated.  Set the
-+`nonegate` flag to suppress this behavior, and treat leading `!`
-+characters normally.  This is perhaps relevant if you wish to start the
-+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
-+characters at the start of a pattern will negate the pattern multiple
-+times.
-+
-+If a pattern starts with `#`, then it is treated as a comment, and
-+will not match anything.  Use `\#` to match a literal `#` at the
-+start of a line, or set the `nocomment` flag to suppress this behavior.
-+
-+The double-star character `**` is supported by default, unless the
-+`noglobstar` flag is set.  This is supported in the manner of bsdglob
-+and bash 4.1, where `**` only has special significance if it is the only
-+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
-+`a/**b` will not.
-+
-+If an escaped pattern has no matches, and the `nonull` flag is set,
-+then minimatch.match returns the pattern as-provided, rather than
-+interpreting the character escapes.  For example,
-+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
-+that it does not resolve escaped pattern characters.
-+
-+If brace expansion is not disabled, then it is performed before any
-+other interpretation of the glob pattern.  Thus, a pattern like
-+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-+checked for validity.  Since those two are valid, matching proceeds.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/minimatch.js
-@@ -0,0 +1,1061 @@
-+;(function (require, exports, module, platform) {
-+
-+if (module) module.exports = minimatch
-+else exports.minimatch = minimatch
-+
-+if (!require) {
-+  require = function (id) {
-+    switch (id) {
-+      case "sigmund": return function sigmund (obj) {
-+        return JSON.stringify(obj)
-+      }
-+      case "path": return { basename: function (f) {
-+        f = f.split(/[\/\\]/)
-+        var e = f.pop()
-+        if (!e) e = f.pop()
-+        return e
-+      }}
-+      case "lru-cache": return function LRUCache () {
-+        // not quite an LRU, but still space-limited.
-+        var cache = {}
-+        var cnt = 0
-+        this.set = function (k, v) {
-+          cnt ++
-+          if (cnt >= 100) cache = {}
-+          cache[k] = v
-+        }
-+        this.get = function (k) { return cache[k] }
-+      }
-+    }
-+  }
-+}
-+
-+minimatch.Minimatch = Minimatch
-+
-+var LRU = require("lru-cache")
-+  , cache = minimatch.cache = new LRU({max: 100})
-+  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
-+  , sigmund = require("sigmund")
-+
-+var path = require("path")
-+  // any single thing other than /
-+  // don't need to escape / when using new RegExp()
-+  , qmark = "[^/]"
-+
-+  // * => any number of characters
-+  , star = qmark + "*?"
-+
-+  // ** when dots are allowed.  Anything goes, except .. and .
-+  // not (^ or / followed by one or two dots followed by $ or /),
-+  // followed by anything, any number of times.
-+  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
-+
-+  // not a ^ or / followed by a dot,
-+  // followed by anything, any number of times.
-+  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
-+
-+  // characters that need to be escaped in RegExp.
-+  , reSpecials = charSet("().*{}+?[]^$\\!")
-+
-+// "abc" -> { a:true, b:true, c:true }
-+function charSet (s) {
-+  return s.split("").reduce(function (set, c) {
-+    set[c] = true
-+    return set
-+  }, {})
-+}
-+
-+// normalizes slashes.
-+var slashSplit = /\/+/
-+
-+minimatch.filter = filter
-+function filter (pattern, options) {
-+  options = options || {}
-+  return function (p, i, list) {
-+    return minimatch(p, pattern, options)
-+  }
-+}
-+
-+function ext (a, b) {
-+  a = a || {}
-+  b = b || {}
-+  var t = {}
-+  Object.keys(b).forEach(function (k) {
-+    t[k] = b[k]
-+  })
-+  Object.keys(a).forEach(function (k) {
-+    t[k] = a[k]
-+  })
-+  return t
-+}
-+
-+minimatch.defaults = function (def) {
-+  if (!def || !Object.keys(def).length) return minimatch
-+
-+  var orig = minimatch
-+
-+  var m = function minimatch (p, pattern, options) {
-+    return orig.minimatch(p, pattern, ext(def, options))
-+  }
-+
-+  m.Minimatch = function Minimatch (pattern, options) {
-+    return new orig.Minimatch(pattern, ext(def, options))
-+  }
-+
-+  return m
-+}
-+
-+Minimatch.defaults = function (def) {
-+  if (!def || !Object.keys(def).length) return Minimatch
-+  return minimatch.defaults(def).Minimatch
-+}
-+
-+
-+function minimatch (p, pattern, options) {
-+  if (typeof pattern !== "string") {
-+    throw new TypeError("glob pattern string required")
-+  }
-+
-+  if (!options) options = {}
-+
-+  // shortcut: comments match nothing.
-+  if (!options.nocomment && pattern.charAt(0) === "#") {
-+    return false
-+  }
-+
-+  // "" only matches ""
-+  if (pattern.trim() === "") return p === ""
-+
-+  return new Minimatch(pattern, options).match(p)
-+}
-+
-+function Minimatch (pattern, options) {
-+  if (!(this instanceof Minimatch)) {
-+    return new Minimatch(pattern, options, cache)
-+  }
-+
-+  if (typeof pattern !== "string") {
-+    throw new TypeError("glob pattern string required")
-+  }
-+
-+  if (!options) options = {}
-+  pattern = pattern.trim()
-+
-+  // windows: need to use /, not \
-+  // On other platforms, \ is a valid (albeit bad) filename char.
-+  if (platform === "win32") {
-+    pattern = pattern.split("\\").join("/")
-+  }
-+
-+  // lru storage.
-+  // these things aren't particularly big, but walking down the string
-+  // and turning it into a regexp can get pretty costly.
-+  var cacheKey = pattern + "\n" + sigmund(options)
-+  var cached = minimatch.cache.get(cacheKey)
-+  if (cached) return cached
-+  minimatch.cache.set(cacheKey, this)
-+
-+  this.options = options
-+  this.set = []
-+  this.pattern = pattern
-+  this.regexp = null
-+  this.negate = false
-+  this.comment = false
-+  this.empty = false
-+
-+  // make the set of regexps etc.
-+  this.make()
-+}
-+
-+Minimatch.prototype.debug = function() {}
-+
-+Minimatch.prototype.make = make
-+function make () {
-+  // don't do it more than once.
-+  if (this._made) return
-+
-+  var pattern = this.pattern
-+  var options = this.options
-+
-+  // empty patterns and comments match nothing.
-+  if (!options.nocomment && pattern.charAt(0) === "#") {
-+    this.comment = true
-+    return
-+  }
-+  if (!pattern) {
-+    this.empty = true
-+    return
-+  }
-+
-+  // step 1: figure out negation, etc.
-+  this.parseNegate()
-+
-+  // step 2: expand braces
-+  var set = this.globSet = this.braceExpand()
-+
-+  if (options.debug) this.debug = console.error
-+
-+  this.debug(this.pattern, set)
-+
-+  // step 3: now we have a set, so turn each one into a series of path-portion
-+  // matching patterns.
-+  // These will be regexps, except in the case of "**", which is
-+  // set to the GLOBSTAR object for globstar behavior,
-+  // and will not contain any / characters
-+  set = this.globParts = set.map(function (s) {
-+    return s.split(slashSplit)
-+  })
-+
-+  this.debug(this.pattern, set)
-+
-+  // glob --> regexps
-+  set = set.map(function (s, si, set) {
-+    return s.map(this.parse, this)
-+  }, this)
-+
-+  this.debug(this.pattern, set)
-+
-+  // filter out everything that didn't compile properly.
-+  set = set.filter(function (s) {
-+    return -1 === s.indexOf(false)
-+  })
-+
-+  this.debug(this.pattern, set)
-+
-+  this.set = set
-+}
-+
-+Minimatch.prototype.parseNegate = parseNegate
-+function parseNegate () {
-+  var pattern = this.pattern
-+    , negate = false
-+    , options = this.options
-+    , negateOffset = 0
-+
-+  if (options.nonegate) return
-+
-+  for ( var i = 0, l = pattern.length
-+      ; i < l && pattern.charAt(i) === "!"
-+      ; i ++) {
-+    negate = !negate
-+    negateOffset ++
-+  }
-+
-+  if (negateOffset) this.pattern = pattern.substr(negateOffset)
-+  this.negate = negate
-+}
-+
-+// Brace expansion:
-+// a{b,c}d -> abd acd
-+// a{b,}c -> abc ac
-+// a{0..3}d -> a0d a1d a2d a3d
-+// a{b,c{d,e}f}g -> abg acdfg acefg
-+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-+//
-+// Invalid sets are not expanded.
-+// a{2..}b -> a{2..}b
-+// a{b}c -> a{b}c
-+minimatch.braceExpand = function (pattern, options) {
-+  return new Minimatch(pattern, options).braceExpand()
-+}
-+
-+Minimatch.prototype.braceExpand = braceExpand
-+function braceExpand (pattern, options) {
-+  options = options || this.options
-+  pattern = typeof pattern === "undefined"
-+    ? this.pattern : pattern
-+
-+  if (typeof pattern === "undefined") {
-+    throw new Error("undefined pattern")
-+  }
-+
-+  if (options.nobrace ||
-+      !pattern.match(/\{.*\}/)) {
-+    // shortcut. no need to expand.
-+    return [pattern]
-+  }
-+
-+  var escaping = false
-+
-+  // examples and comments refer to this crazy pattern:
-+  // a{b,c{d,e},{f,g}h}x{y,z}
-+  // expected:
-+  // abxy
-+  // abxz
-+  // acdxy
-+  // acdxz
-+  // acexy
-+  // acexz
-+  // afhxy
-+  // afhxz
-+  // aghxy
-+  // aghxz
-+
-+  // everything before the first \{ is just a prefix.
-+  // So, we pluck that off, and work with the rest,
-+  // and then prepend it to everything we find.
-+  if (pattern.charAt(0) !== "{") {
-+    this.debug(pattern)
-+    var prefix = null
-+    for (var i = 0, l = pattern.length; i < l; i ++) {
-+      var c = pattern.charAt(i)
-+      this.debug(i, c)
-+      if (c === "\\") {
-+        escaping = !escaping
-+      } else if (c === "{" && !escaping) {
-+        prefix = pattern.substr(0, i)
-+        break
-+      }
-+    }
-+
-+    // actually no sets, all { were escaped.
-+    if (prefix === null) {
-+      this.debug("no sets")
-+      return [pattern]
-+    }
-+
-+   var tail = braceExpand.call(this, pattern.substr(i), options)
-+    return tail.map(function (t) {
-+      return prefix + t
-+    })
-+  }
-+
-+  // now we have something like:
-+  // {b,c{d,e},{f,g}h}x{y,z}
-+  // walk through the set, expanding each part, until
-+  // the set ends.  then, we'll expand the suffix.
-+  // If the set only has a single member, then'll put the {} back
-+
-+  // first, handle numeric sets, since they're easier
-+  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
-+  if (numset) {
-+    this.debug("numset", numset[1], numset[2])
-+    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
-+      , start = +numset[1]
-+      , end = +numset[2]
-+      , inc = start > end ? -1 : 1
-+      , set = []
-+    for (var i = start; i != (end + inc); i += inc) {
-+      // append all the suffixes
-+      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
-+        set.push(i + suf[ii])
-+      }
-+    }
-+    return set
-+  }
-+
-+  // ok, walk through the set
-+  // We hope, somewhat optimistically, that there
-+  // will be a } at the end.
-+  // If the closing brace isn't found, then the pattern is
-+  // interpreted as braceExpand("\\" + pattern) so that
-+  // the leading \{ will be interpreted literally.
-+  var i = 1 // skip the \{
-+    , depth = 1
-+    , set = []
-+    , member = ""
-+    , sawEnd = false
-+    , escaping = false
-+
-+  function addMember () {
-+    set.push(member)
-+    member = ""
-+  }
-+
-+  this.debug("Entering for")
-+  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
-+    var c = pattern.charAt(i)
-+    this.debug("", i, c)
-+
-+    if (escaping) {
-+      escaping = false
-+      member += "\\" + c
-+    } else {
-+      switch (c) {
-+        case "\\":
-+          escaping = true
-+          continue
-+
-+        case "{":
-+          depth ++
-+          member += "{"
-+          continue
-+
-+        case "}":
-+          depth --
-+          // if this closes the actual set, then we're done
-+          if (depth === 0) {
-+            addMember()
-+            // pluck off the close-brace
-+            i ++
-+            break FOR
-+          } else {
-+            member += c
-+            continue
-+          }
-+
-+        case ",":
-+          if (depth === 1) {
-+            addMember()
-+          } else {
-+            member += c
-+          }
-+          continue
-+
-+        default:
-+          member += c
-+          continue
-+      } // switch
-+    } // else
-+  } // for
-+
-+  // now we've either finished the set, and the suffix is
-+  // pattern.substr(i), or we have *not* closed the set,
-+  // and need to escape the leading brace
-+  if (depth !== 0) {
-+    this.debug("didn't close", pattern)
-+    return braceExpand.call(this, "\\" + pattern, options)
-+  }
-+
-+  // x{y,z} -> ["xy", "xz"]
-+  this.debug("set", set)
-+  this.debug("suffix", pattern.substr(i))
-+  var suf = braceExpand.call(this, pattern.substr(i), options)
-+  // ["b", "c{d,e}","{f,g}h"] ->
-+  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
-+  var addBraces = set.length === 1
-+  this.debug("set pre-expanded", set)
-+  set = set.map(function (p) {
-+    return braceExpand.call(this, p, options)
-+  }, this)
-+  this.debug("set expanded", set)
-+
-+
-+  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
-+  //   ["b", "cd", "ce", "fh", "gh"]
-+  set = set.reduce(function (l, r) {
-+    return l.concat(r)
-+  })
-+
-+  if (addBraces) {
-+    set = set.map(function (s) {
-+      return "{" + s + "}"
-+    })
-+  }
-+
-+  // now attach the suffixes.
-+  var ret = []
-+  for (var i = 0, l = set.length; i < l; i ++) {
-+    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
-+      ret.push(set[i] + suf[ii])
-+    }
-+  }
-+  return ret
-+}
-+
-+// parse a component of the expanded set.
-+// At this point, no pattern may contain "/" in it
-+// so we're going to return a 2d array, where each entry is the full
-+// pattern, split on '/', and then turned into a regular expression.
-+// A regexp is made at the end which joins each array with an
-+// escaped /, and another full one which joins each regexp with |.
-+//
-+// Following the lead of Bash 4.1, note that "**" only has special meaning
-+// when it is the *only* thing in a path portion.  Otherwise, any series
-+// of * is equivalent to a single *.  Globstar behavior is enabled by
-+// default, and can be disabled by setting options.noglobstar.
-+Minimatch.prototype.parse = parse
-+var SUBPARSE = {}
-+function parse (pattern, isSub) {
-+  var options = this.options
-+
-+  // shortcuts
-+  if (!options.noglobstar && pattern === "**") return GLOBSTAR
-+  if (pattern === "") return ""
-+
-+  var re = ""
-+    , hasMagic = !!options.nocase
-+    , escaping = false
-+    // ? => one single character
-+    , patternListStack = []
-+    , plType
-+    , stateChar
-+    , inClass = false
-+    , reClassStart = -1
-+    , classStart = -1
-+    // . and .. never match anything that doesn't start with .,
-+    // even when options.dot is set.
-+    , patternStart = pattern.charAt(0) === "." ? "" // anything
-+      // not (start or / followed by . or .. followed by / or end)
-+      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
-+      : "(?!\\.)"
-+    , self = this
-+
-+  function clearStateChar () {
-+    if (stateChar) {
-+      // we had some state-tracking character
-+      // that wasn't consumed by this pass.
-+      switch (stateChar) {
-+        case "*":
-+          re += star
-+          hasMagic = true
-+          break
-+        case "?":
-+          re += qmark
-+          hasMagic = true
-+          break
-+        default:
-+          re += "\\"+stateChar
-+          break
-+      }
-+      self.debug('clearStateChar %j %j', stateChar, re)
-+      stateChar = false
-+    }
-+  }
-+
-+  for ( var i = 0, len = pattern.length, c
-+      ; (i < len) && (c = pattern.charAt(i))
-+      ; i ++ ) {
-+
-+    this.debug("%s\t%s %s %j", pattern, i, re, c)
-+
-+    // skip over any that are escaped.
-+    if (escaping && reSpecials[c]) {
-+      re += "\\" + c
-+      escaping = false
-+      continue
-+    }
-+
-+    SWITCH: switch (c) {
-+      case "/":
-+        // completely not allowed, even escaped.
-+        // Should already be path-split by now.
-+        return false
-+
-+      case "\\":
-+        clearStateChar()
-+        escaping = true
-+        continue
-+
-+      // the various stateChar values
-+      // for the "extglob" stuff.
-+      case "?":
-+      case "*":
-+      case "+":
-+      case "@":
-+      case "!":
-+        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
-+
-+        // all of those are literals inside a class, except that
-+        // the glob [!a] means [^a] in regexp
-+        if (inClass) {
-+          this.debug('  in class')
-+          if (c === "!" && i === classStart + 1) c = "^"
-+          re += c
-+          continue
-+        }
-+
-+        // if we already have a stateChar, then it means
-+        // that there was something like ** or +? in there.
-+        // Handle the stateChar, then proceed with this one.
-+        self.debug('call clearStateChar %j', stateChar)
-+        clearStateChar()
-+        stateChar = c
-+        // if extglob is disabled, then +(asdf|foo) isn't a thing.
-+        // just clear the statechar *now*, rather than even diving into
-+        // the patternList stuff.
-+        if (options.noext) clearStateChar()
-+        continue
-+
-+      case "(":
-+        if (inClass) {
-+          re += "("
-+          continue
-+        }
-+
-+        if (!stateChar) {
-+          re += "\\("
-+          continue
-+        }
-+
-+        plType = stateChar
-+        patternListStack.push({ type: plType
-+                              , start: i - 1
-+                              , reStart: re.length })
-+        // negation is (?:(?!js)[^/]*)
-+        re += stateChar === "!" ? "(?:(?!" : "(?:"
-+        this.debug('plType %j %j', stateChar, re)
-+        stateChar = false
-+        continue
-+
-+      case ")":
-+        if (inClass || !patternListStack.length) {
-+          re += "\\)"
-+          continue
-+        }
-+
-+        clearStateChar()
-+        hasMagic = true
-+        re += ")"
-+        plType = patternListStack.pop().type
-+        // negation is (?:(?!js)[^/]*)
-+        // The others are (?:<pattern>)<type>
-+        switch (plType) {
-+          case "!":
-+            re += "[^/]*?)"
-+            break
-+          case "?":
-+          case "+":
-+          case "*": re += plType
-+          case "@": break // the default anyway
-+        }
-+        continue
-+
-+      case "|":
-+        if (inClass || !patternListStack.length || escaping) {
-+          re += "\\|"
-+          escaping = false
-+          continue
-+        }
-+
-+        clearStateChar()
-+        re += "|"
-+        continue
-+
-+      // these are mostly the same in regexp and glob
-+      case "[":
-+        // swallow any state-tracking char before the [
-+        clearStateChar()
-+
-+        if (inClass) {
-+          re += "\\" + c
-+          continue
-+        }
-+
-+        inClass = true
-+        classStart = i
-+        reClassStart = re.length
-+        re += c
-+        continue
-+
-+      case "]":
-+        //  a right bracket shall lose its special
-+        //  meaning and represent itself in
-+        //  a bracket expression if it occurs
-+        //  first in the list.  -- POSIX.2 2.8.3.2
-+        if (i === classStart + 1 || !inClass) {
-+          re += "\\" + c
-+          escaping = false
-+          continue
-+        }
-+
-+        // finish up the class.
-+        hasMagic = true
-+        inClass = false
-+        re += c
-+        continue
-+
-+      default:
-+        // swallow any state char that wasn't consumed
-+        clearStateChar()
-+
-+        if (escaping) {
-+          // no need
-+          escaping = false
-+        } else if (reSpecials[c]
-+                   && !(c === "^" && inClass)) {
-+          re += "\\"
-+        }
-+
-+        re += c
-+
-+    } // switch
-+  } // for
-+
-+
-+  // handle the case where we left a class open.
-+  // "[abc" is valid, equivalent to "\[abc"
-+  if (inClass) {
-+    // split where the last [ was, and escape it
-+    // this is a huge pita.  We now have to re-walk
-+    // the contents of the would-be class to re-translate
-+    // any characters that were passed through as-is
-+    var cs = pattern.substr(classStart + 1)
-+      , sp = this.parse(cs, SUBPARSE)
-+    re = re.substr(0, reClassStart) + "\\[" + sp[0]
-+    hasMagic = hasMagic || sp[1]
-+  }
-+
-+  // handle the case where we had a +( thing at the *end*
-+  // of the pattern.
-+  // each pattern list stack adds 3 chars, and we need to go through
-+  // and escape any | chars that were passed through as-is for the regexp.
-+  // Go through and escape them, taking care not to double-escape any
-+  // | chars that were already escaped.
-+  var pl
-+  while (pl = patternListStack.pop()) {
-+    var tail = re.slice(pl.reStart + 3)
-+    // maybe some even number of \, then maybe 1 \, followed by a |
-+    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
-+      if (!$2) {
-+        // the | isn't already escaped, so escape it.
-+        $2 = "\\"
-+      }
-+
-+      // need to escape all those slashes *again*, without escaping the
-+      // one that we need for escaping the | character.  As it works out,
-+      // escaping an even number of slashes can be done by simply repeating
-+      // it exactly after itself.  That's why this trick works.
-+      //
-+      // I am sorry that you have to see this.
-+      return $1 + $1 + $2 + "|"
-+    })
-+
-+    this.debug("tail=%j\n   %s", tail, tail)
-+    var t = pl.type === "*" ? star
-+          : pl.type === "?" ? qmark
-+          : "\\" + pl.type
-+
-+    hasMagic = true
-+    re = re.slice(0, pl.reStart)
-+       + t + "\\("
-+       + tail
-+  }
-+
-+  // handle trailing things that only matter at the very end.
-+  clearStateChar()
-+  if (escaping) {
-+    // trailing \\
-+    re += "\\\\"
-+  }
-+
-+  // only need to apply the nodot start if the re starts with
-+  // something that could conceivably capture a dot
-+  var addPatternStart = false
-+  switch (re.charAt(0)) {
-+    case ".":
-+    case "[":
-+    case "(": addPatternStart = true
-+  }
-+
-+  // if the re is not "" at this point, then we need to make sure
-+  // it doesn't match against an empty path part.
-+  // Otherwise a/* will match a/, which it should not.
-+  if (re !== "" && hasMagic) re = "(?=.)" + re
-+
-+  if (addPatternStart) re = patternStart + re
-+
-+  // parsing just a piece of a larger pattern.
-+  if (isSub === SUBPARSE) {
-+    return [ re, hasMagic ]
-+  }
-+
-+  // skip the regexp for non-magical patterns
-+  // unescape anything in it, though, so that it'll be
-+  // an exact match against a file etc.
-+  if (!hasMagic) {
-+    return globUnescape(pattern)
-+  }
-+
-+  var flags = options.nocase ? "i" : ""
-+    , regExp = new RegExp("^" + re + "$", flags)
-+
-+  regExp._glob = pattern
-+  regExp._src = re
-+
-+  return regExp
-+}
-+
-+minimatch.makeRe = function (pattern, options) {
-+  return new Minimatch(pattern, options || {}).makeRe()
-+}
-+
-+Minimatch.prototype.makeRe = makeRe
-+function makeRe () {
-+  if (this.regexp || this.regexp === false) return this.regexp
-+
-+  // at this point, this.set is a 2d array of partial
-+  // pattern strings, or "**".
-+  //
-+  // It's better to use .match().  This function shouldn't
-+  // be used, really, but it's pretty convenient sometimes,
-+  // when you just want to work with a regex.
-+  var set = this.set
-+
-+  if (!set.length) return this.regexp = false
-+  var options = this.options
-+
-+  var twoStar = options.noglobstar ? star
-+      : options.dot ? twoStarDot
-+      : twoStarNoDot
-+    , flags = options.nocase ? "i" : ""
-+
-+  var re = set.map(function (pattern) {
-+    return pattern.map(function (p) {
-+      return (p === GLOBSTAR) ? twoStar
-+           : (typeof p === "string") ? regExpEscape(p)
-+           : p._src
-+    }).join("\\\/")
-+  }).join("|")
-+
-+  // must match entire pattern
-+  // ending in a * or ** will make it less strict.
-+  re = "^(?:" + re + ")$"
-+
-+  // can match anything, as long as it's not this.
-+  if (this.negate) re = "^(?!" + re + ").*$"
-+
-+  try {
-+    return this.regexp = new RegExp(re, flags)
-+  } catch (ex) {
-+    return this.regexp = false
-+  }
-+}
-+
-+minimatch.match = function (list, pattern, options) {
-+  options = options || {}
-+  var mm = new Minimatch(pattern, options)
-+  list = list.filter(function (f) {
-+    return mm.match(f)
-+  })
-+  if (mm.options.nonull && !list.length) {
-+    list.push(pattern)
-+  }
-+  return list
-+}
-+
-+Minimatch.prototype.match = match
-+function match (f, partial) {
-+  this.debug("match", f, this.pattern)
-+  // short-circuit in the case of busted things.
-+  // comments, etc.
-+  if (this.comment) return false
-+  if (this.empty) return f === ""
-+
-+  if (f === "/" && partial) return true
-+
-+  var options = this.options
-+
-+  // windows: need to use /, not \
-+  // On other platforms, \ is a valid (albeit bad) filename char.
-+  if (platform === "win32") {
-+    f = f.split("\\").join("/")
-+  }
-+
-+  // treat the test path as a set of pathparts.
-+  f = f.split(slashSplit)
-+  this.debug(this.pattern, "split", f)
-+
-+  // just ONE of the pattern sets in this.set needs to match
-+  // in order for it to be valid.  If negating, then just one
-+  // match means that we have failed.
-+  // Either way, return on the first hit.
-+
-+  var set = this.set
-+  this.debug(this.pattern, "set", set)
-+
-+  // Find the basename of the path by looking for the last non-empty segment
-+  var filename;
-+  for (var i = f.length - 1; i >= 0; i--) {
-+    filename = f[i]
-+    if (filename) break
-+  }
-+
-+  for (var i = 0, l = set.length; i < l; i ++) {
-+    var pattern = set[i], file = f
-+    if (options.matchBase && pattern.length === 1) {
-+      file = [filename]
-+    }
-+    var hit = this.matchOne(file, pattern, partial)
-+    if (hit) {
-+      if (options.flipNegate) return true
-+      return !this.negate
-+    }
-+  }
-+
-+  // didn't get any hits.  this is success if it's a negative
-+  // pattern, failure otherwise.
-+  if (options.flipNegate) return false
-+  return this.negate
-+}
-+
-+// set partial to true to test if, for example,
-+// "/a/b" matches the start of "/*/b/*/d"
-+// Partial means, if you run out of file before you run
-+// out of pattern, then that's fine, as long as all
-+// the parts match.
-+Minimatch.prototype.matchOne = function (file, pattern, partial) {
-+  var options = this.options
-+
-+  this.debug("matchOne",
-+              { "this": this
-+              , file: file
-+              , pattern: pattern })
-+
-+  this.debug("matchOne", file.length, pattern.length)
-+
-+  for ( var fi = 0
-+          , pi = 0
-+          , fl = file.length
-+          , pl = pattern.length
-+      ; (fi < fl) && (pi < pl)
-+      ; fi ++, pi ++ ) {
-+
-+    this.debug("matchOne loop")
-+    var p = pattern[pi]
-+      , f = file[fi]
-+
-+    this.debug(pattern, p, f)
-+
-+    // should be impossible.
-+    // some invalid regexp stuff in the set.
-+    if (p === false) return false
-+
-+    if (p === GLOBSTAR) {
-+      this.debug('GLOBSTAR', [pattern, p, f])
-+
-+      // "**"
-+      // a/**/b/**/c would match the following:
-+      // a/b/x/y/z/c
-+      // a/x/y/z/b/c
-+      // a/b/x/b/x/c
-+      // a/b/c
-+      // To do this, take the rest of the pattern after
-+      // the **, and see if it would match the file remainder.
-+      // If so, return success.
-+      // If not, the ** "swallows" a segment, and try again.
-+      // This is recursively awful.
-+      //
-+      // a/**/b/**/c matching a/b/x/y/z/c
-+      // - a matches a
-+      // - doublestar
-+      //   - matchOne(b/x/y/z/c, b/**/c)
-+      //     - b matches b
-+      //     - doublestar
-+      //       - matchOne(x/y/z/c, c) -> no
-+      //       - matchOne(y/z/c, c) -> no
-+      //       - matchOne(z/c, c) -> no
-+      //       - matchOne(c, c) yes, hit
-+      var fr = fi
-+        , pr = pi + 1
-+      if (pr === pl) {
-+        this.debug('** at the end')
-+        // a ** at the end will just swallow the rest.
-+        // We have found a match.
-+        // however, it will not swallow /.x, unless
-+        // options.dot is set.
-+        // . and .. are *never* matched by **, for explosively
-+        // exponential reasons.
-+        for ( ; fi < fl; fi ++) {
-+          if (file[fi] === "." || file[fi] === ".." ||
-+              (!options.dot && file[fi].charAt(0) === ".")) return false
-+        }
-+        return true
-+      }
-+
-+      // ok, let's see if we can swallow whatever we can.
-+      WHILE: while (fr < fl) {
-+        var swallowee = file[fr]
-+
-+        this.debug('\nglobstar while',
-+                    file, fr, pattern, pr, swallowee)
-+
-+        // XXX remove this slice.  Just pass the start index.
-+        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-+          this.debug('globstar found match!', fr, fl, swallowee)
-+          // found a match.
-+          return true
-+        } else {
-+          // can't swallow "." or ".." ever.
-+          // can only swallow ".foo" when explicitly asked.
-+          if (swallowee === "." || swallowee === ".." ||
-+              (!options.dot && swallowee.charAt(0) === ".")) {
-+            this.debug("dot detected!", file, fr, pattern, pr)
-+            break WHILE
-+          }
-+
-+          // ** swallows a segment, and continue.
-+          this.debug('globstar swallow a segment, and continue')
-+          fr ++
-+        }
-+      }
-+      // no match was found.
-+      // However, in partial mode, we can't say this is necessarily over.
-+      // If there's more *pattern* left, then
-+      if (partial) {
-+        // ran out of file
-+        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
-+        if (fr === fl) return true
-+      }
-+      return false
-+    }
-+
-+    // something other than **
-+    // non-magic patterns just have to match exactly
-+    // patterns with magic have been turned into regexps.
-+    var hit
-+    if (typeof p === "string") {
-+      if (options.nocase) {
-+        hit = f.toLowerCase() === p.toLowerCase()
-+      } else {
-+        hit = f === p
-+      }
-+      this.debug("string match", p, f, hit)
-+    } else {
-+      hit = f.match(p)
-+      this.debug("pattern match", p, f, hit)
-+    }
-+
-+    if (!hit) return false
-+  }
-+
-+  // Note: ending in / means that we'll get a final ""
-+  // at the end of the pattern.  This can only match a
-+  // corresponding "" at the end of the file.
-+  // If the file ends in /, then it can only match a
-+  // a pattern that ends in /, unless the pattern just
-+  // doesn't have any more for it. But, a/b/ should *not*
-+  // match "a/b/*", even though "" matches against the
-+  // [^/]*? pattern, except in partial mode, where it might
-+  // simply not be reached yet.
-+  // However, a/b/ should still satisfy a/*
-+
-+  // now either we fell off the end of the pattern, or we're done.
-+  if (fi === fl && pi === pl) {
-+    // ran out of pattern and filename at the same time.
-+    // an exact hit!
-+    return true
-+  } else if (fi === fl) {
-+    // ran out of file, but still had pattern left.
-+    // this is ok if we're doing the match as part of
-+    // a glob fs traversal.
-+    return partial
-+  } else if (pi === pl) {
-+    // ran out of pattern, still have file left.
-+    // this is only acceptable if we're on the very last
-+    // empty segment of a file with a trailing slash.
-+    // a/* should match a/b/
-+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
-+    return emptyFileEnd
-+  }
-+
-+  // should be unreachable.
-+  throw new Error("wtf?")
-+}
-+
-+
-+// replace stuff like \* with *
-+function globUnescape (s) {
-+  return s.replace(/\\(.)/g, "$1")
-+}
-+
-+
-+function regExpEscape (s) {
-+  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-+}
-+
-+})( typeof require === "function" ? require : null,
-+    this,
-+    typeof module === "object" ? module : null,
-+    typeof process === "object" ? process.platform : "win32"
-+  )
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
-@@ -0,0 +1 @@
-+/node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
-@@ -0,0 +1,14 @@
-+# Authors, sorted by whether or not they are me
-+Isaac Z. Schlueter <i at izs.me>
-+Brian Cottingham <spiffytech at gmail.com>
-+Carlos Brito Lage <carlos at carloslage.net>
-+Jesse Dailey <jesse.dailey at gmail.com>
-+Kevin O'Hara <kevinohara80 at gmail.com>
-+Marco Rogers <marco.rogers at gmail.com>
-+Mark Cavage <mcavage at gmail.com>
-+Marko Mikulicic <marko.mikulicic at isti.cnr.it>
-+Nathan Rajlich <nathan at tootallnate.net>
-+Satheesh Natesan <snateshan at myspace-inc.com>
-+Trent Mick <trentm at gmail.com>
-+ashleybrener <ashley at starlogik.com>
-+n4kz <n4kz at n4kz.com>
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-+All rights reserved.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
-@@ -0,0 +1,97 @@
-+# lru cache
-+
-+A cache object that deletes the least-recently-used items.
-+
-+## Usage:
-+
-+```javascript
-+var LRU = require("lru-cache")
-+  , options = { max: 500
-+              , length: function (n) { return n * 2 }
-+              , dispose: function (key, n) { n.close() }
-+              , maxAge: 1000 * 60 * 60 }
-+  , cache = LRU(options)
-+  , otherCache = LRU(50) // sets just the max size
-+
-+cache.set("key", "value")
-+cache.get("key") // "value"
-+
-+cache.reset()    // empty the cache
-+```
-+
-+If you put more stuff in it, then items will fall out.
-+
-+If you try to put an oversized thing in it, then it'll fall out right
-+away.
-+
-+## Options
-+
-+* `max` The maximum size of the cache, checked by applying the length
-+  function to all values in the cache.  Not setting this is kind of
-+  silly, since that's the whole purpose of this lib, but it defaults
-+  to `Infinity`.
-+* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out
-+  as they age, but if you try to get an item that is too old, it'll
-+  drop it and return undefined instead of giving it to you.
-+* `length` Function that is used to calculate the length of stored
-+  items.  If you're storing strings or buffers, then you probably want
-+  to do something like `function(n){return n.length}`.  The default is
-+  `function(n){return 1}`, which is fine if you want to store `n`
-+  like-sized things.
-+* `dispose` Function that is called on items when they are dropped
-+  from the cache.  This can be handy if you want to close file
-+  descriptors or do other cleanup tasks when items are no longer
-+  accessible.  Called with `key, value`.  It's called *before*
-+  actually removing the item from the internal cache, so if you want
-+  to immediately put it back in, you'll have to do that in a
-+  `nextTick` or `setTimeout` callback or it won't do anything.
-+* `stale` By default, if you set a `maxAge`, it'll only actually pull
-+  stale items out of the cache when you `get(key)`.  (That is, it's
-+  not pre-emptively doing a `setTimeout` or anything.)  If you set
-+  `stale:true`, it'll return the stale value before deleting it.  If
-+  you don't set this, then it'll return `undefined` when you try to
-+  get a stale entry, as if it had already been deleted.
-+
-+## API
-+
-+* `set(key, value)`
-+* `get(key) => value`
-+
-+    Both of these will update the "recently used"-ness of the key.
-+    They do what you think.
-+
-+* `peek(key)`
-+
-+    Returns the key value (or `undefined` if not found) without
-+    updating the "recently used"-ness of the key.
-+
-+    (If you find yourself using this a lot, you *might* be using the
-+    wrong sort of data structure, but there are some use cases where
-+    it's handy.)
-+
-+* `del(key)`
-+
-+    Deletes a key out of the cache.
-+
-+* `reset()`
-+
-+    Clear the cache entirely, throwing away all values.
-+
-+* `has(key)`
-+
-+    Check if a key is in the cache, without updating the recent-ness
-+    or deleting it for being stale.
-+
-+* `forEach(function(value,key,cache), [thisp])`
-+
-+    Just like `Array.prototype.forEach`.  Iterates over all the keys
-+    in the cache, in order of recent-ness.  (Ie, more recently used
-+    items are iterated over first.)
-+
-+* `keys()`
-+
-+    Return an array of the keys in the cache.
-+
-+* `values()`
-+
-+    Return an array of the values in the cache.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
-@@ -0,0 +1,252 @@
-+;(function () { // closure for web browsers
-+
-+if (typeof module === 'object' && module.exports) {
-+  module.exports = LRUCache
-+} else {
-+  // just set the global for non-node platforms.
-+  this.LRUCache = LRUCache
-+}
-+
-+function hOP (obj, key) {
-+  return Object.prototype.hasOwnProperty.call(obj, key)
-+}
-+
-+function naiveLength () { return 1 }
-+
-+function LRUCache (options) {
-+  if (!(this instanceof LRUCache))
-+    return new LRUCache(options)
-+
-+  if (typeof options === 'number')
-+    options = { max: options }
-+
-+  if (!options)
-+    options = {}
-+
-+  this._max = options.max
-+  // Kind of weird to have a default max of Infinity, but oh well.
-+  if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
-+    this._max = Infinity
-+
-+  this._lengthCalculator = options.length || naiveLength
-+  if (typeof this._lengthCalculator !== "function")
-+    this._lengthCalculator = naiveLength
-+
-+  this._allowStale = options.stale || false
-+  this._maxAge = options.maxAge || null
-+  this._dispose = options.dispose
-+  this.reset()
-+}
-+
-+// resize the cache when the max changes.
-+Object.defineProperty(LRUCache.prototype, "max",
-+  { set : function (mL) {
-+      if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
-+      this._max = mL
-+      if (this._length > this._max) trim(this)
-+    }
-+  , get : function () { return this._max }
-+  , enumerable : true
-+  })
-+
-+// resize the cache when the lengthCalculator changes.
-+Object.defineProperty(LRUCache.prototype, "lengthCalculator",
-+  { set : function (lC) {
-+      if (typeof lC !== "function") {
-+        this._lengthCalculator = naiveLength
-+        this._length = this._itemCount
-+        for (var key in this._cache) {
-+          this._cache[key].length = 1
-+        }
-+      } else {
-+        this._lengthCalculator = lC
-+        this._length = 0
-+        for (var key in this._cache) {
-+          this._cache[key].length = this._lengthCalculator(this._cache[key].value)
-+          this._length += this._cache[key].length
-+        }
-+      }
-+
-+      if (this._length > this._max) trim(this)
-+    }
-+  , get : function () { return this._lengthCalculator }
-+  , enumerable : true
-+  })
-+
-+Object.defineProperty(LRUCache.prototype, "length",
-+  { get : function () { return this._length }
-+  , enumerable : true
-+  })
-+
-+
-+Object.defineProperty(LRUCache.prototype, "itemCount",
-+  { get : function () { return this._itemCount }
-+  , enumerable : true
-+  })
-+
-+LRUCache.prototype.forEach = function (fn, thisp) {
-+  thisp = thisp || this
-+  var i = 0;
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    i++
-+    var hit = this._lruList[k]
-+    if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
-+      del(this, hit)
-+      if (!this._allowStale) hit = undefined
-+    }
-+    if (hit) {
-+      fn.call(thisp, hit.value, hit.key, this)
-+    }
-+  }
-+}
-+
-+LRUCache.prototype.keys = function () {
-+  var keys = new Array(this._itemCount)
-+  var i = 0
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    var hit = this._lruList[k]
-+    keys[i++] = hit.key
-+  }
-+  return keys
-+}
-+
-+LRUCache.prototype.values = function () {
-+  var values = new Array(this._itemCount)
-+  var i = 0
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    var hit = this._lruList[k]
-+    values[i++] = hit.value
-+  }
-+  return values
-+}
-+
-+LRUCache.prototype.reset = function () {
-+  if (this._dispose && this._cache) {
-+    for (var k in this._cache) {
-+      this._dispose(k, this._cache[k].value)
-+    }
-+  }
-+
-+  this._cache = Object.create(null) // hash of items by key
-+  this._lruList = Object.create(null) // list of items in order of use recency
-+  this._mru = 0 // most recently used
-+  this._lru = 0 // least recently used
-+  this._length = 0 // number of items in the list
-+  this._itemCount = 0
-+}
-+
-+// Provided for debugging/dev purposes only. No promises whatsoever that
-+// this API stays stable.
-+LRUCache.prototype.dump = function () {
-+  return this._cache
-+}
-+
-+LRUCache.prototype.dumpLru = function () {
-+  return this._lruList
-+}
-+
-+LRUCache.prototype.set = function (key, value) {
-+  if (hOP(this._cache, key)) {
-+    // dispose of the old one before overwriting
-+    if (this._dispose) this._dispose(key, this._cache[key].value)
-+    if (this._maxAge) this._cache[key].now = Date.now()
-+    this._cache[key].value = value
-+    this.get(key)
-+    return true
-+  }
-+
-+  var len = this._lengthCalculator(value)
-+  var age = this._maxAge ? Date.now() : 0
-+  var hit = new Entry(key, value, this._mru++, len, age)
-+
-+  // oversized objects fall out of cache automatically.
-+  if (hit.length > this._max) {
-+    if (this._dispose) this._dispose(key, value)
-+    return false
-+  }
-+
-+  this._length += hit.length
-+  this._lruList[hit.lu] = this._cache[key] = hit
-+  this._itemCount ++
-+
-+  if (this._length > this._max) trim(this)
-+  return true
-+}
-+
-+LRUCache.prototype.has = function (key) {
-+  if (!hOP(this._cache, key)) return false
-+  var hit = this._cache[key]
-+  if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
-+    return false
-+  }
-+  return true
-+}
-+
-+LRUCache.prototype.get = function (key) {
-+  return get(this, key, true)
-+}
-+
-+LRUCache.prototype.peek = function (key) {
-+  return get(this, key, false)
-+}
-+
-+LRUCache.prototype.pop = function () {
-+  var hit = this._lruList[this._lru]
-+  del(this, hit)
-+  return hit || null
-+}
-+
-+LRUCache.prototype.del = function (key) {
-+  del(this, this._cache[key])
-+}
-+
-+function get (self, key, doUse) {
-+  var hit = self._cache[key]
-+  if (hit) {
-+    if (self._maxAge && (Date.now() - hit.now > self._maxAge)) {
-+      del(self, hit)
-+      if (!self._allowStale) hit = undefined
-+    } else {
-+      if (doUse) use(self, hit)
-+    }
-+    if (hit) hit = hit.value
-+  }
-+  return hit
-+}
-+
-+function use (self, hit) {
-+  shiftLU(self, hit)
-+  hit.lu = self._mru ++
-+  self._lruList[hit.lu] = hit
-+}
-+
-+function trim (self) {
-+  while (self._lru < self._mru && self._length > self._max)
-+    del(self, self._lruList[self._lru])
-+}
-+
-+function shiftLU (self, hit) {
-+  delete self._lruList[ hit.lu ]
-+  while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
-+}
-+
-+function del (self, hit) {
-+  if (hit) {
-+    if (self._dispose) self._dispose(hit.key, hit.value)
-+    self._length -= hit.length
-+    self._itemCount --
-+    delete self._cache[ hit.key ]
-+    shiftLU(self, hit)
-+  }
-+}
-+
-+// classy, since V8 prefers predictable objects.
-+function Entry (key, value, lu, length, now) {
-+  this.key = key
-+  this.value = value
-+  this.lu = lu
-+  this.length = length
-+  this.now = now
-+}
-+
-+})()
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "lru-cache",
-+  "description": "A cache object that deletes the least-recently-used items.",
-+  "version": "2.5.0",
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me"
-+  },
-+  "scripts": {
-+    "test": "tap test --gc"
-+  },
-+  "main": "lib/lru-cache.js",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/node-lru-cache.git"
-+  },
-+  "devDependencies": {
-+    "tap": "",
-+    "weak": ""
-+  },
-+  "license": {
-+    "type": "MIT",
-+    "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE"
-+  },
-+  "readme": "# lru cache\n\nA cache object that deletes the least-recently-used items.\n\n## Usage:\n\n```javascript\nvar LRU = require(\"lru-cache\")\n  , options = { max: 500\n              , length: function (n) { return n * 2 }\n              , dispose: function (key, n) { n.close() }\n              , maxAge: 1000 * 60 * 60 }\n  , cache = LRU(options)\n  , otherCache = LRU(50) // sets just the max size\n\ncache.set(\"key\", \"value\")\ncache.get(\"key\") // \"value\"\n\ncache.reset()    // empty the cache\n```\n\nIf you put more stuff in it, then items will fall out.\n\nIf you try to put an oversized thing in it, then it'll fall out right\naway.\n\n## Options\n\n* `max` The maximum size of the cache, checked by applying the length\n  function to all values in the cache.  Not setting this is kind of\n  silly, since that's the whole purpose of this lib, but it defaults\n  to `Infinity`.\n* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out\n  as they age, but if you try to get an item that is too old, it'll\n  drop it and return undefined instead of giving it to you.\n* `length` Function that is used to calculate the length of stored\n  items.  If you're storing strings or buffers, then you probably want\n  to do something like `function(n){return n.length}`.  The default is\n  `function(n){return 1}`, which is fine if you want to store `n`\n  like-sized things.\n* `dispose` Function that is called on items when they are dropped\n  from the cache.  This can be handy if you want to close file\n  descriptors or do other cleanup tasks when items are no longer\n  accessible.  Called with `key, value`.  It's called *before*\n  actually removing the item from the internal cache, so if you want\n  to immediately put it back in, you'll have to do that in a\n  `nextTick` or `setTimeout` callback or it won't do anything.\n* `stale` By default, if you set a `maxAge`, it'll only actually pull\n  stale items out of the cache when you `get(key)`.  (That is, it's\n  not pre-emptively doing a `setTimeout` or anything.)  If you set\n  `stale:true`, it'll return the stale value before deleting it.  If\n  you don't set this, then it'll return `undefined` when you try to\n  get a stale entry, as if it had already been deleted.\n\n## API\n\n* `set(key, value)`\n* `get(key) => value`\n\n    Both of these will update the \"recently used\"-ness of the key.\n    They do what you think.\n\n* `peek(key)`\n\n    Returns the key value (or `undefined` if not found) without\n    updating the \"recently used\"-ness of the key.\n\n    (If you find yourself using this a lot, you *might* be using the\n    wrong sort of data structure, but there are some use cases where\n    it's handy.)\n\n* `del(key)`\n\n    Deletes a key out of the cache.\n\n* `reset()`\n\n    Clear the cache entirely, throwing away all values.\n\n* `has(key)`\n\n    Check if a key is in the cache, without updating the recent-ness\n    or deleting it for being stale.\n\n* `forEach(function(value,key,cache), [thisp])`\n\n    Just like `Array.prototype.forEach`.  Iterates over all the keys\n    in the cache, in order of recent-ness.  (Ie, more recently used\n    items are iterated over first.)\n\n* `keys()`\n\n    Return an array of the keys in the cache.\n\n* `values()`\n\n    Return an array of the values in the cache.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/node-lru-cache/issues"
-+  },
-+  "_id": "lru-cache at 2.5.0",
-+  "_from": "lru-cache at 2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
-@@ -0,0 +1,369 @@
-+var test = require("tap").test
-+  , LRU = require("../")
-+
-+test("basic", function (t) {
-+  var cache = new LRU({max: 10})
-+  cache.set("key", "value")
-+  t.equal(cache.get("key"), "value")
-+  t.equal(cache.get("nada"), undefined)
-+  t.equal(cache.length, 1)
-+  t.equal(cache.max, 10)
-+  t.end()
-+})
-+
-+test("least recently set", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), "B")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("lru recently gotten", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.get("a")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), undefined)
-+  t.equal(cache.get("a"), "A")
-+  t.end()
-+})
-+
-+test("del", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.del("a")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("max", function (t) {
-+  var cache = new LRU(3)
-+
-+  // test changing the max, verify that the LRU items get dropped.
-+  cache.max = 100
-+  for (var i = 0; i < 100; i ++) cache.set(i, i)
-+  t.equal(cache.length, 100)
-+  for (var i = 0; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  cache.max = 3
-+  t.equal(cache.length, 3)
-+  for (var i = 0; i < 97; i ++) {
-+    t.equal(cache.get(i), undefined)
-+  }
-+  for (var i = 98; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+
-+  // now remove the max restriction, and try again.
-+  cache.max = "hello"
-+  for (var i = 0; i < 100; i ++) cache.set(i, i)
-+  t.equal(cache.length, 100)
-+  for (var i = 0; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  // should trigger an immediate resize
-+  cache.max = 3
-+  t.equal(cache.length, 3)
-+  for (var i = 0; i < 97; i ++) {
-+    t.equal(cache.get(i), undefined)
-+  }
-+  for (var i = 98; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  t.end()
-+})
-+
-+test("reset", function (t) {
-+  var cache = new LRU(10)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.reset()
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 10)
-+  t.equal(cache.get("a"), undefined)
-+  t.equal(cache.get("b"), undefined)
-+  t.end()
-+})
-+
-+
-+// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made
-+// about the format/layout of the response.
-+test("dump", function (t) {
-+  var cache = new LRU(10)
-+  var d = cache.dump();
-+  t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
-+  cache.set("a", "A")
-+  var d = cache.dump()  // { a: { key: "a", value: "A", lu: 0 } }
-+  t.ok(d.a)
-+  t.equal(d.a.key, "a")
-+  t.equal(d.a.value, "A")
-+  t.equal(d.a.lu, 0)
-+
-+  cache.set("b", "B")
-+  cache.get("b")
-+  d = cache.dump()
-+  t.ok(d.b)
-+  t.equal(d.b.key, "b")
-+  t.equal(d.b.value, "B")
-+  t.equal(d.b.lu, 2)
-+
-+  t.end()
-+})
-+
-+
-+test("basic with weighed length", function (t) {
-+  var cache = new LRU({
-+    max: 100,
-+    length: function (item) { return item.size }
-+  })
-+  cache.set("key", {val: "value", size: 50})
-+  t.equal(cache.get("key").val, "value")
-+  t.equal(cache.get("nada"), undefined)
-+  t.equal(cache.lengthCalculator(cache.get("key")), 50)
-+  t.equal(cache.length, 50)
-+  t.equal(cache.max, 100)
-+  t.end()
-+})
-+
-+
-+test("weighed length item too large", function (t) {
-+  var cache = new LRU({
-+    max: 10,
-+    length: function (item) { return item.size }
-+  })
-+  t.equal(cache.max, 10)
-+
-+  // should fall out immediately
-+  cache.set("key", {val: "value", size: 50})
-+
-+  t.equal(cache.length, 0)
-+  t.equal(cache.get("key"), undefined)
-+  t.end()
-+})
-+
-+test("least recently set with weighed length", function (t) {
-+  var cache = new LRU({
-+    max:8,
-+    length: function (item) { return item.length }
-+  })
-+  cache.set("a", "A")
-+  cache.set("b", "BB")
-+  cache.set("c", "CCC")
-+  cache.set("d", "DDDD")
-+  t.equal(cache.get("d"), "DDDD")
-+  t.equal(cache.get("c"), "CCC")
-+  t.equal(cache.get("b"), undefined)
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("lru recently gotten with weighed length", function (t) {
-+  var cache = new LRU({
-+    max: 8,
-+    length: function (item) { return item.length }
-+  })
-+  cache.set("a", "A")
-+  cache.set("b", "BB")
-+  cache.set("c", "CCC")
-+  cache.get("a")
-+  cache.get("b")
-+  cache.set("d", "DDDD")
-+  t.equal(cache.get("c"), undefined)
-+  t.equal(cache.get("d"), "DDDD")
-+  t.equal(cache.get("b"), "BB")
-+  t.equal(cache.get("a"), "A")
-+  t.end()
-+})
-+
-+test("set returns proper booleans", function(t) {
-+  var cache = new LRU({
-+    max: 5,
-+    length: function (item) { return item.length }
-+  })
-+
-+  t.equal(cache.set("a", "A"), true)
-+
-+  // should return false for max exceeded
-+  t.equal(cache.set("b", "donuts"), false)
-+
-+  t.equal(cache.set("b", "B"), true)
-+  t.equal(cache.set("c", "CCCC"), true)
-+  t.end()
-+})
-+
-+test("drop the old items", function(t) {
-+  var cache = new LRU({
-+    max: 5,
-+    maxAge: 50
-+  })
-+
-+  cache.set("a", "A")
-+
-+  setTimeout(function () {
-+    cache.set("b", "b")
-+    t.equal(cache.get("a"), "A")
-+  }, 25)
-+
-+  setTimeout(function () {
-+    cache.set("c", "C")
-+    // timed out
-+    t.notOk(cache.get("a"))
-+  }, 60)
-+
-+  setTimeout(function () {
-+    t.notOk(cache.get("b"))
-+    t.equal(cache.get("c"), "C")
-+  }, 90)
-+
-+  setTimeout(function () {
-+    t.notOk(cache.get("c"))
-+    t.end()
-+  }, 155)
-+})
-+
-+test("disposal function", function(t) {
-+  var disposed = false
-+  var cache = new LRU({
-+    max: 1,
-+    dispose: function (k, n) {
-+      disposed = n
-+    }
-+  })
-+
-+  cache.set(1, 1)
-+  cache.set(2, 2)
-+  t.equal(disposed, 1)
-+  cache.set(3, 3)
-+  t.equal(disposed, 2)
-+  cache.reset()
-+  t.equal(disposed, 3)
-+  t.end()
-+})
-+
-+test("disposal function on too big of item", function(t) {
-+  var disposed = false
-+  var cache = new LRU({
-+    max: 1,
-+    length: function (k) {
-+      return k.length
-+    },
-+    dispose: function (k, n) {
-+      disposed = n
-+    }
-+  })
-+  var obj = [ 1, 2 ]
-+
-+  t.equal(disposed, false)
-+  cache.set("obj", obj)
-+  t.equal(disposed, obj)
-+  t.end()
-+})
-+
-+test("has()", function(t) {
-+  var cache = new LRU({
-+    max: 1,
-+    maxAge: 10
-+  })
-+
-+  cache.set('foo', 'bar')
-+  t.equal(cache.has('foo'), true)
-+  cache.set('blu', 'baz')
-+  t.equal(cache.has('foo'), false)
-+  t.equal(cache.has('blu'), true)
-+  setTimeout(function() {
-+    t.equal(cache.has('blu'), false)
-+    t.end()
-+  }, 15)
-+})
-+
-+test("stale", function(t) {
-+  var cache = new LRU({
-+    maxAge: 10,
-+    stale: true
-+  })
-+
-+  cache.set('foo', 'bar')
-+  t.equal(cache.get('foo'), 'bar')
-+  t.equal(cache.has('foo'), true)
-+  setTimeout(function() {
-+    t.equal(cache.has('foo'), false)
-+    t.equal(cache.get('foo'), 'bar')
-+    t.equal(cache.get('foo'), undefined)
-+    t.end()
-+  }, 15)
-+})
-+
-+test("lru update via set", function(t) {
-+  var cache = LRU({ max: 2 });
-+
-+  cache.set('foo', 1);
-+  cache.set('bar', 2);
-+  cache.del('bar');
-+  cache.set('baz', 3);
-+  cache.set('qux', 4);
-+
-+  t.equal(cache.get('foo'), undefined)
-+  t.equal(cache.get('bar'), undefined)
-+  t.equal(cache.get('baz'), 3)
-+  t.equal(cache.get('qux'), 4)
-+  t.end()
-+})
-+
-+test("least recently set w/ peek", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  t.equal(cache.peek("a"), "A")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), "B")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("pop the least used item", function (t) {
-+  var cache = new LRU(3)
-+  , last
-+
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.set("c", "C")
-+
-+  t.equal(cache.length, 3)
-+  t.equal(cache.max, 3)
-+
-+  // Ensure we pop a, c, b
-+  cache.get("b", "B")
-+
-+  last = cache.pop()
-+  t.equal(last.key, "a")
-+  t.equal(last.value, "A")
-+  t.equal(cache.length, 2)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last.key, "c")
-+  t.equal(last.value, "C")
-+  t.equal(cache.length, 1)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last.key, "b")
-+  t.equal(last.value, "B")
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last, null)
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 3)
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
-@@ -0,0 +1,52 @@
-+var test = require('tap').test
-+var LRU = require('../')
-+
-+test('forEach', function (t) {
-+  var l = new LRU(5)
-+  for (var i = 0; i < 10; i ++) {
-+    l.set(i.toString(), i.toString(2))
-+  }
-+
-+  var i = 9
-+  l.forEach(function (val, key, cache) {
-+    t.equal(cache, l)
-+    t.equal(key, i.toString())
-+    t.equal(val, i.toString(2))
-+    i -= 1
-+  })
-+
-+  // get in order of most recently used
-+  l.get(6)
-+  l.get(8)
-+
-+  var order = [ 8, 6, 9, 7, 5 ]
-+  var i = 0
-+
-+  l.forEach(function (val, key, cache) {
-+    var j = order[i ++]
-+    t.equal(cache, l)
-+    t.equal(key, j.toString())
-+    t.equal(val, j.toString(2))
-+  })
-+
-+  t.end()
-+})
-+
-+test('keys() and values()', function (t) {
-+  var l = new LRU(5)
-+  for (var i = 0; i < 10; i ++) {
-+    l.set(i.toString(), i.toString(2))
-+  }
-+
-+  t.similar(l.keys(), ['9', '8', '7', '6', '5'])
-+  t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
-+
-+  // get in order of most recently used
-+  l.get(6)
-+  l.get(8)
-+
-+  t.similar(l.keys(), ['8', '6', '9', '7', '5'])
-+  t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
-@@ -0,0 +1,50 @@
-+#!/usr/bin/env node --expose_gc
-+
-+var weak = require('weak');
-+var test = require('tap').test
-+var LRU = require('../')
-+var l = new LRU({ max: 10 })
-+var refs = 0
-+function X() {
-+  refs ++
-+  weak(this, deref)
-+}
-+
-+function deref() {
-+  refs --
-+}
-+
-+test('no leaks', function (t) {
-+  // fill up the cache
-+  for (var i = 0; i < 100; i++) {
-+    l.set(i, new X);
-+    // throw some gets in there, too.
-+    if (i % 2 === 0)
-+      l.get(i / 2)
-+  }
-+
-+  gc()
-+
-+  var start = process.memoryUsage()
-+
-+  // capture the memory
-+  var startRefs = refs
-+
-+  // do it again, but more
-+  for (var i = 0; i < 10000; i++) {
-+    l.set(i, new X);
-+    // throw some gets in there, too.
-+    if (i % 2 === 0)
-+      l.get(i / 2)
-+  }
-+
-+  gc()
-+
-+  var end = process.memoryUsage()
-+  t.equal(refs, startRefs, 'no leaky refs')
-+
-+  console.error('start: %j\n' +
-+                'end:   %j', start, end);
-+  t.pass();
-+  t.end();
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
-@@ -0,0 +1,27 @@
-+Copyright (c) Isaac Z. Schlueter ("Author")
-+All rights reserved.
-+
-+The BSD License
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+1. Redistributions of source code must retain the above copyright
-+   notice, this list of conditions and the following disclaimer.
-+
-+2. Redistributions in binary form must reproduce the above copyright
-+   notice, this list of conditions and the following disclaimer in the
-+   documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
-@@ -0,0 +1,53 @@
-+# sigmund
-+
-+Quick and dirty signatures for Objects.
-+
-+This is like a much faster `deepEquals` comparison, which returns a
-+string key suitable for caches and the like.
-+
-+## Usage
-+
-+```javascript
-+function doSomething (someObj) {
-+  var key = sigmund(someObj, maxDepth) // max depth defaults to 10
-+  var cached = cache.get(key)
-+  if (cached) return cached)
-+
-+  var result = expensiveCalculation(someObj)
-+  cache.set(key, result)
-+  return result
-+}
-+```
-+
-+The resulting key will be as unique and reproducible as calling
-+`JSON.stringify` or `util.inspect` on the object, but is much faster.
-+In order to achieve this speed, some differences are glossed over.
-+For example, the object `{0:'foo'}` will be treated identically to the
-+array `['foo']`.
-+
-+Also, just as there is no way to summon the soul from the scribblings
-+of a cocain-addled psychoanalyst, there is no way to revive the object
-+from the signature string that sigmund gives you.  In fact, it's
-+barely even readable.
-+
-+As with `sys.inspect` and `JSON.stringify`, larger objects will
-+produce larger signature strings.
-+
-+Because sigmund is a bit less strict than the more thorough
-+alternatives, the strings will be shorter, and also there is a
-+slightly higher chance for collisions.  For example, these objects
-+have the same signature:
-+
-+    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-+    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-+
-+Like a good Freudian, sigmund is most effective when you already have
-+some understanding of what you're looking for.  It can help you help
-+yourself, but you must be willing to do some work as well.
-+
-+Cycles are handled, and cyclical objects are silently omitted (though
-+the key is included in the signature output.)
-+
-+The second argument is the maximum depth, which defaults to 10,
-+because that is the maximum object traversal depth covered by most
-+insurance carriers.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
-@@ -0,0 +1,283 @@
-+// different ways to id objects
-+// use a req/res pair, since it's crazy deep and cyclical
-+
-+// sparseFE10 and sigmund are usually pretty close, which is to be expected,
-+// since they are essentially the same algorithm, except that sigmund handles
-+// regular expression objects properly.
-+
-+
-+var http = require('http')
-+var util = require('util')
-+var sigmund = require('./sigmund.js')
-+var sreq, sres, creq, cres, test
-+
-+http.createServer(function (q, s) {
-+  sreq = q
-+  sres = s
-+  sres.end('ok')
-+  this.close(function () { setTimeout(function () {
-+    start()
-+  }, 200) })
-+}).listen(1337, function () {
-+  creq = http.get({ port: 1337 })
-+  creq.on('response', function (s) { cres = s })
-+})
-+
-+function start () {
-+  test = [sreq, sres, creq, cres]
-+  // test = sreq
-+  // sreq.sres = sres
-+  // sreq.creq = creq
-+  // sreq.cres = cres
-+
-+  for (var i in exports.compare) {
-+    console.log(i)
-+    var hash = exports.compare[i]()
-+    console.log(hash)
-+    console.log(hash.length)
-+    console.log('')
-+  }
-+
-+  require('bench').runMain()
-+}
-+
-+function customWs (obj, md, d) {
-+  d = d || 0
-+  var to = typeof obj
-+  if (to === 'undefined' || to === 'function' || to === null) return ''
-+  if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
-+
-+  if (Array.isArray(obj)) {
-+    return obj.map(function (i, _, __) {
-+      return customWs(i, md, d + 1)
-+    }).reduce(function (a, b) { return a + b }, '')
-+  }
-+
-+  var keys = Object.keys(obj)
-+  return keys.map(function (k, _, __) {
-+    return k + ':' + customWs(obj[k], md, d + 1)
-+  }).reduce(function (a, b) { return a + b }, '')
-+}
-+
-+function custom (obj, md, d) {
-+  d = d || 0
-+  var to = typeof obj
-+  if (to === 'undefined' || to === 'function' || to === null) return ''
-+  if (d > md || !obj || to !== 'object') return '' + obj
-+
-+  if (Array.isArray(obj)) {
-+    return obj.map(function (i, _, __) {
-+      return custom(i, md, d + 1)
-+    }).reduce(function (a, b) { return a + b }, '')
-+  }
-+
-+  var keys = Object.keys(obj)
-+  return keys.map(function (k, _, __) {
-+    return k + ':' + custom(obj[k], md, d + 1)
-+  }).reduce(function (a, b) { return a + b }, '')
-+}
-+
-+function sparseFE2 (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    Object.keys(v).forEach(function (k, _, __) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') return
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') return
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+    })
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function sparseFE (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    Object.keys(v).forEach(function (k, _, __) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') return
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') return
-+      soFar += k
-+      ch(v[k], depth + 1)
-+    })
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function sparse (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k
-+      ch(v[k], depth + 1)
-+    }
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function noCommas (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+    }
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+
-+function flatten (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+      soFar += ','
-+    }
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+exports.compare =
-+{
-+  // 'custom 2': function () {
-+  //   return custom(test, 2, 0)
-+  // },
-+  // 'customWs 2': function () {
-+  //   return customWs(test, 2, 0)
-+  // },
-+  'JSON.stringify (guarded)': function () {
-+    var seen = []
-+    return JSON.stringify(test, function (k, v) {
-+      if (typeof v !== 'object' || !v) return v
-+      if (seen.indexOf(v) !== -1) return undefined
-+      seen.push(v)
-+      return v
-+    })
-+  },
-+
-+  'flatten 10': function () {
-+    return flatten(test, 10)
-+  },
-+
-+  // 'flattenFE 10': function () {
-+  //   return flattenFE(test, 10)
-+  // },
-+
-+  'noCommas 10': function () {
-+    return noCommas(test, 10)
-+  },
-+
-+  'sparse 10': function () {
-+    return sparse(test, 10)
-+  },
-+
-+  'sparseFE 10': function () {
-+    return sparseFE(test, 10)
-+  },
-+
-+  'sparseFE2 10': function () {
-+    return sparseFE2(test, 10)
-+  },
-+
-+  sigmund: function() {
-+    return sigmund(test, 10)
-+  },
-+
-+
-+  // 'util.inspect 1': function () {
-+  //   return util.inspect(test, false, 1, false)
-+  // },
-+  // 'util.inspect undefined': function () {
-+  //   util.inspect(test)
-+  // },
-+  // 'util.inspect 2': function () {
-+  //   util.inspect(test, false, 2, false)
-+  // },
-+  // 'util.inspect 3': function () {
-+  //   util.inspect(test, false, 3, false)
-+  // },
-+  // 'util.inspect 4': function () {
-+  //   util.inspect(test, false, 4, false)
-+  // },
-+  // 'util.inspect Infinity': function () {
-+  //   util.inspect(test, false, Infinity, false)
-+  // }
-+}
-+
-+/** results
-+**/
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
-@@ -0,0 +1,41 @@
-+{
-+  "name": "sigmund",
-+  "version": "1.0.0",
-+  "description": "Quick and dirty signatures for Objects.",
-+  "main": "sigmund.js",
-+  "directories": {
-+    "test": "test"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "~0.3.0"
-+  },
-+  "scripts": {
-+    "test": "tap test/*.js",
-+    "bench": "node bench.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/sigmund"
-+  },
-+  "keywords": [
-+    "object",
-+    "signature",
-+    "key",
-+    "data",
-+    "psychoanalysis"
-+  ],
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": "BSD",
-+  "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n  var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n  var cached = cache.get(key)\n  if (cached) return cached)\n\n  var result = expensiveCalculation(someObj)\n  cache.set(key, result)\n  return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you.  In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions.  For example, these objects\nhave the same signature:\n\n    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for.  It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/sigmund/issues"
-+  },
-+  "_id": "sigmund at 1.0.0",
-+  "_from": "sigmund@~1.0.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
-@@ -0,0 +1,39 @@
-+module.exports = sigmund
-+function sigmund (subject, maxSessions) {
-+    maxSessions = maxSessions || 10;
-+    var notes = [];
-+    var analysis = '';
-+    var RE = RegExp;
-+
-+    function psychoAnalyze (subject, session) {
-+        if (session > maxSessions) return;
-+
-+        if (typeof subject === 'function' ||
-+            typeof subject === 'undefined') {
-+            return;
-+        }
-+
-+        if (typeof subject !== 'object' || !subject ||
-+            (subject instanceof RE)) {
-+            analysis += subject;
-+            return;
-+        }
-+
-+        if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
-+
-+        notes.push(subject);
-+        analysis += '{';
-+        Object.keys(subject).forEach(function (issue, _, __) {
-+            // pseudo-private values.  skip those.
-+            if (issue.charAt(0) === '_') return;
-+            var to = typeof subject[issue];
-+            if (to === 'function' || to === 'undefined') return;
-+            analysis += issue;
-+            psychoAnalyze(subject[issue], session + 1);
-+        });
-+    }
-+    psychoAnalyze(subject, 0);
-+    return analysis;
-+}
-+
-+// vim: set softtabstop=4 shiftwidth=4:
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
-@@ -0,0 +1,24 @@
-+var test = require('tap').test
-+var sigmund = require('../sigmund.js')
-+
-+
-+// occasionally there are duplicates
-+// that's an acceptable edge-case.  JSON.stringify and util.inspect
-+// have some collision potential as well, though less, and collision
-+// detection is expensive.
-+var hash = '{abc/def/g{0h1i2{jkl'
-+var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-+var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-+
-+var obj3 = JSON.parse(JSON.stringify(obj1))
-+obj3.c = /def/
-+obj3.g[2].cycle = obj3
-+var cycleHash = '{abc/def/g{0h1i2{jklcycle'
-+
-+test('basic', function (t) {
-+    t.equal(sigmund(obj1), hash)
-+    t.equal(sigmund(obj2), hash)
-+    t.equal(sigmund(obj3), cycleHash)
-+    t.end()
-+})
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/package.json
-@@ -0,0 +1,39 @@
-+{
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me"
-+  },
-+  "name": "minimatch",
-+  "description": "a glob matcher in javascript",
-+  "version": "0.3.0",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/minimatch.git"
-+  },
-+  "main": "minimatch.js",
-+  "scripts": {
-+    "test": "tap test/*.js"
-+  },
-+  "engines": {
-+    "node": "*"
-+  },
-+  "dependencies": {
-+    "lru-cache": "2",
-+    "sigmund": "~1.0.0"
-+  },
-+  "devDependencies": {
-+    "tap": ""
-+  },
-+  "license": {
-+    "type": "MIT",
-+    "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
-+  },
-+  "readme": "# minimatch\n\nA minimal matching utility.\n\n[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)\n\n\nThis is the matching library used internally by npm.\n\nEventually, it will replace the C binding in node-glob.\n\nIt works by converting glob expressions into JavaScript `RegExp`\nobjects.\n\n## Usage\n\n```javascript\nvar minimatch = require(\"minimatch\")\n\nminimatch(\"bar.foo\", \"*.foo\") // true!\nminimatch(\"bar.foo\", \"*.bar\") // false!\nminimatch(\"bar.foo\", \"*.+(bar|foo)\", { debug: true }) // true, and noisy!\n```\n\n## Features\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n\n## Minimatch Class\n\nCreate a minimatch object by instanting the `minimatch.Minimatch` class.\n\n```javascript\nvar Minimatch = require(\"minimatch\").Minimatch\nvar mm = new Minimatch(pattern, options)\n```\n\n### Properties\n\n* `pattern` The original pattern the minimatch object represents.\n* `options` The options supplied to the constructor.\n* `set` A 2-dimensional array of regexp or string expressions.\n  Each row in the\n  array corresponds to a brace-expanded pattern.  Each item in the row\n  corresponds to a single path-part.  For example, the pattern\n  `{a,b/c}/d` would expand to a set of patterns like:\n\n        [ [ a, d ]\n        , [ b, c, d ] ]\n\n    If a portion of the pattern doesn't have any \"magic\" in it\n    (that is, it's something like `\"foo\"` rather than `fo*o?`), then it\n    will be left as a string rather than converted to a regular\n    expression.\n\n* `regexp` Created by the `makeRe` method.  A single regular expression\n  expressing the entire pattern.  This is useful in cases where you wish\n  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.\n* `negate` True if the pattern is negated.\n* `comment` True if the pattern is a comment.\n* `empty` True if the pattern is `\"\"`.\n\n### Methods\n\n* `makeRe` Generate the `regexp` member if necessary, and return it.\n  Will return `false` if the pattern is invalid.\n* `match(fname)` Return true if the filename matches the pattern, or\n  false otherwise.\n* `matchOne(fileArray, patternArray, partial)` Take a `/`-split\n  filename, and match it against a single row in the `regExpSet`.  This\n  method is mainly for internal use, but is exposed so that it can be\n  used by a glob-walker that needs to avoid excessive filesystem calls.\n\nAll other methods are internal, and will be called as necessary.\n\n## Functions\n\nThe top-level exported function has a `cache` property, which is an LRU\ncache set to store 100 items.  So, calling these methods repeatedly\nwith the same pattern and options will use the same Minimatch object,\nsaving the cost of parsing it multiple times.\n\n### minimatch(path, pattern, options)\n\nMain export.  Tests a path against the pattern using the options.\n\n```javascript\nvar isJS = minimatch(file, \"*.js\", { matchBase: true })\n```\n\n### minimatch.filter(pattern, options)\n\nReturns a function that tests its\nsupplied argument, suitable for use with `Array.filter`.  Example:\n\n```javascript\nvar javascripts = fileList.filter(minimatch.filter(\"*.js\", {matchBase: true}))\n```\n\n### minimatch.match(list, pattern, options)\n\nMatch against the list of\nfiles, in the style of fnmatch or glob.  If nothing is matched, and\noptions.nonull is set, then return a list containing the pattern itself.\n\n```javascript\nvar javascripts = minimatch.match(fileList, \"*.js\", {matchBase: true}))\n```\n\n### minimatch.makeRe(pattern, options)\n\nMake a regular expression object from the pattern.\n\n## Options\n\nAll options are `false` by default.\n\n### debug\n\nDump a ton of stuff to stderr.\n\n### nobrace\n\nDo not expand `{a,b}` and `{1..3}` brace sets.\n\n### noglobstar\n\nDisable `**` matching against multiple folder names.\n\n### dot\n\nAllow patterns to match filenames starting with a period, even if\nthe pattern does not explicitly have a period in that spot.\n\nNote that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`\nis set.\n\n### noext\n\nDisable \"extglob\" style patterns like `+(a|b)`.\n\n### nocase\n\nPerform a case-insensitive match.\n\n### nonull\n\nWhen a match is not found by `minimatch.match`, return a list containing\nthe pattern itself if this option is set.  When not set, an empty list\nis returned if there are no matches.\n\n### matchBase\n\nIf set, then patterns without slashes will be matched\nagainst the basename of the path if it contains slashes.  For example,\n`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.\n\n### nocomment\n\nSuppress the behavior of treating `#` at the start of a pattern as a\ncomment.\n\n### nonegate\n\nSuppress the behavior of treating a leading `!` character as negation.\n\n### flipNegate\n\nReturns from negate expressions the same as if they were not negated.\n(Ie, true on a hit, false on a miss.)\n\n\n## Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between minimatch and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen minimatch.match returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`minimatch.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/minimatch/issues"
-+  },
-+  "_id": "minimatch at 0.3.0",
-+  "_from": "minimatch at 0.3"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/test/basic.js
-@@ -0,0 +1,399 @@
-+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-+//
-+// TODO: Some of these tests do very bad things with backslashes, and will
-+// most likely fail badly on windows.  They should probably be skipped.
-+
-+var tap = require("tap")
-+  , globalBefore = Object.keys(global)
-+  , mm = require("../")
-+  , files = [ "a", "b", "c", "d", "abc"
-+            , "abd", "abe", "bb", "bcd"
-+            , "ca", "cb", "dd", "de"
-+            , "bdir/", "bdir/cfile"]
-+  , next = files.concat([ "a-b", "aXb"
-+                        , ".x", ".y" ])
-+
-+
-+var patterns =
-+  [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
-+  , ["a*", ["a", "abc", "abd", "abe"]]
-+  , ["X*", ["X*"], {nonull: true}]
-+
-+  // allow null glob expansion
-+  , ["X*", []]
-+
-+  // isaacs: Slightly different than bash/sh/ksh
-+  // \\* is not un-escaped to literal "*" in a failed match,
-+  // but it does make it get treated as a literal star
-+  , ["\\*", ["\\*"], {nonull: true}]
-+  , ["\\**", ["\\**"], {nonull: true}]
-+  , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-+
-+  , ["b*/", ["bdir/"]]
-+  , ["c*", ["c", "ca", "cb"]]
-+  , ["**", files]
-+
-+  , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
-+  , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-+
-+  , "legendary larry crashes bashes"
-+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
-+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-+
-+  , "character classes"
-+  , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
-+  , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
-+     "bdir/", "ca", "cb", "dd", "de"]]
-+  , ["a*[^c]", ["abd", "abe"]]
-+  , function () { files.push("a-b", "aXb") }
-+  , ["a[X-]b", ["a-b", "aXb"]]
-+  , function () { files.push(".x", ".y") }
-+  , ["[^a-c]*", ["d", "dd", "de"]]
-+  , function () { files.push("a*b/", "a*b/ooo") }
-+  , ["a\\*b/*", ["a*b/ooo"]]
-+  , ["a\\*?/*", ["a*b/ooo"]]
-+  , ["*\\\\!*", [], {null: true}, ["echo !7"]]
-+  , ["*\\!*", ["echo !7"], null, ["echo !7"]]
-+  , ["*.\\*", ["r.*"], null, ["r.*"]]
-+  , ["a[b]c", ["abc"]]
-+  , ["a[\\b]c", ["abc"]]
-+  , ["a?c", ["abc"]]
-+  , ["a\\*c", [], {null: true}, ["abc"]]
-+  , ["", [""], { null: true }, [""]]
-+
-+  , "http://www.opensource.apple.com/source/bash/bash-23/" +
-+    "bash/tests/glob-test"
-+  , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
-+  , ["*/man*/bash.*", ["man/man1/bash.1"]]
-+  , ["man/man1/bash.1", ["man/man1/bash.1"]]
-+  , ["a***c", ["abc"], null, ["abc"]]
-+  , ["a*****?c", ["abc"], null, ["abc"]]
-+  , ["?*****??", ["abc"], null, ["abc"]]
-+  , ["*****??", ["abc"], null, ["abc"]]
-+  , ["?*****?c", ["abc"], null, ["abc"]]
-+  , ["?***?****c", ["abc"], null, ["abc"]]
-+  , ["?***?****?", ["abc"], null, ["abc"]]
-+  , ["?***?****", ["abc"], null, ["abc"]]
-+  , ["*******c", ["abc"], null, ["abc"]]
-+  , ["*******?", ["abc"], null, ["abc"]]
-+  , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["[-abc]", ["-"], null, ["-"]]
-+  , ["[abc-]", ["-"], null, ["-"]]
-+  , ["\\", ["\\"], null, ["\\"]]
-+  , ["[\\\\]", ["\\"], null, ["\\"]]
-+  , ["[[]", ["["], null, ["["]]
-+  , ["[", ["["], null, ["["]]
-+  , ["[*", ["[abc"], null, ["[abc"]]
-+  , "a right bracket shall lose its special meaning and\n" +
-+    "represent itself in a bracket expression if it occurs\n" +
-+    "first in the list.  -- POSIX.2 2.8.3.2"
-+  , ["[]]", ["]"], null, ["]"]]
-+  , ["[]-]", ["]"], null, ["]"]]
-+  , ["[a-\z]", ["p"], null, ["p"]]
-+  , ["??**********?****?", [], { null: true }, ["abc"]]
-+  , ["??**********?****c", [], { null: true }, ["abc"]]
-+  , ["?************c****?****", [], { null: true }, ["abc"]]
-+  , ["*c*?**", [], { null: true }, ["abc"]]
-+  , ["a*****c*?**", [], { null: true }, ["abc"]]
-+  , ["a********???*******", [], { null: true }, ["abc"]]
-+  , ["[]", [], { null: true }, ["a"]]
-+  , ["[abc", [], { null: true }, ["["]]
-+
-+  , "nocase tests"
-+  , ["XYZ", ["xYz"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+  , ["ab*", ["ABC"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+  , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  , "onestar/twostar"
-+  , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
-+  , ["{/?,*}", ["/a", "bb"], {null: true}
-+    , ["/a", "/b/b", "/a/b/c", "bb"]]
-+
-+  , "dots should not match unless requested"
-+  , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-+
-+  // .. and . can only match patterns starting with .,
-+  // even when options.dot is set.
-+  , function () {
-+      files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
-+    }
-+  , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
-+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
-+  , ["a/*/b", ["a/c/b"], {dot:false}]
-+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-+
-+
-+  // this also tests that changing the options needs
-+  // to change the cache key, even if the pattern is
-+  // the same!
-+  , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
-+    , [ ".a/.d", "a/.d", "a/b"]]
-+
-+  , "paren sets cannot contain slashes"
-+  , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-+
-+  // brace sets trump all else.
-+  //
-+  // invalid glob pattern.  fails on bash4 and bsdglob.
-+  // however, in this implementation, it's easier just
-+  // to do the intuitive thing, and let brace-expansion
-+  // actually come before parsing any extglob patterns,
-+  // like the documentation seems to say.
-+  //
-+  // XXX: if anyone complains about this, either fix it
-+  // or tell them to grow up and stop complaining.
-+  //
-+  // bash/bsdglob says this:
-+  // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
-+  // but we do this instead:
-+  , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-+
-+  // test partial parsing in the presence of comment/negation chars
-+  , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
-+  , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-+
-+  // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
-+  , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
-+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
-+    , {}
-+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-+
-+
-+  // crazy nested {,,} and *(||) tests.
-+  , function () {
-+      files = [ "a", "b", "c", "d"
-+              , "ab", "ac", "ad"
-+              , "bc", "cb"
-+              , "bc,d", "c,db", "c,d"
-+              , "d)", "(b|c", "*(b|c"
-+              , "b|c", "b|cc", "cb|c"
-+              , "x(a|b|c)", "x(a|c)"
-+              , "(a|b|c)", "(a|c)"]
-+    }
-+  , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
-+  , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
-+  // a
-+  // *(b|c)
-+  // *(b|d)
-+  , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
-+  , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-+
-+
-+  // test various flag settings.
-+  , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
-+    , { noext: true } ]
-+  , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
-+    , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
-+  , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-+
-+
-+  // begin channelling Boole and deMorgan...
-+  , "negation tests"
-+  , function () {
-+      files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
-+    }
-+
-+  // anything that is NOT a* matches.
-+  , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-+
-+  // anything that IS !a* matches.
-+  , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-+
-+  // anything that IS a* matches
-+  , ["!!a*", ["a!b"]]
-+
-+  // anything that is NOT !a* matches
-+  , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-+
-+  // negation nestled within a pattern
-+  , function () {
-+      files = [ "foo.js"
-+              , "foo.bar"
-+              // can't match this one without negative lookbehind.
-+              , "foo.js.js"
-+              , "blar.js"
-+              , "foo."
-+              , "boo.js.boo" ]
-+    }
-+  , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-+
-+  // https://github.com/isaacs/minimatch/issues/5
-+  , function () {
-+      files = [ 'a/b/.x/c'
-+              , 'a/b/.x/c/d'
-+              , 'a/b/.x/c/d/e'
-+              , 'a/b/.x'
-+              , 'a/b/.x/'
-+              , 'a/.x/b'
-+              , '.x'
-+              , '.x/'
-+              , '.x/a'
-+              , '.x/a/b'
-+              , 'a/.x/b/.x/c'
-+              , '.x/.x' ]
-+  }
-+  , ["**/.x/**", [ '.x/'
-+                 , '.x/a'
-+                 , '.x/a/b'
-+                 , 'a/.x/b'
-+                 , 'a/b/.x/'
-+                 , 'a/b/.x/c'
-+                 , 'a/b/.x/c/d'
-+                 , 'a/b/.x/c/d/e' ] ]
-+
-+  ]
-+
-+var regexps =
-+  [ '/^(?:(?=.)a[^/]*?)$/',
-+    '/^(?:(?=.)X[^/]*?)$/',
-+    '/^(?:(?=.)X[^/]*?)$/',
-+    '/^(?:\\*)$/',
-+    '/^(?:(?=.)\\*[^/]*?)$/',
-+    '/^(?:\\*\\*)$/',
-+    '/^(?:(?=.)b[^/]*?\\/)$/',
-+    '/^(?:(?=.)c[^/]*?)$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
-+    '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
-+    '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
-+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
-+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
-+    '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
-+    '/^(?:(?=.)a[^/]*?[^c])$/',
-+    '/^(?:(?=.)a[X-]b)$/',
-+    '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
-+    '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
-+    '/^(?:(?=.)a[b]c)$/',
-+    '/^(?:(?=.)a[b]c)$/',
-+    '/^(?:(?=.)a[^/]c)$/',
-+    '/^(?:a\\*c)$/',
-+    'false',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
-+    '/^(?:man\\/man1\\/bash\\.1)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[-abc])$/',
-+    '/^(?:(?!\\.)(?=.)[abc-])$/',
-+    '/^(?:\\\\)$/',
-+    '/^(?:(?!\\.)(?=.)[\\\\])$/',
-+    '/^(?:(?!\\.)(?=.)[\\[])$/',
-+    '/^(?:\\[)$/',
-+    '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[\\]])$/',
-+    '/^(?:(?!\\.)(?=.)[\\]-])$/',
-+    '/^(?:(?!\\.)(?=.)[a-z])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:\\[\\])$/',
-+    '/^(?:\\[abc)$/',
-+    '/^(?:(?=.)XYZ)$/i',
-+    '/^(?:(?=.)ab[^/]*?)$/i',
-+    '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
-+    '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
-+    '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
-+    '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
-+    '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
-+    '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
-+    '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
-+    '/^(?:(?=.)a[^/]b)$/',
-+    '/^(?:(?=.)#[^/]*?)$/',
-+    '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
-+    '/^(?:(?=.)\\!a[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?)$/',
-+    '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
-+var re = 0;
-+
-+tap.test("basic tests", function (t) {
-+  var start = Date.now()
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  patterns.forEach(function (c) {
-+    if (typeof c === "function") return c()
-+    if (typeof c === "string") return t.comment(c)
-+
-+    var pattern = c[0]
-+      , expect = c[1].sort(alpha)
-+      , options = c[2] || {}
-+      , f = c[3] || files
-+      , tapOpts = c[4] || {}
-+
-+    // options.debug = true
-+    var m = new mm.Minimatch(pattern, options)
-+    var r = m.makeRe()
-+    var expectRe = regexps[re++]
-+    tapOpts.re = String(r) || JSON.stringify(r)
-+    tapOpts.files = JSON.stringify(f)
-+    tapOpts.pattern = pattern
-+    tapOpts.set = m.set
-+    tapOpts.negated = m.negate
-+
-+    var actual = mm.match(f, pattern, options)
-+    actual.sort(alpha)
-+
-+    t.equivalent( actual, expect
-+                , JSON.stringify(pattern) + " " + JSON.stringify(expect)
-+                , tapOpts )
-+
-+    t.equal(tapOpts.re, expectRe, tapOpts)
-+  })
-+
-+  t.comment("time=" + (Date.now() - start) + "ms")
-+  t.end()
-+})
-+
-+tap.test("global leak test", function (t) {
-+  var globalAfter = Object.keys(global)
-+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
-+  t.end()
-+})
-+
-+function alpha (a, b) {
-+  return a > b ? 1 : -1
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/test/brace-expand.js
-@@ -0,0 +1,33 @@
-+var tap = require("tap")
-+  , minimatch = require("../")
-+
-+tap.test("brace expansion", function (t) {
-+  // [ pattern, [expanded] ]
-+  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
-+      , [ "abxy"
-+        , "abxz"
-+        , "acdxy"
-+        , "acdxz"
-+        , "acexy"
-+        , "acexz"
-+        , "afhxy"
-+        , "afhxz"
-+        , "aghxy"
-+        , "aghxz" ] ]
-+    , [ "a{1..5}b"
-+      , [ "a1b"
-+        , "a2b"
-+        , "a3b"
-+        , "a4b"
-+        , "a5b" ] ]
-+    , [ "a{b}c", ["a{b}c"] ]
-+  ].forEach(function (tc) {
-+    var p = tc[0]
-+      , expect = tc[1]
-+    t.equivalent(minimatch.braceExpand(p), expect, p)
-+  })
-+  console.error("ending")
-+  t.end()
-+})
-+
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/test/caching.js
-@@ -0,0 +1,14 @@
-+var Minimatch = require("../minimatch.js").Minimatch
-+var tap = require("tap")
-+tap.test("cache test", function (t) {
-+  var mm1 = new Minimatch("a?b")
-+  var mm2 = new Minimatch("a?b")
-+  t.equal(mm1, mm2, "should get the same object")
-+  // the lru should drop it after 100 entries
-+  for (var i = 0; i < 100; i ++) {
-+    new Minimatch("a"+i)
-+  }
-+  mm2 = new Minimatch("a?b")
-+  t.notEqual(mm1, mm2, "cache should have dropped")
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/test/defaults.js
-@@ -0,0 +1,274 @@
-+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-+//
-+// TODO: Some of these tests do very bad things with backslashes, and will
-+// most likely fail badly on windows.  They should probably be skipped.
-+
-+var tap = require("tap")
-+  , globalBefore = Object.keys(global)
-+  , mm = require("../")
-+  , files = [ "a", "b", "c", "d", "abc"
-+            , "abd", "abe", "bb", "bcd"
-+            , "ca", "cb", "dd", "de"
-+            , "bdir/", "bdir/cfile"]
-+  , next = files.concat([ "a-b", "aXb"
-+                        , ".x", ".y" ])
-+
-+tap.test("basic tests", function (t) {
-+  var start = Date.now()
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  ; [ "http://www.bashcookbook.com/bashinfo" +
-+      "/source/bash-1.14.7/tests/glob-test"
-+    , ["a*", ["a", "abc", "abd", "abe"]]
-+    , ["X*", ["X*"], {nonull: true}]
-+
-+    // allow null glob expansion
-+    , ["X*", []]
-+
-+    // isaacs: Slightly different than bash/sh/ksh
-+    // \\* is not un-escaped to literal "*" in a failed match,
-+    // but it does make it get treated as a literal star
-+    , ["\\*", ["\\*"], {nonull: true}]
-+    , ["\\**", ["\\**"], {nonull: true}]
-+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-+
-+    , ["b*/", ["bdir/"]]
-+    , ["c*", ["c", "ca", "cb"]]
-+    , ["**", files]
-+
-+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
-+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-+
-+    , "legendary larry crashes bashes"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
-+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
-+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-+
-+    , "character classes"
-+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
-+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
-+       "bdir/", "ca", "cb", "dd", "de"]]
-+    , ["a*[^c]", ["abd", "abe"]]
-+    , function () { files.push("a-b", "aXb") }
-+    , ["a[X-]b", ["a-b", "aXb"]]
-+    , function () { files.push(".x", ".y") }
-+    , ["[^a-c]*", ["d", "dd", "de"]]
-+    , function () { files.push("a*b/", "a*b/ooo") }
-+    , ["a\\*b/*", ["a*b/ooo"]]
-+    , ["a\\*?/*", ["a*b/ooo"]]
-+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
-+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
-+    , ["*.\\*", ["r.*"], null, ["r.*"]]
-+    , ["a[b]c", ["abc"]]
-+    , ["a[\\b]c", ["abc"]]
-+    , ["a?c", ["abc"]]
-+    , ["a\\*c", [], {null: true}, ["abc"]]
-+    , ["", [""], { null: true }, [""]]
-+
-+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
-+      "bash/tests/glob-test"
-+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
-+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
-+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
-+    , ["a***c", ["abc"], null, ["abc"]]
-+    , ["a*****?c", ["abc"], null, ["abc"]]
-+    , ["?*****??", ["abc"], null, ["abc"]]
-+    , ["*****??", ["abc"], null, ["abc"]]
-+    , ["?*****?c", ["abc"], null, ["abc"]]
-+    , ["?***?****c", ["abc"], null, ["abc"]]
-+    , ["?***?****?", ["abc"], null, ["abc"]]
-+    , ["?***?****", ["abc"], null, ["abc"]]
-+    , ["*******c", ["abc"], null, ["abc"]]
-+    , ["*******?", ["abc"], null, ["abc"]]
-+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["[-abc]", ["-"], null, ["-"]]
-+    , ["[abc-]", ["-"], null, ["-"]]
-+    , ["\\", ["\\"], null, ["\\"]]
-+    , ["[\\\\]", ["\\"], null, ["\\"]]
-+    , ["[[]", ["["], null, ["["]]
-+    , ["[", ["["], null, ["["]]
-+    , ["[*", ["[abc"], null, ["[abc"]]
-+    , "a right bracket shall lose its special meaning and\n" +
-+      "represent itself in a bracket expression if it occurs\n" +
-+      "first in the list.  -- POSIX.2 2.8.3.2"
-+    , ["[]]", ["]"], null, ["]"]]
-+    , ["[]-]", ["]"], null, ["]"]]
-+    , ["[a-\z]", ["p"], null, ["p"]]
-+    , ["??**********?****?", [], { null: true }, ["abc"]]
-+    , ["??**********?****c", [], { null: true }, ["abc"]]
-+    , ["?************c****?****", [], { null: true }, ["abc"]]
-+    , ["*c*?**", [], { null: true }, ["abc"]]
-+    , ["a*****c*?**", [], { null: true }, ["abc"]]
-+    , ["a********???*******", [], { null: true }, ["abc"]]
-+    , ["[]", [], { null: true }, ["a"]]
-+    , ["[abc", [], { null: true }, ["["]]
-+
-+    , "nocase tests"
-+    , ["XYZ", ["xYz"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+    , ["ab*", ["ABC"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+
-+    // [ pattern, [matches], MM opts, files, TAP opts]
-+    , "onestar/twostar"
-+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
-+    , ["{/?,*}", ["/a", "bb"], {null: true}
-+      , ["/a", "/b/b", "/a/b/c", "bb"]]
-+
-+    , "dots should not match unless requested"
-+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-+
-+    // .. and . can only match patterns starting with .,
-+    // even when options.dot is set.
-+    , function () {
-+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
-+      }
-+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
-+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
-+    , ["a/*/b", ["a/c/b"], {dot:false}]
-+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-+
-+
-+    // this also tests that changing the options needs
-+    // to change the cache key, even if the pattern is
-+    // the same!
-+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
-+      , [ ".a/.d", "a/.d", "a/b"]]
-+
-+    , "paren sets cannot contain slashes"
-+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-+
-+    // brace sets trump all else.
-+    //
-+    // invalid glob pattern.  fails on bash4 and bsdglob.
-+    // however, in this implementation, it's easier just
-+    // to do the intuitive thing, and let brace-expansion
-+    // actually come before parsing any extglob patterns,
-+    // like the documentation seems to say.
-+    //
-+    // XXX: if anyone complains about this, either fix it
-+    // or tell them to grow up and stop complaining.
-+    //
-+    // bash/bsdglob says this:
-+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
-+    // but we do this instead:
-+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-+
-+    // test partial parsing in the presence of comment/negation chars
-+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
-+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-+
-+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
-+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
-+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
-+      , {}
-+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-+
-+
-+    // crazy nested {,,} and *(||) tests.
-+    , function () {
-+        files = [ "a", "b", "c", "d"
-+                , "ab", "ac", "ad"
-+                , "bc", "cb"
-+                , "bc,d", "c,db", "c,d"
-+                , "d)", "(b|c", "*(b|c"
-+                , "b|c", "b|cc", "cb|c"
-+                , "x(a|b|c)", "x(a|c)"
-+                , "(a|b|c)", "(a|c)"]
-+      }
-+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
-+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
-+    // a
-+    // *(b|c)
-+    // *(b|d)
-+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
-+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-+
-+
-+    // test various flag settings.
-+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
-+      , { noext: true } ]
-+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
-+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
-+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-+
-+
-+    // begin channelling Boole and deMorgan...
-+    , "negation tests"
-+    , function () {
-+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
-+      }
-+
-+    // anything that is NOT a* matches.
-+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-+
-+    // anything that IS !a* matches.
-+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-+
-+    // anything that IS a* matches
-+    , ["!!a*", ["a!b"]]
-+
-+    // anything that is NOT !a* matches
-+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-+
-+    // negation nestled within a pattern
-+    , function () {
-+        files = [ "foo.js"
-+                , "foo.bar"
-+                // can't match this one without negative lookbehind.
-+                , "foo.js.js"
-+                , "blar.js"
-+                , "foo."
-+                , "boo.js.boo" ]
-+      }
-+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-+
-+    ].forEach(function (c) {
-+      if (typeof c === "function") return c()
-+      if (typeof c === "string") return t.comment(c)
-+
-+      var pattern = c[0]
-+        , expect = c[1].sort(alpha)
-+        , options = c[2]
-+        , f = c[3] || files
-+        , tapOpts = c[4] || {}
-+
-+      // options.debug = true
-+      var Class = mm.defaults(options).Minimatch
-+      var m = new Class(pattern, {})
-+      var r = m.makeRe()
-+      tapOpts.re = String(r) || JSON.stringify(r)
-+      tapOpts.files = JSON.stringify(f)
-+      tapOpts.pattern = pattern
-+      tapOpts.set = m.set
-+      tapOpts.negated = m.negate
-+
-+      var actual = mm.match(f, pattern, options)
-+      actual.sort(alpha)
-+
-+      t.equivalent( actual, expect
-+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
-+                  , tapOpts )
-+    })
-+
-+  t.comment("time=" + (Date.now() - start) + "ms")
-+  t.end()
-+})
-+
-+tap.test("global leak test", function (t) {
-+  var globalAfter = Object.keys(global)
-+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
-+  t.end()
-+})
-+
-+function alpha (a, b) {
-+  return a > b ? 1 : -1
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
-@@ -0,0 +1,8 @@
-+var test = require('tap').test
-+var minimatch = require('../')
-+
-+test('extglob ending with statechar', function(t) {
-+  t.notOk(minimatch('ax', 'a?(b*)'))
-+  t.ok(minimatch('ax', '?(a*|b)'))
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/package.json
-@@ -0,0 +1,39 @@
-+{
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "name": "glob",
-+  "description": "a little globber",
-+  "version": "3.2.11",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/node-glob.git"
-+  },
-+  "main": "glob.js",
-+  "engines": {
-+    "node": "*"
-+  },
-+  "dependencies": {
-+    "inherits": "2",
-+    "minimatch": "0.3"
-+  },
-+  "devDependencies": {
-+    "tap": "~0.4.0",
-+    "mkdirp": "0",
-+    "rimraf": "1"
-+  },
-+  "scripts": {
-+    "test": "tap test/*.js",
-+    "test-regen": "TEST_REGEN=1 node test/00-setup.js"
-+  },
-+  "license": "BSD",
-+  "readme": "# Glob\n\nMatch files using the patterns the shell uses, like stars and stuff.\n\nThis is a glob implementation in JavaScript.  It uses the `minimatch`\nlibrary to do its matching.\n\n## Attention: node-glob users!\n\nThe API has changed dramatically between 2.x and 3.x. This library is\nnow 100% JavaScript, and the integer flags have been replaced with an\noptions object.\n\nAlso, there's an event emitter class, proper tests, and all the other\nthings you've come to expect from node modules.\n\nAnd best of all, no compilation!\n\n## Usage\n\n```javascript\nvar glob = require(\"glob\")\n\n// options is optional\nglob(\"**/*.js\", options, function (er, files) {\n  // files is an array of filenames.\n  // If the `nonull` option is set, and nothing\n  // was found, then files is [\"**/*.js\"]\n  // er is an error object or null.\n})\n```\n\n## Features\n\nPlease see the [minimatch\ndocumentation](https://github.com/isaacs/minimatch) for more details.\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n* [minimatch documentation](https://github.com/isaacs/minimatch)\n\n## glob(pattern, [options], cb)\n\n* `pattern` {String} Pattern to be matched\n* `options` {Object}\n* `cb` {Function}\n  * `err` {Error | null}\n  * `matches` {Array<String>} filenames found matching the pattern\n\nPerform an asynchronous glob search.\n\n## glob.sync(pattern, [options])\n\n* `pattern` {String} Pattern to be matched\n* `options` {Object}\n* return: {Array<String>} filenames found matching the pattern\n\nPerform a synchronous glob search.\n\n## Class: glob.Glob\n\nCreate a Glob object by instanting the `glob.Glob` class.\n\n```javascript\nvar Glob = require(\"glob\").Glob\nvar mg = new Glob(pattern, options, cb)\n```\n\nIt's an EventEmitter, and starts walking the filesystem to find matches\nimmediately.\n\n### new glob.Glob(pattern, [options], [cb])\n\n* `pattern` {String} pattern to search for\n* `options` {Object}\n* `cb` {Function} Called when an error occurs, or matches are found\n  * `err` {Error | null}\n  * `matches` {Array<String>} filenames found matching the pattern\n\nNote that if the `sync` flag is set in the options, then matches will\nbe immediately available on the `g.found` member.\n\n### Properties\n\n* `minimatch` The minimatch object that the glob uses.\n* `options` The options object passed in.\n* `error` The error encountered.  When an error is encountered, the\n  glob object is in an undefined state, and should be discarded.\n* `aborted` Boolean which is set to true when calling `abort()`.  There\n  is no way at this time to continue a glob search after aborting, but\n  you can re-use the statCache to avoid having to duplicate syscalls.\n* `statCache` Collection of all the stat results the glob search\n  performed.\n* `cache` Convenience object.  Each field has the following possible\n  values:\n  * `false` - Path does not exist\n  * `true` - Path exists\n  * `1` - Path exists, and is not a directory\n  * `2` - Path exists, and is a directory\n  * `[file, entries, ...]` - Path exists, is a directory, and the\n    array value is the results of `fs.readdir`\n\n### Events\n\n* `end` When the matching is finished, this is emitted with all the\n  matches found.  If the `nonull` option is set, and no match was found,\n  then the `matches` list contains the original pattern.  The matches\n  are sorted, unless the `nosort` flag is set.\n* `match` Every time a match is found, this is emitted with the matched.\n* `error` Emitted when an unexpected error is encountered, or whenever\n  any fs error occurs if `options.strict` is set.\n* `abort` When `abort()` is called, this event is raised.\n\n### Methods\n\n* `abort` Stop the search.\n\n### Options\n\nAll the options that can be passed to Minimatch can also be passed to\nGlob to change pattern matching behavior.  Also, some have been added,\nor have glob-specific ramifications.\n\nAll options are false by default, unless otherwise noted.\n\nAll options are added to the glob object, as well.\n\n* `cwd` The current working directory in which to search.  Defaults\n  to `process.cwd()`.\n* `root` The place where patterns starting with `/` will be mounted\n  onto.  Defaults to `path.resolve(options.cwd, \"/\")` (`/` on Unix\n  systems, and `C:\\` or some such on Windows.)\n* `dot` Include `.dot` files in normal matches and `globstar` matches.\n  Note that an explicit dot in a portion of the pattern will always\n  match dot files.\n* `nomount` By default, a pattern starting with a forward-slash will be\n  \"mounted\" onto the root setting, so that a valid filesystem path is\n  returned.  Set this flag to disable that behavior.\n* `mark` Add a `/` character to directory matches.  Note that this\n  requires additional stat calls.\n* `nosort` Don't sort the results.\n* `stat` Set to true to stat *all* results.  This reduces performance\n  somewhat, and is completely unnecessary, unless `readdir` is presumed\n  to be an untrustworthy indicator of file existence.  It will cause\n  ELOOP to be triggered one level sooner in the case of cyclical\n  symbolic links.\n* `silent` When an unusual error is encountered\n  when attempting to read a directory, a warning will be printed to\n  stderr.  Set the `silent` option to true to suppress these warnings.\n* `strict` When an unusual error is encountered\n  when attempting to read a directory, the process will just continue on\n  in search of other matches.  Set the `strict` option to raise an error\n  in these cases.\n* `cache` See `cache` property above.  Pass in a previously generated\n  cache object to save some fs calls.\n* `statCache` A cache of results of filesystem information, to prevent\n  unnecessary stat calls.  While it should not normally be necessary to\n  set this, you may pass the statCache from one glob() call to the\n  options object of another, if you know that the filesystem will not\n  change between calls.  (See \"Race Conditions\" below.)\n* `sync` Perform a synchronous glob search.\n* `nounique` In some cases, brace-expanded patterns can result in the\n  same file showing up multiple times in the result set.  By default,\n  this implementation prevents duplicates in the result set.\n  Set this flag to disable that behavior.\n* `nonull` Set to never return an empty set, instead returning a set\n  containing the pattern itself.  This is the default in glob(3).\n* `nocase` Perform a case-insensitive match.  Note that case-insensitive\n  filesystems will sometimes result in glob returning results that are\n  case-insensitively matched anyway, since readdir and stat will not\n  raise an error.\n* `debug` Set to enable debug logging in minimatch and glob.\n* `globDebug` Set to enable debug logging in glob, but not minimatch.\n\n## Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between node-glob and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen glob returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`glob.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n\n## Windows\n\n**Please only use forward-slashes in glob expressions.**\n\nThough windows uses either `/` or `\\` as its path separator, only `/`\ncharacters are used by this glob implementation.  You must use\nforward-slashes **only** in glob expressions.  Back-slashes will always\nbe interpreted as escape characters, not path separators.\n\nResults from absolute patterns such as `/foo/*` are mounted onto the\nroot setting using `path.join`.  On windows, this will by default result\nin `/foo/*` matching `C:\\foo\\bar.txt`.\n\n## Race Conditions\n\nGlob searching, by its very nature, is susceptible to race conditions,\nsince it relies on directory walking and such.\n\nAs a result, it is possible that a file that exists when glob looks for\nit may have been deleted or modified by the time it returns the result.\n\nAs part of its internal implementation, this program caches all stat\nand readdir calls that it makes, in order to cut down on system\noverhead.  However, this also makes it even more susceptible to races,\nespecially if the cache or statCache objects are reused between glob\ncalls.\n\nUsers are thus advised not to use a glob result as a guarantee of\nfilesystem state in the face of rapid changes.  For the vast majority\nof operations, this is never a problem.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/node-glob/issues"
-+  },
-+  "_id": "glob at 3.2.11",
-+  "_from": "glob@~3.2.6"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/00-setup.js
-@@ -0,0 +1,176 @@
-+// just a little pre-run script to set up the fixtures.
-+// zz-finish cleans it up
-+
-+var mkdirp = require("mkdirp")
-+var path = require("path")
-+var i = 0
-+var tap = require("tap")
-+var fs = require("fs")
-+var rimraf = require("rimraf")
-+
-+var files =
-+[ "a/.abcdef/x/y/z/a"
-+, "a/abcdef/g/h"
-+, "a/abcfed/g/h"
-+, "a/b/c/d"
-+, "a/bc/e/f"
-+, "a/c/d/c/b"
-+, "a/cb/e/f"
-+]
-+
-+var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
-+var symlinkFrom = "../.."
-+
-+files = files.map(function (f) {
-+  return path.resolve(__dirname, f)
-+})
-+
-+tap.test("remove fixtures", function (t) {
-+  rimraf(path.resolve(__dirname, "a"), function (er) {
-+    t.ifError(er, "remove fixtures")
-+    t.end()
-+  })
-+})
-+
-+files.forEach(function (f) {
-+  tap.test(f, function (t) {
-+    var d = path.dirname(f)
-+    mkdirp(d, 0755, function (er) {
-+      if (er) {
-+        t.fail(er)
-+        return t.bailout()
-+      }
-+      fs.writeFile(f, "i like tests", function (er) {
-+        t.ifError(er, "make file")
-+        t.end()
-+      })
-+    })
-+  })
-+})
-+
-+if (process.platform !== "win32") {
-+  tap.test("symlinky", function (t) {
-+    var d = path.dirname(symlinkTo)
-+    console.error("mkdirp", d)
-+    mkdirp(d, 0755, function (er) {
-+      t.ifError(er)
-+      fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
-+        t.ifError(er, "make symlink")
-+        t.end()
-+      })
-+    })
-+  })
-+}
-+
-+;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
-+  w = "/tmp/glob-test/" + w
-+  tap.test("create " + w, function (t) {
-+    mkdirp(w, function (er) {
-+      if (er)
-+        throw er
-+      t.pass(w)
-+      t.end()
-+    })
-+  })
-+})
-+
-+
-+// generate the bash pattern test-fixtures if possible
-+if (process.platform === "win32" || !process.env.TEST_REGEN) {
-+  console.error("Windows, or TEST_REGEN unset.  Using cached fixtures.")
-+  return
-+}
-+
-+var spawn = require("child_process").spawn;
-+var globs =
-+  // put more patterns here.
-+  // anything that would be directly in / should be in /tmp/glob-test
-+  ["test/a/*/+(c|g)/./d"
-+  ,"test/a/**/[cg]/../[cg]"
-+  ,"test/a/{b,c,d,e,f}/**/g"
-+  ,"test/a/b/**"
-+  ,"test/**/g"
-+  ,"test/a/abc{fed,def}/g/h"
-+  ,"test/a/abc{fed/g,def}/**/"
-+  ,"test/a/abc{fed/g,def}/**///**/"
-+  ,"test/**/a/**/"
-+  ,"test/+(a|b|c)/a{/,bc*}/**"
-+  ,"test/*/*/*/f"
-+  ,"test/**/f"
-+  ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
-+  ,"{./*/*,/tmp/glob-test/*}"
-+  ,"{/tmp/glob-test/*,*}" // evil owl face!  how you taunt me!
-+  ,"test/a/!(symlink)/**"
-+  ]
-+var bashOutput = {}
-+var fs = require("fs")
-+
-+globs.forEach(function (pattern) {
-+  tap.test("generate fixture " + pattern, function (t) {
-+    var cmd = "shopt -s globstar && " +
-+              "shopt -s extglob && " +
-+              "shopt -s nullglob && " +
-+              // "shopt >&2; " +
-+              "eval \'for i in " + pattern + "; do echo $i; done\'"
-+    var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
-+    var out = []
-+    cp.stdout.on("data", function (c) {
-+      out.push(c)
-+    })
-+    cp.stderr.pipe(process.stderr)
-+    cp.on("close", function (code) {
-+      out = flatten(out)
-+      if (!out)
-+        out = []
-+      else
-+        out = cleanResults(out.split(/\r*\n/))
-+
-+      bashOutput[pattern] = out
-+      t.notOk(code, "bash test should finish nicely")
-+      t.end()
-+    })
-+  })
-+})
-+
-+tap.test("save fixtures", function (t) {
-+  var fname = path.resolve(__dirname, "bash-results.json")
-+  var data = JSON.stringify(bashOutput, null, 2) + "\n"
-+  fs.writeFile(fname, data, function (er) {
-+    t.ifError(er)
-+    t.end()
-+  })
-+})
-+
-+function cleanResults (m) {
-+  // normalize discrepancies in ordering, duplication,
-+  // and ending slashes.
-+  return m.map(function (m) {
-+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
-+  }).sort(alphasort).reduce(function (set, f) {
-+    if (f !== set[set.length - 1]) set.push(f)
-+    return set
-+  }, []).sort(alphasort).map(function (f) {
-+    // de-windows
-+    return (process.platform !== 'win32') ? f
-+           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
-+  })
-+}
-+
-+function flatten (chunks) {
-+  var s = 0
-+  chunks.forEach(function (c) { s += c.length })
-+  var out = new Buffer(s)
-+  s = 0
-+  chunks.forEach(function (c) {
-+    c.copy(out, s)
-+    s += c.length
-+  })
-+
-+  return out.toString().trim()
-+}
-+
-+function alphasort (a, b) {
-+  a = a.toLowerCase()
-+  b = b.toLowerCase()
-+  return a > b ? 1 : a < b ? -1 : 0
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/bash-comparison.js
-@@ -0,0 +1,63 @@
-+// basic test
-+// show that it does the same thing by default as the shell.
-+var tap = require("tap")
-+, child_process = require("child_process")
-+, bashResults = require("./bash-results.json")
-+, globs = Object.keys(bashResults)
-+, glob = require("../")
-+, path = require("path")
-+
-+// run from the root of the project
-+// this is usually where you're at anyway, but be sure.
-+process.chdir(path.resolve(__dirname, ".."))
-+
-+function alphasort (a, b) {
-+  a = a.toLowerCase()
-+  b = b.toLowerCase()
-+  return a > b ? 1 : a < b ? -1 : 0
-+}
-+
-+globs.forEach(function (pattern) {
-+  var expect = bashResults[pattern]
-+  // anything regarding the symlink thing will fail on windows, so just skip it
-+  if (process.platform === "win32" &&
-+      expect.some(function (m) {
-+        return /\/symlink\//.test(m)
-+      }))
-+    return
-+
-+  tap.test(pattern, function (t) {
-+    glob(pattern, function (er, matches) {
-+      if (er)
-+        throw er
-+
-+      // sort and unmark, just to match the shell results
-+      matches = cleanResults(matches)
-+
-+      t.deepEqual(matches, expect, pattern)
-+      t.end()
-+    })
-+  })
-+
-+  tap.test(pattern + " sync", function (t) {
-+    var matches = cleanResults(glob.sync(pattern))
-+
-+    t.deepEqual(matches, expect, "should match shell")
-+    t.end()
-+  })
-+})
-+
-+function cleanResults (m) {
-+  // normalize discrepancies in ordering, duplication,
-+  // and ending slashes.
-+  return m.map(function (m) {
-+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
-+  }).sort(alphasort).reduce(function (set, f) {
-+    if (f !== set[set.length - 1]) set.push(f)
-+    return set
-+  }, []).sort(alphasort).map(function (f) {
-+    // de-windows
-+    return (process.platform !== 'win32') ? f
-+           : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
-+  })
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/bash-results.json
-@@ -0,0 +1,351 @@
-+{
-+  "test/a/*/+(c|g)/./d": [
-+    "test/a/b/c/./d"
-+  ],
-+  "test/a/**/[cg]/../[cg]": [
-+    "test/a/abcdef/g/../g",
-+    "test/a/abcfed/g/../g",
-+    "test/a/b/c/../c",
-+    "test/a/c/../c",
-+    "test/a/c/d/c/../c",
-+    "test/a/symlink/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
-+  ],
-+  "test/a/{b,c,d,e,f}/**/g": [],
-+  "test/a/b/**": [
-+    "test/a/b",
-+    "test/a/b/c",
-+    "test/a/b/c/d"
-+  ],
-+  "test/**/g": [
-+    "test/a/abcdef/g",
-+    "test/a/abcfed/g"
-+  ],
-+  "test/a/abc{fed,def}/g/h": [
-+    "test/a/abcdef/g/h",
-+    "test/a/abcfed/g/h"
-+  ],
-+  "test/a/abc{fed/g,def}/**/": [
-+    "test/a/abcdef",
-+    "test/a/abcdef/g",
-+    "test/a/abcfed/g"
-+  ],
-+  "test/a/abc{fed/g,def}/**///**/": [
-+    "test/a/abcdef",
-+    "test/a/abcdef/g",
-+    "test/a/abcfed/g"
-+  ],
-+  "test/**/a/**/": [
-+    "test/a",
-+    "test/a/abcdef",
-+    "test/a/abcdef/g",
-+    "test/a/abcfed",
-+    "test/a/abcfed/g",
-+    "test/a/b",
-+    "test/a/b/c",
-+    "test/a/bc",
-+    "test/a/bc/e",
-+    "test/a/c",
-+    "test/a/c/d",
-+    "test/a/c/d/c",
-+    "test/a/cb",
-+    "test/a/cb/e",
-+    "test/a/symlink",
-+    "test/a/symlink/a",
-+    "test/a/symlink/a/b",
-+    "test/a/symlink/a/b/c",
-+    "test/a/symlink/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
-+  ],
-+  "test/+(a|b|c)/a{/,bc*}/**": [
-+    "test/a/abcdef",
-+    "test/a/abcdef/g",
-+    "test/a/abcdef/g/h",
-+    "test/a/abcfed",
-+    "test/a/abcfed/g",
-+    "test/a/abcfed/g/h"
-+  ],
-+  "test/*/*/*/f": [
-+    "test/a/bc/e/f",
-+    "test/a/cb/e/f"
-+  ],
-+  "test/**/f": [
-+    "test/a/bc/e/f",
-+    "test/a/cb/e/f"
-+  ],
-+  "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
-+    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
-+  ],
-+  "{./*/*,/tmp/glob-test/*}": [
-+    "./examples/g.js",
-+    "./examples/usr-local.js",
-+    "./node_modules/inherits",
-+    "./node_modules/minimatch",
-+    "./node_modules/mkdirp",
-+    "./node_modules/rimraf",
-+    "./node_modules/tap",
-+    "./test/00-setup.js",
-+    "./test/a",
-+    "./test/bash-comparison.js",
-+    "./test/bash-results.json",
-+    "./test/cwd-test.js",
-+    "./test/globstar-match.js",
-+    "./test/mark.js",
-+    "./test/new-glob-optional-options.js",
-+    "./test/nocase-nomagic.js",
-+    "./test/pause-resume.js",
-+    "./test/readme-issue.js",
-+    "./test/root-nomount.js",
-+    "./test/root.js",
-+    "./test/stat.js",
-+    "./test/zz-cleanup.js",
-+    "/tmp/glob-test/asdf",
-+    "/tmp/glob-test/bar",
-+    "/tmp/glob-test/baz",
-+    "/tmp/glob-test/foo",
-+    "/tmp/glob-test/quux",
-+    "/tmp/glob-test/qwer",
-+    "/tmp/glob-test/rewq"
-+  ],
-+  "{/tmp/glob-test/*,*}": [
-+    "/tmp/glob-test/asdf",
-+    "/tmp/glob-test/bar",
-+    "/tmp/glob-test/baz",
-+    "/tmp/glob-test/foo",
-+    "/tmp/glob-test/quux",
-+    "/tmp/glob-test/qwer",
-+    "/tmp/glob-test/rewq",
-+    "examples",
-+    "glob.js",
-+    "LICENSE",
-+    "node_modules",
-+    "package.json",
-+    "README.md",
-+    "test"
-+  ],
-+  "test/a/!(symlink)/**": [
-+    "test/a/abcdef",
-+    "test/a/abcdef/g",
-+    "test/a/abcdef/g/h",
-+    "test/a/abcfed",
-+    "test/a/abcfed/g",
-+    "test/a/abcfed/g/h",
-+    "test/a/b",
-+    "test/a/b/c",
-+    "test/a/b/c/d",
-+    "test/a/bc",
-+    "test/a/bc/e",
-+    "test/a/bc/e/f",
-+    "test/a/c",
-+    "test/a/c/d",
-+    "test/a/c/d/c",
-+    "test/a/c/d/c/b",
-+    "test/a/cb",
-+    "test/a/cb/e",
-+    "test/a/cb/e/f"
-+  ]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/cwd-test.js
-@@ -0,0 +1,55 @@
-+var tap = require("tap")
-+
-+var origCwd = process.cwd()
-+process.chdir(__dirname)
-+
-+tap.test("changing cwd and searching for **/d", function (t) {
-+  var glob = require('../')
-+  var path = require('path')
-+  t.test('.', function (t) {
-+    glob('**/d', function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('a', function (t) {
-+    glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ 'b/c/d', 'c/d' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('a/b', function (t) {
-+    glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ 'c/d' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('a/b/', function (t) {
-+    glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ 'c/d' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('.', function (t) {
-+    glob('**/d', {cwd: process.cwd()}, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('cd -', function (t) {
-+    process.chdir(origCwd)
-+    t.end()
-+  })
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/globstar-match.js
-@@ -0,0 +1,19 @@
-+var Glob = require("../glob.js").Glob
-+var test = require('tap').test
-+
-+test('globstar should not have dupe matches', function(t) {
-+  var pattern = 'a/**/[gh]'
-+  var g = new Glob(pattern, { cwd: __dirname })
-+  var matches = []
-+  g.on('match', function(m) {
-+    console.error('match %j', m)
-+    matches.push(m)
-+  })
-+  g.on('end', function(set) {
-+    console.error('set', set)
-+    matches = matches.sort()
-+    set = set.sort()
-+    t.same(matches, set, 'should have same set of matches')
-+    t.end()
-+  })
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/mark.js
-@@ -0,0 +1,118 @@
-+var test = require("tap").test
-+var glob = require('../')
-+process.chdir(__dirname)
-+
-+// expose timing issues
-+var lag = 5
-+glob.Glob.prototype._stat = function(o) { return function(f, cb) {
-+  var args = arguments
-+  setTimeout(function() {
-+    o.call(this, f, cb)
-+  }.bind(this), lag += 5)
-+}}(glob.Glob.prototype._stat)
-+
-+
-+test("mark, with **", function (t) {
-+  glob("a/*b*/**", {mark: true}, function (er, results) {
-+    if (er)
-+      throw er
-+    var expect =
-+      [ 'a/abcdef/',
-+        'a/abcdef/g/',
-+        'a/abcdef/g/h',
-+        'a/abcfed/',
-+        'a/abcfed/g/',
-+        'a/abcfed/g/h',
-+        'a/b/',
-+        'a/b/c/',
-+        'a/b/c/d',
-+        'a/bc/',
-+        'a/bc/e/',
-+        'a/bc/e/f',
-+        'a/cb/',
-+        'a/cb/e/',
-+        'a/cb/e/f' ]
-+
-+    t.same(results, expect)
-+    t.end()
-+  })
-+})
-+
-+test("mark, no / on pattern", function (t) {
-+  glob("a/*", {mark: true}, function (er, results) {
-+    if (er)
-+      throw er
-+    var expect = [ 'a/abcdef/',
-+                   'a/abcfed/',
-+                   'a/b/',
-+                   'a/bc/',
-+                   'a/c/',
-+                   'a/cb/' ]
-+
-+    if (process.platform !== "win32")
-+      expect.push('a/symlink/')
-+
-+    t.same(results, expect)
-+    t.end()
-+  }).on('match', function(m) {
-+    t.similar(m, /\/$/)
-+  })
-+})
-+
-+test("mark=false, no / on pattern", function (t) {
-+  glob("a/*", function (er, results) {
-+    if (er)
-+      throw er
-+    var expect = [ 'a/abcdef',
-+                   'a/abcfed',
-+                   'a/b',
-+                   'a/bc',
-+                   'a/c',
-+                   'a/cb' ]
-+
-+    if (process.platform !== "win32")
-+      expect.push('a/symlink')
-+    t.same(results, expect)
-+    t.end()
-+  }).on('match', function(m) {
-+    t.similar(m, /[^\/]$/)
-+  })
-+})
-+
-+test("mark=true, / on pattern", function (t) {
-+  glob("a/*/", {mark: true}, function (er, results) {
-+    if (er)
-+      throw er
-+    var expect = [ 'a/abcdef/',
-+                    'a/abcfed/',
-+                    'a/b/',
-+                    'a/bc/',
-+                    'a/c/',
-+                    'a/cb/' ]
-+    if (process.platform !== "win32")
-+      expect.push('a/symlink/')
-+    t.same(results, expect)
-+    t.end()
-+  }).on('match', function(m) {
-+    t.similar(m, /\/$/)
-+  })
-+})
-+
-+test("mark=false, / on pattern", function (t) {
-+  glob("a/*/", function (er, results) {
-+    if (er)
-+      throw er
-+    var expect = [ 'a/abcdef/',
-+                   'a/abcfed/',
-+                   'a/b/',
-+                   'a/bc/',
-+                   'a/c/',
-+                   'a/cb/' ]
-+    if (process.platform !== "win32")
-+      expect.push('a/symlink/')
-+    t.same(results, expect)
-+    t.end()
-+  }).on('match', function(m) {
-+    t.similar(m, /\/$/)
-+  })
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/new-glob-optional-options.js
-@@ -0,0 +1,10 @@
-+var Glob = require('../glob.js').Glob;
-+var test = require('tap').test;
-+
-+test('new glob, with cb, and no options', function (t) {
-+  new Glob(__filename, function(er, results) {
-+    if (er) throw er;
-+    t.same(results, [__filename]);
-+    t.end();
-+  });
-+});
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/nocase-nomagic.js
-@@ -0,0 +1,113 @@
-+var fs = require('fs');
-+var test = require('tap').test;
-+var glob = require('../');
-+
-+test('mock fs', function(t) {
-+  var stat = fs.stat
-+  var statSync = fs.statSync
-+  var readdir = fs.readdir
-+  var readdirSync = fs.readdirSync
-+
-+  function fakeStat(path) {
-+    var ret
-+    switch (path.toLowerCase()) {
-+      case '/tmp': case '/tmp/':
-+        ret = { isDirectory: function() { return true } }
-+        break
-+      case '/tmp/a':
-+        ret = { isDirectory: function() { return false } }
-+        break
-+    }
-+    return ret
-+  }
-+
-+  fs.stat = function(path, cb) {
-+    var f = fakeStat(path);
-+    if (f) {
-+      process.nextTick(function() {
-+        cb(null, f)
-+      })
-+    } else {
-+      stat.call(fs, path, cb)
-+    }
-+  }
-+
-+  fs.statSync = function(path) {
-+    return fakeStat(path) || statSync.call(fs, path)
-+  }
-+
-+  function fakeReaddir(path) {
-+    var ret
-+    switch (path.toLowerCase()) {
-+      case '/tmp': case '/tmp/':
-+        ret = [ 'a', 'A' ]
-+        break
-+      case '/':
-+        ret = ['tmp', 'tMp', 'tMP', 'TMP']
-+    }
-+    return ret
-+  }
-+
-+  fs.readdir = function(path, cb) {
-+    var f = fakeReaddir(path)
-+    if (f)
-+      process.nextTick(function() {
-+        cb(null, f)
-+      })
-+    else
-+      readdir.call(fs, path, cb)
-+  }
-+
-+  fs.readdirSync = function(path) {
-+    return fakeReaddir(path) || readdirSync.call(fs, path)
-+  }
-+
-+  t.pass('mocked')
-+  t.end()
-+})
-+
-+test('nocase, nomagic', function(t) {
-+  var n = 2
-+  var want = [ '/TMP/A',
-+               '/TMP/a',
-+               '/tMP/A',
-+               '/tMP/a',
-+               '/tMp/A',
-+               '/tMp/a',
-+               '/tmp/A',
-+               '/tmp/a' ]
-+  glob('/tmp/a', { nocase: true }, function(er, res) {
-+    if (er)
-+      throw er
-+    t.same(res.sort(), want)
-+    if (--n === 0) t.end()
-+  })
-+  glob('/tmp/A', { nocase: true }, function(er, res) {
-+    if (er)
-+      throw er
-+    t.same(res.sort(), want)
-+    if (--n === 0) t.end()
-+  })
-+})
-+
-+test('nocase, with some magic', function(t) {
-+  t.plan(2)
-+  var want = [ '/TMP/A',
-+               '/TMP/a',
-+               '/tMP/A',
-+               '/tMP/a',
-+               '/tMp/A',
-+               '/tMp/a',
-+               '/tmp/A',
-+               '/tmp/a' ]
-+  glob('/tmp/*', { nocase: true }, function(er, res) {
-+    if (er)
-+      throw er
-+    t.same(res.sort(), want)
-+  })
-+  glob('/tmp/*', { nocase: true }, function(er, res) {
-+    if (er)
-+      throw er
-+    t.same(res.sort(), want)
-+  })
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/pause-resume.js
-@@ -0,0 +1,73 @@
-+// show that no match events happen while paused.
-+var tap = require("tap")
-+, child_process = require("child_process")
-+// just some gnarly pattern with lots of matches
-+, pattern = "test/a/!(symlink)/**"
-+, bashResults = require("./bash-results.json")
-+, patterns = Object.keys(bashResults)
-+, glob = require("../")
-+, Glob = glob.Glob
-+, path = require("path")
-+
-+// run from the root of the project
-+// this is usually where you're at anyway, but be sure.
-+process.chdir(path.resolve(__dirname, ".."))
-+
-+function alphasort (a, b) {
-+  a = a.toLowerCase()
-+  b = b.toLowerCase()
-+  return a > b ? 1 : a < b ? -1 : 0
-+}
-+
-+function cleanResults (m) {
-+  // normalize discrepancies in ordering, duplication,
-+  // and ending slashes.
-+  return m.map(function (m) {
-+    return m.replace(/\/+/g, "/").replace(/\/$/, "")
-+  }).sort(alphasort).reduce(function (set, f) {
-+    if (f !== set[set.length - 1]) set.push(f)
-+    return set
-+  }, []).sort(alphasort).map(function (f) {
-+    // de-windows
-+    return (process.platform !== 'win32') ? f
-+           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
-+  })
-+}
-+
-+var globResults = []
-+tap.test("use a Glob object, and pause/resume it", function (t) {
-+  var g = new Glob(pattern)
-+  , paused = false
-+  , res = []
-+  , expect = bashResults[pattern]
-+
-+  g.on("pause", function () {
-+    console.error("pause")
-+  })
-+
-+  g.on("resume", function () {
-+    console.error("resume")
-+  })
-+
-+  g.on("match", function (m) {
-+    t.notOk(g.paused, "must not be paused")
-+    globResults.push(m)
-+    g.pause()
-+    t.ok(g.paused, "must be paused")
-+    setTimeout(g.resume.bind(g), 10)
-+  })
-+
-+  g.on("end", function (matches) {
-+    t.pass("reached glob end")
-+    globResults = cleanResults(globResults)
-+    matches = cleanResults(matches)
-+    t.deepEqual(matches, globResults,
-+      "end event matches should be the same as match events")
-+
-+    t.deepEqual(matches, expect,
-+      "glob matches should be the same as bash results")
-+
-+    t.end()
-+  })
-+})
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/readme-issue.js
-@@ -0,0 +1,36 @@
-+var test = require("tap").test
-+var glob = require("../")
-+
-+var mkdirp = require("mkdirp")
-+var fs = require("fs")
-+var rimraf = require("rimraf")
-+var dir = __dirname + "/package"
-+
-+test("setup", function (t) {
-+  mkdirp.sync(dir)
-+  fs.writeFileSync(dir + "/package.json", "{}", "ascii")
-+  fs.writeFileSync(dir + "/README", "x", "ascii")
-+  t.pass("setup done")
-+  t.end()
-+})
-+
-+test("glob", function (t) {
-+  var opt = {
-+    cwd: dir,
-+    nocase: true,
-+    mark: true
-+  }
-+
-+  glob("README?(.*)", opt, function (er, files) {
-+    if (er)
-+      throw er
-+    t.same(files, ["README"])
-+    t.end()
-+  })
-+})
-+
-+test("cleanup", function (t) {
-+  rimraf.sync(dir)
-+  t.pass("clean")
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/root-nomount.js
-@@ -0,0 +1,39 @@
-+var tap = require("tap")
-+
-+var origCwd = process.cwd()
-+process.chdir(__dirname)
-+
-+tap.test("changing root and searching for /b*/**", function (t) {
-+  var glob = require('../')
-+  var path = require('path')
-+  t.test('.', function (t) {
-+    glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('a', function (t) {
-+    glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('root=a, cwd=a/b', function (t) {
-+    glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
-+      t.ifError(er)
-+      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
-+      t.end()
-+    })
-+  })
-+
-+  t.test('cd -', function (t) {
-+    process.chdir(origCwd)
-+    t.end()
-+  })
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/root.js
-@@ -0,0 +1,46 @@
-+var t = require("tap")
-+
-+var origCwd = process.cwd()
-+process.chdir(__dirname)
-+
-+var glob = require('../')
-+var path = require('path')
-+
-+t.test('.', function (t) {
-+  glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
-+    t.ifError(er)
-+    t.like(matches, [])
-+    t.end()
-+  })
-+})
-+
-+
-+t.test('a', function (t) {
-+  console.error("root=" + path.resolve('a'))
-+  glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
-+    t.ifError(er)
-+    var wanted = [
-+        '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
-+      ].map(function (m) {
-+        return path.join(path.resolve('a'), m).replace(/\\/g, '/')
-+      })
-+
-+    t.like(matches, wanted)
-+    t.end()
-+  })
-+})
-+
-+t.test('root=a, cwd=a/b', function (t) {
-+  glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
-+    t.ifError(er)
-+    t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
-+      return path.join(path.resolve('a'), m).replace(/\\/g, '/')
-+    }))
-+    t.end()
-+  })
-+})
-+
-+t.test('cd -', function (t) {
-+  process.chdir(origCwd)
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/stat.js
-@@ -0,0 +1,32 @@
-+var glob = require('../')
-+var test = require('tap').test
-+var path = require('path')
-+
-+test('stat all the things', function(t) {
-+  var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname })
-+  var matches = []
-+  g.on('match', function(m) {
-+    matches.push(m)
-+  })
-+  var stats = []
-+  g.on('stat', function(m) {
-+    stats.push(m)
-+  })
-+  g.on('end', function(eof) {
-+    stats = stats.sort()
-+    matches = matches.sort()
-+    eof = eof.sort()
-+    t.same(stats, matches)
-+    t.same(eof, matches)
-+    var cache = Object.keys(this.statCache)
-+    t.same(cache.map(function (f) {
-+      return path.relative(__dirname, f)
-+    }).sort(), matches)
-+
-+    cache.forEach(function(c) {
-+      t.equal(typeof this.statCache[c], 'object')
-+    }, this)
-+
-+    t.end()
-+  })
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/glob/test/zz-cleanup.js
-@@ -0,0 +1,11 @@
-+// remove the fixtures
-+var tap = require("tap")
-+, rimraf = require("rimraf")
-+, path = require("path")
-+
-+tap.test("cleanup fixtures", function (t) {
-+  rimraf(path.resolve(__dirname, "a"), function (er) {
-+    t.ifError(er, "removed")
-+    t.end()
-+  })
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/.npmignore
-@@ -0,0 +1,3 @@
-+node_modules
-+*~
-+*sublime-*
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/.travis.yml
-@@ -0,0 +1,5 @@
-+ language: node_js
-+ node_js:
-+   - 0.4
-+   - 0.6
-+   - 0.8
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/LICENSE
-@@ -0,0 +1,21 @@
-+Copyright (c) 2011 Alexander Shtuchkin
-+
-+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.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/README.md
-@@ -0,0 +1,72 @@
-+iconv-lite - pure javascript character encoding conversion
-+======================================================================
-+
-+[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite)
-+
-+## Features
-+
-+*   Pure javascript. Doesn't need native code compilation.
-+*   Easy API.
-+*   Works on Windows and in sandboxed environments like [Cloud9](http://c9.io).
-+*   Encoding is much faster than node-iconv (see below for performance comparison).
-+
-+## Usage
-+
-+    var iconv = require('iconv-lite');
-+    
-+    // Convert from an encoded buffer to string.
-+    str = iconv.decode(buf, 'win1251');
-+    
-+    // Convert from string to an encoded buffer.
-+    buf = iconv.encode("Sample input string", 'win1251');
-+
-+    // Check if encoding is supported
-+    iconv.encodingExists("us-ascii")
-+
-+
-+## Supported encodings
-+
-+*   All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64'
-+*   All widespread single byte encodings: Windows 125x family, ISO-8859 family, 
-+    IBM/DOS codepages, Macintosh family, KOI8 family. 
-+    Aliases like 'latin1', 'us-ascii' also supported.
-+*   Multibyte encodings: 'gbk', 'gb2313', 'Big5', 'cp950'.
-+
-+Others are easy to add, see the source. Please, participate.
-+Most encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors!
-+
-+Not supported yet: EUC family, Shift_JIS.
-+
-+
-+## Encoding/decoding speed
-+
-+Comparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). 
-+Note: your results may vary, so please always check on your hardware.
-+
-+    operation             iconv at 1.2.4   iconv-lite at 0.2.4 
-+    ----------------------------------------------------------
-+    encode('win1251')     ~115 Mb/s     ~230 Mb/s
-+    decode('win1251')     ~95 Mb/s      ~130 Mb/s
-+
-+
-+## Notes
-+
-+When decoding, a 'binary'-encoded string can be used as a source buffer.  
-+Untranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome.
-+
-+## Testing
-+
-+    git clone git at github.com:ashtuchkin/iconv-lite.git
-+    cd iconv-lite
-+    npm install
-+    npm test
-+    
-+    # To view performance:
-+    node test/performance.js
-+
-+## TODO
-+
-+*   Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')).
-+*   Add more encodings.
-+*   Add transliteration (best fit char).
-+*   Add tests and correct support of variable-byte encodings (currently work is delegated to node).
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/encodings/big5.js
-@@ -0,0 +1,9 @@
-+var big5Table = require('./table/big5.js');
-+module.exports = {
-+	'windows950': 'big5',
-+	'cp950': 'big5',
-+	'big5': {
-+		type: 'table',
-+		table: big5Table
-+	}
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/encodings/gbk.js
-@@ -0,0 +1,9 @@
-+var gbkTable = require('./table/gbk.js');
-+module.exports = {
-+	'windows936': 'gbk',
-+	'gb2312': 'gbk',
-+	'gbk': {
-+		type: 'table',
-+		table: gbkTable
-+	}
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/encodings/singlebyte.js
-@@ -0,0 +1,340 @@
-+module.exports = {
-+  "437": "cp437",
-+  "737": "cp737",
-+  "775": "cp775",
-+  "850": "cp850",
-+  "852": "cp852",
-+  "855": "cp855",
-+  "857": "cp857",
-+  "858": "cp858",
-+  "860": "cp860",
-+  "861": "cp861",
-+  "862": "cp862",
-+  "863": "cp863",
-+  "864": "cp864",
-+  "865": "cp865",
-+  "866": "cp866",
-+  "869": "cp869",
-+  "874": "iso885911",
-+  "1250": "windows1250",
-+  "1251": "windows1251",
-+  "1252": "windows1252",
-+  "1253": "windows1253",
-+  "1254": "windows1254",
-+  "1255": "windows1255",
-+  "1256": "windows1256",
-+  "1257": "windows1257",
-+  "1258": "windows1258",
-+  "10000": "macroman",
-+  "10006": "macgreek",
-+  "10007": "maccyrillic",
-+  "10029": "maccenteuro",
-+  "10079": "maciceland",
-+  "10081": "macturkish",
-+  "20866": "koi8r",
-+  "21866": "koi8u",
-+  "28591": "iso88591",
-+  "28592": "iso88592",
-+  "28593": "iso88593",
-+  "28594": "iso88594",
-+  "28595": "iso88595",
-+  "28596": "iso88596",
-+  "28597": "iso88597",
-+  "28598": "iso88598",
-+  "28599": "iso88599",
-+  "28600": "iso885910",
-+  "28601": "iso885911",
-+  "28603": "iso885913",
-+  "28604": "iso885914",
-+  "28605": "iso885915",
-+  "28606": "iso885916",
-+  "ascii8bit": "ascii",
-+  "usascii": "ascii",
-+  "latin1": "iso88591",
-+  "latin2": "iso88592",
-+  "latin3": "iso88593",
-+  "latin4": "iso88594",
-+  "latin6": "iso885910",
-+  "latin7": "iso885913",
-+  "latin8": "iso885914",
-+  "latin9": "iso885915",
-+  "latin10": "iso885916",
-+  "cp819": "iso88951",
-+  "arabic": "iso88596",
-+  "arabic8": "iso88596",
-+  "greek": "iso88597",
-+  "greek8": "iso88597",
-+  "hebrew": "iso88598",
-+  "hebrew8": "iso88598",
-+  "turkish": "iso88599",
-+  "turkish8": "iso88599",
-+  "thai": "iso885911",
-+  "thai8": "iso885911",
-+  "tis620": "iso885911",
-+  "windows874": "iso885911",
-+  "win874": "iso885911",
-+  "cp874": "iso885911",
-+  "celtic": "iso885914",
-+  "celtic8": "iso885914",
-+  "cp20866": "koi8r",
-+  "ibm878": "koi8r",
-+  "cp21866": "koi8u",
-+  "ibm1168": "koi8u",
-+  "windows1250": {
-+    "type": "singlebyte",
-+    "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"
-+  },
-+  "win1250": "windows1250",
-+  "cp1250": "windows1250",
-+  "windows1251": {
-+    "type": "singlebyte",
-+    "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"
-+  },
-+  "win1251": "windows1251",
-+  "cp1251": "windows1251",
-+  "windows1252": {
-+    "type": "singlebyte",
-+    "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
-+  },
-+  "win1252": "windows1252",
-+  "cp1252": "windows1252",
-+  "windows1253": {
-+    "type": "singlebyte",
-+    "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"
-+  },
-+  "win1253": "windows1253",
-+  "cp1253": "windows1253",
-+  "windows1254": {
-+    "type": "singlebyte",
-+    "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"
-+  },
-+  "win1254": "windows1254",
-+  "cp1254": "windows1254",
-+  "windows1255": {
-+    "type": "singlebyte",
-+    "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ�ֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�"
-+  },
-+  "win1255": "windows1255",
-+  "cp1255": "windows1255",
-+  "windows1256": {
-+    "type": "singlebyte",
-+    "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے"
-+  },
-+  "win1256": "windows1256",
-+  "cp1256": "windows1256",
-+  "windows1257": {
-+    "type": "singlebyte",
-+    "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙"
-+  },
-+  "win1257": "windows1257",
-+  "cp1257": "windows1257",
-+  "windows1258": {
-+    "type": "singlebyte",
-+    "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"
-+  },
-+  "win1258": "windows1258",
-+  "cp1258": "windows1258",
-+  "iso88591": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
-+  },
-+  "cp28591": "iso88591",
-+  "iso88592": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"
-+  },
-+  "cp28592": "iso88592",
-+  "iso88593": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙"
-+  },
-+  "cp28593": "iso88593",
-+  "iso88594": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙"
-+  },
-+  "cp28594": "iso88594",
-+  "iso88595": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ"
-+  },
-+  "cp28595": "iso88595",
-+  "iso88596": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������"
-+  },
-+  "cp28596": "iso88596",
-+  "iso88597": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"
-+  },
-+  "cp28597": "iso88597",
-+  "iso88598": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�"
-+  },
-+  "cp28598": "iso88598",
-+  "iso88599": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"
-+  },
-+  "cp28599": "iso88599",
-+  "iso885910": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ"
-+  },
-+  "cp28600": "iso885910",
-+  "iso885911": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"
-+  },
-+  "cp28601": "iso885911",
-+  "iso885913": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’"
-+  },
-+  "cp28603": "iso885913",
-+  "iso885914": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ"
-+  },
-+  "cp28604": "iso885914",
-+  "iso885915": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
-+  },
-+  "cp28605": "iso885915",
-+  "iso885916": {
-+    "type": "singlebyte",
-+    "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ"
-+  },
-+  "cp28606": "iso885916",
-+  "cp437": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm437": "cp437",
-+  "cp737": {
-+    "type": "singlebyte",
-+    "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm737": "cp737",
-+  "cp775": {
-+    "type": "singlebyte",
-+    "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ "
-+  },
-+  "ibm775": "cp775",
-+  "cp850": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ "
-+  },
-+  "ibm850": "cp850",
-+  "cp852": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ "
-+  },
-+  "ibm852": "cp852",
-+  "cp855": {
-+    "type": "singlebyte",
-+    "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ "
-+  },
-+  "ibm855": "cp855",
-+  "cp857": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ "
-+  },
-+  "ibm857": "cp857",
-+  "cp858": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ "
-+  },
-+  "ibm858": "cp858",
-+  "cp860": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm860": "cp860",
-+  "cp861": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm861": "cp861",
-+  "cp862": {
-+    "type": "singlebyte",
-+    "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm862": "cp862",
-+  "cp863": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm863": "cp863",
-+  "cp864": {
-+    "type": "singlebyte",
-+    "chars": "°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�"
-+  },
-+  "ibm864": "cp864",
-+  "cp865": {
-+    "type": "singlebyte",
-+    "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
-+  },
-+  "ibm865": "cp865",
-+  "cp866": {
-+    "type": "singlebyte",
-+    "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ "
-+  },
-+  "ibm866": "cp866",
-+  "cp869": {
-+    "type": "singlebyte",
-+    "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ "
-+  },
-+  "ibm869": "cp869",
-+  "maccenteuro": {
-+    "type": "singlebyte",
-+    "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ"
-+  },
-+  "maccroatian": {
-+    "type": "singlebyte",
-+    "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ"
-+  },
-+  "maccyrillic": {
-+    "type": "singlebyte",
-+    "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤"
-+  },
-+  "macgreek": {
-+    "type": "singlebyte",
-+    "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�"
-+  },
-+  "maciceland": {
-+    "type": "singlebyte",
-+    "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
-+  },
-+  "macroman": {
-+    "type": "singlebyte",
-+    "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
-+  },
-+  "macromania": {
-+    "type": "singlebyte",
-+    "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
-+  },
-+  "macthai": {
-+    "type": "singlebyte",
-+    "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����"
-+  },
-+  "macturkish": {
-+    "type": "singlebyte",
-+    "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ"
-+  },
-+  "macukraine": {
-+    "type": "singlebyte",
-+    "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤"
-+  },
-+  "koi8r": {
-+    "type": "singlebyte",
-+    "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
-+  },
-+  "koi8u": {
-+    "type": "singlebyte",
-+    "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/encodings/table/big5.js
-@@ -0,0 +1 @@
-+module.exports={"33088":19991,"33089":20002,"33090":20012,"33091":20053,"33092":20066,"33093":20106,"33094":20144,"33095":20203,"33096":20205,"33097":20220,"33098":20252,"33099":20362,"33100":20479,"33101":20546,"33102":20560,"33103":20600,"33104":20696,"33105":20702,"33106":20724,"33107":20758,"33108":20810,"33109":20817,"33110":20836,"33111":20842,"33112":20869,"33113":20880,"33114":20893,"33115":20902,"33116":20904,"33117":20905,"33118":20935,"33119":20950,"33120":20955,"33121":20972,"33122":20988,"33123":21003,"33124":21012,"33125":21013,"33126":21024,"33127":21035,"33128":21049,"33129":21071,"33130":21105,"33131":21136,"33132":21138,"33133":21140,"33134":21148,"33135":21167,"33136":21173,"33137":21200,"33138":21248,"33139":21255,"33140":21284,"33141":21318,"33142":21343,"33143":21395,"33144":21424,"33145":21469,"33146":21539,"33147":21584,"33148":21585,"33149":21642,"33150":21661,"33185":21667,"33186":21684,"33187":21712,"33188":21795,"33189":21823,"33190":21836,"33191":21843,"33192":21853,"33193":21868,"33194":21918,"33195":21929,"33196":21996,"33197":22005,"33198":22051,"33199":22096,"33200":22140,"33201":22154,"33202":22164,"33203":22176,"33204":22191,"33205":22232,"33206":22272,"33207":22361,"33208":22373,"33209":22399,"33210":22405,"33211":22409,"33212":22433,"33213":22444,"33214":22452,"33215":22464,"33216":22472,"33217":22483,"33218":22511,"33219":22596,"33220":22636,"33221":22674,"33222":22682,"33223":22706,"33224":22712,"33225":22757,"33226":22779,"33227":22786,"33228":22795,"33229":22800,"33230":22808,"33231":22811,"33232":29836,"33233":29837,"33234":29849,"33235":29851,"33236":29860,"33237":29876,"33238":29881,"33239":29896,"33240":29900,"33241":29904,"33242":29907,"33243":30018,"33244":30037,"33245":30062,"33246":30093,"33247":30110,"33248":30172,"33249":30252,"33250":30287,"33251":30289,"33252":30323,"33253":30324,"33254":30373,"33255":30425,"33256":30478,"33257":30479,"33258":30552,"33259":30578,"33260":30583,"33261":30584,"33262":30586,"33263":30587,"33264":30616,"33265":30639,"33266":30654,"33267":30659,"33268":30661,"33269":30667,"33270":30685,"33271":30694,"33272":30708,"33273":30750,"33274":30781,"33275":30786,"33276":30788,"33277":30795,"33278":30801,"33344":21782,"33345":22775,"33346":38964,"33347":33883,"33348":28948,"33349":33398,"33350":35158,"33351":40236,"33352":40206,"33353":36527,"33354":24674,"33355":26214,"33356":34510,"33357":25785,"33358":37772,"33359":22107,"33360":28485,"33361":35532,"33362":29001,"33363":24012,"33364":34633,"33365":39464,"33366":31658,"33367":36107,"33368":39255,"33369":23597,"33370":32331,"33371":38938,"33372":20518,"33373":25458,"33374":40568,"33375":30783,"33376":40633,"33377":40634,"33378":36046,"33379":35715,"33380":61305,"33381":33931,"33382":37284,"33383":31331,"33384":25776,"33385":24061,"33386":24214,"33387":32865,"33388":26965,"33389":31466,"33390":28710,"33391":26812,"33392":31095,"33393":28060,"33394":36841,"33395":31074,"33396":22178,"33397":34687,"33398":21093,"33399":31108,"33400":28300,"33401":37271,"33402":31622,"33403":38956,"33404":26717,"33405":20397,"33406":34222,"33441":31725,"33442":34635,"33443":20534,"33444":26893,"33445":27542,"33446":24910,"33447":20855,"33448":30495,"33449":20516,"33450":32622,"33451":30452,"33452":27097,"33453":24803,"33454":25334,"33455":21599,"33456":38788,"33457":22092,"33458":20677,"33459":22040,"33460":34398,"33461":22834,"33462":22875,"33463":22877,"33464":22883,"33465":22892,"33466":22939,"33467":22999,"33468":23019,"33469":23066,"33470":23210,"33471":23248,"33472":23281,"33473":23350,"33474":23497,"33475":23539,"33476":23571,"33477":23580,"33478":23582,"33479":23635,"33480":23705,"33481":23708,"33482":23738,"33483":23739,"33484":23745,"33485":23797,"33486":23802,"33487":23829,"33488":23832,"33489":23870,"33490":23891,"33491":23900,"33492":23917,"33493":23923,"33494":23924,"33495":23948,"33496":23952,"33497":23993,"33498":24016,"33499":24019,"33500":24135,"33501":24164,"33502":24271,"33503":24272,"33504":24298,"33505":24304,"33506":24329,"33507":24332,"33508":24337,"33509":24353,"33510":24372,"33511":24385,"33512":24389,"33513":24401,"33514":24412,"33515":24422,"33516":24451,"33517":24560,"33518":24650,"33519":24672,"33520":24715,"33521":24742,"33522":24798,"33523":24849,"33524":24864,"33525":24865,"33526":24892,"33527":24893,"33528":24984,"33529":25015,"33530":25076,"33531":25107,"33532":25117,"33533":25118,"33534":25143,"33600":24186,"33601":27664,"33602":21454,"33603":20267,"33604":20302,"33605":21556,"33606":22257,"33607":22766,"33608":22841,"33609":22918,"33610":23596,"33611":20915,"33612":20914,"33613":28798,"33614":35265,"33615":35282,"33616":36125,"33617":36710,"33618":20122,"33619":26469,"33620":20177,"33621":20004,"33622":21327,"33623":23626,"33624":20872,"33625":24213,"33626":25269,"33627":19996,"33628":20105,"33629":29366,"33630":31868,"33631":32416,"33632":21351,"33633":36711,"33634":37048,"33635":38271,"33636":38376,"33637":20384,"33638":20387,"33639":20822,"33640":21017,"33641":21170,"33642":21364,"33643":22850,"33644":24069,"33645":26594,"33646":27769,"33647":20026,"33648":32419,"33649":32418,"33650":32426,"33651":32427,"33652":32421,"33653":32422,"33654":32417,"33655":32989,"33656":33486,"33657":35745,"33658":35746,"33659":35747,"33660":36126,"33661":36127,"33662":20891,"33697":36712,"33698":38377,"33699":38886,"33700":39029,"33701":39118,"33702":39134,"33703":20457,"33704":20204,"33705":20261,"33706":20010,"33707":20262,"33708":20179,"33709":20923,"33710":21018,"33711":21093,"33712":21592,"33713":23089,"33714":23385,"33715":23777,"33716":23707,"33717":23704,"33718":24072,"33719":24211,"33720":24452,"33721":25375,"33722":26102,"33723":26187,"33724":20070,"33725":27902,"33726":27971,"33727":20044,"33728":29421,"33729":29384,"33730":20137,"33731":30757,"33732":31210,"33733":32442,"33734":32433,"33735":32441,"33736":32431,"33737":32445,"33738":32432,"33739":32423,"33740":32429,"33741":32435,"33742":32440,"33743":32439,"33744":32961,"33745":33033,"33746":21005,"33747":35760,"33748":35750,"33749":35752,"33750":35751,"33751":35754,"33752":35759,"33753":35757,"33754":35755,"33755":23682,"33756":36130,"33757":36129,"33758":36713,"33759":36715,"33760":38025,"33761":38024,"33762":38026,"33763":38027,"33764":38378,"33765":38453,"33766":38485,"33767":38473,"33768":39269,"33769":39532,"33770":39592,"33771":20266,"33772":20255,"33773":20390,"33774":20391,"33775":21153,"33776":21160,"33777":21306,"33778":21442,"33779":21713,"33780":38382,"33781":34900,"33782":22269,"33783":22362,"33784":22441,"33785":25191,"33786":22815,"33787":23044,"33788":22919,"33789":19987,"33790":23558,"33856":23625,"33857":23781,"33858":23703,"33859":24102,"33860":24080,"33861":24352,"33862":24378,"33863":20174,"33864":24469,"33865":20932,"33866":24581,"33867":25195,"33868":25346,"33869":25194,"33870":25249,"33871":25379,"33872":36133,"33873":21551,"33874":26011,"33875":26025,"33876":26172,"33877":21206,"33878":24323,"33879":26465,"33880":26541,"33881":26432,"33882":27682,"33883":20937,"33884":27973,"33885":28170,"33886":27882,"33887":27814,"33888":20928,"33889":29301,"33890":29424,"33891":29616,"33892":20135,"33893":27605,"33894":24322,"33895":20247,"33896":32458,"33897":32479,"33898":32461,"33899":32459,"33900":32460,"33901":32454,"33902":32453,"33903":32452,"33904":32456,"33905":32449,"33906":32450,"33907":38069,"33908":20064,"33909":33626,"33910":33550,"33911":33682,"33912":24196,"33913":33483,"33914":22788,"33915":26415,"33916":34926,"33917":35269,"33918":35268,"33953":35775,"33954":35766,"33955":35776,"33956":35767,"33957":35768,"33958":35774,"33959":35772,"33960":35769,"33961":36137,"33962":36131,"33963":36143,"33964":36135,"33965":36138,"33966":36139,"33967":36717,"33968":36719,"33969":36825,"33970":36830,"33971":36851,"33972":38039,"33973":38035,"33974":38031,"33975":38034,"33976":38381,"33977":38472,"33978":38470,"33979":38452,"33980":39030,"33981":39031,"33982":40060,"33983":40479,"33984":21348,"33985":40614,"33986":22791,"33987":20263,"33988":20254,"33989":20975,"33990":21056,"33991":21019,"33992":21171,"33993":21195,"33994":20007,"33995":21333,"33996":21727,"33997":21796,"33998":20052,"33999":22260,"34000":23591,"34001":22330,"34002":25253,"34003":22490,"34004":22774,"34005":23090,"34006":23547,"34007":23706,"34008":24103,"34009":24079,"34010":21397,"34011":21417,"34012":24694,"34013":38391,"34014":24812,"34015":24699,"34016":24700,"34017":25315,"34018":25381,"34019":25442,"34020":25196,"34021":26531,"34022":26635,"34023":26632,"34024":38054,"34025":27531,"34026":22771,"34027":27695,"34028":27689,"34029":28044,"34030":20945,"34031":28270,"34032":28065,"34033":27748,"34034":27979,"34035":27985,"34036":28067,"34037":26080,"34038":29369,"34039":33487,"34040":30011,"34041":30153,"34042":21457,"34043":30423,"34044":30746,"34045":31174,"34046":31383,"34112":31508,"34113":31499,"34114":32478,"34115":32467,"34116":32466,"34117":32477,"34118":19997,"34119":32476,"34120":32473,"34121":32474,"34122":32470,"34123":32475,"34124":32899,"34125":32958,"34126":32960,"34127":21326,"34128":33713,"34129":33484,"34130":34394,"34131":35270,"34132":35780,"34133":35789,"34134":35777,"34135":35778,"34136":35791,"34137":35781,"34138":35784,"34139":35787,"34140":35785,"34141":35786,"34142":35779,"34143":36142,"34144":36148,"34145":36144,"34146":36155,"34147":36146,"34148":36153,"34149":36154,"34150":36149,"34151":20080,"34152":36140,"34153":36152,"34154":36151,"34155":36722,"34156":36724,"34157":36726,"34158":36827,"34159":37038,"34160":20065,"34161":38046,"34162":38062,"34163":38041,"34164":38048,"34165":38055,"34166":38045,"34167":38052,"34168":38051,"34169":38389,"34170":38384,"34171":24320,"34172":38386,"34173":38388,"34174":38387,"34209":38431,"34210":38454,"34211":38451,"34212":38887,"34213":39033,"34214":39034,"34215":39035,"34216":39274,"34217":39277,"34218":39272,"34219":39278,"34220":39276,"34221":20911,"34222":39533,"34223":20081,"34224":20538,"34225":20256,"34226":20165,"34227":20542,"34228":20260,"34229":20588,"34230":38130,"34231":21183,"34232":31215,"34233":27719,"34234":21527,"34235":21596,"34236":21595,"34237":22253,"34238":22278,"34239":28034,"34240":22359,"34241":22366,"34242":22488,"34243":33556,"34244":22885,"34245":22920,"34246":29233,"34247":24574,"34248":24582,"34249":24698,"34250":25439,"34251":25250,"34252":25443,"34253":26500,"34254":26198,"34255":26197,"34256":26104,"34257":20250,"34258":19994,"34259":26497,"34260":26472,"34261":26722,"34262":26539,"34263":23681,"34264":27807,"34265":28781,"34266":28287,"34267":28369,"34268":27815,"34269":28902,"34270":28860,"34271":28800,"34272":28949,"34273":29239,"34274":29422,"34275":29502,"34276":29682,"34277":24403,"34278":30415,"34279":30544,"34280":30529,"34281":38606,"34282":30860,"34283":33410,"34284":31509,"34285":31908,"34286":32463,"34287":32482,"34288":32465,"34289":32485,"34290":32486,"34291":20041,"34292":32673,"34293":22307,"34294":32928,"34295":33050,"34296":32959,"34297":33041,"34298":33636,"34299":33479,"34300":21494,"34301":33716,"34302":34398,"34368":34383,"34369":21495,"34370":34568,"34371":34476,"34372":34917,"34373":35013,"34374":35815,"34375":35813,"34376":35814,"34377":35797,"34378":35799,"34379":35800,"34380":35801,"34381":35811,"34382":35802,"34383":35805,"34384":35803,"34385":35809,"34386":35810,"34387":35808,"34388":35807,"34389":36156,"34390":36164,"34391":36158,"34392":36159,"34393":36160,"34394":36161,"34395":36162,"34396":36165,"34397":36739,"34398":36733,"34399":36732,"34400":36734,"34401":20892,"34402":36816,"34403":36798,"34404":36829,"34405":36807,"34406":37049,"34407":38068,"34408":38067,"34409":38073,"34410":38072,"34411":38078,"34412":38080,"34413":38085,"34414":38057,"34415":38082,"34416":38083,"34417":38089,"34418":38091,"34419":38044,"34420":38093,"34421":38079,"34422":38086,"34423":38392,"34424":38504,"34425":38589,"34426":30005,"34427":39044,"34428":39037,"34429":39039,"34430":39036,"34465":39041,"34466":39042,"34467":39282,"34468":39284,"34469":39281,"34470":39280,"34471":39536,"34472":39534,"34473":39535,"34474":40480,"34475":20389,"34476":20392,"34477":21294,"34478":21388,"34479":23581,"34480":21589,"34481":21497,"34482":21949,"34483":21863,"34484":21716,"34485":22242,"34486":22270,"34487":23576,"34488":22443,"34489":22545,"34490":23551,"34491":26790,"34492":22842,"34493":22849,"34494":22954,"34495":23454,"34496":23517,"34497":23545,"34498":23649,"34499":23853,"34500":23702,"34501":24065,"34502":24124,"34503":24443,"34504":24577,"34505":24815,"34506":24696,"34507":24813,"34508":24808,"34509":25602,"34510":25524,"34511":25530,"34512":30021,"34513":33635,"34514":26538,"34515":28378,"34516":28173,"34517":27721,"34518":28385,"34519":28382,"34520":28176,"34521":28072,"34522":28063,"34523":27818,"34524":28180,"34525":28183,"34526":28068,"34527":33639,"34528":23572,"34529":33638,"34530":29425,"34531":29712,"34532":29595,"34533":30111,"34534":30113,"34535":30127,"34536":30186,"34537":23613,"34538":30417,"34539":30805,"34540":31087,"34541":31096,"34542":31181,"34543":31216,"34544":27964,"34545":31389,"34546":31546,"34547":31581,"34548":32509,"34549":32510,"34550":32508,"34551":32496,"34552":32491,"34553":32511,"34554":32039,"34555":32512,"34556":32434,"34557":32494,"34558":32504,"34624":32501,"34625":32438,"34626":32500,"34627":32490,"34628":32513,"34629":32502,"34630":32602,"34631":38395,"34632":33669,"34633":30422,"34634":33642,"34635":33485,"34636":34432,"34637":35829,"34638":35821,"34639":35820,"34640":35748,"34641":35819,"34642":35823,"34643":35828,"34644":35824,"34645":35826,"34646":35825,"34647":35827,"34648":35822,"34649":23486,"34650":36168,"34651":36170,"34652":36213,"34653":36214,"34654":36741,"34655":36740,"34656":36731,"34657":36828,"34658":36874,"34659":36882,"34660":38128,"34661":38134,"34662":38108,"34663":38125,"34664":38114,"34665":38124,"34666":38120,"34667":38133,"34668":38115,"34669":38402,"34670":38394,"34671":38397,"34672":38401,"34673":38400,"34674":38469,"34675":39047,"34676":39046,"34677":39122,"34678":39290,"34679":39292,"34680":39285,"34681":39287,"34682":39539,"34683":32942,"34684":39600,"34685":40483,"34686":40482,"34721":20964,"34722":40784,"34723":20159,"34724":20202,"34725":20215,"34726":20396,"34727":20393,"34728":20461,"34729":21095,"34730":21016,"34731":21073,"34732":21053,"34733":21385,"34734":21792,"34735":22068,"34736":21719,"34737":22040,"34738":21943,"34739":21880,"34740":21501,"34741":22687,"34742":22367,"34743":22368,"34744":22549,"34745":23092,"34746":23157,"34747":22953,"34748":23047,"34749":23046,"34750":23485,"34751":23457,"34752":20889,"34753":23618,"34754":23956,"34755":24092,"34756":24223,"34757":21416,"34758":24217,"34759":21422,"34760":24191,"34761":24377,"34762":24198,"34763":34385,"34764":24551,"34765":24578,"34766":24751,"34767":24814,"34768":24868,"34769":24579,"34770":25370,"34771":25169,"34772":25438,"34773":25320,"34774":25376,"34775":25242,"34776":25528,"34777":25599,"34778":25932,"34779":25968,"34780":26242,"34781":26165,"34782":26679,"34783":26729,"34784":26530,"34785":26631,"34786":27004,"34787":26728,"34788":20048,"34789":26526,"34790":27431,"34791":27527,"34792":27572,"34793":27974,"34794":27900,"34795":27905,"34796":27975,"34797":28291,"34798":28070,"34799":28071,"34800":27988,"34801":28909,"34802":22870,"34803":33721,"34804":30126,"34805":30353,"34806":30385,"34807":30424,"34808":30830,"34809":30721,"34810":31377,"34811":31351,"34812":32532,"34813":32451,"34814":32428,"34880":32516,"34881":32517,"34882":32521,"34883":32534,"34884":32536,"34885":32447,"34886":32526,"34887":32531,"34888":32525,"34889":32514,"34890":32520,"34891":32519,"34892":39554,"34893":32610,"34894":33014,"34895":32932,"34896":33714,"34897":33643,"34898":33931,"34899":34430,"34900":34583,"34901":21355,"34902":35850,"34903":35845,"34904":35848,"34905":35846,"34906":35806,"34907":35831,"34908":35832,"34909":35838,"34910":35839,"34911":35844,"34912":35843,"34913":35841,"34914":35770,"34915":35812,"34916":35847,"34917":35837,"34918":35840,"34919":31446,"34920":36180,"34921":36175,"34922":36171,"34923":36145,"34924":36134,"34925":36172,"34926":36132,"34927":21334,"34928":36176,"34929":36136,"34930":36179,"34931":36341,"34932":36745,"34933":36742,"34934":36749,"34935":36744,"34936":36743,"34937":36718,"34938":36750,"34939":36747,"34940":36746,"34941":36866,"34942":36801,"34977":37051,"34978":37073,"34979":37011,"34980":38156,"34981":38161,"34982":38144,"34983":38138,"34984":38096,"34985":38148,"34986":38109,"34987":38160,"34988":38153,"34989":38155,"34990":38049,"34991":38146,"34992":38398,"34993":38405,"34994":24041,"34995":39049,"34996":39052,"34997":20859,"34998":39295,"34999":39297,"35000":39548,"35001":39547,"35002":39543,"35003":39542,"35004":39549,"35005":39550,"35006":39545,"35007":39544,"35008":39607,"35009":38393,"35010":40063,"35011":40065,"35012":40489,"35013":40486,"35014":40632,"35015":40831,"35016":20454,"35017":20647,"35018":20394,"35019":24130,"35020":21058,"35021":21544,"35022":21725,"35023":22003,"35024":22438,"35025":22363,"35026":22859,"35027":34949,"35028":23398,"35029":23548,"35030":23466,"35031":20973,"35032":24811,"35033":25044,"35034":24518,"35035":25112,"35036":25317,"35037":25377,"35038":25374,"35039":25454,"35040":25523,"35041":25321,"35042":25441,"35043":25285,"35044":25373,"35045":21382,"35046":26195,"35047":26196,"35048":26137,"35049":26726,"35050":27178,"35051":26641,"35052":26925,"35053":26725,"35054":26426,"35055":26721,"35056":28096,"35057":27987,"35058":27901,"35059":27978,"35060":27811,"35061":28582,"35062":28177,"35063":28861,"35064":28903,"35065":28783,"35066":28907,"35067":28950,"35068":29420,"35069":29585,"35070":29935,"35136":30232,"35137":21346,"35138":30610,"35139":30742,"35140":30875,"35141":31215,"35142":39062,"35143":31267,"35144":31397,"35145":31491,"35146":31579,"35147":32546,"35148":32547,"35149":33830,"35150":32538,"35151":21439,"35152":32543,"35153":32540,"35154":32537,"35155":32457,"35156":33147,"35157":20852,"35158":33329,"35159":33633,"35160":33831,"35161":33436,"35162":34434,"35163":33828,"35164":35044,"35165":20146,"35166":35278,"35167":35867,"35168":35866,"35169":35855,"35170":35763,"35171":35851,"35172":35853,"35173":35856,"35174":35864,"35175":35834,"35176":35858,"35177":35859,"35178":35773,"35179":35861,"35180":35865,"35181":35852,"35182":35862,"35183":36182,"35184":36752,"35185":36753,"35186":36755,"35187":36751,"35188":21150,"35189":36873,"35190":36831,"35191":36797,"35192":36951,"35193":37050,"35194":38189,"35195":38191,"35196":38192,"35197":38169,"35198":38065,"35233":38050,"35234":38177,"35235":24405,"35236":38126,"35237":38181,"35238":38182,"35239":38175,"35240":38178,"35241":38193,"35242":38414,"35243":38543,"35244":38505,"35245":38745,"35246":33148,"35247":39050,"35248":39048,"35249":39057,"35250":39060,"35251":22836,"35252":39059,"35253":39056,"35254":39302,"35255":39279,"35256":39300,"35257":39301,"35258":39559,"35259":39560,"35260":39558,"35261":39608,"35262":39612,"35263":40077,"35264":40501,"35265":40490,"35266":40495,"35267":40493,"35268":40499,"35269":40857,"35270":40863,"35271":20248,"35272":20607,"35273":20648,"35274":21169,"35275":21659,"35276":21523,"35277":21387,"35278":22489,"35279":23156,"35280":23252,"35281":23351,"35282":23604,"35283":23654,"35284":23679,"35285":23896,"35286":24110,"35287":24357,"35288":24212,"35289":24691,"35290":25103,"35291":20987,"35292":25380,"35293":25319,"35294":25311,"35295":25601,"35296":25947,"35297":27609,"35298":26279,"35299":26723,"35300":26816,"35301":26727,"35302":26633,"35303":27183,"35304":27539,"35305":27617,"35306":27870,"35307":28392,"35308":27982,"35309":28059,"35310":28389,"35311":28073,"35312":28493,"35313":33829,"35314":28799,"35315":28891,"35316":28905,"35317":22681,"35318":29406,"35319":33719,"35320":29615,"35321":29815,"35322":30184,"35323":30103,"35324":30699,"35325":30970,"35326":30710,"35392":31699,"35393":31914,"35394":38214,"35395":31937,"35396":32553,"35397":32489,"35398":32554,"35399":32533,"35400":32551,"35401":32503,"35402":32541,"35403":24635,"35404":32437,"35405":32555,"35406":32420,"35407":32549,"35408":32358,"35409":32550,"35410":22768,"35411":32874,"35412":32852,"35413":32824,"35414":33043,"35415":32966,"35416":33080,"35417":33037,"35418":20020,"35419":20030,"35420":33392,"35421":34103,"35422":34015,"35423":20111,"35424":34684,"35425":34632,"35426":20149,"35427":35099,"35428":35274,"35429":35868,"35430":35876,"35431":35878,"35432":35762,"35433":35854,"35434":35875,"35435":35874,"35436":35466,"35437":35879,"35438":36186,"35439":36187,"35440":36141,"35441":36185,"35442":36235,"35443":36758,"35444":36759,"35445":27586,"35446":36757,"35447":33286,"35448":36824,"35449":36808,"35450":37213,"35451":38208,"35452":38209,"35453":38170,"35454":38190,"35489":38194,"35490":38149,"35491":38180,"35492":38202,"35493":38201,"35494":38203,"35495":38206,"35496":38199,"35497":38420,"35498":38421,"35499":38417,"35500":38385,"35501":38544,"35502":38582,"35503":34429,"35504":38889,"35505":39063,"35506":39123,"35507":39563,"35508":39567,"35509":40092,"35510":40091,"35511":40084,"35512":40081,"35513":40511,"35514":40509,"35515":28857,"35516":25995,"35517":19995,"35518":22108,"35519":22329,"35520":22418,"35521":23158,"35522":25041,"35523":25193,"35524":25527,"35525":25200,"35526":25781,"35527":25670,"35528":25822,"35529":25783,"35530":26029,"35531":27103,"35532":26588,"35533":27099,"35534":26592,"35535":27428,"35536":24402,"35537":27553,"35538":27899,"35539":28182,"35540":28388,"35541":28174,"35542":28293,"35543":27983,"35544":28908,"35545":28952,"35546":29367,"35547":29454,"35548":29934,"35549":30112,"35550":30545,"35551":30784,"35552":31036,"35553":31313,"35554":31229,"35555":31388,"35556":31373,"35557":31659,"35558":31783,"35559":31658,"35560":31697,"35561":31616,"35562":31918,"35563":32455,"35564":32558,"35565":32469,"35566":32557,"35567":32483,"35568":32559,"35569":32728,"35570":32844,"35571":32834,"35572":33040,"35573":33169,"35574":26087,"35575":33832,"35576":34013,"35577":33632,"35578":34546,"35579":34633,"35580":35280,"35581":35294,"35582":35871,"35648":35880,"35649":35884,"35650":35882,"35651":36184,"35652":36434,"35653":36857,"35654":36344,"35655":36527,"35656":36716,"35657":36761,"35658":36841,"35659":21307,"35660":37233,"35661":38225,"35662":38145,"35663":38056,"35664":38221,"35665":38215,"35666":38224,"35667":38226,"35668":38217,"35669":38422,"35670":38383,"35671":38423,"35672":38425,"35673":26434,"35674":21452,"35675":38607,"35676":40481,"35677":39069,"35678":39068,"35679":39064,"35680":39066,"35681":39067,"35682":39311,"35683":39306,"35684":39304,"35685":39569,"35686":39617,"35687":40104,"35688":40100,"35689":40107,"35690":40103,"35691":40515,"35692":40517,"35693":40516,"35694":22404,"35695":22364,"35696":23456,"35697":24222,"35698":24208,"35699":24809,"35700":24576,"35701":25042,"35702":25314,"35703":26103,"35704":27249,"35705":26911,"35706":27016,"35707":27257,"35708":28487,"35709":28625,"35710":27813,"35745":28626,"35746":27896,"35747":28865,"35748":29261,"35749":29322,"35750":20861,"35751":29549,"35752":29626,"35753":29756,"35754":30068,"35755":30250,"35756":30861,"35757":31095,"35758":31283,"35759":31614,"35760":33575,"35761":32462,"35762":32499,"35763":32472,"35764":32599,"35765":32564,"35766":33211,"35767":33402,"35768":34222,"35769":33647,"35770":34433,"35771":34631,"35772":35014,"35773":34948,"35774":35889,"35775":35782,"35776":35885,"35777":35890,"35778":35749,"35779":35887,"35780":36192,"35781":36190,"35782":36343,"35783":36762,"35784":36735,"35785":36766,"35786":36793,"35787":38236,"35788":38237,"35789":38238,"35790":38142,"35791":38231,"35792":38232,"35793":38230,"35794":38233,"35795":38197,"35796":38210,"35797":38143,"35798":37694,"35799":20851,"35800":38471,"35801":38590,"35802":38654,"35803":38892,"35804":38901,"35805":31867,"35806":39072,"35807":39125,"35808":39314,"35809":39313,"35810":39579,"35811":39575,"35812":40120,"35813":40115,"35814":40109,"35815":40119,"35816":40529,"35817":40521,"35818":40522,"35819":40524,"35820":40527,"35821":20029,"35822":40628,"35823":21149,"35824":21657,"35825":22052,"35826":20005,"35827":23453,"35828":24748,"35829":24527,"35830":25318,"35831":25600,"35832":32999,"35833":27015,"35834":28572,"35835":28491,"35836":28809,"35837":29649,"35838":30719,"35904":30778,"35905":30718,"35906":30782,"35907":31398,"35908":31454,"35909":31609,"35910":31726,"35911":36779,"35912":32548,"35913":32487,"35914":32578,"35915":33002,"35916":33328,"35917":34108,"35918":34106,"35919":33446,"35920":33529,"35921":34164,"35922":34461,"35923":35124,"35924":35273,"35925":35302,"35926":35758,"35927":35793,"35928":35893,"35929":36194,"35930":36193,"35931":36280,"35932":37322,"35933":38047,"35934":38105,"35935":38152,"35936":38416,"35937":39128,"35938":39286,"35939":39269,"35940":39582,"35941":33150,"35942":39578,"35943":40131,"35944":40133,"35945":20826,"35946":40835,"35947":40836,"35948":20458,"35949":21995,"35950":21869,"35951":22179,"35952":23646,"35953":24807,"35954":24913,"35955":25668,"35956":25658,"35957":26003,"35958":27185,"35959":26639,"35960":26818,"35961":27516,"35962":28866,"35963":29306,"35964":38262,"35965":29838,"35966":30302,"36001":32544,"36002":32493,"36003":20848,"36004":34259,"36005":34510,"36006":35272,"36007":35892,"36008":25252,"36009":35465,"36010":36163,"36011":36364,"36012":36291,"36013":36347,"36014":36720,"36015":36777,"36016":38256,"36017":38253,"36018":38081,"36019":38107,"36020":38094,"36021":38255,"36022":38220,"36023":21709,"36024":39038,"36025":39074,"36026":39144,"36027":39537,"36028":39584,"36029":34022,"36030":39585,"36031":39621,"36032":40141,"36033":40143,"36034":33722,"36035":40548,"36036":40542,"36037":40839,"36038":40840,"36039":21870,"36040":20456,"36041":20645,"36042":21587,"36043":23402,"36044":24005,"36045":23782,"36046":24367,"36047":25674,"36048":26435,"36049":27426,"36050":28393,"36051":29473,"36052":21472,"36053":30270,"36054":30307,"36055":31548,"36056":31809,"36057":32843,"36058":33039,"36059":34989,"36060":34924,"36061":35835,"36062":36174,"36063":36189,"36064":36399,"36065":36396,"36066":36756,"36067":37094,"36068":38136,"36069":37492,"36070":38657,"36071":38801,"36072":32366,"36073":39076,"36074":39556,"36075":39553,"36076":40150,"36077":40098,"36078":40148,"36079":40151,"36080":40551,"36081":40485,"36082":40761,"36083":40841,"36084":40842,"36085":40858,"36086":24651,"36087":25371,"36088":25605,"36089":29906,"36090":31363,"36091":32552,"36092":33250,"36093":33821,"36094":34506,"36160":21464,"36161":36902,"36162":36923,"36163":38259,"36164":38084,"36165":38757,"36166":26174,"36167":39181,"36168":24778,"36169":39551,"36170":39564,"36171":39635,"36172":39633,"36173":40157,"36174":40158,"36175":40156,"36176":40502,"36177":22065,"36178":22365,"36179":25597,"36180":30251,"36181":30315,"36182":32641,"36183":34453,"36184":35753,"36185":35863,"36186":35894,"36187":33395,"36188":36195,"36189":37247,"36190":38643,"36191":28789,"36192":38701,"36193":39078,"36194":39588,"36195":39699,"36196":39751,"36197":40078,"36198":40560,"36199":40557,"36200":30839,"36201":30416,"36202":40140,"36203":40844,"36204":40843,"36205":21381,"36206":27012,"36207":28286,"36208":31729,"36209":31657,"36210":34542,"36211":35266,"36212":36433,"36213":34885,"36214":38053,"36215":39045,"36216":39307,"36217":39627,"36218":40649,"36219":28390,"36220":30633,"36221":38218,"36222":38831,"36257":39540,"36258":39589,"36259":32518,"36260":35872,"36261":36495,"36262":37245,"36263":38075,"36264":37550,"36265":38179,"36266":40132,"36267":40072,"36268":40681,"36269":20991,"36270":40550,"36271":39562,"36272":40563,"36273":40510,"36274":38074,"36275":20162,"36276":34381,"36277":27538,"36278":22439,"36279":22395,"36280":25099,"36281":20451,"36282":21037,"36283":21389,"36284":21593,"36285":21370,"36286":32424,"36287":33543,"36288":38023,"36289":38022,"36290":21591,"36291":24362,"36292":31059,"36293":32446,"36294":37071,"36295":38028,"36296":21072,"36297":21286,"36298":22261,"36299":22445,"36300":23045,"36301":23741,"36302":23811,"36303":28062,"36304":28172,"36305":28867,"36306":30502,"36307":32448,"36308":32464,"36309":33003,"36310":38030,"36311":38032,"36312":38037,"36313":38029,"36314":38379,"36315":22955,"36316":23899,"36317":24701,"36318":26720,"36319":26536,"36320":27817,"36321":27976,"36322":30066,"36323":30743,"36324":32471,"36325":33757,"36326":35271,"36327":35765,"36328":35790,"36329":35794,"36330":36150,"36331":36147,"36332":36730,"36333":36725,"36334":36728,"36335":36911,"36336":37075,"36337":37124,"36338":38059,"36339":38060,"36340":38043,"36341":38063,"36342":38061,"36343":38058,"36344":38390,"36345":38503,"36346":39032,"36347":39275,"36348":40697,"36349":20251,"36350":20603,"36416":20325,"36417":21794,"36418":22450,"36419":24047,"36420":24493,"36421":28828,"36422":33557,"36423":29426,"36424":29614,"36425":32488,"36426":32480,"36427":32481,"36428":32671,"36429":33645,"36430":34545,"36431":35795,"36432":35798,"36433":35817,"36434":35796,"36435":35804,"36436":36241,"36437":36738,"36438":36737,"36439":37036,"36440":38090,"36441":38088,"36442":38064,"36443":38066,"36444":38070,"36445":38157,"36446":38092,"36447":38077,"36448":38076,"36449":39043,"36450":39040,"36451":20971,"36452":40702,"36453":20606,"36454":21787,"36455":23901,"36456":24123,"36457":24747,"36458":24749,"36459":24580,"36460":25132,"36461":25111,"36462":25247,"36463":25248,"36464":25532,"36465":26724,"36466":26473,"36467":33637,"36468":27986,"36469":27812,"36470":28829,"36471":30386,"36472":30720,"36473":32507,"36474":32498,"36475":32495,"36476":32506,"36477":33715,"36478":35275,"36513":35830,"36514":36167,"36515":38129,"36516":38098,"36517":38097,"36518":38101,"36519":38111,"36520":38123,"36521":38127,"36522":38122,"36523":38135,"36524":38102,"36525":38117,"36526":39121,"36527":21055,"36528":21154,"36529":21715,"36530":21586,"36531":23810,"36532":23780,"36533":24209,"36534":24870,"36535":25378,"36536":26912,"36537":27637,"36538":39053,"36539":28061,"36540":28514,"36541":28064,"36542":28375,"36543":29711,"36544":29825,"36545":30231,"36546":32515,"36547":32535,"36548":32524,"36549":32527,"36550":32529,"36551":33628,"36552":33932,"36553":33553,"36554":33473,"36555":35833,"36556":35836,"36557":35842,"36558":36181,"36559":37112,"36560":38162,"36561":38103,"36562":38141,"36563":38163,"36564":38154,"36565":38116,"36566":38150,"36567":38151,"36568":38164,"36569":38406,"36570":38403,"36571":38739,"36572":39055,"36573":39293,"36574":39541,"36575":39552,"36576":40066,"36577":40488,"36578":21714,"36579":21717,"36580":21721,"36581":23250,"36582":23748,"36583":24639,"36584":27546,"36585":27981,"36586":28904,"36587":29443,"36588":29423,"36589":30876,"36590":31405,"36591":32279,"36592":32539,"36593":33927,"36594":33640,"36595":33929,"36596":33630,"36597":33720,"36598":33431,"36599":34547,"36600":35816,"36601":35857,"36602":35860,"36603":35869,"36604":37072,"36605":38185,"36606":38188,"36672":38166,"36673":38167,"36674":38140,"36675":38171,"36676":38165,"36677":38174,"36678":38036,"36679":38415,"36680":38408,"36681":38409,"36682":38410,"36683":38412,"36684":38413,"36685":40498,"36686":40497,"36687":21724,"36688":24113,"36689":24697,"36690":25672,"36691":58305,"36692":27894,"36693":29461,"36694":29971,"36695":30213,"36696":30187,"36697":30807,"36698":31654,"36699":31578,"36700":31976,"36701":32545,"36702":32807,"36703":33631,"36704":33718,"36705":34544,"36706":35042,"36707":35279,"36708":35873,"36709":35788,"36710":35877,"36711":36292,"36712":38200,"36713":38196,"36714":38113,"36715":38198,"36716":38418,"36717":39271,"36718":40082,"36719":40085,"36720":40504,"36721":40505,"36722":40506,"36723":40832,"36724":24636,"36725":25669,"36726":25784,"36727":27898,"36728":30102,"36729":32523,"36730":32873,"36731":33641,"36732":34789,"36733":34414,"36734":35764,"36769":35881,"36770":36188,"36771":36157,"36772":36760,"36773":37021,"36774":38227,"36775":38112,"36776":38204,"36777":38223,"36778":34021,"36779":38890,"36780":39273,"36781":39568,"36782":39570,"36783":39571,"36784":38411,"36785":40105,"36786":40096,"36787":40520,"36788":40513,"36789":40518,"36790":21411,"36791":21590,"36792":22406,"36793":27104,"36794":26638,"36795":27655,"36796":27895,"36797":28486,"36798":31074,"36799":32562,"36800":32563,"36801":32628,"36802":33315,"36803":34511,"36804":34431,"36805":35043,"36806":35281,"36807":35311,"36808":35886,"36809":38235,"36810":38239,"36811":38250,"36812":38214,"36813":38121,"36814":38891,"36815":39073,"36816":39312,"36817":39618,"36818":40117,"36819":40118,"36820":40123,"36821":40113,"36822":40526,"36823":40491,"36824":40700,"36825":21950,"36826":25732,"36827":26634,"36828":26533,"36829":26636,"36830":32561,"36831":32845,"36832":33551,"36833":33480,"36834":34162,"36835":34548,"36836":34686,"36837":38132,"36838":38246,"36839":38248,"36840":38241,"36841":38243,"36842":38212,"36843":38251,"36844":38119,"36845":38244,"36846":38137,"36847":38426,"36848":39071,"36849":39316,"36850":39546,"36851":39581,"36852":39583,"36853":39576,"36854":40535,"36855":40538,"36856":40540,"36857":40838,"36858":40837,"36859":20649,"36860":23743,"36861":30152,"36862":25786,"36928":27017,"36929":28384,"36930":30779,"36931":31901,"36932":32425,"36933":32556,"36934":34105,"36935":36166,"36936":38257,"36937":38396,"36938":39129,"36939":39586,"36940":39574,"36941":39580,"36942":40101,"36943":40142,"36944":40144,"36945":40547,"36946":40536,"36947":40574,"36948":20865,"36949":23048,"36950":28757,"36951":25874,"36952":30271,"36953":31656,"36954":31860,"36955":33339,"36956":35276,"36957":36345,"36958":36318,"36959":36729,"36960":38228,"36961":38252,"36962":39587,"36963":39557,"36964":40149,"36965":40099,"36966":40102,"36967":40552,"36968":40503,"36969":40859,"36970":26686,"36971":26916,"36972":34016,"36973":38624,"36974":36723,"36975":40159,"36976":40095,"36977":40553,"36978":40556,"36979":40554,"36980":40555,"36981":40519,"36982":28751,"36983":31766,"36984":35888,"36985":39628,"36986":31550,"36987":31900,"36988":32565,"36989":33044,"36990":36479,"37025":38247,"37026":40090,"37027":36273,"37028":36508,"37029":37246,"37030":35891,"37031":39070,"37032":39079,"37033":39591,"37034":40492,"37035":25094,"37036":38404,"37037":40097,"37038":40514,"37039":31160,"37040":25300,"37041":36299,"37042":29648,"37043":23467,"37044":25296,"37045":27585,"37046":20943,"37047":31108,"37048":21525,"37049":28508,"37050":34972,"37051":37095,"37052":20857,"37053":25144,"37054":25243,"37055":25383,"37056":25531,"37057":25566,"37058":25594,"37059":25745,"37060":25792,"37061":25825,"37062":25846,"37063":25861,"37064":25909,"37065":25934,"37066":25963,"37067":25992,"37068":26073,"37069":26142,"37070":26171,"37071":26175,"37072":26180,"37073":26199,"37074":26217,"37075":26227,"37076":26243,"37077":26300,"37078":26303,"37079":26305,"37080":26357,"37081":26362,"37082":26363,"37083":26382,"37084":26390,"37085":26423,"37086":26468,"37087":26470,"37088":26534,"37089":26535,"37090":26537,"37091":26619,"37092":26621,"37093":26624,"37094":26625,"37095":26629,"37096":26654,"37097":26698,"37098":26706,"37099":26709,"37100":26713,"37101":26765,"37102":26809,"37103":26831,"37104":20616,"37105":38184,"37106":40087,"37107":26914,"37108":26918,"37109":220,"37110":58591,"37111":58592,"37112":252,"37113":58594,"37114":58595,"37115":220,"37116":252,"37117":26934,"37118":26977,"37184":33477,"37185":33482,"37186":33496,"37187":33560,"37188":33562,"37189":33571,"37190":33606,"37191":33627,"37192":33634,"37193":33644,"37194":33646,"37195":33692,"37196":33695,"37197":33717,"37198":33724,"37199":33783,"37200":33834,"37201":33864,"37202":33884,"37203":33890,"37204":33924,"37205":33928,"37206":34012,"37207":34019,"37208":34104,"37209":34138,"37210":34199,"37211":34219,"37212":34241,"37213":34323,"37214":34326,"37215":8715,"37216":34581,"37217":34672,"37218":34685,"37219":34699,"37220":34728,"37221":34759,"37222":34768,"37223":34823,"37224":34830,"37225":34855,"37226":34990,"37227":8712,"37228":34997,"37229":35007,"37230":35045,"37231":35061,"37232":35100,"37233":35101,"37234":35191,"37235":35303,"37236":35383,"37237":35500,"37238":35546,"37239":35675,"37240":35697,"37241":35883,"37242":35898,"37243":35964,"37244":35982,"37245":36014,"37246":36114,"37281":36169,"37282":36173,"37283":36209,"37284":36360,"37285":36410,"37286":36464,"37287":36505,"37288":36528,"37289":36529,"37290":36549,"37291":36550,"37292":36558,"37293":36579,"37294":36620,"37295":36721,"37296":36727,"37297":36775,"37298":36847,"37299":36878,"37300":36921,"37301":36965,"37302":37001,"37303":37086,"37304":37141,"37305":37334,"37306":37339,"37307":37342,"37308":37345,"37309":37349,"37310":37366,"37311":37372,"37312":37417,"37313":37420,"37314":65287,"37315":37465,"37316":37495,"37317":37613,"37318":37690,"37319":58701,"37320":58702,"37321":29227,"37322":20866,"37323":20886,"37324":20023,"37325":20843,"37326":20799,"37327":58709,"37328":58710,"37329":26409,"37330":27706,"37331":21378,"37332":30098,"37333":32896,"37334":34916,"37335":19974,"37336":58718,"37337":58719,"37338":58720,"37339":11927,"37340":21241,"37341":21269,"37342":8225,"37343":58725,"37344":13316,"37345":58727,"37346":58728,"37347":58729,"37348":58730,"37349":58731,"37350":20981,"37351":58733,"37352":23662,"37353":58735,"37354":22231,"37355":20128,"37356":20907,"37357":11904,"37358":27079,"37359":58741,"37360":9550,"37361":9688,"37362":9689,"37363":9794,"37364":9654,"37365":9668,"37366":8597,"37367":8252,"37368":182,"37369":8704,"37370":8616,"37371":8596,"37372":8962,"37373":58755,"37374":58756,"37440":20124,"37441":24746,"37442":22311,"37443":22258,"37444":21307,"37445":22769,"37446":36920,"37447":38560,"37448":26628,"37449":21942,"37450":39365,"37451":35585,"37452":20870,"37453":32257,"37454":24540,"37455":27431,"37456":27572,"37457":26716,"37458":22885,"37459":31311,"37460":20206,"37461":20385,"37462":30011,"37463":28784,"37464":20250,"37465":24724,"37466":28023,"37467":32117,"37468":22730,"37469":25040,"37470":25313,"37471":27579,"37472":35226,"37473":23398,"37474":27005,"37475":21917,"37476":28167,"37477":58794,"37478":24059,"37479":38501,"37480":21223,"37481":23515,"37482":28450,"37483":38306,"37484":27475,"37485":35251,"37486":27671,"37487":24112,"37488":25135,"37489":29344,"37490":34384,"37491":26087,"37492":24613,"37493":25312,"37494":25369,"37495":34394,"37496":23777,"37497":25375,"37498":29421,"37499":37111,"37500":38911,"37501":26241,"37502":21220,"37537":35641,"37538":21306,"37539":39366,"37540":21234,"37541":58824,"37542":24452,"37543":33550,"37544":24693,"37545":25522,"37546":28179,"37547":32076,"37548":34509,"37549":36605,"37550":32153,"37551":40335,"37552":25731,"37553":30476,"37554":20537,"37555":21091,"37556":38522,"37557":22287,"37558":26908,"37559":27177,"37560":38997,"37561":39443,"37562":21427,"37563":21577,"37564":23087,"37565":35492,"37566":24195,"37567":28207,"37568":37489,"37569":21495,"37570":22269,"37571":40658,"37572":31296,"37573":30741,"37574":28168,"37575":25998,"37576":27507,"37577":21092,"37578":38609,"37579":21442,"37580":26719,"37581":24808,"37582":36059,"37583":27531,"37584":27503,"37585":20816,"37586":36766,"37587":28287,"37588":23455,"37589":20889,"37590":33294,"37591":25448,"37592":37320,"37593":23551,"37594":21454,"37595":34886,"37596":24467,"37597":28171,"37598":29539,"37599":32294,"37600":31899,"37601":20966,"37602":23558,"37603":31216,"37604":28169,"37605":28988,"37606":22888,"37607":26465,"37608":29366,"37609":20055,"37610":27972,"37611":21104,"37612":30067,"37613":32260,"37614":22732,"37615":23330,"37616":35698,"37617":37304,"37618":35302,"37619":22065,"37620":23517,"37621":23613,"37622":22259,"37623":31883,"37624":37204,"37625":31298,"37626":38543,"37627":39620,"37628":26530,"37629":25968,"37630":25454,"37696":28716,"37697":22768,"37698":25993,"37699":38745,"37700":31363,"37701":25666,"37702":32118,"37703":23554,"37704":27973,"37705":25126,"37706":36341,"37707":37549,"37708":28508,"37709":36983,"37710":36984,"37711":32330,"37712":31109,"37713":30094,"37714":22766,"37715":20105,"37716":33624,"37717":25436,"37718":25407,"37719":24035,"37720":31379,"37721":35013,"37722":20711,"37723":23652,"37724":32207,"37725":39442,"37726":22679,"37727":24974,"37728":34101,"37729":36104,"37730":33235,"37731":23646,"37732":32154,"37733":22549,"37734":23550,"37735":24111,"37736":28382,"37737":28381,"37738":25246,"37739":27810,"37740":28655,"37741":21336,"37742":22022,"37743":22243,"37744":26029,"37745":24382,"37746":36933,"37747":26172,"37748":37619,"37749":24193,"37750":24500,"37751":32884,"37752":25074,"37753":22618,"37754":36883,"37755":37444,"37756":28857,"37757":36578,"37758":20253,"37793":38651,"37794":28783,"37795":24403,"37796":20826,"37797":30423,"37798":31282,"37799":38360,"37800":24499,"37801":27602,"37802":29420,"37803":35501,"37804":23626,"37805":38627,"37806":24336,"37807":24745,"37808":33075,"37809":25309,"37810":24259,"37811":22770,"37812":26757,"37813":21338,"37814":34180,"37815":40614,"37816":32283,"37817":30330,"37818":39658,"37819":25244,"37820":27996,"37821":27996,"37822":25935,"37823":25975,"37824":20398,"37825":25173,"37826":20175,"37827":36794,"37828":22793,"37829":27497,"37830":33303,"37831":31807,"37832":21253,"37833":23453,"37834":25265,"37835":27873,"37836":32990,"37837":30770,"37838":35914,"37839":39165,"37840":22696,"37841":27598,"37842":28288,"37843":33032,"37844":40665,"37845":35379,"37846":34220,"37847":36493,"37848":19982,"37849":35465,"37850":25671,"37851":27096,"37852":35617,"37853":26332,"37854":26469,"37855":38972,"37856":20081,"37857":35239,"37858":31452,"37859":38534,"37860":26053,"37861":20001,"37862":29471,"37863":32209,"37864":28057,"37865":22593,"37866":31036,"37867":21169,"37868":25147,"37869":38666,"37870":40802,"37871":26278,"37872":27508,"37873":24651,"37874":32244,"37875":37676,"37876":28809,"37877":21172,"37878":27004,"37879":37682,"37880":28286,"37881":24357,"37882":20096,"37883":26365,"37884":22985,"37885":23437,"37886":23947,"37952":27179,"37953":26907,"37954":21936,"37955":31874,"37956":36796,"37957":27018,"37958":21682,"37959":40235,"37960":38635,"37961":26905,"37962":25539,"37963":39364,"37964":20967,"37965":26626,"37966":36795,"37967":20685,"37968":23776,"37969":26627,"37970":20970,"37971":21250,"37972":30834,"37973":30033,"37974":30048,"37975":22138,"37976":37618,"37977":22592,"37978":26622,"37979":20451,"37980":26466,"37981":31870,"37982":21249,"37983":20452,"37984":20453,"37985":20969,"37986":21498,"37987":21720,"37988":22222,"37989":22310,"37990":22327,"37991":22328,"37992":22408,"37993":22451,"37994":22442,"37995":22448,"37996":22486,"37997":22640,"37998":22713,"37999":22743,"38000":23670,"38001":23740,"38002":23749,"38003":23742,"38004":23926,"38005":24342,"38006":24634,"38007":25525,"38008":26433,"38009":26467,"38010":26529,"38011":26810,"38012":26917,"38013":26920,"38014":27258,"38049":26915,"38050":26913,"38051":27006,"38052":27009,"38053":27101,"38054":27182,"38055":27250,"38056":27423,"38057":27615,"38058":28181,"38059":29077,"38060":29927,"38061":29938,"38062":29936,"38063":29937,"38064":29944,"38065":29957,"38066":30057,"38067":30314,"38068":30836,"38069":31437,"38070":31439,"38071":31445,"38072":31443,"38073":31457,"38074":31472,"38075":31490,"38076":31763,"38077":31767,"38078":31888,"38079":31917,"38080":31936,"38081":31960,"38082":32155,"38083":32261,"38084":32359,"38085":32387,"38086":32400,"38087":33188,"38088":33373,"38089":33826,"38090":34009,"38091":34352,"38092":34475,"38093":34543,"38094":34992,"38095":35011,"38096":35012,"38097":35076,"38098":59183,"38099":36542,"38100":36552,"38101":36684,"38102":36791,"38103":36826,"38104":36903,"38105":36950,"38106":37685,"38107":37691,"38108":37817,"38109":38282,"38110":38294,"38111":38777,"38112":38790,"38113":38800,"38114":39082,"38115":39830,"38116":39831,"38117":39860,"38118":39887,"38119":39889,"38120":39890,"38121":39922,"38122":39921,"38123":39984,"38124":40007,"38125":40026,"38126":40176,"38127":40262,"38128":40292,"38129":40363,"38130":20036,"38131":21583,"38132":25368,"38133":39857,"38134":40041,"38135":40263,"38136":40293,"38137":39983,"38138":40639,"38139":20916,"38140":21610,"38141":26528,"38142":39822,"38208":37032,"38209":20914,"38210":13869,"38211":25285,"38212":21189,"38213":26545,"38214":21709,"38215":24658,"38216":21441,"38217":28913,"38218":22531,"38219":21855,"38220":37390,"38221":30528,"38222":29756,"38223":29002,"38224":28377,"38225":21472,"38226":29486,"38227":35023,"38228":30861,"38229":32675,"38230":32171,"38231":36394,"38232":37979,"38233":25452,"38234":24487,"38235":23557,"38236":32827,"38237":23791,"38238":14776,"38239":29009,"38240":36045,"38241":38894,"38242":22642,"38243":23139,"38244":32632,"38245":23895,"38246":24943,"38247":27032,"38248":32137,"38249":31918,"38250":32179,"38251":28545,"38252":23290,"38253":22715,"38254":29269,"38255":30286,"38256":36653,"38257":37561,"38258":40286,"38259":40623,"38260":32583,"38261":40388,"38262":36120,"38263":20915,"38264":34412,"38265":21668,"38266":21414,"38267":21030,"38268":26422,"38269":20001,"38270":21364,"38305":24313,"38306":21177,"38307":21647,"38308":24312,"38309":22956,"38310":24625,"38311":29248,"38312":33047,"38313":30267,"38314":24333,"38315":26187,"38316":26280,"38317":24932,"38318":25423,"38319":28895,"38320":27940,"38321":31911,"38322":31945,"38323":21465,"38324":25933,"38325":22338,"38326":29647,"38327":32966,"38328":13649,"38329":27445,"38330":30849,"38331":21452,"38332":29483,"38333":29482,"38334":29641,"38335":30026,"38336":23033,"38337":29124,"38338":29966,"38339":32220,"38340":39393,"38341":35241,"38342":28662,"38343":14935,"38344":25834,"38345":15341,"38346":27809,"38347":28284,"38348":30055,"38349":22633,"38350":22633,"38351":20996,"38352":59338,"38353":24967,"38354":25658,"38355":33263,"38356":59342,"38357":20917,"38358":20945,"38359":27769,"38360":22815,"38361":36857,"38362":39153,"38363":25911,"38364":33033,"38365":34996,"38366":14890,"38367":36525,"38368":32663,"38369":39440,"38370":32037,"38371":27336,"38372":20876,"38373":21031,"38374":59360,"38375":33050,"38376":21408,"38377":21410,"38378":27738,"38379":27703,"38380":33304,"38381":21894,"38382":24315,"38383":20937,"38384":30897,"38385":37474,"38386":21357,"38387":20931,"38388":59374,"38389":33905,"38390":35207,"38391":38765,"38392":35728,"38393":38563,"38394":24316,"38395":38583,"38396":20814,"38397":39952,"38398":26160,"38464":37461,"38465":30728,"38466":37701,"38467":37491,"38468":37737,"38469":59390,"38470":59391,"38471":59392,"38472":59393,"38473":37343,"38474":37338,"38475":30804,"38476":30822,"38477":30856,"38478":30902,"38479":30919,"38480":30930,"38481":30935,"38482":8491,"38483":8651,"38484":30948,"38485":30958,"38486":30960,"38487":30961,"38488":30965,"38489":31026,"38490":31027,"38491":31030,"38492":31064,"38493":12307,"38494":31065,"38495":31089,"38496":31102,"38497":31107,"38498":31110,"38499":31111,"38500":31121,"38501":31129,"38502":31135,"38503":31141,"38504":31202,"38505":31217,"38506":31220,"38507":31274,"38508":31290,"38509":31301,"38510":31333,"38511":31420,"38512":31426,"38513":31433,"38514":31451,"38515":31465,"38516":31486,"38517":31500,"38518":31527,"38519":31529,"38520":31554,"38521":31555,"38522":31573,"38523":31599,"38524":31666,"38525":27102,"38526":27129,"38561":37238,"38562":33114,"38563":33527,"38564":21579,"38565":33074,"38566":32957,"38567":33816,"38568":37214,"38569":37232,"38570":37260,"38571":33096,"38572":59459,"38573":17462,"38574":33113,"38575":32927,"38576":59463,"38577":21833,"38578":21537,"38579":21722,"38580":21554,"38581":21945,"38582":21652,"38583":59470,"38584":30802,"38585":30789,"38586":30796,"38587":59474,"38588":33981,"38589":33820,"38590":33476,"38591":59478,"38592":33915,"38593":35629,"38594":59481,"38595":22347,"38596":59483,"38597":59484,"38598":22341,"38599":34766,"38600":22112,"38601":21994,"38602":22139,"38603":32956,"38604":59491,"38605":30904,"38606":27148,"38607":21708,"38608":31696,"38609":31724,"38610":31738,"38611":31765,"38612":31771,"38613":31797,"38614":31812,"38615":31853,"38616":31886,"38617":31928,"38618":31939,"38619":31974,"38620":31981,"38621":31987,"38622":31989,"38623":31993,"38624":59511,"38625":31996,"38626":32139,"38627":32151,"38628":32164,"38629":32168,"38630":32205,"38631":32208,"38632":32211,"38633":32229,"38634":32253,"38635":27154,"38636":27170,"38637":27184,"38638":27190,"38639":27237,"38640":59527,"38641":59528,"38642":59529,"38643":59530,"38644":59531,"38645":59532,"38646":59533,"38647":59534,"38648":27251,"38649":27256,"38650":59537,"38651":59538,"38652":27260,"38653":27305,"38654":27306,"38720":9450,"38721":9312,"38722":9313,"38723":9314,"38724":9315,"38725":9316,"38726":9317,"38727":9318,"38728":9319,"38729":9320,"38730":9321,"38731":9322,"38732":9323,"38733":9324,"38734":9325,"38735":9326,"38736":9327,"38737":9328,"38738":9329,"38739":9330,"38740":9331,"38741":37700,"38742":37805,"38743":37830,"38744":37861,"38745":37914,"38746":37921,"38747":37950,"38748":37953,"38749":37971,"38750":37978,"38751":38042,"38752":38071,"38753":38104,"38754":38110,"38755":38131,"38756":38147,"38757":38158,"38758":38159,"38759":38168,"38760":38173,"38761":38186,"38762":38187,"38763":38207,"38764":38213,"38765":38222,"38766":38242,"38767":38245,"38768":38249,"38769":38258,"38770":38279,"38771":38297,"38772":38304,"38773":38322,"38774":38502,"38775":38557,"38776":38575,"38777":38578,"38778":38707,"38779":38715,"38780":38733,"38781":38735,"38782":38737,"38817":38741,"38818":38756,"38819":38763,"38820":38769,"38821":38802,"38822":38834,"38823":38898,"38824":38973,"38825":38996,"38826":39077,"38827":39107,"38828":39130,"38829":39150,"38830":39197,"38831":39200,"38832":39267,"38833":39296,"38834":39303,"38835":39309,"38836":39315,"38837":39317,"38838":39356,"38839":39368,"38840":39410,"38841":39606,"38842":39641,"38843":39646,"38844":39695,"38845":39753,"38846":39794,"38847":39811,"38848":39839,"38849":39867,"38850":39907,"38851":39925,"38852":39936,"38853":39940,"38854":39963,"38855":9398,"38856":9399,"38857":9400,"38858":9401,"38859":9402,"38860":9403,"38861":9404,"38862":9405,"38863":9406,"38864":9407,"38865":9408,"38866":9409,"38867":9410,"38868":9411,"38869":9412,"38870":9413,"38871":9414,"38872":9415,"38873":9416,"38874":9417,"38875":9418,"38876":9419,"38877":9420,"38878":9421,"38879":9422,"38880":9423,"38881":9424,"38882":9425,"38883":9426,"38884":9427,"38885":9428,"38886":9429,"38887":9430,"38888":9431,"38889":9432,"38890":9433,"38891":9434,"38892":9435,"38893":9436,"38894":9437,"38895":9438,"38896":9439,"38897":9440,"38898":9441,"38899":9442,"38900":9443,"38901":9444,"38902":9445,"38903":9446,"38904":9447,"38905":9448,"38906":9449,"38907":174,"38908":8482,"38909":59697,"38910":59698,"38976":40054,"38977":10122,"38978":10123,"38979":10124,"38980":10125,"38981":10126,"38982":10127,"38983":10128,"38984":10129,"38985":10130,"38986":10131,"38987":40069,"38988":40070,"38989":40071,"38990":40075,"38991":40080,"38992":40094,"38993":40110,"38994":40112,"38995":40114,"38996":40116,"38997":40122,"38998":40124,"38999":40125,"39000":40134,"39001":40135,"39002":40138,"39003":40139,"39004":40147,"39005":40152,"39006":40153,"39007":40162,"39008":40171,"39009":40172,"39010":40234,"39011":40264,"39012":40272,"39013":40314,"39014":40390,"39015":40523,"39016":40533,"39017":40539,"39018":40561,"39019":40618,"39020":40637,"39021":40644,"39022":40674,"39023":40682,"39024":40712,"39025":40715,"39026":40717,"39027":40737,"39028":40772,"39029":40785,"39030":40861,"39031":64014,"39032":64015,"39033":64017,"39034":64019,"39035":64020,"39036":64024,"39037":64031,"39038":64032,"39073":64033,"39074":64035,"39075":64036,"39076":64039,"39077":64040,"39078":64041,"39079":19972,"39080":20015,"39081":20097,"39082":20103,"39083":20131,"39084":20151,"39085":20156,"39086":20216,"39087":20264,"39088":20265,"39089":20279,"39090":20290,"39091":20293,"39092":20299,"39093":20338,"39094":20386,"39095":20400,"39096":20413,"39097":20424,"39098":20428,"39099":20464,"39100":20466,"39101":20473,"39102":20483,"39103":20488,"39104":20532,"39105":20539,"39106":20568,"39107":20582,"39108":20609,"39109":20624,"39110":20668,"39111":20688,"39112":20703,"39113":20705,"39114":20732,"39115":20749,"39116":20779,"39117":20832,"39118":20910,"39119":20920,"39120":20946,"39121":20962,"39122":20997,"39123":21044,"39124":21052,"39125":21081,"39126":21096,"39127":21113,"39128":21156,"39129":21196,"39130":21287,"39131":21314,"39132":21341,"39133":21373,"39134":21374,"39135":21445,"39136":21456,"39137":21458,"39138":21502,"39139":21613,"39140":21637,"39141":21651,"39142":21662,"39143":21689,"39144":21731,"39145":21743,"39146":21773,"39147":21784,"39148":21797,"39149":21800,"39150":21803,"39151":21831,"39152":21881,"39153":21904,"39154":21940,"39155":21953,"39156":21975,"39157":21976,"39158":22011,"39159":20404,"39160":22049,"39161":8707,"39162":22098,"39163":59852,"39164":9787,"39165":59854,"39166":59855,"39232":22109,"39233":9332,"39234":9333,"39235":9334,"39236":9335,"39237":9336,"39238":9337,"39239":9338,"39240":9339,"39241":9340,"39242":9341,"39243":9342,"39244":9343,"39245":9344,"39246":9345,"39247":9346,"39248":9347,"39249":9348,"39250":9349,"39251":9350,"39252":9351,"39253":22113,"39254":22153,"39255":22155,"39256":22174,"39257":22177,"39258":22193,"39259":22201,"39260":22207,"39261":22230,"39262":22255,"39263":22293,"39264":22301,"39265":22322,"39266":22333,"39267":22335,"39268":22339,"39269":8660,"39270":22398,"39271":22410,"39272":22413,"39273":22416,"39274":22428,"39275":22459,"39276":22462,"39277":22468,"39278":22494,"39279":22526,"39280":22546,"39281":22562,"39282":22599,"39283":22620,"39284":22623,"39285":22643,"39286":22695,"39287":22698,"39288":22704,"39289":22709,"39290":22710,"39291":22731,"39292":22736,"39293":22752,"39294":22789,"39329":22801,"39330":22921,"39331":22932,"39332":22938,"39333":22943,"39334":22960,"39335":22968,"39336":22980,"39337":23023,"39338":23024,"39339":23032,"39340":23042,"39341":23051,"39342":23053,"39343":23058,"39344":23073,"39345":23076,"39346":23079,"39347":23082,"39348":23083,"39349":23084,"39350":23101,"39351":23109,"39352":23124,"39353":23129,"39354":23137,"39355":23144,"39356":23147,"39357":23150,"39358":23153,"39359":23161,"39360":23166,"39361":23169,"39362":23170,"39363":23174,"39364":23176,"39365":23185,"39366":23193,"39367":23200,"39368":23201,"39369":23211,"39370":23235,"39371":23246,"39372":23247,"39373":23251,"39374":23268,"39375":23280,"39376":23294,"39377":23309,"39378":23313,"39379":23317,"39380":23327,"39381":23339,"39382":23361,"39383":23364,"39384":23366,"39385":23370,"39386":23375,"39387":23400,"39388":23412,"39389":23414,"39390":23420,"39391":23426,"39392":23440,"39393":9372,"39394":9373,"39395":9374,"39396":9375,"39397":9376,"39398":9377,"39399":9378,"39400":9379,"39401":9380,"39402":9381,"39403":9382,"39404":9383,"39405":9384,"39406":9385,"39407":9386,"39408":9387,"39409":9388,"39410":9389,"39411":9390,"39412":9391,"39413":9392,"39414":9393,"39415":9394,"39416":9395,"39417":9396,"39418":9397,"39419":60009,"39420":12850,"39421":12849,"39422":27307,"39488":23446,"39489":9352,"39490":9353,"39491":9354,"39492":9355,"39493":9356,"39494":9357,"39495":9358,"39496":9359,"39497":9360,"39498":9361,"39499":9362,"39500":9363,"39501":9364,"39502":9365,"39503":9366,"39504":9367,"39505":9368,"39506":9369,"39507":9370,"39508":9371,"39509":23509,"39510":23511,"39511":23587,"39512":23685,"39513":23710,"39514":23746,"39515":23824,"39516":23852,"39517":23855,"39518":23880,"39519":23894,"39520":23920,"39521":23931,"39522":23941,"39523":23972,"39524":23979,"39525":23990,"39526":24001,"39527":24023,"39528":24073,"39529":24136,"39530":24210,"39531":24253,"39532":24334,"39533":24434,"39534":24497,"39535":24514,"39536":24539,"39537":24543,"39538":24611,"39539":24702,"39540":24791,"39541":24839,"39542":24844,"39543":24857,"39544":24866,"39545":24912,"39546":24928,"39547":24961,"39548":24981,"39549":25017,"39550":25024,"39585":25039,"39586":25043,"39587":25050,"39588":25232,"39589":25393,"39590":8835,"39591":25399,"39592":25465,"39593":25483,"39594":25537,"39595":25570,"39596":25574,"39597":25595,"39598":25598,"39599":25607,"39600":25650,"39601":25656,"39602":25659,"39603":25690,"39604":25713,"39605":25724,"39606":25741,"39607":25775,"39608":25780,"39609":25782,"39610":25821,"39611":25829,"39612":25866,"39613":25873,"39614":25887,"39615":25951,"39616":25965,"39617":25990,"39618":26037,"39619":26046,"39620":26065,"39621":26068,"39622":26083,"39623":26111,"39624":26136,"39625":26147,"39626":26211,"39627":26219,"39628":26237,"39629":26245,"39630":26258,"39631":26266,"39632":26276,"39633":26285,"39634":26291,"39635":26294,"39636":26317,"39637":26318,"39638":26370,"39639":26380,"39640":26393,"39641":26436,"39642":26475,"39643":26511,"39644":26532,"39645":26559,"39646":26582,"39647":26583,"39648":8834,"39649":26637,"39650":26640,"39651":26651,"39652":26678,"39653":26695,"39654":26710,"39655":26756,"39656":26760,"39657":26813,"39658":26819,"39659":26821,"39660":26882,"39661":26883,"39662":26889,"39663":26904,"39664":26947,"39665":26950,"39666":26980,"39667":26983,"39668":26994,"39669":27013,"39670":27039,"39671":27042,"39672":27089,"39673":27093,"39674":27094,"39675":39457,"39676":39462,"39677":39471,"39678":27329,"39744":22975,"39745":27105,"39746":27139,"39747":27162,"39748":27164,"39749":27180,"39750":27181,"39751":27187,"39752":27203,"39753":27205,"39754":27212,"39755":27219,"39756":27223,"39757":27235,"39758":27252,"39759":27266,"39760":27274,"39761":27279,"39762":27289,"39763":27303,"39764":27313,"39765":27317,"39766":27326,"39767":27337,"39768":27348,"39769":27352,"39770":27382,"39771":27479,"39772":27514,"39773":27612,"39774":27676,"39775":27697,"39776":27736,"39777":27758,"39778":27765,"39779":27775,"39780":27823,"39781":27851,"39782":27871,"39783":27903,"39784":27906,"39785":27909,"39786":27910,"39787":27942,"39788":27991,"39789":27995,"39790":28017,"39791":28033,"39792":28047,"39793":28069,"39794":28081,"39795":28158,"39796":28162,"39797":28164,"39798":28175,"39799":28184,"39800":28202,"39801":28240,"39802":28249,"39803":28314,"39804":28341,"39805":28344,"39806":28379,"39841":28410,"39842":28420,"39843":28427,"39844":28428,"39845":28438,"39846":28439,"39847":28468,"39848":28477,"39849":28502,"39850":28537,"39851":28554,"39852":28573,"39853":28575,"39854":28603,"39855":28606,"39856":28627,"39857":28633,"39858":28664,"39859":28675,"39860":28747,"39861":28749,"39862":28752,"39863":28756,"39864":28764,"39865":28775,"39866":28791,"39867":28793,"39868":28811,"39869":28815,"39870":28832,"39871":28835,"39872":28837,"39873":28838,"39874":28839,"39875":28868,"39876":28876,"39877":28880,"39878":28886,"39879":618,"39880":603,"39881":230,"39882":652,"39883":593,"39884":596,"39885":650,"39886":605,"39887":601,"39888":602,"39889":604,"39890":609,"39891":7747,"39892":7753,"39893":330,"39894":7739,"39895":629,"39896":240,"39897":643,"39898":658,"39899":679,"39900":676,"39901":227,"39902":60294,"39903":60295,"39904":623,"39905":632,"39906":647,"39907":60299,"39908":199,"39909":339,"39910":594,"39911":65351,"39912":715,"39913":719,"39914":65345,"39915":65346,"39916":65348,"39917":65349,"39918":65350,"39919":65352,"39920":65353,"39921":65354,"39922":65355,"39923":65356,"39924":65357,"39925":65358,"39926":65359,"39927":65360,"39928":65362,"39929":65363,"39930":65364,"39931":65365,"39932":65366,"39933":65367,"39934":65370,"40000":28917,"40001":12832,"40002":12833,"40003":12834,"40004":12835,"40005":12836,"40006":12837,"40007":12838,"40008":12839,"40009":12840,"40010":12841,"40011":28926,"40012":28933,"40013":28957,"40014":28969,"40015":28971,"40016":28972,"40017":28979,"40018":28981,"40019":28987,"40020":28990,"40021":28992,"40022":29007,"40023":29035,"40024":29045,"40025":29047,"40026":29052,"40027":29054,"40028":29068,"40029":29070,"40030":29073,"40031":29078,"40032":29090,"40033":29091,"40034":29101,"40035":29108,"40036":29111,"40037":29114,"40038":29137,"40039":29149,"40040":29163,"40041":29184,"40042":29193,"40043":29198,"40044":29199,"40045":29206,"40046":29207,"40047":29220,"40048":23204,"40049":29230,"40050":8838,"40051":29271,"40052":29276,"40053":29332,"40054":29444,"40055":29456,"40056":29505,"40057":29556,"40058":29580,"40059":29583,"40060":29592,"40061":29596,"40062":29598,"40097":29607,"40098":29610,"40099":29653,"40100":29665,"40101":29666,"40102":29668,"40103":29670,"40104":29679,"40105":29683,"40106":8839,"40107":29689,"40108":29691,"40109":29698,"40110":29713,"40111":29714,"40112":29716,"40113":29717,"40114":29719,"40115":29721,"40116":29724,"40117":29726,"40118":29727,"40119":29751,"40120":29752,"40121":29753,"40122":29763,"40123":29765,"40124":29767,"40125":29768,"40126":29769,"40127":29779,"40128":29782,"40129":29797,"40130":29803,"40131":29804,"40132":29812,"40133":29818,"40134":29826,"40135":21378,"40136":24191,"40137":20008,"40138":24186,"40139":20886,"40140":23424,"40141":21353,"40142":11911,"40143":60436,"40144":21251,"40145":9746,"40146":33401,"40147":17553,"40148":11916,"40149":11914,"40150":20022,"40151":60444,"40152":21274,"40153":60446,"40154":60447,"40155":11925,"40156":60449,"40157":60450,"40158":9492,"40159":20058,"40160":36790,"40161":24308,"40162":20872,"40163":20101,"40164":60457,"40165":20031,"40166":60459,"40167":60460,"40168":20059,"40169":21430,"40170":36710,"40171":32415,"40172":35744,"40173":36125,"40174":40479,"40175":38376,"40176":38021,"40177":38429,"40178":25164,"40179":27701,"40180":20155,"40181":24516,"40182":28780,"40183":11950,"40184":21475,"40185":27362,"40186":39483,"40187":39484,"40188":39512,"40189":39516,"40190":39523,"40256":9742,"40257":8594,"40258":8592,"40259":8593,"40260":8595,"40261":8680,"40262":8678,"40263":8679,"40264":8681,"40265":8680,"40266":8678,"40267":8679,"40268":8681,"40269":9758,"40270":9756,"40271":9755,"40272":9759,"40273":12310,"40274":12311,"40275":9675,"40276":10005,"40277":10003,"40278":22267,"40279":9789,"40280":22813,"40281":26189,"40282":29221,"40283":10025,"40284":10017,"40285":9786,"40286":9785,"40287":60515,"40288":60516,"40289":60517,"40290":60518,"40291":60519,"40292":23672,"40293":9836,"40294":9834,"40295":23249,"40296":23479,"40297":23804,"40298":60526,"40299":9993,"40300":9986,"40301":60529,"40302":60530,"40303":60531,"40304":60532,"40305":23765,"40306":26478,"40307":29793,"40308":29853,"40309":32595,"40310":34195,"40311":10063,"40312":60540,"40313":60541,"40314":23928,"40315":24379,"40316":60544,"40317":9473,"40318":9475,"40353":60547,"40354":60548,"40355":60549,"40356":60550,"40357":60551,"40358":60552,"40359":60553,"40360":60554,"40361":60555,"40362":60556,"40363":60557,"40364":60558,"40365":60559,"40366":60560,"40367":60561,"40368":39602,"40369":39648,"40370":39700,"40371":39732,"40372":39737,"40373":39744,"40374":39760,"40375":39807,"40376":9788,"40377":32149,"40378":9729,"40379":38708,"40380":9730,"40381":60575,"40382":60576,"40383":60577,"40384":9992,"40385":60579,"40386":60580,"40387":60581,"40388":60582,"40389":60583,"40390":60584,"40391":60585,"40392":8507,"40393":8481,"40394":26343,"40395":28247,"40396":60590,"40397":29015,"40398":31178,"40399":8470,"40400":33132,"40401":35577,"40402":38998,"40403":60597,"40404":60598,"40405":9760,"40406":60600,"40407":9828,"40408":9824,"40409":9831,"40410":9827,"40411":9826,"40412":9830,"40413":9825,"40414":9829,"40415":60609,"40416":60610,"40417":27364,"40418":8478,"40419":13250,"40420":13272,"40421":13217,"40422":60616,"40423":13221,"40424":60618,"40425":60619,"40426":60620,"40427":60621,"40428":60622,"40429":9745,"40430":39809,"40431":39819,"40432":39821,"40433":39901,"40434":39913,"40435":39917,"40436":39924,"40437":39967,"40438":39968,"40439":39974,"40440":40019,"40441":40029,"40442":40059,"40443":40204,"40444":40214,"40445":8626,"40446":27397,"40512":36073,"40513":36082,"40514":36099,"40515":36113,"40516":36124,"40517":36218,"40518":36265,"40519":36288,"40520":36353,"40521":36366,"40522":36422,"40523":36456,"40524":36465,"40525":36478,"40526":36480,"40527":36534,"40528":36537,"40529":36540,"40530":36547,"40531":36580,"40532":36589,"40533":36594,"40534":36656,"40535":36673,"40536":36682,"40537":36773,"40538":36787,"40539":36792,"40540":36810,"40541":36815,"40542":36872,"40543":36915,"40544":36919,"40545":36964,"40546":36972,"40547":37289,"40548":37302,"40549":37316,"40550":37370,"40551":37384,"40552":37395,"40553":37409,"40554":37416,"40555":37419,"40556":37429,"40557":37436,"40558":37441,"40559":37464,"40560":37469,"40561":37471,"40562":37483,"40563":37486,"40564":37505,"40565":37508,"40566":37513,"40567":37519,"40568":37553,"40569":37562,"40570":37567,"40571":37588,"40572":37595,"40573":37603,"40574":37605,"40609":37611,"40610":37612,"40611":37620,"40612":37622,"40613":37629,"40614":37635,"40615":37639,"40616":37680,"40617":37681,"40618":37696,"40619":37698,"40620":37699,"40621":37727,"40622":37730,"40623":37734,"40624":37736,"40625":37747,"40626":37748,"40627":37752,"40628":37757,"40629":37761,"40630":37764,"40631":37766,"40632":37767,"40633":37776,"40634":37788,"40635":37792,"40636":37816,"40637":37819,"40638":37821,"40639":37823,"40640":37835,"40641":37843,"40642":37851,"40643":37856,"40644":37872,"40645":37873,"40646":37875,"40647":37876,"40648":37889,"40649":37892,"40650":37896,"40651":37911,"40652":37915,"40653":37917,"40654":37924,"40655":37925,"40656":37926,"40657":37933,"40658":37954,"40659":37955,"40660":37965,"40661":37972,"40662":37976,"40663":37989,"40664":37991,"40665":37996,"40666":38009,"40667":38011,"40668":38264,"40669":38277,"40670":38310,"40671":38314,"40672":38486,"40673":38523,"40674":38565,"40675":38644,"40676":38683,"40677":38710,"40678":38720,"40679":38721,"40680":38743,"40681":38791,"40682":38793,"40683":38811,"40684":38833,"40685":38845,"40686":38848,"40687":38850,"40688":38866,"40689":38880,"40690":38932,"40691":38933,"40692":38947,"40693":38963,"40694":39016,"40695":39095,"40696":39097,"40697":39111,"40698":39114,"40699":39136,"40700":39137,"40701":39148,"40702":39157,"40768":40225,"40769":40244,"40770":40249,"40771":40265,"40772":40270,"40773":40301,"40774":8759,"40775":40302,"40776":40316,"40777":40323,"40778":40339,"40779":40357,"40780":8748,"40781":40381,"40782":27521,"40783":27569,"40784":40015,"40785":40592,"40786":40384,"40787":60817,"40788":60818,"40789":9775,"40790":9776,"40791":9783,"40792":9779,"40793":9780,"40794":9781,"40795":9778,"40796":9782,"40797":9777,"40798":40393,"40799":40404,"40800":40444,"40801":40458,"40802":40460,"40803":40462,"40804":40472,"40805":40571,"40806":40581,"40807":40610,"40808":40620,"40809":40625,"40810":40641,"40811":40646,"40812":40647,"40813":40689,"40814":40696,"40815":40743,"40816":39182,"40817":39193,"40818":39196,"40819":39223,"40820":39261,"40821":39266,"40822":39323,"40823":39332,"40824":39338,"40825":39352,"40826":39392,"40827":39398,"40828":39413,"40829":39455,"40830":32254,"40865":32263,"40866":32347,"40867":32357,"40868":32364,"40869":32567,"40870":32576,"40871":32577,"40872":32585,"40873":32594,"40874":32655,"40875":32659,"40876":32692,"40877":32733,"40878":32743,"40879":32762,"40880":32770,"40881":32776,"40882":32814,"40883":32815,"40884":32828,"40885":32935,"40886":33036,"40887":33066,"40888":33076,"40889":33090,"40890":33110,"40891":33156,"40892":33189,"40893":33252,"40894":33364,"40895":33381,"40896":33403,"40897":33415,"40898":33471,"40899":33506,"40900":33518,"40901":33528,"40902":33532,"40903":33535,"40904":33547,"40905":33565,"40906":33597,"40907":33623,"40908":33681,"40909":33708,"40910":33741,"40911":33773,"40912":33797,"40913":33812,"40914":33814,"40915":33825,"40916":33838,"40917":33854,"40918":33866,"40919":33875,"40920":33877,"40921":33880,"40922":33892,"40923":33906,"40924":33919,"40925":33920,"40926":33938,"40927":33939,"40928":33942,"40929":33955,"40930":33982,"40931":34014,"40932":34017,"40933":34018,"40934":34020,"40935":34040,"40936":34051,"40937":34053,"40938":34064,"40939":34099,"40940":8208,"40941":34114,"40942":34124,"40943":34130,"40944":34143,"40945":34159,"40946":34160,"40947":34163,"40948":34262,"40949":34272,"40950":34286,"40951":34300,"40952":34317,"40953":34319,"40954":34324,"40955":34344,"40956":34370,"40957":34373,"40958":34418,"41024":34972,"41025":23405,"41026":33079,"41027":60958,"41028":39224,"41029":21874,"41030":21867,"41031":60962,"41032":13774,"41033":21873,"41034":21946,"41035":22001,"41036":13778,"41037":22000,"41038":22021,"41039":22050,"41040":22061,"41041":22083,"41042":22046,"41043":22162,"41044":31949,"41045":21530,"41046":21523,"41047":21655,"41048":26353,"41049":30004,"41050":21581,"41051":22180,"41052":22175,"41053":25811,"41054":25390,"41055":25592,"41056":25886,"41057":20088,"41058":27626,"41059":27698,"41060":27709,"41061":27746,"41062":27826,"41063":28152,"41064":28201,"41065":28278,"41066":28290,"41067":28294,"41068":28347,"41069":28383,"41070":28386,"41071":28433,"41072":28452,"41073":28532,"41074":28561,"41075":28597,"41076":28659,"41077":28661,"41078":28859,"41079":28864,"41080":28943,"41081":8706,"41082":29013,"41083":29043,"41084":29050,"41085":61016,"41086":21027,"41121":61018,"41122":13393,"41123":61020,"41124":36812,"41125":61022,"41126":61023,"41127":192,"41128":200,"41129":204,"41130":210,"41131":217,"41132":193,"41133":205,"41134":211,"41135":218,"41136":257,"41137":275,"41138":299,"41139":333,"41140":363,"41141":470,"41142":196,"41143":203,"41144":207,"41145":214,"41146":220,"41147":198,"41148":199,"41149":209,"41150":195,"41151":213,"41152":225,"41153":233,"41154":237,"41155":243,"41156":250,"41157":472,"41158":228,"41159":235,"41160":239,"41161":246,"41162":252,"41163":230,"41164":231,"41165":241,"41166":227,"41167":245,"41168":462,"41169":283,"41170":464,"41171":466,"41172":468,"41173":474,"41174":197,"41175":201,"41176":29064,"41177":216,"41178":208,"41179":7922,"41180":222,"41181":223,"41182":170,"41183":161,"41184":224,"41185":232,"41186":236,"41187":242,"41188":249,"41189":476,"41190":229,"41191":29080,"41192":29143,"41193":248,"41194":240,"41195":7923,"41196":254,"41197":255,"41198":186,"41199":191,"41200":226,"41201":234,"41202":238,"41203":244,"41204":251,"41205":29173,"41206":194,"41207":202,"41208":206,"41209":212,"41210":219,"41211":184,"41212":164,"41213":61110,"41214":402,"41280":12288,"41281":65292,"41282":12289,"41283":12290,"41284":65294,"41285":8231,"41286":65307,"41287":65306,"41288":65311,"41289":65281,"41290":65072,"41291":8230,"41292":8229,"41293":65104,"41294":65105,"41295":65106,"41296":183,"41297":65108,"41298":65109,"41299":65110,"41300":65111,"41301":65372,"41302":8211,"41303":65073,"41304":8212,"41305":65075,"41306":9588,"41307":65076,"41308":65103,"41309":65288,"41310":65289,"41311":65077,"41312":65078,"41313":65371,"41314":65373,"41315":65079,"41316":65080,"41317":12308,"41318":12309,"41319":65081,"41320":65082,"41321":12304,"41322":12305,"41323":65083,"41324":65084,"41325":12298,"41326":12299,"41327":65085,"41328":65086,"41329":12296,"41330":12297,"41331":65087,"41332":65088,"41333":12300,"41334":12301,"41335":65089,"41336":65090,"41337":12302,"41338":12303,"41339":65091,"41340":65092,"41341":65113,"41342":65114,"41377":65115,"41378":65116,"41379":65117,"41380":65118,"41381":8216,"41382":8217,"41383":8220,"41384":8221,"41385":12317,"41386":12318,"41387":8245,"41388":8242,"41389":65283,"41390":65286,"41391":65290,"41392":8251,"41393":167,"41394":12291,"41395":9675,"41396":9679,"41397":9651,"41398":9650,"41399":9678,"41400":9734,"41401":9733,"41402":9671,"41403":9670,"41404":9633,"41405":9632,"41406":9661,"41407":9660,"41408":12963,"41409":8453,"41410":175,"41411":65507,"41412":65343,"41413":717,"41414":65097,"41415":65098,"41416":65101,"41417":65102,"41418":65099,"41419":65100,"41420":65119,"41421":65120,"41422":65121,"41423":65291,"41424":65293,"41425":215,"41426":247,"41427":177,"41428":8730,"41429":65308,"41430":65310,"41431":65309,"41432":8806,"41433":8807,"41434":8800,"41435":8734,"41436":8786,"41437":8801,"41438":65122,"41439":65123,"41440":65124,"41441":65125,"41442":65126,"41443":65374,"41444":8745,"41445":8746,"41446":8869,"41447":8736,"41448":8735,"41449":8895,"41450":13266,"41451":13265,"41452":8747,"41453":8750,"41454":8757,"41455":8756,"41456":9792,"41457":9794,"41458":8853,"41459":8857,"41460":8593,"41461":8595,"41462":8592,"41463":8594,"41464":8598,"41465":8599,"41466":8601,"41467":8600,"41468":8741,"41469":8739,"41470":65295,"41536":65340,"41537":8725,"41538":65128,"41539":65284,"41540":65509,"41541":12306,"41542":65504,"41543":65505,"41544":65285,"41545":65312,"41546":8451,"41547":8457,"41548":65129,"41549":65130,"41550":65131,"41551":13269,"41552":13212,"41553":13213,"41554":13214,"41555":13262,"41556":13217,"41557":13198,"41558":13199,"41559":13252,"41560":176,"41561":20825,"41562":20827,"41563":20830,"41564":20829,"41565":20833,"41566":20835,"41567":21991,"41568":29929,"41569":31950,"41570":9601,"41571":9602,"41572":9603,"41573":9604,"41574":9605,"41575":9606,"41576":9607,"41577":9608,"41578":9615,"41579":9614,"41580":9613,"41581":9612,"41582":9611,"41583":9610,"41584":9609,"41585":9532,"41586":9524,"41587":9516,"41588":9508,"41589":9500,"41590":9620,"41591":9472,"41592":9474,"41593":9621,"41594":9484,"41595":9488,"41596":9492,"41597":9496,"41598":9581,"41633":9582,"41634":9584,"41635":9583,"41636":9552,"41637":9566,"41638":9578,"41639":9569,"41640":9698,"41641":9699,"41642":9701,"41643":9700,"41644":9585,"41645":9586,"41646":9587,"41647":65296,"41648":65297,"41649":65298,"41650":65299,"41651":65300,"41652":65301,"41653":65302,"41654":65303,"41655":65304,"41656":65305,"41657":8544,"41658":8545,"41659":8546,"41660":8547,"41661":8548,"41662":8549,"41663":8550,"41664":8551,"41665":8552,"41666":8553,"41667":12321,"41668":12322,"41669":12323,"41670":12324,"41671":12325,"41672":12326,"41673":12327,"41674":12328,"41675":12329,"41676":21313,"41677":21316,"41678":21317,"41679":65313,"41680":65314,"41681":65315,"41682":65316,"41683":65317,"41684":65318,"41685":65319,"41686":65320,"41687":65321,"41688":65322,"41689":65323,"41690":65324,"41691":65325,"41692":65326,"41693":65327,"41694":65328,"41695":65329,"41696":65330,"41697":65331,"41698":65332,"41699":65333,"41700":65334,"41701":65335,"41702":65336,"41703":65337,"41704":65338,"41705":65345,"41706":65346,"41707":65347,"41708":65348,"41709":65349,"41710":65350,"41711":65351,"41712":65352,"41713":65353,"41714":65354,"41715":65355,"41716":65356,"41717":65357,"41718":65358,"41719":65359,"41720":65360,"41721":65361,"41722":65362,"41723":65363,"41724":65364,"41725":65365,"41726":65366,"41792":65367,"41793":65368,"41794":65369,"41795":65370,"41796":913,"41797":914,"41798":915,"41799":916,"41800":917,"41801":918,"41802":919,"41803":920,"41804":921,"41805":922,"41806":923,"41807":924,"41808":925,"41809":926,"41810":927,"41811":928,"41812":929,"41813":931,"41814":932,"41815":933,"41816":934,"41817":935,"41818":936,"41819":937,"41820":945,"41821":946,"41822":947,"41823":948,"41824":949,"41825":950,"41826":951,"41827":952,"41828":953,"41829":954,"41830":955,"41831":956,"41832":957,"41833":958,"41834":959,"41835":960,"41836":961,"41837":963,"41838":964,"41839":965,"41840":966,"41841":967,"41842":968,"41843":969,"41844":12549,"41845":12550,"41846":12551,"41847":12552,"41848":12553,"41849":12554,"41850":12555,"41851":12556,"41852":12557,"41853":12558,"41854":12559,"41889":12560,"41890":12561,"41891":12562,"41892":12563,"41893":12564,"41894":12565,"41895":12566,"41896":12567,"41897":12568,"41898":12569,"41899":12570,"41900":12571,"41901":12572,"41902":12573,"41903":12574,"41904":12575,"41905":12576,"41906":12577,"41907":12578,"41908":12579,"41909":12580,"41910":12581,"41911":12582,"41912":12583,"41913":12584,"41914":12585,"41915":729,"41916":713,"41917":714,"41918":711,"41919":715,"41920":9216,"41921":9217,"41922":9218,"41923":9219,"41924":9220,"41925":9221,"41926":9222,"41927":9223,"41928":9224,"41929":9225,"41930":9226,"41931":9227,"41932":9228,"41933":9229,"41934":9230,"41935":9231,"41936":9232,"41937":9233,"41938":9234,"41939":9235,"41940":9236,"41941":9237,"41942":9238,"41943":9239,"41944":9240,"41945":9241,"41946":9242,"41947":9243,"41948":9244,"41949":9245,"41950":9246,"41951":9247,"41952":9249,"41953":8364,"41954":63561,"41955":63562,"41956":63563,"41957":63564,"41958":63565,"41959":63566,"41960":63567,"41961":63568,"41962":63569,"41963":63570,"41964":63571,"41965":63572,"41966":63573,"41967":63574,"41968":63575,"41969":63576,"41970":63577,"41971":63578,"41972":63579,"41973":63580,"41974":63581,"41975":63582,"41976":63583,"41977":63584,"41978":63585,"41979":63586,"41980":63587,"41981":63588,"41982":63589,"42048":19968,"42049":20057,"42050":19969,"42051":19971,"42052":20035,"42053":20061,"42054":20102,"42055":20108,"42056":20154,"42057":20799,"42058":20837,"42059":20843,"42060":20960,"42061":20992,"42062":20993,"42063":21147,"42064":21269,"42065":21313,"42066":21340,"42067":21448,"42068":19977,"42069":19979,"42070":19976,"42071":19978,"42072":20011,"42073":20024,"42074":20961,"42075":20037,"42076":20040,"42077":20063,"42078":20062,"42079":20110,"42080":20129,"42081":20800,"42082":20995,"42083":21242,"42084":21315,"42085":21449,"42086":21475,"42087":22303,"42088":22763,"42089":22805,"42090":22823,"42091":22899,"42092":23376,"42093":23377,"42094":23379,"42095":23544,"42096":23567,"42097":23586,"42098":23608,"42099":23665,"42100":24029,"42101":24037,"42102":24049,"42103":24050,"42104":24051,"42105":24062,"42106":24178,"42107":24318,"42108":24331,"42109":24339,"42110":25165,"42145":19985,"42146":19984,"42147":19981,"42148":20013,"42149":20016,"42150":20025,"42151":20043,"42152":23609,"42153":20104,"42154":20113,"42155":20117,"42156":20114,"42157":20116,"42158":20130,"42159":20161,"42160":20160,"42161":20163,"42162":20166,"42163":20167,"42164":20173,"42165":20170,"42166":20171,"42167":20164,"42168":20803,"42169":20801,"42170":20839,"42171":20845,"42172":20846,"42173":20844,"42174":20887,"42175":20982,"42176":20998,"42177":20999,"42178":21000,"42179":21243,"42180":21246,"42181":21247,"42182":21270,"42183":21305,"42184":21320,"42185":21319,"42186":21317,"42187":21342,"42188":21380,"42189":21451,"42190":21450,"42191":21453,"42192":22764,"42193":22825,"42194":22827,"42195":22826,"42196":22829,"42197":23380,"42198":23569,"42199":23588,"42200":23610,"42201":23663,"42202":24052,"42203":24187,"42204":24319,"42205":24340,"42206":24341,"42207":24515,"42208":25096,"42209":25142,"42210":25163,"42211":25166,"42212":25903,"42213":25991,"42214":26007,"42215":26020,"42216":26041,"42217":26085,"42218":26352,"42219":26376,"42220":26408,"42221":27424,"42222":27490,"42223":27513,"42224":27595,"42225":27604,"42226":27611,"42227":27663,"42228":27700,"42229":28779,"42230":29226,"42231":29238,"42232":29243,"42233":29255,"42234":29273,"42235":29275,"42236":29356,"42237":29579,"42238":19993,"42304":19990,"42305":19989,"42306":19988,"42307":19992,"42308":20027,"42309":20045,"42310":20047,"42311":20046,"42312":20197,"42313":20184,"42314":20180,"42315":20181,"42316":20182,"42317":20183,"42318":20195,"42319":20196,"42320":20185,"42321":20190,"42322":20805,"42323":20804,"42324":20873,"42325":20874,"42326":20908,"42327":20985,"42328":20986,"42329":20984,"42330":21002,"42331":21152,"42332":21151,"42333":21253,"42334":21254,"42335":21271,"42336":21277,"42337":20191,"42338":21322,"42339":21321,"42340":21345,"42341":21344,"42342":21359,"42343":21358,"42344":21435,"42345":21487,"42346":21476,"42347":21491,"42348":21484,"42349":21486,"42350":21481,"42351":21480,"42352":21500,"42353":21496,"42354":21493,"42355":21483,"42356":21478,"42357":21482,"42358":21490,"42359":21489,"42360":21488,"42361":21477,"42362":21485,"42363":21499,"42364":22235,"42365":22234,"42366":22806,"42401":22830,"42402":22833,"42403":22900,"42404":22902,"42405":23381,"42406":23427,"42407":23612,"42408":24040,"42409":24039,"42410":24038,"42411":24066,"42412":24067,"42413":24179,"42414":24188,"42415":24321,"42416":24344,"42417":24343,"42418":24517,"42419":25098,"42420":25171,"42421":25172,"42422":25170,"42423":25169,"42424":26021,"42425":26086,"42426":26414,"42427":26412,"42428":26410,"42429":26411,"42430":26413,"42431":27491,"42432":27597,"42433":27665,"42434":27664,"42435":27704,"42436":27713,"42437":27712,"42438":27710,"42439":29359,"42440":29572,"42441":29577,"42442":29916,"42443":29926,"42444":29976,"42445":29983,"42446":29992,"42447":29993,"42448":30000,"42449":30001,"42450":30002,"42451":30003,"42452":30091,"42453":30333,"42454":30382,"42455":30399,"42456":30446,"42457":30683,"42458":30690,"42459":30707,"42460":31034,"42461":31166,"42462":31348,"42463":31435,"42464":19998,"42465":19999,"42466":20050,"42467":20051,"42468":20073,"42469":20121,"42470":20132,"42471":20134,"42472":20133,"42473":20223,"42474":20233,"42475":20249,"42476":20234,"42477":20245,"42478":20237,"42479":20240,"42480":20241,"42481":20239,"42482":20210,"42483":20214,"42484":20219,"42485":20208,"42486":20211,"42487":20221,"42488":20225,"42489":20235,"42490":20809,"42491":20807,"42492":20806,"42493":20808,"42494":20840,"42560":20849,"42561":20877,"42562":20912,"42563":21015,"42564":21009,"42565":21010,"42566":21006,"42567":21014,"42568":21155,"42569":21256,"42570":21281,"42571":21280,"42572":21360,"42573":21361,"42574":21513,"42575":21519,"42576":21516,"42577":21514,"42578":21520,"42579":21505,"42580":21515,"42581":21508,"42582":21521,"42583":21517,"42584":21512,"42585":21507,"42586":21518,"42587":21510,"42588":21522,"42589":22240,"42590":22238,"42591":22237,"42592":22323,"42593":22320,"42594":22312,"42595":22317,"42596":22316,"42597":22319,"42598":22313,"42599":22809,"42600":22810,"42601":22839,"42602":22840,"42603":22916,"42604":22904,"42605":22915,"42606":22909,"42607":22905,"42608":22914,"42609":22913,"42610":23383,"42611":23384,"42612":23431,"42613":23432,"42614":23429,"42615":23433,"42616":23546,"42617":23574,"42618":23673,"42619":24030,"42620":24070,"42621":24182,"42622":24180,"42657":24335,"42658":24347,"42659":24537,"42660":24534,"42661":25102,"42662":25100,"42663":25101,"42664":25104,"42665":25187,"42666":25179,"42667":25176,"42668":25910,"42669":26089,"42670":26088,"42671":26092,"42672":26093,"42673":26354,"42674":26355,"42675":26377,"42676":26429,"42677":26420,"42678":26417,"42679":26421,"42680":27425,"42681":27492,"42682":27515,"42683":27670,"42684":27741,"42685":27735,"42686":27737,"42687":27743,"42688":27744,"42689":27728,"42690":27733,"42691":27745,"42692":27739,"42693":27725,"42694":27726,"42695":28784,"42696":29279,"42697":29277,"42698":30334,"42699":31481,"42700":31859,"42701":31992,"42702":32566,"42703":32650,"42704":32701,"42705":32769,"42706":32771,"42707":32780,"42708":32786,"42709":32819,"42710":32895,"42711":32905,"42712":32907,"42713":32908,"42714":33251,"42715":33258,"42716":33267,"42717":33276,"42718":33292,"42719":33307,"42720":33311,"42721":33390,"42722":33394,"42723":33406,"42724":34411,"42725":34880,"42726":34892,"42727":34915,"42728":35199,"42729":38433,"42730":20018,"42731":20136,"42732":20301,"42733":20303,"42734":20295,"42735":20311,"42736":20318,"42737":20276,"42738":20315,"42739":20309,"42740":20272,"42741":20304,"42742":20305,"42743":20285,"42744":20282,"42745":20280,"42746":20291,"42747":20308,"42748":20284,"42749":20294,"42750":20323,"42816":20316,"42817":20320,"42818":20271,"42819":20302,"42820":20278,"42821":20313,"42822":20317,"42823":20296,"42824":20314,"42825":20812,"42826":20811,"42827":20813,"42828":20853,"42829":20918,"42830":20919,"42831":21029,"42832":21028,"42833":21033,"42834":21034,"42835":21032,"42836":21163,"42837":21161,"42838":21162,"42839":21164,"42840":21283,"42841":21363,"42842":21365,"42843":21533,"42844":21549,"42845":21534,"42846":21566,"42847":21542,"42848":21582,"42849":21543,"42850":21574,"42851":21571,"42852":21555,"42853":21576,"42854":21570,"42855":21531,"42856":21545,"42857":21578,"42858":21561,"42859":21563,"42860":21560,"42861":21550,"42862":21557,"42863":21558,"42864":21536,"42865":21564,"42866":21568,"42867":21553,"42868":21547,"42869":21535,"42870":21548,"42871":22250,"42872":22256,"42873":22244,"42874":22251,"42875":22346,"42876":22353,"42877":22336,"42878":22349,"42913":22343,"42914":22350,"42915":22334,"42916":22352,"42917":22351,"42918":22331,"42919":22767,"42920":22846,"42921":22941,"42922":22930,"42923":22952,"42924":22942,"42925":22947,"42926":22937,"42927":22934,"42928":22925,"42929":22948,"42930":22931,"42931":22922,"42932":22949,"42933":23389,"42934":23388,"42935":23386,"42936":23387,"42937":23436,"42938":23435,"42939":23439,"42940":23596,"42941":23616,"42942":23617,"42943":23615,"42944":23614,"42945":23696,"42946":23697,"42947":23700,"42948":23692,"42949":24043,"42950":24076,"42951":24207,"42952":24199,"42953":24202,"42954":24311,"42955":24324,"42956":24351,"42957":24420,"42958":24418,"42959":24439,"42960":24441,"42961":24536,"42962":24524,"42963":24535,"42964":24525,"42965":24561,"42966":24555,"42967":24568,"42968":24554,"42969":25106,"42970":25105,"42971":25220,"42972":25239,"42973":25238,"42974":25216,"42975":25206,"42976":25225,"42977":25197,"42978":25226,"42979":25212,"42980":25214,"42981":25209,"42982":25203,"42983":25234,"42984":25199,"42985":25240,"42986":25198,"42987":25237,"42988":25235,"42989":25233,"42990":25222,"42991":25913,"42992":25915,"42993":25912,"42994":26097,"42995":26356,"42996":26463,"42997":26446,"42998":26447,"42999":26448,"43000":26449,"43001":26460,"43002":26454,"43003":26462,"43004":26441,"43005":26438,"43006":26464,"43072":26451,"43073":26455,"43074":27493,"43075":27599,"43076":27714,"43077":27742,"43078":27801,"43079":27777,"43080":27784,"43081":27785,"43082":27781,"43083":27803,"43084":27754,"43085":27770,"43086":27792,"43087":27760,"43088":27788,"43089":27752,"43090":27798,"43091":27794,"43092":27773,"43093":27779,"43094":27762,"43095":27774,"43096":27764,"43097":27782,"43098":27766,"43099":27789,"43100":27796,"43101":27800,"43102":27778,"43103":28790,"43104":28796,"43105":28797,"43106":28792,"43107":29282,"43108":29281,"43109":29280,"43110":29380,"43111":29378,"43112":29590,"43113":29996,"43114":29995,"43115":30007,"43116":30008,"43117":30338,"43118":30447,"43119":30691,"43120":31169,"43121":31168,"43122":31167,"43123":31350,"43124":31995,"43125":32597,"43126":32918,"43127":32915,"43128":32925,"43129":32920,"43130":32923,"43131":32922,"43132":32946,"43133":33391,"43134":33426,"43169":33419,"43170":33421,"43171":35211,"43172":35282,"43173":35328,"43174":35895,"43175":35910,"43176":35925,"43177":35997,"43178":36196,"43179":36208,"43180":36275,"43181":36523,"43182":36554,"43183":36763,"43184":36784,"43185":36802,"43186":36806,"43187":36805,"43188":36804,"43189":24033,"43190":37009,"43191":37026,"43192":37034,"43193":37030,"43194":37027,"43195":37193,"43196":37318,"43197":37324,"43198":38450,"43199":38446,"43200":38449,"43201":38442,"43202":38444,"43203":20006,"43204":20054,"43205":20083,"43206":20107,"43207":20123,"43208":20126,"43209":20139,"43210":20140,"43211":20335,"43212":20381,"43213":20365,"43214":20339,"43215":20351,"43216":20332,"43217":20379,"43218":20363,"43219":20358,"43220":20355,"43221":20336,"43222":20341,"43223":20360,"43224":20329,"43225":20347,"43226":20374,"43227":20350,"43228":20367,"43229":20369,"43230":20346,"43231":20820,"43232":20818,"43233":20821,"43234":20841,"43235":20855,"43236":20854,"43237":20856,"43238":20925,"43239":20989,"43240":21051,"43241":21048,"43242":21047,"43243":21050,"43244":21040,"43245":21038,"43246":21046,"43247":21057,"43248":21182,"43249":21179,"43250":21330,"43251":21332,"43252":21331,"43253":21329,"43254":21350,"43255":21367,"43256":21368,"43257":21369,"43258":21462,"43259":21460,"43260":21463,"43261":21619,"43262":21621,"43328":21654,"43329":21624,"43330":21653,"43331":21632,"43332":21627,"43333":21623,"43334":21636,"43335":21650,"43336":21638,"43337":21628,"43338":21648,"43339":21617,"43340":21622,"43341":21644,"43342":21658,"43343":21602,"43344":21608,"43345":21643,"43346":21629,"43347":21646,"43348":22266,"43349":22403,"43350":22391,"43351":22378,"43352":22377,"43353":22369,"43354":22374,"43355":22372,"43356":22396,"43357":22812,"43358":22857,"43359":22855,"43360":22856,"43361":22852,"43362":22868,"43363":22974,"43364":22971,"43365":22996,"43366":22969,"43367":22958,"43368":22993,"43369":22982,"43370":22992,"43371":22989,"43372":22987,"43373":22995,"43374":22986,"43375":22959,"43376":22963,"43377":22994,"43378":22981,"43379":23391,"43380":23396,"43381":23395,"43382":23447,"43383":23450,"43384":23448,"43385":23452,"43386":23449,"43387":23451,"43388":23578,"43389":23624,"43390":23621,"43425":23622,"43426":23735,"43427":23713,"43428":23736,"43429":23721,"43430":23723,"43431":23729,"43432":23731,"43433":24088,"43434":24090,"43435":24086,"43436":24085,"43437":24091,"43438":24081,"43439":24184,"43440":24218,"43441":24215,"43442":24220,"43443":24213,"43444":24214,"43445":24310,"43446":24358,"43447":24359,"43448":24361,"43449":24448,"43450":24449,"43451":24447,"43452":24444,"43453":24541,"43454":24544,"43455":24573,"43456":24565,"43457":24575,"43458":24591,"43459":24596,"43460":24623,"43461":24629,"43462":24598,"43463":24618,"43464":24597,"43465":24609,"43466":24615,"43467":24617,"43468":24619,"43469":24603,"43470":25110,"43471":25109,"43472":25151,"43473":25150,"43474":25152,"43475":25215,"43476":25289,"43477":25292,"43478":25284,"43479":25279,"43480":25282,"43481":25273,"43482":25298,"43483":25307,"43484":25259,"43485":25299,"43486":25300,"43487":25291,"43488":25288,"43489":25256,"43490":25277,"43491":25276,"43492":25296,"43493":25305,"43494":25287,"43495":25293,"43496":25269,"43497":25306,"43498":25265,"43499":25304,"43500":25302,"43501":25303,"43502":25286,"43503":25260,"43504":25294,"43505":25918,"43506":26023,"43507":26044,"43508":26106,"43509":26132,"43510":26131,"43511":26124,"43512":26118,"43513":26114,"43514":26126,"43515":26112,"43516":26127,"43517":26133,"43518":26122,"43584":26119,"43585":26381,"43586":26379,"43587":26477,"43588":26507,"43589":26517,"43590":26481,"43591":26524,"43592":26483,"43593":26487,"43594":26503,"43595":26525,"43596":26519,"43597":26479,"43598":26480,"43599":26495,"43600":26505,"43601":26494,"43602":26512,"43603":26485,"43604":26522,"43605":26515,"43606":26492,"43607":26474,"43608":26482,"43609":27427,"43610":27494,"43611":27495,"43612":27519,"43613":27667,"43614":27675,"43615":27875,"43616":27880,"43617":27891,"43618":27825,"43619":27852,"43620":27877,"43621":27827,"43622":27837,"43623":27838,"43624":27836,"43625":27874,"43626":27819,"43627":27861,"43628":27859,"43629":27832,"43630":27844,"43631":27833,"43632":27841,"43633":27822,"43634":27863,"43635":27845,"43636":27889,"43637":27839,"43638":27835,"43639":27873,"43640":27867,"43641":27850,"43642":27820,"43643":27887,"43644":27868,"43645":27862,"43646":27872,"43681":28821,"43682":28814,"43683":28818,"43684":28810,"43685":28825,"43686":29228,"43687":29229,"43688":29240,"43689":29256,"43690":29287,"43691":29289,"43692":29376,"43693":29390,"43694":29401,"43695":29399,"43696":29392,"43697":29609,"43698":29608,"43699":29599,"43700":29611,"43701":29605,"43702":30013,"43703":30109,"43704":30105,"43705":30106,"43706":30340,"43707":30402,"43708":30450,"43709":30452,"43710":30693,"43711":30717,"43712":31038,"43713":31040,"43714":31041,"43715":31177,"43716":31176,"43717":31354,"43718":31353,"43719":31482,"43720":31998,"43721":32596,"43722":32652,"43723":32651,"43724":32773,"43725":32954,"43726":32933,"43727":32930,"43728":32945,"43729":32929,"43730":32939,"43731":32937,"43732":32948,"43733":32938,"43734":32943,"43735":33253,"43736":33278,"43737":33293,"43738":33459,"43739":33437,"43740":33433,"43741":33453,"43742":33469,"43743":33439,"43744":33465,"43745":33457,"43746":33452,"43747":33445,"43748":33455,"43749":33464,"43750":33443,"43751":33456,"43752":33470,"43753":33463,"43754":34382,"43755":34417,"43756":21021,"43757":34920,"43758":36555,"43759":36814,"43760":36820,"43761":36817,"43762":37045,"43763":37048,"43764":37041,"43765":37046,"43766":37319,"43767":37329,"43768":38263,"43769":38272,"43770":38428,"43771":38464,"43772":38463,"43773":38459,"43774":38468,"43840":38466,"43841":38585,"43842":38632,"43843":38738,"43844":38750,"43845":20127,"43846":20141,"43847":20142,"43848":20449,"43849":20405,"43850":20399,"43851":20415,"43852":20448,"43853":20433,"43854":20431,"43855":20445,"43856":20419,"43857":20406,"43858":20440,"43859":20447,"43860":20426,"43861":20439,"43862":20398,"43863":20432,"43864":20420,"43865":20418,"43866":20442,"43867":20430,"43868":20446,"43869":20407,"43870":20823,"43871":20882,"43872":20881,"43873":20896,"43874":21070,"43875":21059,"43876":21066,"43877":21069,"43878":21068,"43879":21067,"43880":21063,"43881":21191,"43882":21193,"43883":21187,"43884":21185,"43885":21261,"43886":21335,"43887":21371,"43888":21402,"43889":21467,"43890":21676,"43891":21696,"43892":21672,"43893":21710,"43894":21705,"43895":21688,"43896":21670,"43897":21683,"43898":21703,"43899":21698,"43900":21693,"43901":21674,"43902":21697,"43937":21700,"43938":21704,"43939":21679,"43940":21675,"43941":21681,"43942":21691,"43943":21673,"43944":21671,"43945":21695,"43946":22271,"43947":22402,"43948":22411,"43949":22432,"43950":22435,"43951":22434,"43952":22478,"43953":22446,"43954":22419,"43955":22869,"43956":22865,"43957":22863,"43958":22862,"43959":22864,"43960":23004,"43961":23000,"43962":23039,"43963":23011,"43964":23016,"43965":23043,"43966":23013,"43967":23018,"43968":23002,"43969":23014,"43970":23041,"43971":23035,"43972":23401,"43973":23459,"43974":23462,"43975":23460,"43976":23458,"43977":23461,"43978":23553,"43979":23630,"43980":23631,"43981":23629,"43982":23627,"43983":23769,"43984":23762,"43985":24055,"43986":24093,"43987":24101,"43988":24095,"43989":24189,"43990":24224,"43991":24230,"43992":24314,"43993":24328,"43994":24365,"43995":24421,"43996":24456,"43997":24453,"43998":24458,"43999":24459,"44000":24455,"44001":24460,"44002":24457,"44003":24594,"44004":24605,"44005":24608,"44006":24613,"44007":24590,"44008":24616,"44009":24653,"44010":24688,"44011":24680,"44012":24674,"44013":24646,"44014":24643,"44015":24684,"44016":24683,"44017":24682,"44018":24676,"44019":25153,"44020":25308,"44021":25366,"44022":25353,"44023":25340,"44024":25325,"44025":25345,"44026":25326,"44027":25341,"44028":25351,"44029":25329,"44030":25335,"44096":25327,"44097":25324,"44098":25342,"44099":25332,"44100":25361,"44101":25346,"44102":25919,"44103":25925,"44104":26027,"44105":26045,"44106":26082,"44107":26149,"44108":26157,"44109":26144,"44110":26151,"44111":26159,"44112":26143,"44113":26152,"44114":26161,"44115":26148,"44116":26359,"44117":26623,"44118":26579,"44119":26609,"44120":26580,"44121":26576,"44122":26604,"44123":26550,"44124":26543,"44125":26613,"44126":26601,"44127":26607,"44128":26564,"44129":26577,"44130":26548,"44131":26586,"44132":26597,"44133":26552,"44134":26575,"44135":26590,"44136":26611,"44137":26544,"44138":26585,"44139":26594,"44140":26589,"44141":26578,"44142":27498,"44143":27523,"44144":27526,"44145":27573,"44146":27602,"44147":27607,"44148":27679,"44149":27849,"44150":27915,"44151":27954,"44152":27946,"44153":27969,"44154":27941,"44155":27916,"44156":27953,"44157":27934,"44158":27927,"44193":27963,"44194":27965,"44195":27966,"44196":27958,"44197":27931,"44198":27893,"44199":27961,"44200":27943,"44201":27960,"44202":27945,"44203":27950,"44204":27957,"44205":27918,"44206":27947,"44207":28843,"44208":28858,"44209":28851,"44210":28844,"44211":28847,"44212":28845,"44213":28856,"44214":28846,"44215":28836,"44216":29232,"44217":29298,"44218":29295,"44219":29300,"44220":29417,"44221":29408,"44222":29409,"44223":29623,"44224":29642,"44225":29627,"44226":29618,"44227":29645,"44228":29632,"44229":29619,"44230":29978,"44231":29997,"44232":30031,"44233":30028,"44234":30030,"44235":30027,"44236":30123,"44237":30116,"44238":30117,"44239":30114,"44240":30115,"44241":30328,"44242":30342,"44243":30343,"44244":30344,"44245":30408,"44246":30406,"44247":30403,"44248":30405,"44249":30465,"44250":30457,"44251":30456,"44252":30473,"44253":30475,"44254":30462,"44255":30460,"44256":30471,"44257":30684,"44258":30722,"44259":30740,"44260":30732,"44261":30733,"44262":31046,"44263":31049,"44264":31048,"44265":31047,"44266":31161,"44267":31162,"44268":31185,"44269":31186,"44270":31179,"44271":31359,"44272":31361,"44273":31487,"44274":31485,"44275":31869,"44276":32002,"44277":32005,"44278":32000,"44279":32009,"44280":32007,"44281":32004,"44282":32006,"44283":32568,"44284":32654,"44285":32703,"44286":32772,"44352":32784,"44353":32781,"44354":32785,"44355":32822,"44356":32982,"44357":32997,"44358":32986,"44359":32963,"44360":32964,"44361":32972,"44362":32993,"44363":32987,"44364":32974,"44365":32990,"44366":32996,"44367":32989,"44368":33268,"44369":33314,"44370":33511,"44371":33539,"44372":33541,"44373":33507,"44374":33499,"44375":33510,"44376":33540,"44377":33509,"44378":33538,"44379":33545,"44380":33490,"44381":33495,"44382":33521,"44383":33537,"44384":33500,"44385":33492,"44386":33489,"44387":33502,"44388":33491,"44389":33503,"44390":33519,"44391":33542,"44392":34384,"44393":34425,"44394":34427,"44395":34426,"44396":34893,"44397":34923,"44398":35201,"44399":35284,"44400":35336,"44401":35330,"44402":35331,"44403":35998,"44404":36000,"44405":36212,"44406":36211,"44407":36276,"44408":36557,"44409":36556,"44410":36848,"44411":36838,"44412":36834,"44413":36842,"44414":36837,"44449":36845,"44450":36843,"44451":36836,"44452":36840,"44453":37066,"44454":37070,"44455":37057,"44456":37059,"44457":37195,"44458":37194,"44459":37325,"44460":38274,"44461":38480,"44462":38475,"44463":38476,"44464":38477,"44465":38754,"44466":38761,"44467":38859,"44468":38893,"44469":38899,"44470":38913,"44471":39080,"44472":39131,"44473":39135,"44474":39318,"44475":39321,"44476":20056,"44477":20147,"44478":20492,"44479":20493,"44480":20515,"44481":20463,"44482":20518,"44483":20517,"44484":20472,"44485":20521,"44486":20502,"44487":20486,"44488":20540,"44489":20511,"44490":20506,"44491":20498,"44492":20497,"44493":20474,"44494":20480,"44495":20500,"44496":20520,"44497":20465,"44498":20513,"44499":20491,"44500":20505,"44501":20504,"44502":20467,"44503":20462,"44504":20525,"44505":20522,"44506":20478,"44507":20523,"44508":20489,"44509":20860,"44510":20900,"44511":20901,"44512":20898,"44513":20941,"44514":20940,"44515":20934,"44516":20939,"44517":21078,"44518":21084,"44519":21076,"44520":21083,"44521":21085,"44522":21290,"44523":21375,"44524":21407,"44525":21405,"44526":21471,"44527":21736,"44528":21776,"44529":21761,"44530":21815,"44531":21756,"44532":21733,"44533":21746,"44534":21766,"44535":21754,"44536":21780,"44537":21737,"44538":21741,"44539":21729,"44540":21769,"44541":21742,"44542":21738,"44608":21734,"44609":21799,"44610":21767,"44611":21757,"44612":21775,"44613":22275,"44614":22276,"44615":22466,"44616":22484,"44617":22475,"44618":22467,"44619":22537,"44620":22799,"44621":22871,"44622":22872,"44623":22874,"44624":23057,"44625":23064,"44626":23068,"44627":23071,"44628":23067,"44629":23059,"44630":23020,"44631":23072,"44632":23075,"44633":23081,"44634":23077,"44635":23052,"44636":23049,"44637":23403,"44638":23640,"44639":23472,"44640":23475,"44641":23478,"44642":23476,"44643":23470,"44644":23477,"44645":23481,"44646":23480,"44647":23556,"44648":23633,"44649":23637,"44650":23632,"44651":23789,"44652":23805,"44653":23803,"44654":23786,"44655":23784,"44656":23792,"44657":23798,"44658":23809,"44659":23796,"44660":24046,"44661":24109,"44662":24107,"44663":24235,"44664":24237,"44665":24231,"44666":24369,"44667":24466,"44668":24465,"44669":24464,"44670":24665,"44705":24675,"44706":24677,"44707":24656,"44708":24661,"44709":24685,"44710":24681,"44711":24687,"44712":24708,"44713":24735,"44714":24730,"44715":24717,"44716":24724,"44717":24716,"44718":24709,"44719":24726,"44720":25159,"44721":25331,"44722":25352,"44723":25343,"44724":25422,"44725":25406,"44726":25391,"44727":25429,"44728":25410,"44729":25414,"44730":25423,"44731":25417,"44732":25402,"44733":25424,"44734":25405,"44735":25386,"44736":25387,"44737":25384,"44738":25421,"44739":25420,"44740":25928,"44741":25929,"44742":26009,"44743":26049,"44744":26053,"44745":26178,"44746":26185,"44747":26191,"44748":26179,"44749":26194,"44750":26188,"44751":26181,"44752":26177,"44753":26360,"44754":26388,"44755":26389,"44756":26391,"44757":26657,"44758":26680,"44759":26696,"44760":26694,"44761":26707,"44762":26681,"44763":26690,"44764":26708,"44765":26665,"44766":26803,"44767":26647,"44768":26700,"44769":26705,"44770":26685,"44771":26612,"44772":26704,"44773":26688,"44774":26684,"44775":26691,"44776":26666,"44777":26693,"44778":26643,"44779":26648,"44780":26689,"44781":27530,"44782":27529,"44783":27575,"44784":27683,"44785":27687,"44786":27688,"44787":27686,"44788":27684,"44789":27888,"44790":28010,"44791":28053,"44792":28040,"44793":28039,"44794":28006,"44795":28024,"44796":28023,"44797":27993,"44798":28051,"44864":28012,"44865":28041,"44866":28014,"44867":27994,"44868":28020,"44869":28009,"44870":28044,"44871":28042,"44872":28025,"44873":28037,"44874":28005,"44875":28052,"44876":28874,"44877":28888,"44878":28900,"44879":28889,"44880":28872,"44881":28879,"44882":29241,"44883":29305,"44884":29436,"44885":29433,"44886":29437,"44887":29432,"44888":29431,"44889":29574,"44890":29677,"44891":29705,"44892":29678,"44893":29664,"44894":29674,"44895":29662,"44896":30036,"44897":30045,"44898":30044,"44899":30042,"44900":30041,"44901":30142,"44902":30149,"44903":30151,"44904":30130,"44905":30131,"44906":30141,"44907":30140,"44908":30137,"44909":30146,"44910":30136,"44911":30347,"44912":30384,"44913":30410,"44914":30413,"44915":30414,"44916":30505,"44917":30495,"44918":30496,"44919":30504,"44920":30697,"44921":30768,"44922":30759,"44923":30776,"44924":30749,"44925":30772,"44926":30775,"44961":30757,"44962":30765,"44963":30752,"44964":30751,"44965":30770,"44966":31061,"44967":31056,"44968":31072,"44969":31071,"44970":31062,"44971":31070,"44972":31069,"44973":31063,"44974":31066,"44975":31204,"44976":31203,"44977":31207,"44978":31199,"44979":31206,"44980":31209,"44981":31192,"44982":31364,"44983":31368,"44984":31449,"44985":31494,"44986":31505,"44987":31881,"44988":32033,"44989":32023,"44990":32011,"44991":32010,"44992":32032,"44993":32034,"44994":32020,"44995":32016,"44996":32021,"44997":32026,"44998":32028,"44999":32013,"45000":32025,"45001":32027,"45002":32570,"45003":32607,"45004":32660,"45005":32709,"45006":32705,"45007":32774,"45008":32792,"45009":32789,"45010":32793,"45011":32791,"45012":32829,"45013":32831,"45014":33009,"45015":33026,"45016":33008,"45017":33029,"45018":33005,"45019":33012,"45020":33030,"45021":33016,"45022":33011,"45023":33032,"45024":33021,"45025":33034,"45026":33020,"45027":33007,"45028":33261,"45029":33260,"45030":33280,"45031":33296,"45032":33322,"45033":33323,"45034":33320,"45035":33324,"45036":33467,"45037":33579,"45038":33618,"45039":33620,"45040":33610,"45041":33592,"45042":33616,"45043":33609,"45044":33589,"45045":33588,"45046":33615,"45047":33586,"45048":33593,"45049":33590,"45050":33559,"45051":33600,"45052":33585,"45053":33576,"45054":33603,"45120":34388,"45121":34442,"45122":34474,"45123":34451,"45124":34468,"45125":34473,"45126":34444,"45127":34467,"45128":34460,"45129":34928,"45130":34935,"45131":34945,"45132":34946,"45133":34941,"45134":34937,"45135":35352,"45136":35344,"45137":35342,"45138":35340,"45139":35349,"45140":35338,"45141":35351,"45142":35347,"45143":35350,"45144":35343,"45145":35345,"45146":35912,"45147":35962,"45148":35961,"45149":36001,"45150":36002,"45151":36215,"45152":36524,"45153":36562,"45154":36564,"45155":36559,"45156":36785,"45157":36865,"45158":36870,"45159":36855,"45160":36864,"45161":36858,"45162":36852,"45163":36867,"45164":36861,"45165":36869,"45166":36856,"45167":37013,"45168":37089,"45169":37085,"45170":37090,"45171":37202,"45172":37197,"45173":37196,"45174":37336,"45175":37341,"45176":37335,"45177":37340,"45178":37337,"45179":38275,"45180":38498,"45181":38499,"45182":38497,"45217":38491,"45218":38493,"45219":38500,"45220":38488,"45221":38494,"45222":38587,"45223":39138,"45224":39340,"45225":39592,"45226":39640,"45227":39717,"45228":39730,"45229":39740,"45230":20094,"45231":20602,"45232":20605,"45233":20572,"45234":20551,"45235":20547,"45236":20556,"45237":20570,"45238":20553,"45239":20581,"45240":20598,"45241":20558,"45242":20565,"45243":20597,"45244":20596,"45245":20599,"45246":20559,"45247":20495,"45248":20591,"45249":20589,"45250":20828,"45251":20885,"45252":20976,"45253":21098,"45254":21103,"45255":21202,"45256":21209,"45257":21208,"45258":21205,"45259":21264,"45260":21263,"45261":21273,"45262":21311,"45263":21312,"45264":21310,"45265":21443,"45266":26364,"45267":21830,"45268":21866,"45269":21862,"45270":21828,"45271":21854,"45272":21857,"45273":21827,"45274":21834,"45275":21809,"45276":21846,"45277":21839,"45278":21845,"45279":21807,"45280":21860,"45281":21816,"45282":21806,"45283":21852,"45284":21804,"45285":21859,"45286":21811,"45287":21825,"45288":21847,"45289":22280,"45290":22283,"45291":22281,"45292":22495,"45293":22533,"45294":22538,"45295":22534,"45296":22496,"45297":22500,"45298":22522,"45299":22530,"45300":22581,"45301":22519,"45302":22521,"45303":22816,"45304":22882,"45305":23094,"45306":23105,"45307":23113,"45308":23142,"45309":23146,"45310":23104,"45376":23100,"45377":23138,"45378":23130,"45379":23110,"45380":23114,"45381":23408,"45382":23495,"45383":23493,"45384":23492,"45385":23490,"45386":23487,"45387":23494,"45388":23561,"45389":23560,"45390":23559,"45391":23648,"45392":23644,"45393":23645,"45394":23815,"45395":23814,"45396":23822,"45397":23835,"45398":23830,"45399":23842,"45400":23825,"45401":23849,"45402":23828,"45403":23833,"45404":23844,"45405":23847,"45406":23831,"45407":24034,"45408":24120,"45409":24118,"45410":24115,"45411":24119,"45412":24247,"45413":24248,"45414":24246,"45415":24245,"45416":24254,"45417":24373,"45418":24375,"45419":24407,"45420":24428,"45421":24425,"45422":24427,"45423":24471,"45424":24473,"45425":24478,"45426":24472,"45427":24481,"45428":24480,"45429":24476,"45430":24703,"45431":24739,"45432":24713,"45433":24736,"45434":24744,"45435":24779,"45436":24756,"45437":24806,"45438":24765,"45473":24773,"45474":24763,"45475":24757,"45476":24796,"45477":24764,"45478":24792,"45479":24789,"45480":24774,"45481":24799,"45482":24760,"45483":24794,"45484":24775,"45485":25114,"45486":25115,"45487":25160,"45488":25504,"45489":25511,"45490":25458,"45491":25494,"45492":25506,"45493":25509,"45494":25463,"45495":25447,"45496":25496,"45497":25514,"45498":25457,"45499":25513,"45500":25481,"45501":25475,"45502":25499,"45503":25451,"45504":25512,"45505":25476,"45506":25480,"45507":25497,"45508":25505,"45509":25516,"45510":25490,"45511":25487,"45512":25472,"45513":25467,"45514":25449,"45515":25448,"45516":25466,"45517":25949,"45518":25942,"45519":25937,"45520":25945,"45521":25943,"45522":21855,"45523":25935,"45524":25944,"45525":25941,"45526":25940,"45527":26012,"45528":26011,"45529":26028,"45530":26063,"45531":26059,"45532":26060,"45533":26062,"45534":26205,"45535":26202,"45536":26212,"45537":26216,"45538":26214,"45539":26206,"45540":26361,"45541":21207,"45542":26395,"45543":26753,"45544":26799,"45545":26786,"45546":26771,"45547":26805,"45548":26751,"45549":26742,"45550":26801,"45551":26791,"45552":26775,"45553":26800,"45554":26755,"45555":26820,"45556":26797,"45557":26758,"45558":26757,"45559":26772,"45560":26781,"45561":26792,"45562":26783,"45563":26785,"45564":26754,"45565":27442,"45566":27578,"45632":27627,"45633":27628,"45634":27691,"45635":28046,"45636":28092,"45637":28147,"45638":28121,"45639":28082,"45640":28129,"45641":28108,"45642":28132,"45643":28155,"45644":28154,"45645":28165,"45646":28103,"45647":28107,"45648":28079,"45649":28113,"45650":28078,"45651":28126,"45652":28153,"45653":28088,"45654":28151,"45655":28149,"45656":28101,"45657":28114,"45658":28186,"45659":28085,"45660":28122,"45661":28139,"45662":28120,"45663":28138,"45664":28145,"45665":28142,"45666":28136,"45667":28102,"45668":28100,"45669":28074,"45670":28140,"45671":28095,"45672":28134,"45673":28921,"45674":28937,"45675":28938,"45676":28925,"45677":28911,"45678":29245,"45679":29309,"45680":29313,"45681":29468,"45682":29467,"45683":29462,"45684":29459,"45685":29465,"45686":29575,"45687":29701,"45688":29706,"45689":29699,"45690":29702,"45691":29694,"45692":29709,"45693":29920,"45694":29942,"45729":29943,"45730":29980,"45731":29986,"45732":30053,"45733":30054,"45734":30050,"45735":30064,"45736":30095,"45737":30164,"45738":30165,"45739":30133,"45740":30154,"45741":30157,"45742":30350,"45743":30420,"45744":30418,"45745":30427,"45746":30519,"45747":30526,"45748":30524,"45749":30518,"45750":30520,"45751":30522,"45752":30827,"45753":30787,"45754":30798,"45755":31077,"45756":31080,"45757":31085,"45758":31227,"45759":31378,"45760":31381,"45761":31520,"45762":31528,"45763":31515,"45764":31532,"45765":31526,"45766":31513,"45767":31518,"45768":31534,"45769":31890,"45770":31895,"45771":31893,"45772":32070,"45773":32067,"45774":32113,"45775":32046,"45776":32057,"45777":32060,"45778":32064,"45779":32048,"45780":32051,"45781":32068,"45782":32047,"45783":32066,"45784":32050,"45785":32049,"45786":32573,"45787":32670,"45788":32666,"45789":32716,"45790":32718,"45791":32722,"45792":32796,"45793":32842,"45794":32838,"45795":33071,"45796":33046,"45797":33059,"45798":33067,"45799":33065,"45800":33072,"45801":33060,"45802":33282,"45803":33333,"45804":33335,"45805":33334,"45806":33337,"45807":33678,"45808":33694,"45809":33688,"45810":33656,"45811":33698,"45812":33686,"45813":33725,"45814":33707,"45815":33682,"45816":33674,"45817":33683,"45818":33673,"45819":33696,"45820":33655,"45821":33659,"45822":33660,"45888":33670,"45889":33703,"45890":34389,"45891":24426,"45892":34503,"45893":34496,"45894":34486,"45895":34500,"45896":34485,"45897":34502,"45898":34507,"45899":34481,"45900":34479,"45901":34505,"45902":34899,"45903":34974,"45904":34952,"45905":34987,"45906":34962,"45907":34966,"45908":34957,"45909":34955,"45910":35219,"45911":35215,"45912":35370,"45913":35357,"45914":35363,"45915":35365,"45916":35377,"45917":35373,"45918":35359,"45919":35355,"45920":35362,"45921":35913,"45922":35930,"45923":36009,"45924":36012,"45925":36011,"45926":36008,"45927":36010,"45928":36007,"45929":36199,"45930":36198,"45931":36286,"45932":36282,"45933":36571,"45934":36575,"45935":36889,"45936":36877,"45937":36890,"45938":36887,"45939":36899,"45940":36895,"45941":36893,"45942":36880,"45943":36885,"45944":36894,"45945":36896,"45946":36879,"45947":36898,"45948":36886,"45949":36891,"45950":36884,"45985":37096,"45986":37101,"45987":37117,"45988":37207,"45989":37326,"45990":37365,"45991":37350,"45992":37347,"45993":37351,"45994":37357,"45995":37353,"45996":38281,"45997":38506,"45998":38517,"45999":38515,"46000":38520,"46001":38512,"46002":38516,"46003":38518,"46004":38519,"46005":38508,"46006":38592,"46007":38634,"46008":38633,"46009":31456,"46010":31455,"46011":38914,"46012":38915,"46013":39770,"46014":40165,"46015":40565,"46016":40575,"46017":40613,"46018":40635,"46019":20642,"46020":20621,"46021":20613,"46022":20633,"46023":20625,"46024":20608,"46025":20630,"46026":20632,"46027":20634,"46028":26368,"46029":20977,"46030":21106,"46031":21108,"46032":21109,"46033":21097,"46034":21214,"46035":21213,"46036":21211,"46037":21338,"46038":21413,"46039":21883,"46040":21888,"46041":21927,"46042":21884,"46043":21898,"46044":21917,"46045":21912,"46046":21890,"46047":21916,"46048":21930,"46049":21908,"46050":21895,"46051":21899,"46052":21891,"46053":21939,"46054":21934,"46055":21919,"46056":21822,"46057":21938,"46058":21914,"46059":21947,"46060":21932,"46061":21937,"46062":21886,"46063":21897,"46064":21931,"46065":21913,"46066":22285,"46067":22575,"46068":22570,"46069":22580,"46070":22564,"46071":22576,"46072":22577,"46073":22561,"46074":22557,"46075":22560,"46076":22777,"46077":22778,"46078":22880,"46144":23159,"46145":23194,"46146":23167,"46147":23186,"46148":23195,"46149":23207,"46150":23411,"46151":23409,"46152":23506,"46153":23500,"46154":23507,"46155":23504,"46156":23562,"46157":23563,"46158":23601,"46159":23884,"46160":23888,"46161":23860,"46162":23879,"46163":24061,"46164":24133,"46165":24125,"46166":24128,"46167":24131,"46168":24190,"46169":24266,"46170":24257,"46171":24258,"46172":24260,"46173":24380,"46174":24429,"46175":24489,"46176":24490,"46177":24488,"46178":24785,"46179":24801,"46180":24754,"46181":24758,"46182":24800,"46183":24860,"46184":24867,"46185":24826,"46186":24853,"46187":24816,"46188":24827,"46189":24820,"46190":24936,"46191":24817,"46192":24846,"46193":24822,"46194":24841,"46195":24832,"46196":24850,"46197":25119,"46198":25161,"46199":25507,"46200":25484,"46201":25551,"46202":25536,"46203":25577,"46204":25545,"46205":25542,"46206":25549,"46241":25554,"46242":25571,"46243":25552,"46244":25569,"46245":25558,"46246":25581,"46247":25582,"46248":25462,"46249":25588,"46250":25578,"46251":25563,"46252":25682,"46253":25562,"46254":25593,"46255":25950,"46256":25958,"46257":25954,"46258":25955,"46259":26001,"46260":26000,"46261":26031,"46262":26222,"46263":26224,"46264":26228,"46265":26230,"46266":26223,"46267":26257,"46268":26234,"46269":26238,"46270":26231,"46271":26366,"46272":26367,"46273":26399,"46274":26397,"46275":26874,"46276":26837,"46277":26848,"46278":26840,"46279":26839,"46280":26885,"46281":26847,"46282":26869,"46283":26862,"46284":26855,"46285":26873,"46286":26834,"46287":26866,"46288":26851,"46289":26827,"46290":26829,"46291":26893,"46292":26898,"46293":26894,"46294":26825,"46295":26842,"46296":26990,"46297":26875,"46298":27454,"46299":27450,"46300":27453,"46301":27544,"46302":27542,"46303":27580,"46304":27631,"46305":27694,"46306":27695,"46307":27692,"46308":28207,"46309":28216,"46310":28244,"46311":28193,"46312":28210,"46313":28263,"46314":28234,"46315":28192,"46316":28197,"46317":28195,"46318":28187,"46319":28251,"46320":28248,"46321":28196,"46322":28246,"46323":28270,"46324":28205,"46325":28198,"46326":28271,"46327":28212,"46328":28237,"46329":28218,"46330":28204,"46331":28227,"46332":28189,"46333":28222,"46334":28363,"46400":28297,"46401":28185,"46402":28238,"46403":28259,"46404":28228,"46405":28274,"46406":28265,"46407":28255,"46408":28953,"46409":28954,"46410":28966,"46411":28976,"46412":28961,"46413":28982,"46414":29038,"46415":28956,"46416":29260,"46417":29316,"46418":29312,"46419":29494,"46420":29477,"46421":29492,"46422":29481,"46423":29754,"46424":29738,"46425":29747,"46426":29730,"46427":29733,"46428":29749,"46429":29750,"46430":29748,"46431":29743,"46432":29723,"46433":29734,"46434":29736,"46435":29989,"46436":29990,"46437":30059,"46438":30058,"46439":30178,"46440":30171,"46441":30179,"46442":30169,"46443":30168,"46444":30174,"46445":30176,"46446":30331,"46447":30332,"46448":30358,"46449":30355,"46450":30388,"46451":30428,"46452":30543,"46453":30701,"46454":30813,"46455":30828,"46456":30831,"46457":31245,"46458":31240,"46459":31243,"46460":31237,"46461":31232,"46462":31384,"46497":31383,"46498":31382,"46499":31461,"46500":31459,"46501":31561,"46502":31574,"46503":31558,"46504":31568,"46505":31570,"46506":31572,"46507":31565,"46508":31563,"46509":31567,"46510":31569,"46511":31903,"46512":31909,"46513":32094,"46514":32080,"46515":32104,"46516":32085,"46517":32043,"46518":32110,"46519":32114,"46520":32097,"46521":32102,"46522":32098,"46523":32112,"46524":32115,"46525":21892,"46526":32724,"46527":32725,"46528":32779,"46529":32850,"46530":32901,"46531":33109,"46532":33108,"46533":33099,"46534":33105,"46535":33102,"46536":33081,"46537":33094,"46538":33086,"46539":33100,"46540":33107,"46541":33140,"46542":33298,"46543":33308,"46544":33769,"46545":33795,"46546":33784,"46547":33805,"46548":33760,"46549":33733,"46550":33803,"46551":33729,"46552":33775,"46553":33777,"46554":33780,"46555":33879,"46556":33802,"46557":33776,"46558":33804,"46559":33740,"46560":33789,"46561":33778,"46562":33738,"46563":33848,"46564":33806,"46565":33796,"46566":33756,"46567":33799,"46568":33748,"46569":33759,"46570":34395,"46571":34527,"46572":34521,"46573":34541,"46574":34516,"46575":34523,"46576":34532,"46577":34512,"46578":34526,"46579":34903,"46580":35009,"46581":35010,"46582":34993,"46583":35203,"46584":35222,"46585":35387,"46586":35424,"46587":35413,"46588":35422,"46589":35388,"46590":35393,"46656":35412,"46657":35419,"46658":35408,"46659":35398,"46660":35380,"46661":35386,"46662":35382,"46663":35414,"46664":35937,"46665":35970,"46666":36015,"46667":36028,"46668":36019,"46669":36029,"46670":36033,"46671":36027,"46672":36032,"46673":36020,"46674":36023,"46675":36022,"46676":36031,"46677":36024,"46678":36234,"46679":36229,"46680":36225,"46681":36302,"46682":36317,"46683":36299,"46684":36314,"46685":36305,"46686":36300,"46687":36315,"46688":36294,"46689":36603,"46690":36600,"46691":36604,"46692":36764,"46693":36910,"46694":36917,"46695":36913,"46696":36920,"46697":36914,"46698":36918,"46699":37122,"46700":37109,"46701":37129,"46702":37118,"46703":37219,"46704":37221,"46705":37327,"46706":37396,"46707":37397,"46708":37411,"46709":37385,"46710":37406,"46711":37389,"46712":37392,"46713":37383,"46714":37393,"46715":38292,"46716":38287,"46717":38283,"46718":38289,"46753":38291,"46754":38290,"46755":38286,"46756":38538,"46757":38542,"46758":38539,"46759":38525,"46760":38533,"46761":38534,"46762":38541,"46763":38514,"46764":38532,"46765":38593,"46766":38597,"46767":38596,"46768":38598,"46769":38599,"46770":38639,"46771":38642,"46772":38860,"46773":38917,"46774":38918,"46775":38920,"46776":39143,"46777":39146,"46778":39151,"46779":39145,"46780":39154,"46781":39149,"46782":39342,"46783":39341,"46784":40643,"46785":40653,"46786":40657,"46787":20098,"46788":20653,"46789":20661,"46790":20658,"46791":20659,"46792":20677,"46793":20670,"46794":20652,"46795":20663,"46796":20667,"46797":20655,"46798":20679,"46799":21119,"46800":21111,"46801":21117,"46802":21215,"46803":21222,"46804":21220,"46805":21218,"46806":21219,"46807":21295,"46808":21983,"46809":21992,"46810":21971,"46811":21990,"46812":21966,"46813":21980,"46814":21959,"46815":21969,"46816":21987,"46817":21988,"46818":21999,"46819":21978,"46820":21985,"46821":21957,"46822":21958,"46823":21989,"46824":21961,"46825":22290,"46826":22291,"46827":22622,"46828":22609,"46829":22616,"46830":22615,"46831":22618,"46832":22612,"46833":22635,"46834":22604,"46835":22637,"46836":22602,"46837":22626,"46838":22610,"46839":22603,"46840":22887,"46841":23233,"46842":23241,"46843":23244,"46844":23230,"46845":23229,"46846":23228,"46912":23219,"46913":23234,"46914":23218,"46915":23913,"46916":23919,"46917":24140,"46918":24185,"46919":24265,"46920":24264,"46921":24338,"46922":24409,"46923":24492,"46924":24494,"46925":24858,"46926":24847,"46927":24904,"46928":24863,"46929":24819,"46930":24859,"46931":24825,"46932":24833,"46933":24840,"46934":24910,"46935":24908,"46936":24900,"46937":24909,"46938":24894,"46939":24884,"46940":24871,"46941":24845,"46942":24838,"46943":24887,"46944":25121,"46945":25122,"46946":25619,"46947":25662,"46948":25630,"46949":25642,"46950":25645,"46951":25661,"46952":25644,"46953":25615,"46954":25628,"46955":25620,"46956":25613,"46957":25654,"46958":25622,"46959":25623,"46960":25606,"46961":25964,"46962":26015,"46963":26032,"46964":26263,"46965":26249,"46966":26247,"46967":26248,"46968":26262,"46969":26244,"46970":26264,"46971":26253,"46972":26371,"46973":27028,"46974":26989,"47009":26970,"47010":26999,"47011":26976,"47012":26964,"47013":26997,"47014":26928,"47015":27010,"47016":26954,"47017":26984,"47018":26987,"47019":26974,"47020":26963,"47021":27001,"47022":27014,"47023":26973,"47024":26979,"47025":26971,"47026":27463,"47027":27506,"47028":27584,"47029":27583,"47030":27603,"47031":27645,"47032":28322,"47033":28335,"47034":28371,"47035":28342,"47036":28354,"47037":28304,"47038":28317,"47039":28359,"47040":28357,"47041":28325,"47042":28312,"47043":28348,"47044":28346,"47045":28331,"47046":28369,"47047":28310,"47048":28316,"47049":28356,"47050":28372,"47051":28330,"47052":28327,"47053":28340,"47054":29006,"47055":29017,"47056":29033,"47057":29028,"47058":29001,"47059":29031,"47060":29020,"47061":29036,"47062":29030,"47063":29004,"47064":29029,"47065":29022,"47066":28998,"47067":29032,"47068":29014,"47069":29242,"47070":29266,"47071":29495,"47072":29509,"47073":29503,"47074":29502,"47075":29807,"47076":29786,"47077":29781,"47078":29791,"47079":29790,"47080":29761,"47081":29759,"47082":29785,"47083":29787,"47084":29788,"47085":30070,"47086":30072,"47087":30208,"47088":30192,"47089":30209,"47090":30194,"47091":30193,"47092":30202,"47093":30207,"47094":30196,"47095":30195,"47096":30430,"47097":30431,"47098":30555,"47099":30571,"47100":30566,"47101":30558,"47102":30563,"47168":30585,"47169":30570,"47170":30572,"47171":30556,"47172":30565,"47173":30568,"47174":30562,"47175":30702,"47176":30862,"47177":30896,"47178":30871,"47179":30872,"47180":30860,"47181":30857,"47182":30844,"47183":30865,"47184":30867,"47185":30847,"47186":31098,"47187":31103,"47188":31105,"47189":33836,"47190":31165,"47191":31260,"47192":31258,"47193":31264,"47194":31252,"47195":31263,"47196":31262,"47197":31391,"47198":31392,"47199":31607,"47200":31680,"47201":31584,"47202":31598,"47203":31591,"47204":31921,"47205":31923,"47206":31925,"47207":32147,"47208":32121,"47209":32145,"47210":32129,"47211":32143,"47212":32091,"47213":32622,"47214":32617,"47215":32618,"47216":32626,"47217":32681,"47218":32680,"47219":32676,"47220":32854,"47221":32856,"47222":32902,"47223":32900,"47224":33137,"47225":33136,"47226":33144,"47227":33125,"47228":33134,"47229":33139,"47230":33131,"47265":33145,"47266":33146,"47267":33126,"47268":33285,"47269":33351,"47270":33922,"47271":33911,"47272":33853,"47273":33841,"47274":33909,"47275":33894,"47276":33899,"47277":33865,"47278":33900,"47279":33883,"47280":33852,"47281":33845,"47282":33889,"47283":33891,"47284":33897,"47285":33901,"47286":33862,"47287":34398,"47288":34396,"47289":34399,"47290":34553,"47291":34579,"47292":34568,"47293":34567,"47294":34560,"47295":34558,"47296":34555,"47297":34562,"47298":34563,"47299":34566,"47300":34570,"47301":34905,"47302":35039,"47303":35028,"47304":35033,"47305":35036,"47306":35032,"47307":35037,"47308":35041,"47309":35018,"47310":35029,"47311":35026,"47312":35228,"47313":35299,"47314":35435,"47315":35442,"47316":35443,"47317":35430,"47318":35433,"47319":35440,"47320":35463,"47321":35452,"47322":35427,"47323":35488,"47324":35441,"47325":35461,"47326":35437,"47327":35426,"47328":35438,"47329":35436,"47330":35449,"47331":35451,"47332":35390,"47333":35432,"47334":35938,"47335":35978,"47336":35977,"47337":36042,"47338":36039,"47339":36040,"47340":36036,"47341":36018,"47342":36035,"47343":36034,"47344":36037,"47345":36321,"47346":36319,"47347":36328,"47348":36335,"47349":36339,"47350":36346,"47351":36330,"47352":36324,"47353":36326,"47354":36530,"47355":36611,"47356":36617,"47357":36606,"47358":36618,"47424":36767,"47425":36786,"47426":36939,"47427":36938,"47428":36947,"47429":36930,"47430":36948,"47431":36924,"47432":36949,"47433":36944,"47434":36935,"47435":36943,"47436":36942,"47437":36941,"47438":36945,"47439":36926,"47440":36929,"47441":37138,"47442":37143,"47443":37228,"47444":37226,"47445":37225,"47446":37321,"47447":37431,"47448":37463,"47449":37432,"47450":37437,"47451":37440,"47452":37438,"47453":37467,"47454":37451,"47455":37476,"47456":37457,"47457":37428,"47458":37449,"47459":37453,"47460":37445,"47461":37433,"47462":37439,"47463":37466,"47464":38296,"47465":38552,"47466":38548,"47467":38549,"47468":38605,"47469":38603,"47470":38601,"47471":38602,"47472":38647,"47473":38651,"47474":38649,"47475":38646,"47476":38742,"47477":38772,"47478":38774,"47479":38928,"47480":38929,"47481":38931,"47482":38922,"47483":38930,"47484":38924,"47485":39164,"47486":39156,"47521":39165,"47522":39166,"47523":39347,"47524":39345,"47525":39348,"47526":39649,"47527":40169,"47528":40578,"47529":40718,"47530":40723,"47531":40736,"47532":20711,"47533":20718,"47534":20709,"47535":20694,"47536":20717,"47537":20698,"47538":20693,"47539":20687,"47540":20689,"47541":20721,"47542":20686,"47543":20713,"47544":20834,"47545":20979,"47546":21123,"47547":21122,"47548":21297,"47549":21421,"47550":22014,"47551":22016,"47552":22043,"47553":22039,"47554":22013,"47555":22036,"47556":22022,"47557":22025,"47558":22029,"47559":22030,"47560":22007,"47561":22038,"47562":22047,"47563":22024,"47564":22032,"47565":22006,"47566":22296,"47567":22294,"47568":22645,"47569":22654,"47570":22659,"47571":22675,"47572":22666,"47573":22649,"47574":22661,"47575":22653,"47576":22781,"47577":22821,"47578":22818,"47579":22820,"47580":22890,"47581":22889,"47582":23265,"47583":23270,"47584":23273,"47585":23255,"47586":23254,"47587":23256,"47588":23267,"47589":23413,"47590":23518,"47591":23527,"47592":23521,"47593":23525,"47594":23526,"47595":23528,"47596":23522,"47597":23524,"47598":23519,"47599":23565,"47600":23650,"47601":23940,"47602":23943,"47603":24155,"47604":24163,"47605":24149,"47606":24151,"47607":24148,"47608":24275,"47609":24278,"47610":24330,"47611":24390,"47612":24432,"47613":24505,"47614":24903,"47680":24895,"47681":24907,"47682":24951,"47683":24930,"47684":24931,"47685":24927,"47686":24922,"47687":24920,"47688":24949,"47689":25130,"47690":25735,"47691":25688,"47692":25684,"47693":25764,"47694":25720,"47695":25695,"47696":25722,"47697":25681,"47698":25703,"47699":25652,"47700":25709,"47701":25723,"47702":25970,"47703":26017,"47704":26071,"47705":26070,"47706":26274,"47707":26280,"47708":26269,"47709":27036,"47710":27048,"47711":27029,"47712":27073,"47713":27054,"47714":27091,"47715":27083,"47716":27035,"47717":27063,"47718":27067,"47719":27051,"47720":27060,"47721":27088,"47722":27085,"47723":27053,"47724":27084,"47725":27046,"47726":27075,"47727":27043,"47728":27465,"47729":27468,"47730":27699,"47731":28467,"47732":28436,"47733":28414,"47734":28435,"47735":28404,"47736":28457,"47737":28478,"47738":28448,"47739":28460,"47740":28431,"47741":28418,"47742":28450,"47777":28415,"47778":28399,"47779":28422,"47780":28465,"47781":28472,"47782":28466,"47783":28451,"47784":28437,"47785":28459,"47786":28463,"47787":28552,"47788":28458,"47789":28396,"47790":28417,"47791":28402,"47792":28364,"47793":28407,"47794":29076,"47795":29081,"47796":29053,"47797":29066,"47798":29060,"47799":29074,"47800":29246,"47801":29330,"47802":29334,"47803":29508,"47804":29520,"47805":29796,"47806":29795,"47807":29802,"47808":29808,"47809":29805,"47810":29956,"47811":30097,"47812":30247,"47813":30221,"47814":30219,"47815":30217,"47816":30227,"47817":30433,"47818":30435,"47819":30596,"47820":30589,"47821":30591,"47822":30561,"47823":30913,"47824":30879,"47825":30887,"47826":30899,"47827":30889,"47828":30883,"47829":31118,"47830":31119,"47831":31117,"47832":31278,"47833":31281,"47834":31402,"47835":31401,"47836":31469,"47837":31471,"47838":31649,"47839":31637,"47840":31627,"47841":31605,"47842":31639,"47843":31645,"47844":31636,"47845":31631,"47846":31672,"47847":31623,"47848":31620,"47849":31929,"47850":31933,"47851":31934,"47852":32187,"47853":32176,"47854":32156,"47855":32189,"47856":32190,"47857":32160,"47858":32202,"47859":32180,"47860":32178,"47861":32177,"47862":32186,"47863":32162,"47864":32191,"47865":32181,"47866":32184,"47867":32173,"47868":32210,"47869":32199,"47870":32172,"47936":32624,"47937":32736,"47938":32737,"47939":32735,"47940":32862,"47941":32858,"47942":32903,"47943":33104,"47944":33152,"47945":33167,"47946":33160,"47947":33162,"47948":33151,"47949":33154,"47950":33255,"47951":33274,"47952":33287,"47953":33300,"47954":33310,"47955":33355,"47956":33993,"47957":33983,"47958":33990,"47959":33988,"47960":33945,"47961":33950,"47962":33970,"47963":33948,"47964":33995,"47965":33976,"47966":33984,"47967":34003,"47968":33936,"47969":33980,"47970":34001,"47971":33994,"47972":34623,"47973":34588,"47974":34619,"47975":34594,"47976":34597,"47977":34612,"47978":34584,"47979":34645,"47980":34615,"47981":34601,"47982":35059,"47983":35074,"47984":35060,"47985":35065,"47986":35064,"47987":35069,"47988":35048,"47989":35098,"47990":35055,"47991":35494,"47992":35468,"47993":35486,"47994":35491,"47995":35469,"47996":35489,"47997":35475,"47998":35492,"48033":35498,"48034":35493,"48035":35496,"48036":35480,"48037":35473,"48038":35482,"48039":35495,"48040":35946,"48041":35981,"48042":35980,"48043":36051,"48044":36049,"48045":36050,"48046":36203,"48047":36249,"48048":36245,"48049":36348,"48050":36628,"48051":36626,"48052":36629,"48053":36627,"48054":36771,"48055":36960,"48056":36952,"48057":36956,"48058":36963,"48059":36953,"48060":36958,"48061":36962,"48062":36957,"48063":36955,"48064":37145,"48065":37144,"48066":37150,"48067":37237,"48068":37240,"48069":37239,"48070":37236,"48071":37496,"48072":37504,"48073":37509,"48074":37528,"48075":37526,"48076":37499,"48077":37523,"48078":37532,"48079":37544,"48080":37500,"48081":37521,"48082":38305,"48083":38312,"48084":38313,"48085":38307,"48086":38309,"48087":38308,"48088":38553,"48089":38556,"48090":38555,"48091":38604,"48092":38610,"48093":38656,"48094":38780,"48095":38789,"48096":38902,"48097":38935,"48098":38936,"48099":39087,"48100":39089,"48101":39171,"48102":39173,"48103":39180,"48104":39177,"48105":39361,"48106":39599,"48107":39600,"48108":39654,"48109":39745,"48110":39746,"48111":40180,"48112":40182,"48113":40179,"48114":40636,"48115":40763,"48116":40778,"48117":20740,"48118":20736,"48119":20731,"48120":20725,"48121":20729,"48122":20738,"48123":20744,"48124":20745,"48125":20741,"48126":20956,"48192":21127,"48193":21128,"48194":21129,"48195":21133,"48196":21130,"48197":21232,"48198":21426,"48199":22062,"48200":22075,"48201":22073,"48202":22066,"48203":22079,"48204":22068,"48205":22057,"48206":22099,"48207":22094,"48208":22103,"48209":22132,"48210":22070,"48211":22063,"48212":22064,"48213":22656,"48214":22687,"48215":22686,"48216":22707,"48217":22684,"48218":22702,"48219":22697,"48220":22694,"48221":22893,"48222":23305,"48223":23291,"48224":23307,"48225":23285,"48226":23308,"48227":23304,"48228":23534,"48229":23532,"48230":23529,"48231":23531,"48232":23652,"48233":23653,"48234":23965,"48235":23956,"48236":24162,"48237":24159,"48238":24161,"48239":24290,"48240":24282,"48241":24287,"48242":24285,"48243":24291,"48244":24288,"48245":24392,"48246":24433,"48247":24503,"48248":24501,"48249":24950,"48250":24935,"48251":24942,"48252":24925,"48253":24917,"48254":24962,"48289":24956,"48290":24944,"48291":24939,"48292":24958,"48293":24999,"48294":24976,"48295":25003,"48296":24974,"48297":25004,"48298":24986,"48299":24996,"48300":24980,"48301":25006,"48302":25134,"48303":25705,"48304":25711,"48305":25721,"48306":25758,"48307":25778,"48308":25736,"48309":25744,"48310":25776,"48311":25765,"48312":25747,"48313":25749,"48314":25769,"48315":25746,"48316":25774,"48317":25773,"48318":25771,"48319":25754,"48320":25772,"48321":25753,"48322":25762,"48323":25779,"48324":25973,"48325":25975,"48326":25976,"48327":26286,"48328":26283,"48329":26292,"48330":26289,"48331":27171,"48332":27167,"48333":27112,"48334":27137,"48335":27166,"48336":27161,"48337":27133,"48338":27169,"48339":27155,"48340":27146,"48341":27123,"48342":27138,"48343":27141,"48344":27117,"48345":27153,"48346":27472,"48347":27470,"48348":27556,"48349":27589,"48350":27590,"48351":28479,"48352":28540,"48353":28548,"48354":28497,"48355":28518,"48356":28500,"48357":28550,"48358":28525,"48359":28507,"48360":28536,"48361":28526,"48362":28558,"48363":28538,"48364":28528,"48365":28516,"48366":28567,"48367":28504,"48368":28373,"48369":28527,"48370":28512,"48371":28511,"48372":29087,"48373":29100,"48374":29105,"48375":29096,"48376":29270,"48377":29339,"48378":29518,"48379":29527,"48380":29801,"48381":29835,"48382":29827,"48448":29822,"48449":29824,"48450":30079,"48451":30240,"48452":30249,"48453":30239,"48454":30244,"48455":30246,"48456":30241,"48457":30242,"48458":30362,"48459":30394,"48460":30436,"48461":30606,"48462":30599,"48463":30604,"48464":30609,"48465":30603,"48466":30923,"48467":30917,"48468":30906,"48469":30922,"48470":30910,"48471":30933,"48472":30908,"48473":30928,"48474":31295,"48475":31292,"48476":31296,"48477":31293,"48478":31287,"48479":31291,"48480":31407,"48481":31406,"48482":31661,"48483":31665,"48484":31684,"48485":31668,"48486":31686,"48487":31687,"48488":31681,"48489":31648,"48490":31692,"48491":31946,"48492":32224,"48493":32244,"48494":32239,"48495":32251,"48496":32216,"48497":32236,"48498":32221,"48499":32232,"48500":32227,"48501":32218,"48502":32222,"48503":32233,"48504":32158,"48505":32217,"48506":32242,"48507":32249,"48508":32629,"48509":32631,"48510":32687,"48545":32745,"48546":32806,"48547":33179,"48548":33180,"48549":33181,"48550":33184,"48551":33178,"48552":33176,"48553":34071,"48554":34109,"48555":34074,"48556":34030,"48557":34092,"48558":34093,"48559":34067,"48560":34065,"48561":34083,"48562":34081,"48563":34068,"48564":34028,"48565":34085,"48566":34047,"48567":34054,"48568":34690,"48569":34676,"48570":34678,"48571":34656,"48572":34662,"48573":34680,"48574":34664,"48575":34649,"48576":34647,"48577":34636,"48578":34643,"48579":34907,"48580":34909,"48581":35088,"48582":35079,"48583":35090,"48584":35091,"48585":35093,"48586":35082,"48587":35516,"48588":35538,"48589":35527,"48590":35524,"48591":35477,"48592":35531,"48593":35576,"48594":35506,"48595":35529,"48596":35522,"48597":35519,"48598":35504,"48599":35542,"48600":35533,"48601":35510,"48602":35513,"48603":35547,"48604":35916,"48605":35918,"48606":35948,"48607":36064,"48608":36062,"48609":36070,"48610":36068,"48611":36076,"48612":36077,"48613":36066,"48614":36067,"48615":36060,"48616":36074,"48617":36065,"48618":36205,"48619":36255,"48620":36259,"48621":36395,"48622":36368,"48623":36381,"48624":36386,"48625":36367,"48626":36393,"48627":36383,"48628":36385,"48629":36382,"48630":36538,"48631":36637,"48632":36635,"48633":36639,"48634":36649,"48635":36646,"48636":36650,"48637":36636,"48638":36638,"48704":36645,"48705":36969,"48706":36974,"48707":36968,"48708":36973,"48709":36983,"48710":37168,"48711":37165,"48712":37159,"48713":37169,"48714":37255,"48715":37257,"48716":37259,"48717":37251,"48718":37573,"48719":37563,"48720":37559,"48721":37610,"48722":37548,"48723":37604,"48724":37569,"48725":37555,"48726":37564,"48727":37586,"48728":37575,"48729":37616,"48730":37554,"48731":38317,"48732":38321,"48733":38660,"48734":38662,"48735":38663,"48736":38665,"48737":38752,"48738":38797,"48739":38795,"48740":38799,"48741":38945,"48742":38955,"48743":38940,"48744":39091,"48745":39178,"48746":39187,"48747":39186,"48748":39192,"48749":39389,"48750":39376,"48751":39391,"48752":39387,"48753":39377,"48754":39381,"48755":39378,"48756":39385,"48757":39607,"48758":39662,"48759":39663,"48760":39719,"48761":39749,"48762":39748,"48763":39799,"48764":39791,"48765":40198,"48766":40201,"48801":40195,"48802":40617,"48803":40638,"48804":40654,"48805":22696,"48806":40786,"48807":20754,"48808":20760,"48809":20756,"48810":20752,"48811":20757,"48812":20864,"48813":20906,"48814":20957,"48815":21137,"48816":21139,"48817":21235,"48818":22105,"48819":22123,"48820":22137,"48821":22121,"48822":22116,"48823":22136,"48824":22122,"48825":22120,"48826":22117,"48827":22129,"48828":22127,"48829":22124,"48830":22114,"48831":22134,"48832":22721,"48833":22718,"48834":22727,"48835":22725,"48836":22894,"48837":23325,"48838":23348,"48839":23416,"48840":23536,"48841":23566,"48842":24394,"48843":25010,"48844":24977,"48845":25001,"48846":24970,"48847":25037,"48848":25014,"48849":25022,"48850":25034,"48851":25032,"48852":25136,"48853":25797,"48854":25793,"48855":25803,"48856":25787,"48857":25788,"48858":25818,"48859":25796,"48860":25799,"48861":25794,"48862":25805,"48863":25791,"48864":25810,"48865":25812,"48866":25790,"48867":25972,"48868":26310,"48869":26313,"48870":26297,"48871":26308,"48872":26311,"48873":26296,"48874":27197,"48875":27192,"48876":27194,"48877":27225,"48878":27243,"48879":27224,"48880":27193,"48881":27204,"48882":27234,"48883":27233,"48884":27211,"48885":27207,"48886":27189,"48887":27231,"48888":27208,"48889":27481,"48890":27511,"48891":27653,"48892":28610,"48893":28593,"48894":28577,"48960":28611,"48961":28580,"48962":28609,"48963":28583,"48964":28595,"48965":28608,"48966":28601,"48967":28598,"48968":28582,"48969":28576,"48970":28596,"48971":29118,"48972":29129,"48973":29136,"48974":29138,"48975":29128,"48976":29141,"48977":29113,"48978":29134,"48979":29145,"48980":29148,"48981":29123,"48982":29124,"48983":29544,"48984":29852,"48985":29859,"48986":29848,"48987":29855,"48988":29854,"48989":29922,"48990":29964,"48991":29965,"48992":30260,"48993":30264,"48994":30266,"48995":30439,"48996":30437,"48997":30624,"48998":30622,"48999":30623,"49000":30629,"49001":30952,"49002":30938,"49003":30956,"49004":30951,"49005":31142,"49006":31309,"49007":31310,"49008":31302,"49009":31308,"49010":31307,"49011":31418,"49012":31705,"49013":31761,"49014":31689,"49015":31716,"49016":31707,"49017":31713,"49018":31721,"49019":31718,"49020":31957,"49021":31958,"49022":32266,"49057":32273,"49058":32264,"49059":32283,"49060":32291,"49061":32286,"49062":32285,"49063":32265,"49064":32272,"49065":32633,"49066":32690,"49067":32752,"49068":32753,"49069":32750,"49070":32808,"49071":33203,"49072":33193,"49073":33192,"49074":33275,"49075":33288,"49076":33368,"49077":33369,"49078":34122,"49079":34137,"49080":34120,"49081":34152,"49082":34153,"49083":34115,"49084":34121,"49085":34157,"49086":34154,"49087":34142,"49088":34691,"49089":34719,"49090":34718,"49091":34722,"49092":34701,"49093":34913,"49094":35114,"49095":35122,"49096":35109,"49097":35115,"49098":35105,"49099":35242,"49100":35238,"49101":35558,"49102":35578,"49103":35563,"49104":35569,"49105":35584,"49106":35548,"49107":35559,"49108":35566,"49109":35582,"49110":35585,"49111":35586,"49112":35575,"49113":35565,"49114":35571,"49115":35574,"49116":35580,"49117":35947,"49118":35949,"49119":35987,"49120":36084,"49121":36420,"49122":36401,"49123":36404,"49124":36418,"49125":36409,"49126":36405,"49127":36667,"49128":36655,"49129":36664,"49130":36659,"49131":36776,"49132":36774,"49133":36981,"49134":36980,"49135":36984,"49136":36978,"49137":36988,"49138":36986,"49139":37172,"49140":37266,"49141":37664,"49142":37686,"49143":37624,"49144":37683,"49145":37679,"49146":37666,"49147":37628,"49148":37675,"49149":37636,"49150":37658,"49216":37648,"49217":37670,"49218":37665,"49219":37653,"49220":37678,"49221":37657,"49222":38331,"49223":38567,"49224":38568,"49225":38570,"49226":38613,"49227":38670,"49228":38673,"49229":38678,"49230":38669,"49231":38675,"49232":38671,"49233":38747,"49234":38748,"49235":38758,"49236":38808,"49237":38960,"49238":38968,"49239":38971,"49240":38967,"49241":38957,"49242":38969,"49243":38948,"49244":39184,"49245":39208,"49246":39198,"49247":39195,"49248":39201,"49249":39194,"49250":39405,"49251":39394,"49252":39409,"49253":39608,"49254":39612,"49255":39675,"49256":39661,"49257":39720,"49258":39825,"49259":40213,"49260":40227,"49261":40230,"49262":40232,"49263":40210,"49264":40219,"49265":40664,"49266":40660,"49267":40845,"49268":40860,"49269":20778,"49270":20767,"49271":20769,"49272":20786,"49273":21237,"49274":22158,"49275":22144,"49276":22160,"49277":22149,"49278":22151,"49313":22159,"49314":22741,"49315":22739,"49316":22737,"49317":22734,"49318":23344,"49319":23338,"49320":23332,"49321":23418,"49322":23607,"49323":23656,"49324":23996,"49325":23994,"49326":23997,"49327":23992,"49328":24171,"49329":24396,"49330":24509,"49331":25033,"49332":25026,"49333":25031,"49334":25062,"49335":25035,"49336":25138,"49337":25140,"49338":25806,"49339":25802,"49340":25816,"49341":25824,"49342":25840,"49343":25830,"49344":25836,"49345":25841,"49346":25826,"49347":25837,"49348":25986,"49349":25987,"49350":26329,"49351":26326,"49352":27264,"49353":27284,"49354":27268,"49355":27298,"49356":27292,"49357":27355,"49358":27299,"49359":27262,"49360":27287,"49361":27280,"49362":27296,"49363":27484,"49364":27566,"49365":27610,"49366":27656,"49367":28632,"49368":28657,"49369":28639,"49370":28640,"49371":28635,"49372":28644,"49373":28651,"49374":28655,"49375":28544,"49376":28652,"49377":28641,"49378":28649,"49379":28629,"49380":28654,"49381":28656,"49382":29159,"49383":29151,"49384":29166,"49385":29158,"49386":29157,"49387":29165,"49388":29164,"49389":29172,"49390":29152,"49391":29237,"49392":29254,"49393":29552,"49394":29554,"49395":29865,"49396":29872,"49397":29862,"49398":29864,"49399":30278,"49400":30274,"49401":30284,"49402":30442,"49403":30643,"49404":30634,"49405":30640,"49406":30636,"49472":30631,"49473":30637,"49474":30703,"49475":30967,"49476":30970,"49477":30964,"49478":30959,"49479":30977,"49480":31143,"49481":31146,"49482":31319,"49483":31423,"49484":31751,"49485":31757,"49486":31742,"49487":31735,"49488":31756,"49489":31712,"49490":31968,"49491":31964,"49492":31966,"49493":31970,"49494":31967,"49495":31961,"49496":31965,"49497":32302,"49498":32318,"49499":32326,"49500":32311,"49501":32306,"49502":32323,"49503":32299,"49504":32317,"49505":32305,"49506":32325,"49507":32321,"49508":32308,"49509":32313,"49510":32328,"49511":32309,"49512":32319,"49513":32303,"49514":32580,"49515":32755,"49516":32764,"49517":32881,"49518":32882,"49519":32880,"49520":32879,"49521":32883,"49522":33222,"49523":33219,"49524":33210,"49525":33218,"49526":33216,"49527":33215,"49528":33213,"49529":33225,"49530":33214,"49531":33256,"49532":33289,"49533":33393,"49534":34218,"49569":34180,"49570":34174,"49571":34204,"49572":34193,"49573":34196,"49574":34223,"49575":34203,"49576":34183,"49577":34216,"49578":34186,"49579":34407,"49580":34752,"49581":34769,"49582":34739,"49583":34770,"49584":34758,"49585":34731,"49586":34747,"49587":34746,"49588":34760,"49589":34763,"49590":35131,"49591":35126,"49592":35140,"49593":35128,"49594":35133,"49595":35244,"49596":35598,"49597":35607,"49598":35609,"49599":35611,"49600":35594,"49601":35616,"49602":35613,"49603":35588,"49604":35600,"49605":35905,"49606":35903,"49607":35955,"49608":36090,"49609":36093,"49610":36092,"49611":36088,"49612":36091,"49613":36264,"49614":36425,"49615":36427,"49616":36424,"49617":36426,"49618":36676,"49619":36670,"49620":36674,"49621":36677,"49622":36671,"49623":36991,"49624":36989,"49625":36996,"49626":36993,"49627":36994,"49628":36992,"49629":37177,"49630":37283,"49631":37278,"49632":37276,"49633":37709,"49634":37762,"49635":37672,"49636":37749,"49637":37706,"49638":37733,"49639":37707,"49640":37656,"49641":37758,"49642":37740,"49643":37723,"49644":37744,"49645":37722,"49646":37716,"49647":38346,"49648":38347,"49649":38348,"49650":38344,"49651":38342,"49652":38577,"49653":38584,"49654":38614,"49655":38684,"49656":38686,"49657":38816,"49658":38867,"49659":38982,"49660":39094,"49661":39221,"49662":39425,"49728":39423,"49729":39854,"49730":39851,"49731":39850,"49732":39853,"49733":40251,"49734":40255,"49735":40587,"49736":40655,"49737":40670,"49738":40668,"49739":40669,"49740":40667,"49741":40766,"49742":40779,"49743":21474,"49744":22165,"49745":22190,"49746":22745,"49747":22744,"49748":23352,"49749":24413,"49750":25059,"49751":25139,"49752":25844,"49753":25842,"49754":25854,"49755":25862,"49756":25850,"49757":25851,"49758":25847,"49759":26039,"49760":26332,"49761":26406,"49762":27315,"49763":27308,"49764":27331,"49765":27323,"49766":27320,"49767":27330,"49768":27310,"49769":27311,"49770":27487,"49771":27512,"49772":27567,"49773":28681,"49774":28683,"49775":28670,"49776":28678,"49777":28666,"49778":28689,"49779":28687,"49780":29179,"49781":29180,"49782":29182,"49783":29176,"49784":29559,"49785":29557,"49786":29863,"49787":29887,"49788":29973,"49789":30294,"49790":30296,"49825":30290,"49826":30653,"49827":30655,"49828":30651,"49829":30652,"49830":30990,"49831":31150,"49832":31329,"49833":31330,"49834":31328,"49835":31428,"49836":31429,"49837":31787,"49838":31783,"49839":31786,"49840":31774,"49841":31779,"49842":31777,"49843":31975,"49844":32340,"49845":32341,"49846":32350,"49847":32346,"49848":32353,"49849":32338,"49850":32345,"49851":32584,"49852":32761,"49853":32763,"49854":32887,"49855":32886,"49856":33229,"49857":33231,"49858":33290,"49859":34255,"49860":34217,"49861":34253,"49862":34256,"49863":34249,"49864":34224,"49865":34234,"49866":34233,"49867":34214,"49868":34799,"49869":34796,"49870":34802,"49871":34784,"49872":35206,"49873":35250,"49874":35316,"49875":35624,"49876":35641,"49877":35628,"49878":35627,"49879":35920,"49880":36101,"49881":36441,"49882":36451,"49883":36454,"49884":36452,"49885":36447,"49886":36437,"49887":36544,"49888":36681,"49889":36685,"49890":36999,"49891":36995,"49892":37000,"49893":37291,"49894":37292,"49895":37328,"49896":37780,"49897":37770,"49898":37782,"49899":37794,"49900":37811,"49901":37806,"49902":37804,"49903":37808,"49904":37784,"49905":37786,"49906":37783,"49907":38356,"49908":38358,"49909":38352,"49910":38357,"49911":38626,"49912":38620,"49913":38617,"49914":38619,"49915":38622,"49916":38692,"49917":38819,"49918":38822,"49984":38829,"49985":38905,"49986":38989,"49987":38991,"49988":38988,"49989":38990,"49990":38995,"49991":39098,"49992":39230,"49993":39231,"49994":39229,"49995":39214,"49996":39333,"49997":39438,"49998":39617,"49999":39683,"50000":39686,"50001":39759,"50002":39758,"50003":39757,"50004":39882,"50005":39881,"50006":39933,"50007":39880,"50008":39872,"50009":40273,"50010":40285,"50011":40288,"50012":40672,"50013":40725,"50014":40748,"50015":20787,"50016":22181,"50017":22750,"50018":22751,"50019":22754,"50020":23541,"50021":40848,"50022":24300,"50023":25074,"50024":25079,"50025":25078,"50026":25077,"50027":25856,"50028":25871,"50029":26336,"50030":26333,"50031":27365,"50032":27357,"50033":27354,"50034":27347,"50035":28699,"50036":28703,"50037":28712,"50038":28698,"50039":28701,"50040":28693,"50041":28696,"50042":29190,"50043":29197,"50044":29272,"50045":29346,"50046":29560,"50081":29562,"50082":29885,"50083":29898,"50084":29923,"50085":30087,"50086":30086,"50087":30303,"50088":30305,"50089":30663,"50090":31001,"50091":31153,"50092":31339,"50093":31337,"50094":31806,"50095":31807,"50096":31800,"50097":31805,"50098":31799,"50099":31808,"50100":32363,"50101":32365,"50102":32377,"50103":32361,"50104":32362,"50105":32645,"50106":32371,"50107":32694,"50108":32697,"50109":32696,"50110":33240,"50111":34281,"50112":34269,"50113":34282,"50114":34261,"50115":34276,"50116":34277,"50117":34295,"50118":34811,"50119":34821,"50120":34829,"50121":34809,"50122":34814,"50123":35168,"50124":35167,"50125":35158,"50126":35166,"50127":35649,"50128":35676,"50129":35672,"50130":35657,"50131":35674,"50132":35662,"50133":35663,"50134":35654,"50135":35673,"50136":36104,"50137":36106,"50138":36476,"50139":36466,"50140":36487,"50141":36470,"50142":36460,"50143":36474,"50144":36468,"50145":36692,"50146":36686,"50147":36781,"50148":37002,"50149":37003,"50150":37297,"50151":37294,"50152":37857,"50153":37841,"50154":37855,"50155":37827,"50156":37832,"50157":37852,"50158":37853,"50159":37846,"50160":37858,"50161":37837,"50162":37848,"50163":37860,"50164":37847,"50165":37864,"50166":38364,"50167":38580,"50168":38627,"50169":38698,"50170":38695,"50171":38753,"50172":38876,"50173":38907,"50174":39006,"50240":39000,"50241":39003,"50242":39100,"50243":39237,"50244":39241,"50245":39446,"50246":39449,"50247":39693,"50248":39912,"50249":39911,"50250":39894,"50251":39899,"50252":40329,"50253":40289,"50254":40306,"50255":40298,"50256":40300,"50257":40594,"50258":40599,"50259":40595,"50260":40628,"50261":21240,"50262":22184,"50263":22199,"50264":22198,"50265":22196,"50266":22204,"50267":22756,"50268":23360,"50269":23363,"50270":23421,"50271":23542,"50272":24009,"50273":25080,"50274":25082,"50275":25880,"50276":25876,"50277":25881,"50278":26342,"50279":26407,"50280":27372,"50281":28734,"50282":28720,"50283":28722,"50284":29200,"50285":29563,"50286":29903,"50287":30306,"50288":30309,"50289":31014,"50290":31018,"50291":31020,"50292":31019,"50293":31431,"50294":31478,"50295":31820,"50296":31811,"50297":31821,"50298":31983,"50299":31984,"50300":36782,"50301":32381,"50302":32380,"50337":32386,"50338":32588,"50339":32768,"50340":33242,"50341":33382,"50342":34299,"50343":34297,"50344":34321,"50345":34298,"50346":34310,"50347":34315,"50348":34311,"50349":34314,"50350":34836,"50351":34837,"50352":35172,"50353":35258,"50354":35320,"50355":35696,"50356":35692,"50357":35686,"50358":35695,"50359":35679,"50360":35691,"50361":36111,"50362":36109,"50363":36489,"50364":36481,"50365":36485,"50366":36482,"50367":37300,"50368":37323,"50369":37912,"50370":37891,"50371":37885,"50372":38369,"50373":38704,"50374":39108,"50375":39250,"50376":39249,"50377":39336,"50378":39467,"50379":39472,"50380":39479,"50381":39477,"50382":39955,"50383":39949,"50384":40569,"50385":40629,"50386":40680,"50387":40751,"50388":40799,"50389":40803,"50390":40801,"50391":20791,"50392":20792,"50393":22209,"50394":22208,"50395":22210,"50396":22804,"50397":23660,"50398":24013,"50399":25084,"50400":25086,"50401":25885,"50402":25884,"50403":26005,"50404":26345,"50405":27387,"50406":27396,"50407":27386,"50408":27570,"50409":28748,"50410":29211,"50411":29351,"50412":29910,"50413":29908,"50414":30313,"50415":30675,"50416":31824,"50417":32399,"50418":32396,"50419":32700,"50420":34327,"50421":34349,"50422":34330,"50423":34851,"50424":34850,"50425":34849,"50426":34847,"50427":35178,"50428":35180,"50429":35261,"50430":35700,"50496":35703,"50497":35709,"50498":36115,"50499":36490,"50500":36493,"50501":36491,"50502":36703,"50503":36783,"50504":37306,"50505":37934,"50506":37939,"50507":37941,"50508":37946,"50509":37944,"50510":37938,"50511":37931,"50512":38370,"50513":38712,"50514":38713,"50515":38706,"50516":38911,"50517":39015,"50518":39013,"50519":39255,"50520":39493,"50521":39491,"50522":39488,"50523":39486,"50524":39631,"50525":39764,"50526":39761,"50527":39981,"50528":39973,"50529":40367,"50530":40372,"50531":40386,"50532":40376,"50533":40605,"50534":40687,"50535":40729,"50536":40796,"50537":40806,"50538":40807,"50539":20796,"50540":20795,"50541":22216,"50542":22218,"50543":22217,"50544":23423,"50545":24020,"50546":24018,"50547":24398,"50548":25087,"50549":25892,"50550":27402,"50551":27489,"50552":28753,"50553":28760,"50554":29568,"50555":29924,"50556":30090,"50557":30318,"50558":30316,"50593":31155,"50594":31840,"50595":31839,"50596":32894,"50597":32893,"50598":33247,"50599":35186,"50600":35183,"50601":35324,"50602":35712,"50603":36118,"50604":36119,"50605":36497,"50606":36499,"50607":36705,"50608":37192,"50609":37956,"50610":37969,"50611":37970,"50612":38717,"50613":38718,"50614":38851,"50615":38849,"50616":39019,"50617":39253,"50618":39509,"50619":39501,"50620":39634,"50621":39706,"50622":40009,"50623":39985,"50624":39998,"50625":39995,"50626":40403,"50627":40407,"50628":40756,"50629":40812,"50630":40810,"50631":40852,"50632":22220,"50633":24022,"50634":25088,"50635":25891,"50636":25899,"50637":25898,"50638":26348,"50639":27408,"50640":29914,"50641":31434,"50642":31844,"50643":31843,"50644":31845,"50645":32403,"50646":32406,"50647":32404,"50648":33250,"50649":34360,"50650":34367,"50651":34865,"50652":35722,"50653":37008,"50654":37007,"50655":37987,"50656":37984,"50657":37988,"50658":38760,"50659":39023,"50660":39260,"50661":39514,"50662":39515,"50663":39511,"50664":39635,"50665":39636,"50666":39633,"50667":40020,"50668":40023,"50669":40022,"50670":40421,"50671":40607,"50672":40692,"50673":22225,"50674":22761,"50675":25900,"50676":28766,"50677":30321,"50678":30322,"50679":30679,"50680":32592,"50681":32648,"50682":34870,"50683":34873,"50684":34914,"50685":35731,"50686":35730,"50752":35734,"50753":33399,"50754":36123,"50755":37312,"50756":37994,"50757":38722,"50758":38728,"50759":38724,"50760":38854,"50761":39024,"50762":39519,"50763":39714,"50764":39768,"50765":40031,"50766":40441,"50767":40442,"50768":40572,"50769":40573,"50770":40711,"50771":40823,"50772":40818,"50773":24307,"50774":27414,"50775":28771,"50776":31852,"50777":31854,"50778":34875,"50779":35264,"50780":36513,"50781":37313,"50782":38002,"50783":38000,"50784":39025,"50785":39262,"50786":39638,"50787":39715,"50788":40652,"50789":28772,"50790":30682,"50791":35738,"50792":38007,"50793":38857,"50794":39522,"50795":39525,"50796":32412,"50797":35740,"50798":36522,"50799":37317,"50800":38013,"50801":38014,"50802":38012,"50803":40055,"50804":40056,"50805":40695,"50806":35924,"50807":38015,"50808":40474,"50809":29224,"50810":39530,"50811":39729,"50812":40475,"50813":40478,"50814":31858,"50849":9312,"50850":9313,"50851":9314,"50852":9315,"50853":9316,"50854":9317,"50855":9318,"50856":9319,"50857":9320,"50858":9321,"50859":9332,"50860":9333,"50861":9334,"50862":9335,"50863":9336,"50864":9337,"50865":9338,"50866":9339,"50867":9340,"50868":9341,"50869":8560,"50870":8561,"50871":8562,"50872":8563,"50873":8564,"50874":8565,"50875":8566,"50876":8567,"50877":8568,"50878":8569,"50879":20022,"50880":20031,"50881":20101,"50882":20128,"50883":20866,"50884":20886,"50885":20907,"50886":21241,"50887":21304,"50888":21353,"50889":21430,"50890":22794,"50891":23424,"50892":24027,"50893":24186,"50894":24191,"50895":24308,"50896":24400,"50897":24417,"50898":25908,"50899":26080,"50900":30098,"50901":30326,"50902":36789,"50903":38582,"50904":168,"50905":710,"50906":12541,"50907":12542,"50908":12445,"50909":12446,"50910":12291,"50911":20189,"50912":12293,"50913":12294,"50914":12295,"50915":12540,"50916":65339,"50917":65341,"50918":10045,"50919":12353,"50920":12354,"50921":12355,"50922":12356,"50923":12357,"50924":12358,"50925":12359,"50926":12360,"50927":12361,"50928":12362,"50929":12363,"50930":12364,"50931":12365,"50932":12366,"50933":12367,"50934":12368,"50935":12369,"50936":12370,"50937":12371,"50938":12372,"50939":12373,"50940":12374,"50941":12375,"50942":12376,"51008":12377,"51009":12378,"51010":12379,"51011":12380,"51012":12381,"51013":12382,"51014":12383,"51015":12384,"51016":12385,"51017":12386,"51018":12387,"51019":12388,"51020":12389,"51021":12390,"51022":12391,"51023":12392,"51024":12393,"51025":12394,"51026":12395,"51027":12396,"51028":12397,"51029":12398,"51030":12399,"51031":12400,"51032":12401,"51033":12402,"51034":12403,"51035":12404,"51036":12405,"51037":12406,"51038":12407,"51039":12408,"51040":12409,"51041":12410,"51042":12411,"51043":12412,"51044":12413,"51045":12414,"51046":12415,"51047":12416,"51048":12417,"51049":12418,"51050":12419,"51051":12420,"51052":12421,"51053":12422,"51054":12423,"51055":12424,"51056":12425,"51057":12426,"51058":12427,"51059":12428,"51060":12429,"51061":12430,"51062":12431,"51063":12432,"51064":12433,"51065":12434,"51066":12435,"51067":12449,"51068":12450,"51069":12451,"51070":12452,"51105":12453,"51106":12454,"51107":12455,"51108":12456,"51109":12457,"51110":12458,"51111":12459,"51112":12460,"51113":12461,"51114":12462,"51115":12463,"51116":12464,"51117":12465,"51118":12466,"51119":12467,"51120":12468,"51121":12469,"51122":12470,"51123":12471,"51124":12472,"51125":12473,"51126":12474,"51127":12475,"51128":12476,"51129":12477,"51130":12478,"51131":12479,"51132":12480,"51133":12481,"51134":12482,"51135":12483,"51136":12484,"51137":12485,"51138":12486,"51139":12487,"51140":12488,"51141":12489,"51142":12490,"51143":12491,"51144":12492,"51145":12493,"51146":12494,"51147":12495,"51148":12496,"51149":12497,"51150":12498,"51151":12499,"51152":12500,"51153":12501,"51154":12502,"51155":12503,"51156":12504,"51157":12505,"51158":12506,"51159":12507,"51160":12508,"51161":12509,"51162":12510,"51163":12511,"51164":12512,"51165":12513,"51166":12514,"51167":12515,"51168":12516,"51169":12517,"51170":12518,"51171":12519,"51172":12520,"51173":12521,"51174":12522,"51175":12523,"51176":12524,"51177":12525,"51178":12526,"51179":12527,"51180":12528,"51181":12529,"51182":12530,"51183":12531,"51184":12532,"51185":12533,"51186":12534,"51187":1040,"51188":1041,"51189":1042,"51190":1043,"51191":1044,"51192":1045,"51193":1025,"51194":1046,"51195":1047,"51196":1048,"51197":1049,"51198":1050,"51264":1051,"51265":1052,"51266":1053,"51267":1054,"51268":1055,"51269":1056,"51270":1057,"51271":1058,"51272":1059,"51273":1060,"51274":1061,"51275":1062,"51276":1063,"51277":1064,"51278":1065,"51279":1066,"51280":1067,"51281":1068,"51282":1069,"51283":1070,"51284":1071,"51285":1072,"51286":1073,"51287":1074,"51288":1075,"51289":1076,"51290":1077,"51291":1105,"51292":1078,"51293":1079,"51294":1080,"51295":1081,"51296":1082,"51297":1083,"51298":1084,"51299":1085,"51300":1086,"51301":1087,"51302":1088,"51303":1089,"51304":1090,"51305":1091,"51306":1092,"51307":1093,"51308":1094,"51309":1095,"51310":1096,"51311":1097,"51312":1098,"51313":1099,"51314":1100,"51315":1101,"51316":1102,"51317":1103,"51318":8679,"51319":8632,"51320":8633,"51321":12751,"51322":63462,"51323":20058,"51324":63464,"51325":20994,"51326":17553,"51361":40880,"51362":20872,"51363":40881,"51364":63470,"51365":63471,"51366":63472,"51367":63473,"51368":63474,"51369":63475,"51370":63476,"51371":63477,"51372":63478,"51373":63479,"51374":63480,"51375":63481,"51376":63482,"51377":12443,"51378":12444,"51379":12436,"51380":12535,"51381":12536,"51382":12537,"51383":12538,"51384":12539,"51385":65377,"51386":65378,"51387":65379,"51388":65380,"51389":65381,"51390":65382,"51391":65383,"51392":65384,"51393":65385,"51394":65386,"51395":65387,"51396":65388,"51397":65389,"51398":65390,"51399":65391,"51400":65392,"51401":65393,"51402":65394,"51403":65395,"51404":65396,"51405":65506,"51406":65508,"51407":65287,"51408":65282,"51409":12849,"51410":8470,"51411":8481,"51412":65397,"51413":65398,"51414":65399,"51415":65400,"51416":65401,"51417":65402,"51418":65403,"51419":65404,"51420":65405,"51421":65406,"51422":65407,"51423":65408,"51424":65409,"51425":65410,"51426":65411,"51427":65412,"51428":65413,"51429":65414,"51430":65415,"51431":65416,"51432":65417,"51433":65418,"51434":65419,"51435":65420,"51436":65421,"51437":65422,"51438":65423,"51439":65424,"51440":65425,"51441":65426,"51442":65427,"51443":65428,"51444":65429,"51445":65430,"51446":65431,"51447":65432,"51448":65433,"51449":65434,"51450":65435,"51451":65436,"51452":65437,"51453":65438,"51454":65439,"51520":20034,"51521":20060,"51522":20981,"51523":21274,"51524":21378,"51525":19975,"51526":19980,"51527":20039,"51528":20109,"51529":22231,"51530":64012,"51531":23662,"51532":24435,"51533":19983,"51534":20871,"51535":19982,"51536":20014,"51537":20115,"51538":20162,"51539":20169,"51540":20168,"51541":20888,"51542":21244,"51543":21356,"51544":21433,"51545":22304,"51546":22787,"51547":22828,"51548":23568,"51549":24063,"51550":26081,"51551":27571,"51552":27596,"51553":27668,"51554":29247,"51555":20017,"51556":20028,"51557":20200,"51558":20188,"51559":20201,"51560":20193,"51561":20189,"51562":20186,"51563":21004,"51564":21276,"51565":21324,"51566":22306,"51567":22307,"51568":22807,"51569":22831,"51570":23425,"51571":23428,"51572":23570,"51573":23611,"51574":23668,"51575":23667,"51576":24068,"51577":24192,"51578":24194,"51579":24521,"51580":25097,"51581":25168,"51582":27669,"51617":27702,"51618":27715,"51619":27711,"51620":27707,"51621":29358,"51622":29360,"51623":29578,"51624":31160,"51625":32906,"51626":38430,"51627":20238,"51628":20248,"51629":20268,"51630":20213,"51631":20244,"51632":20209,"51633":20224,"51634":20215,"51635":20232,"51636":20253,"51637":20226,"51638":20229,"51639":20258,"51640":20243,"51641":20228,"51642":20212,"51643":20242,"51644":20913,"51645":21011,"51646":21001,"51647":21008,"51648":21158,"51649":21282,"51650":21279,"51651":21325,"51652":21386,"51653":21511,"51654":22241,"51655":22239,"51656":22318,"51657":22314,"51658":22324,"51659":22844,"51660":22912,"51661":22908,"51662":22917,"51663":22907,"51664":22910,"51665":22903,"51666":22911,"51667":23382,"51668":23573,"51669":23589,"51670":23676,"51671":23674,"51672":23675,"51673":23678,"51674":24031,"51675":24181,"51676":24196,"51677":24322,"51678":24346,"51679":24436,"51680":24533,"51681":24532,"51682":24527,"51683":25180,"51684":25182,"51685":25188,"51686":25185,"51687":25190,"51688":25186,"51689":25177,"51690":25184,"51691":25178,"51692":25189,"51693":26095,"51694":26094,"51695":26430,"51696":26425,"51697":26424,"51698":26427,"51699":26426,"51700":26431,"51701":26428,"51702":26419,"51703":27672,"51704":27718,"51705":27730,"51706":27740,"51707":27727,"51708":27722,"51709":27732,"51710":27723,"51776":27724,"51777":28785,"51778":29278,"51779":29364,"51780":29365,"51781":29582,"51782":29994,"51783":30335,"51784":31349,"51785":32593,"51786":33400,"51787":33404,"51788":33408,"51789":33405,"51790":33407,"51791":34381,"51792":35198,"51793":37017,"51794":37015,"51795":37016,"51796":37019,"51797":37012,"51798":38434,"51799":38436,"51800":38432,"51801":38435,"51802":20310,"51803":20283,"51804":20322,"51805":20297,"51806":20307,"51807":20324,"51808":20286,"51809":20327,"51810":20306,"51811":20319,"51812":20289,"51813":20312,"51814":20269,"51815":20275,"51816":20287,"51817":20321,"51818":20879,"51819":20921,"51820":21020,"51821":21022,"51822":21025,"51823":21165,"51824":21166,"51825":21257,"51826":21347,"51827":21362,"51828":21390,"51829":21391,"51830":21552,"51831":21559,"51832":21546,"51833":21588,"51834":21573,"51835":21529,"51836":21532,"51837":21541,"51838":21528,"51873":21565,"51874":21583,"51875":21569,"51876":21544,"51877":21540,"51878":21575,"51879":22254,"51880":22247,"51881":22245,"51882":22337,"51883":22341,"51884":22348,"51885":22345,"51886":22347,"51887":22354,"51888":22790,"51889":22848,"51890":22950,"51891":22936,"51892":22944,"51893":22935,"51894":22926,"51895":22946,"51896":22928,"51897":22927,"51898":22951,"51899":22945,"51900":23438,"51901":23442,"51902":23592,"51903":23594,"51904":23693,"51905":23695,"51906":23688,"51907":23691,"51908":23689,"51909":23698,"51910":23690,"51911":23686,"51912":23699,"51913":23701,"51914":24032,"51915":24074,"51916":24078,"51917":24203,"51918":24201,"51919":24204,"51920":24200,"51921":24205,"51922":24325,"51923":24349,"51924":24440,"51925":24438,"51926":24530,"51927":24529,"51928":24528,"51929":24557,"51930":24552,"51931":24558,"51932":24563,"51933":24545,"51934":24548,"51935":24547,"51936":24570,"51937":24559,"51938":24567,"51939":24571,"51940":24576,"51941":24564,"51942":25146,"51943":25219,"51944":25228,"51945":25230,"51946":25231,"51947":25236,"51948":25223,"51949":25201,"51950":25211,"51951":25210,"51952":25200,"51953":25217,"51954":25224,"51955":25207,"51956":25213,"51957":25202,"51958":25204,"51959":25911,"51960":26096,"51961":26100,"51962":26099,"51963":26098,"51964":26101,"51965":26437,"51966":26439,"52032":26457,"52033":26453,"52034":26444,"52035":26440,"52036":26461,"52037":26445,"52038":26458,"52039":26443,"52040":27600,"52041":27673,"52042":27674,"52043":27768,"52044":27751,"52045":27755,"52046":27780,"52047":27787,"52048":27791,"52049":27761,"52050":27759,"52051":27753,"52052":27802,"52053":27757,"52054":27783,"52055":27797,"52056":27804,"52057":27750,"52058":27763,"52059":27749,"52060":27771,"52061":27790,"52062":28788,"52063":28794,"52064":29283,"52065":29375,"52066":29373,"52067":29379,"52068":29382,"52069":29377,"52070":29370,"52071":29381,"52072":29589,"52073":29591,"52074":29587,"52075":29588,"52076":29586,"52077":30010,"52078":30009,"52079":30100,"52080":30101,"52081":30337,"52082":31037,"52083":32820,"52084":32917,"52085":32921,"52086":32912,"52087":32914,"52088":32924,"52089":33424,"52090":33423,"52091":33413,"52092":33422,"52093":33425,"52094":33427,"52129":33418,"52130":33411,"52131":33412,"52132":35960,"52133":36809,"52134":36799,"52135":37023,"52136":37025,"52137":37029,"52138":37022,"52139":37031,"52140":37024,"52141":38448,"52142":38440,"52143":38447,"52144":38445,"52145":20019,"52146":20376,"52147":20348,"52148":20357,"52149":20349,"52150":20352,"52151":20359,"52152":20342,"52153":20340,"52154":20361,"52155":20356,"52156":20343,"52157":20300,"52158":20375,"52159":20330,"52160":20378,"52161":20345,"52162":20353,"52163":20344,"52164":20368,"52165":20380,"52166":20372,"52167":20382,"52168":20370,"52169":20354,"52170":20373,"52171":20331,"52172":20334,"52173":20894,"52174":20924,"52175":20926,"52176":21045,"52177":21042,"52178":21043,"52179":21062,"52180":21041,"52181":21180,"52182":21258,"52183":21259,"52184":21308,"52185":21394,"52186":21396,"52187":21639,"52188":21631,"52189":21633,"52190":21649,"52191":21634,"52192":21640,"52193":21611,"52194":21626,"52195":21630,"52196":21605,"52197":21612,"52198":21620,"52199":21606,"52200":21645,"52201":21615,"52202":21601,"52203":21600,"52204":21656,"52205":21603,"52206":21607,"52207":21604,"52208":22263,"52209":22265,"52210":22383,"52211":22386,"52212":22381,"52213":22379,"52214":22385,"52215":22384,"52216":22390,"52217":22400,"52218":22389,"52219":22395,"52220":22387,"52221":22388,"52222":22370,"52288":22376,"52289":22397,"52290":22796,"52291":22853,"52292":22965,"52293":22970,"52294":22991,"52295":22990,"52296":22962,"52297":22988,"52298":22977,"52299":22966,"52300":22972,"52301":22979,"52302":22998,"52303":22961,"52304":22973,"52305":22976,"52306":22984,"52307":22964,"52308":22983,"52309":23394,"52310":23397,"52311":23443,"52312":23445,"52313":23620,"52314":23623,"52315":23726,"52316":23716,"52317":23712,"52318":23733,"52319":23727,"52320":23720,"52321":23724,"52322":23711,"52323":23715,"52324":23725,"52325":23714,"52326":23722,"52327":23719,"52328":23709,"52329":23717,"52330":23734,"52331":23728,"52332":23718,"52333":24087,"52334":24084,"52335":24089,"52336":24360,"52337":24354,"52338":24355,"52339":24356,"52340":24404,"52341":24450,"52342":24446,"52343":24445,"52344":24542,"52345":24549,"52346":24621,"52347":24614,"52348":24601,"52349":24626,"52350":24587,"52385":24628,"52386":24586,"52387":24599,"52388":24627,"52389":24602,"52390":24606,"52391":24620,"52392":24610,"52393":24589,"52394":24592,"52395":24622,"52396":24595,"52397":24593,"52398":24588,"52399":24585,"52400":24604,"52401":25108,"52402":25149,"52403":25261,"52404":25268,"52405":25297,"52406":25278,"52407":25258,"52408":25270,"52409":25290,"52410":25262,"52411":25267,"52412":25263,"52413":25275,"52414":25257,"52415":25264,"52416":25272,"52417":25917,"52418":26024,"52419":26043,"52420":26121,"52421":26108,"52422":26116,"52423":26130,"52424":26120,"52425":26107,"52426":26115,"52427":26123,"52428":26125,"52429":26117,"52430":26109,"52431":26129,"52432":26128,"52433":26358,"52434":26378,"52435":26501,"52436":26476,"52437":26510,"52438":26514,"52439":26486,"52440":26491,"52441":26520,"52442":26502,"52443":26500,"52444":26484,"52445":26509,"52446":26508,"52447":26490,"52448":26527,"52449":26513,"52450":26521,"52451":26499,"52452":26493,"52453":26497,"52454":26488,"52455":26489,"52456":26516,"52457":27429,"52458":27520,"52459":27518,"52460":27614,"52461":27677,"52462":27795,"52463":27884,"52464":27883,"52465":27886,"52466":27865,"52467":27830,"52468":27860,"52469":27821,"52470":27879,"52471":27831,"52472":27856,"52473":27842,"52474":27834,"52475":27843,"52476":27846,"52477":27885,"52478":27890,"52544":27858,"52545":27869,"52546":27828,"52547":27786,"52548":27805,"52549":27776,"52550":27870,"52551":27840,"52552":27952,"52553":27853,"52554":27847,"52555":27824,"52556":27897,"52557":27855,"52558":27881,"52559":27857,"52560":28820,"52561":28824,"52562":28805,"52563":28819,"52564":28806,"52565":28804,"52566":28817,"52567":28822,"52568":28802,"52569":28826,"52570":28803,"52571":29290,"52572":29398,"52573":29387,"52574":29400,"52575":29385,"52576":29404,"52577":29394,"52578":29396,"52579":29402,"52580":29388,"52581":29393,"52582":29604,"52583":29601,"52584":29613,"52585":29606,"52586":29602,"52587":29600,"52588":29612,"52589":29597,"52590":29917,"52591":29928,"52592":30015,"52593":30016,"52594":30014,"52595":30092,"52596":30104,"52597":30383,"52598":30451,"52599":30449,"52600":30448,"52601":30453,"52602":30712,"52603":30716,"52604":30713,"52605":30715,"52606":30714,"52641":30711,"52642":31042,"52643":31039,"52644":31173,"52645":31352,"52646":31355,"52647":31483,"52648":31861,"52649":31997,"52650":32821,"52651":32911,"52652":32942,"52653":32931,"52654":32952,"52655":32949,"52656":32941,"52657":33312,"52658":33440,"52659":33472,"52660":33451,"52661":33434,"52662":33432,"52663":33435,"52664":33461,"52665":33447,"52666":33454,"52667":33468,"52668":33438,"52669":33466,"52670":33460,"52671":33448,"52672":33441,"52673":33449,"52674":33474,"52675":33444,"52676":33475,"52677":33462,"52678":33442,"52679":34416,"52680":34415,"52681":34413,"52682":34414,"52683":35926,"52684":36818,"52685":36811,"52686":36819,"52687":36813,"52688":36822,"52689":36821,"52690":36823,"52691":37042,"52692":37044,"52693":37039,"52694":37043,"52695":37040,"52696":38457,"52697":38461,"52698":38460,"52699":38458,"52700":38467,"52701":20429,"52702":20421,"52703":20435,"52704":20402,"52705":20425,"52706":20427,"52707":20417,"52708":20436,"52709":20444,"52710":20441,"52711":20411,"52712":20403,"52713":20443,"52714":20423,"52715":20438,"52716":20410,"52717":20416,"52718":20409,"52719":20460,"52720":21060,"52721":21065,"52722":21184,"52723":21186,"52724":21309,"52725":21372,"52726":21399,"52727":21398,"52728":21401,"52729":21400,"52730":21690,"52731":21665,"52732":21677,"52733":21669,"52734":21711,"52800":21699,"52801":33549,"52802":21687,"52803":21678,"52804":21718,"52805":21686,"52806":21701,"52807":21702,"52808":21664,"52809":21616,"52810":21692,"52811":21666,"52812":21694,"52813":21618,"52814":21726,"52815":21680,"52816":22453,"52817":22430,"52818":22431,"52819":22436,"52820":22412,"52821":22423,"52822":22429,"52823":22427,"52824":22420,"52825":22424,"52826":22415,"52827":22425,"52828":22437,"52829":22426,"52830":22421,"52831":22772,"52832":22797,"52833":22867,"52834":23009,"52835":23006,"52836":23022,"52837":23040,"52838":23025,"52839":23005,"52840":23034,"52841":23037,"52842":23036,"52843":23030,"52844":23012,"52845":23026,"52846":23031,"52847":23003,"52848":23017,"52849":23027,"52850":23029,"52851":23008,"52852":23038,"52853":23028,"52854":23021,"52855":23464,"52856":23628,"52857":23760,"52858":23768,"52859":23756,"52860":23767,"52861":23755,"52862":23771,"52897":23774,"52898":23770,"52899":23753,"52900":23751,"52901":23754,"52902":23766,"52903":23763,"52904":23764,"52905":23759,"52906":23752,"52907":23750,"52908":23758,"52909":23775,"52910":23800,"52911":24057,"52912":24097,"52913":24098,"52914":24099,"52915":24096,"52916":24100,"52917":24240,"52918":24228,"52919":24226,"52920":24219,"52921":24227,"52922":24229,"52923":24327,"52924":24366,"52925":24406,"52926":24454,"52927":24631,"52928":24633,"52929":24660,"52930":24690,"52931":24670,"52932":24645,"52933":24659,"52934":24647,"52935":24649,"52936":24667,"52937":24652,"52938":24640,"52939":24642,"52940":24671,"52941":24612,"52942":24644,"52943":24664,"52944":24678,"52945":24686,"52946":25154,"52947":25155,"52948":25295,"52949":25357,"52950":25355,"52951":25333,"52952":25358,"52953":25347,"52954":25323,"52955":25337,"52956":25359,"52957":25356,"52958":25336,"52959":25334,"52960":25344,"52961":25363,"52962":25364,"52963":25338,"52964":25365,"52965":25339,"52966":25328,"52967":25921,"52968":25923,"52969":26026,"52970":26047,"52971":26166,"52972":26145,"52973":26162,"52974":26165,"52975":26140,"52976":26150,"52977":26146,"52978":26163,"52979":26155,"52980":26170,"52981":26141,"52982":26164,"52983":26169,"52984":26158,"52985":26383,"52986":26384,"52987":26561,"52988":26610,"52989":26568,"52990":26554,"53056":26588,"53057":26555,"53058":26616,"53059":26584,"53060":26560,"53061":26551,"53062":26565,"53063":26603,"53064":26596,"53065":26591,"53066":26549,"53067":26573,"53068":26547,"53069":26615,"53070":26614,"53071":26606,"53072":26595,"53073":26562,"53074":26553,"53075":26574,"53076":26599,"53077":26608,"53078":26546,"53079":26620,"53080":26566,"53081":26605,"53082":26572,"53083":26542,"53084":26598,"53085":26587,"53086":26618,"53087":26569,"53088":26570,"53089":26563,"53090":26602,"53091":26571,"53092":27432,"53093":27522,"53094":27524,"53095":27574,"53096":27606,"53097":27608,"53098":27616,"53099":27680,"53100":27681,"53101":27944,"53102":27956,"53103":27949,"53104":27935,"53105":27964,"53106":27967,"53107":27922,"53108":27914,"53109":27866,"53110":27955,"53111":27908,"53112":27929,"53113":27962,"53114":27930,"53115":27921,"53116":27904,"53117":27933,"53118":27970,"53153":27905,"53154":27928,"53155":27959,"53156":27907,"53157":27919,"53158":27968,"53159":27911,"53160":27936,"53161":27948,"53162":27912,"53163":27938,"53164":27913,"53165":27920,"53166":28855,"53167":28831,"53168":28862,"53169":28849,"53170":28848,"53171":28833,"53172":28852,"53173":28853,"53174":28841,"53175":29249,"53176":29257,"53177":29258,"53178":29292,"53179":29296,"53180":29299,"53181":29294,"53182":29386,"53183":29412,"53184":29416,"53185":29419,"53186":29407,"53187":29418,"53188":29414,"53189":29411,"53190":29573,"53191":29644,"53192":29634,"53193":29640,"53194":29637,"53195":29625,"53196":29622,"53197":29621,"53198":29620,"53199":29675,"53200":29631,"53201":29639,"53202":29630,"53203":29635,"53204":29638,"53205":29624,"53206":29643,"53207":29932,"53208":29934,"53209":29998,"53210":30023,"53211":30024,"53212":30119,"53213":30122,"53214":30329,"53215":30404,"53216":30472,"53217":30467,"53218":30468,"53219":30469,"53220":30474,"53221":30455,"53222":30459,"53223":30458,"53224":30695,"53225":30696,"53226":30726,"53227":30737,"53228":30738,"53229":30725,"53230":30736,"53231":30735,"53232":30734,"53233":30729,"53234":30723,"53235":30739,"53236":31050,"53237":31052,"53238":31051,"53239":31045,"53240":31044,"53241":31189,"53242":31181,"53243":31183,"53244":31190,"53245":31182,"53246":31360,"53312":31358,"53313":31441,"53314":31488,"53315":31489,"53316":31866,"53317":31864,"53318":31865,"53319":31871,"53320":31872,"53321":31873,"53322":32003,"53323":32008,"53324":32001,"53325":32600,"53326":32657,"53327":32653,"53328":32702,"53329":32775,"53330":32782,"53331":32783,"53332":32788,"53333":32823,"53334":32984,"53335":32967,"53336":32992,"53337":32977,"53338":32968,"53339":32962,"53340":32976,"53341":32965,"53342":32995,"53343":32985,"53344":32988,"53345":32970,"53346":32981,"53347":32969,"53348":32975,"53349":32983,"53350":32998,"53351":32973,"53352":33279,"53353":33313,"53354":33428,"53355":33497,"53356":33534,"53357":33529,"53358":33543,"53359":33512,"53360":33536,"53361":33493,"53362":33594,"53363":33515,"53364":33494,"53365":33524,"53366":33516,"53367":33505,"53368":33522,"53369":33525,"53370":33548,"53371":33531,"53372":33526,"53373":33520,"53374":33514,"53409":33508,"53410":33504,"53411":33530,"53412":33523,"53413":33517,"53414":34423,"53415":34420,"53416":34428,"53417":34419,"53418":34881,"53419":34894,"53420":34919,"53421":34922,"53422":34921,"53423":35283,"53424":35332,"53425":35335,"53426":36210,"53427":36835,"53428":36833,"53429":36846,"53430":36832,"53431":37105,"53432":37053,"53433":37055,"53434":37077,"53435":37061,"53436":37054,"53437":37063,"53438":37067,"53439":37064,"53440":37332,"53441":37331,"53442":38484,"53443":38479,"53444":38481,"53445":38483,"53446":38474,"53447":38478,"53448":20510,"53449":20485,"53450":20487,"53451":20499,"53452":20514,"53453":20528,"53454":20507,"53455":20469,"53456":20468,"53457":20531,"53458":20535,"53459":20524,"53460":20470,"53461":20471,"53462":20503,"53463":20508,"53464":20512,"53465":20519,"53466":20533,"53467":20527,"53468":20529,"53469":20494,"53470":20826,"53471":20884,"53472":20883,"53473":20938,"53474":20932,"53475":20933,"53476":20936,"53477":20942,"53478":21089,"53479":21082,"53480":21074,"53481":21086,"53482":21087,"53483":21077,"53484":21090,"53485":21197,"53486":21262,"53487":21406,"53488":21798,"53489":21730,"53490":21783,"53491":21778,"53492":21735,"53493":21747,"53494":21732,"53495":21786,"53496":21759,"53497":21764,"53498":21768,"53499":21739,"53500":21777,"53501":21765,"53502":21745,"53568":21770,"53569":21755,"53570":21751,"53571":21752,"53572":21728,"53573":21774,"53574":21763,"53575":21771,"53576":22273,"53577":22274,"53578":22476,"53579":22578,"53580":22485,"53581":22482,"53582":22458,"53583":22470,"53584":22461,"53585":22460,"53586":22456,"53587":22454,"53588":22463,"53589":22471,"53590":22480,"53591":22457,"53592":22465,"53593":22798,"53594":22858,"53595":23065,"53596":23062,"53597":23085,"53598":23086,"53599":23061,"53600":23055,"53601":23063,"53602":23050,"53603":23070,"53604":23091,"53605":23404,"53606":23463,"53607":23469,"53608":23468,"53609":23555,"53610":23638,"53611":23636,"53612":23788,"53613":23807,"53614":23790,"53615":23793,"53616":23799,"53617":23808,"53618":23801,"53619":24105,"53620":24104,"53621":24232,"53622":24238,"53623":24234,"53624":24236,"53625":24371,"53626":24368,"53627":24423,"53628":24669,"53629":24666,"53630":24679,"53665":24641,"53666":24738,"53667":24712,"53668":24704,"53669":24722,"53670":24705,"53671":24733,"53672":24707,"53673":24725,"53674":24731,"53675":24727,"53676":24711,"53677":24732,"53678":24718,"53679":25113,"53680":25158,"53681":25330,"53682":25360,"53683":25430,"53684":25388,"53685":25412,"53686":25413,"53687":25398,"53688":25411,"53689":25572,"53690":25401,"53691":25419,"53692":25418,"53693":25404,"53694":25385,"53695":25409,"53696":25396,"53697":25432,"53698":25428,"53699":25433,"53700":25389,"53701":25415,"53702":25395,"53703":25434,"53704":25425,"53705":25400,"53706":25431,"53707":25408,"53708":25416,"53709":25930,"53710":25926,"53711":26054,"53712":26051,"53713":26052,"53714":26050,"53715":26186,"53716":26207,"53717":26183,"53718":26193,"53719":26386,"53720":26387,"53721":26655,"53722":26650,"53723":26697,"53724":26674,"53725":26675,"53726":26683,"53727":26699,"53728":26703,"53729":26646,"53730":26673,"53731":26652,"53732":26677,"53733":26667,"53734":26669,"53735":26671,"53736":26702,"53737":26692,"53738":26676,"53739":26653,"53740":26642,"53741":26644,"53742":26662,"53743":26664,"53744":26670,"53745":26701,"53746":26682,"53747":26661,"53748":26656,"53749":27436,"53750":27439,"53751":27437,"53752":27441,"53753":27444,"53754":27501,"53755":32898,"53756":27528,"53757":27622,"53758":27620,"53824":27624,"53825":27619,"53826":27618,"53827":27623,"53828":27685,"53829":28026,"53830":28003,"53831":28004,"53832":28022,"53833":27917,"53834":28001,"53835":28050,"53836":27992,"53837":28002,"53838":28013,"53839":28015,"53840":28049,"53841":28045,"53842":28143,"53843":28031,"53844":28038,"53845":27998,"53846":28007,"53847":28000,"53848":28055,"53849":28016,"53850":28028,"53851":27999,"53852":28034,"53853":28056,"53854":27951,"53855":28008,"53856":28043,"53857":28030,"53858":28032,"53859":28036,"53860":27926,"53861":28035,"53862":28027,"53863":28029,"53864":28021,"53865":28048,"53866":28892,"53867":28883,"53868":28881,"53869":28893,"53870":28875,"53871":32569,"53872":28898,"53873":28887,"53874":28882,"53875":28894,"53876":28896,"53877":28884,"53878":28877,"53879":28869,"53880":28870,"53881":28871,"53882":28890,"53883":28878,"53884":28897,"53885":29250,"53886":29304,"53921":29303,"53922":29302,"53923":29440,"53924":29434,"53925":29428,"53926":29438,"53927":29430,"53928":29427,"53929":29435,"53930":29441,"53931":29651,"53932":29657,"53933":29669,"53934":29654,"53935":29628,"53936":29671,"53937":29667,"53938":29673,"53939":29660,"53940":29650,"53941":29659,"53942":29652,"53943":29661,"53944":29658,"53945":29655,"53946":29656,"53947":29672,"53948":29918,"53949":29919,"53950":29940,"53951":29941,"53952":29985,"53953":30043,"53954":30047,"53955":30128,"53956":30145,"53957":30139,"53958":30148,"53959":30144,"53960":30143,"53961":30134,"53962":30138,"53963":30346,"53964":30409,"53965":30493,"53966":30491,"53967":30480,"53968":30483,"53969":30482,"53970":30499,"53971":30481,"53972":30485,"53973":30489,"53974":30490,"53975":30498,"53976":30503,"53977":30755,"53978":30764,"53979":30754,"53980":30773,"53981":30767,"53982":30760,"53983":30766,"53984":30763,"53985":30753,"53986":30761,"53987":30771,"53988":30762,"53989":30769,"53990":31060,"53991":31067,"53992":31055,"53993":31068,"53994":31059,"53995":31058,"53996":31057,"53997":31211,"53998":31212,"53999":31200,"54000":31214,"54001":31213,"54002":31210,"54003":31196,"54004":31198,"54005":31197,"54006":31366,"54007":31369,"54008":31365,"54009":31371,"54010":31372,"54011":31370,"54012":31367,"54013":31448,"54014":31504,"54080":31492,"54081":31507,"54082":31493,"54083":31503,"54084":31496,"54085":31498,"54086":31502,"54087":31497,"54088":31506,"54089":31876,"54090":31889,"54091":31882,"54092":31884,"54093":31880,"54094":31885,"54095":31877,"54096":32030,"54097":32029,"54098":32017,"54099":32014,"54100":32024,"54101":32022,"54102":32019,"54103":32031,"54104":32018,"54105":32015,"54106":32012,"54107":32604,"54108":32609,"54109":32606,"54110":32608,"54111":32605,"54112":32603,"54113":32662,"54114":32658,"54115":32707,"54116":32706,"54117":32704,"54118":32790,"54119":32830,"54120":32825,"54121":33018,"54122":33010,"54123":33017,"54124":33013,"54125":33025,"54126":33019,"54127":33024,"54128":33281,"54129":33327,"54130":33317,"54131":33587,"54132":33581,"54133":33604,"54134":33561,"54135":33617,"54136":33573,"54137":33622,"54138":33599,"54139":33601,"54140":33574,"54141":33564,"54142":33570,"54177":33602,"54178":33614,"54179":33563,"54180":33578,"54181":33544,"54182":33596,"54183":33613,"54184":33558,"54185":33572,"54186":33568,"54187":33591,"54188":33583,"54189":33577,"54190":33607,"54191":33605,"54192":33612,"54193":33619,"54194":33566,"54195":33580,"54196":33611,"54197":33575,"54198":33608,"54199":34387,"54200":34386,"54201":34466,"54202":34472,"54203":34454,"54204":34445,"54205":34449,"54206":34462,"54207":34439,"54208":34455,"54209":34438,"54210":34443,"54211":34458,"54212":34437,"54213":34469,"54214":34457,"54215":34465,"54216":34471,"54217":34453,"54218":34456,"54219":34446,"54220":34461,"54221":34448,"54222":34452,"54223":34883,"54224":34884,"54225":34925,"54226":34933,"54227":34934,"54228":34930,"54229":34944,"54230":34929,"54231":34943,"54232":34927,"54233":34947,"54234":34942,"54235":34932,"54236":34940,"54237":35346,"54238":35911,"54239":35927,"54240":35963,"54241":36004,"54242":36003,"54243":36214,"54244":36216,"54245":36277,"54246":36279,"54247":36278,"54248":36561,"54249":36563,"54250":36862,"54251":36853,"54252":36866,"54253":36863,"54254":36859,"54255":36868,"54256":36860,"54257":36854,"54258":37078,"54259":37088,"54260":37081,"54261":37082,"54262":37091,"54263":37087,"54264":37093,"54265":37080,"54266":37083,"54267":37079,"54268":37084,"54269":37092,"54270":37200,"54336":37198,"54337":37199,"54338":37333,"54339":37346,"54340":37338,"54341":38492,"54342":38495,"54343":38588,"54344":39139,"54345":39647,"54346":39727,"54347":20095,"54348":20592,"54349":20586,"54350":20577,"54351":20574,"54352":20576,"54353":20563,"54354":20555,"54355":20573,"54356":20594,"54357":20552,"54358":20557,"54359":20545,"54360":20571,"54361":20554,"54362":20578,"54363":20501,"54364":20549,"54365":20575,"54366":20585,"54367":20587,"54368":20579,"54369":20580,"54370":20550,"54371":20544,"54372":20590,"54373":20595,"54374":20567,"54375":20561,"54376":20944,"54377":21099,"54378":21101,"54379":21100,"54380":21102,"54381":21206,"54382":21203,"54383":21293,"54384":21404,"54385":21877,"54386":21878,"54387":21820,"54388":21837,"54389":21840,"54390":21812,"54391":21802,"54392":21841,"54393":21858,"54394":21814,"54395":21813,"54396":21808,"54397":21842,"54398":21829,"54433":21772,"54434":21810,"54435":21861,"54436":21838,"54437":21817,"54438":21832,"54439":21805,"54440":21819,"54441":21824,"54442":21835,"54443":22282,"54444":22279,"54445":22523,"54446":22548,"54447":22498,"54448":22518,"54449":22492,"54450":22516,"54451":22528,"54452":22509,"54453":22525,"54454":22536,"54455":22520,"54456":22539,"54457":22515,"54458":22479,"54459":22535,"54460":22510,"54461":22499,"54462":22514,"54463":22501,"54464":22508,"54465":22497,"54466":22542,"54467":22524,"54468":22544,"54469":22503,"54470":22529,"54471":22540,"54472":22513,"54473":22505,"54474":22512,"54475":22541,"54476":22532,"54477":22876,"54478":23136,"54479":23128,"54480":23125,"54481":23143,"54482":23134,"54483":23096,"54484":23093,"54485":23149,"54486":23120,"54487":23135,"54488":23141,"54489":23148,"54490":23123,"54491":23140,"54492":23127,"54493":23107,"54494":23133,"54495":23122,"54496":23108,"54497":23131,"54498":23112,"54499":23182,"54500":23102,"54501":23117,"54502":23097,"54503":23116,"54504":23152,"54505":23145,"54506":23111,"54507":23121,"54508":23126,"54509":23106,"54510":23132,"54511":23410,"54512":23406,"54513":23489,"54514":23488,"54515":23641,"54516":23838,"54517":23819,"54518":23837,"54519":23834,"54520":23840,"54521":23820,"54522":23848,"54523":23821,"54524":23846,"54525":23845,"54526":23823,"54592":23856,"54593":23826,"54594":23843,"54595":23839,"54596":23854,"54597":24126,"54598":24116,"54599":24241,"54600":24244,"54601":24249,"54602":24242,"54603":24243,"54604":24374,"54605":24376,"54606":24475,"54607":24470,"54608":24479,"54609":24714,"54610":24720,"54611":24710,"54612":24766,"54613":24752,"54614":24762,"54615":24787,"54616":24788,"54617":24783,"54618":24804,"54619":24793,"54620":24797,"54621":24776,"54622":24753,"54623":24795,"54624":24759,"54625":24778,"54626":24767,"54627":24771,"54628":24781,"54629":24768,"54630":25394,"54631":25445,"54632":25482,"54633":25474,"54634":25469,"54635":25533,"54636":25502,"54637":25517,"54638":25501,"54639":25495,"54640":25515,"54641":25486,"54642":25455,"54643":25479,"54644":25488,"54645":25454,"54646":25519,"54647":25461,"54648":25500,"54649":25453,"54650":25518,"54651":25468,"54652":25508,"54653":25403,"54654":25503,"54689":25464,"54690":25477,"54691":25473,"54692":25489,"54693":25485,"54694":25456,"54695":25939,"54696":26061,"54697":26213,"54698":26209,"54699":26203,"54700":26201,"54701":26204,"54702":26210,"54703":26392,"54704":26745,"54705":26759,"54706":26768,"54707":26780,"54708":26733,"54709":26734,"54710":26798,"54711":26795,"54712":26966,"54713":26735,"54714":26787,"54715":26796,"54716":26793,"54717":26741,"54718":26740,"54719":26802,"54720":26767,"54721":26743,"54722":26770,"54723":26748,"54724":26731,"54725":26738,"54726":26794,"54727":26752,"54728":26737,"54729":26750,"54730":26779,"54731":26774,"54732":26763,"54733":26784,"54734":26761,"54735":26788,"54736":26744,"54737":26747,"54738":26769,"54739":26764,"54740":26762,"54741":26749,"54742":27446,"54743":27443,"54744":27447,"54745":27448,"54746":27537,"54747":27535,"54748":27533,"54749":27534,"54750":27532,"54751":27690,"54752":28096,"54753":28075,"54754":28084,"54755":28083,"54756":28276,"54757":28076,"54758":28137,"54759":28130,"54760":28087,"54761":28150,"54762":28116,"54763":28160,"54764":28104,"54765":28128,"54766":28127,"54767":28118,"54768":28094,"54769":28133,"54770":28124,"54771":28125,"54772":28123,"54773":28148,"54774":28106,"54775":28093,"54776":28141,"54777":28144,"54778":28090,"54779":28117,"54780":28098,"54781":28111,"54782":28105,"54848":28112,"54849":28146,"54850":28115,"54851":28157,"54852":28119,"54853":28109,"54854":28131,"54855":28091,"54856":28922,"54857":28941,"54858":28919,"54859":28951,"54860":28916,"54861":28940,"54862":28912,"54863":28932,"54864":28915,"54865":28944,"54866":28924,"54867":28927,"54868":28934,"54869":28947,"54870":28928,"54871":28920,"54872":28918,"54873":28939,"54874":28930,"54875":28942,"54876":29310,"54877":29307,"54878":29308,"54879":29311,"54880":29469,"54881":29463,"54882":29447,"54883":29457,"54884":29464,"54885":29450,"54886":29448,"54887":29439,"54888":29455,"54889":29470,"54890":29576,"54891":29686,"54892":29688,"54893":29685,"54894":29700,"54895":29697,"54896":29693,"54897":29703,"54898":29696,"54899":29690,"54900":29692,"54901":29695,"54902":29708,"54903":29707,"54904":29684,"54905":29704,"54906":30052,"54907":30051,"54908":30158,"54909":30162,"54910":30159,"54945":30155,"54946":30156,"54947":30161,"54948":30160,"54949":30351,"54950":30345,"54951":30419,"54952":30521,"54953":30511,"54954":30509,"54955":30513,"54956":30514,"54957":30516,"54958":30515,"54959":30525,"54960":30501,"54961":30523,"54962":30517,"54963":30792,"54964":30802,"54965":30793,"54966":30797,"54967":30794,"54968":30796,"54969":30758,"54970":30789,"54971":30800,"54972":31076,"54973":31079,"54974":31081,"54975":31082,"54976":31075,"54977":31083,"54978":31073,"54979":31163,"54980":31226,"54981":31224,"54982":31222,"54983":31223,"54984":31375,"54985":31380,"54986":31376,"54987":31541,"54988":31559,"54989":31540,"54990":31525,"54991":31536,"54992":31522,"54993":31524,"54994":31539,"54995":31512,"54996":31530,"54997":31517,"54998":31537,"54999":31531,"55000":31533,"55001":31535,"55002":31538,"55003":31544,"55004":31514,"55005":31523,"55006":31892,"55007":31896,"55008":31894,"55009":31907,"55010":32053,"55011":32061,"55012":32056,"55013":32054,"55014":32058,"55015":32069,"55016":32044,"55017":32041,"55018":32065,"55019":32071,"55020":32062,"55021":32063,"55022":32074,"55023":32059,"55024":32040,"55025":32611,"55026":32661,"55027":32668,"55028":32669,"55029":32667,"55030":32714,"55031":32715,"55032":32717,"55033":32720,"55034":32721,"55035":32711,"55036":32719,"55037":32713,"55038":32799,"55104":32798,"55105":32795,"55106":32839,"55107":32835,"55108":32840,"55109":33048,"55110":33061,"55111":33049,"55112":33051,"55113":33069,"55114":33055,"55115":33068,"55116":33054,"55117":33057,"55118":33045,"55119":33063,"55120":33053,"55121":33058,"55122":33297,"55123":33336,"55124":33331,"55125":33338,"55126":33332,"55127":33330,"55128":33396,"55129":33680,"55130":33699,"55131":33704,"55132":33677,"55133":33658,"55134":33651,"55135":33700,"55136":33652,"55137":33679,"55138":33665,"55139":33685,"55140":33689,"55141":33653,"55142":33684,"55143":33705,"55144":33661,"55145":33667,"55146":33676,"55147":33693,"55148":33691,"55149":33706,"55150":33675,"55151":33662,"55152":33701,"55153":33711,"55154":33672,"55155":33687,"55156":33712,"55157":33663,"55158":33702,"55159":33671,"55160":33710,"55161":33654,"55162":33690,"55163":34393,"55164":34390,"55165":34495,"55166":34487,"55201":34498,"55202":34497,"55203":34501,"55204":34490,"55205":34480,"55206":34504,"55207":34489,"55208":34483,"55209":34488,"55210":34508,"55211":34484,"55212":34491,"55213":34492,"55214":34499,"55215":34493,"55216":34494,"55217":34898,"55218":34953,"55219":34965,"55220":34984,"55221":34978,"55222":34986,"55223":34970,"55224":34961,"55225":34977,"55226":34975,"55227":34968,"55228":34983,"55229":34969,"55230":34971,"55231":34967,"55232":34980,"55233":34988,"55234":34956,"55235":34963,"55236":34958,"55237":35202,"55238":35286,"55239":35289,"55240":35285,"55241":35376,"55242":35367,"55243":35372,"55244":35358,"55245":35897,"55246":35899,"55247":35932,"55248":35933,"55249":35965,"55250":36005,"55251":36221,"55252":36219,"55253":36217,"55254":36284,"55255":36290,"55256":36281,"55257":36287,"55258":36289,"55259":36568,"55260":36574,"55261":36573,"55262":36572,"55263":36567,"55264":36576,"55265":36577,"55266":36900,"55267":36875,"55268":36881,"55269":36892,"55270":36876,"55271":36897,"55272":37103,"55273":37098,"55274":37104,"55275":37108,"55276":37106,"55277":37107,"55278":37076,"55279":37099,"55280":37100,"55281":37097,"55282":37206,"55283":37208,"55284":37210,"55285":37203,"55286":37205,"55287":37356,"55288":37364,"55289":37361,"55290":37363,"55291":37368,"55292":37348,"55293":37369,"55294":37354,"55360":37355,"55361":37367,"55362":37352,"55363":37358,"55364":38266,"55365":38278,"55366":38280,"55367":38524,"55368":38509,"55369":38507,"55370":38513,"55371":38511,"55372":38591,"55373":38762,"55374":38916,"55375":39141,"55376":39319,"55377":20635,"55378":20629,"55379":20628,"55380":20638,"55381":20619,"55382":20643,"55383":20611,"55384":20620,"55385":20622,"55386":20637,"55387":20584,"55388":20636,"55389":20626,"55390":20610,"55391":20615,"55392":20831,"55393":20948,"55394":21266,"55395":21265,"55396":21412,"55397":21415,"55398":21905,"55399":21928,"55400":21925,"55401":21933,"55402":21879,"55403":22085,"55404":21922,"55405":21907,"55406":21896,"55407":21903,"55408":21941,"55409":21889,"55410":21923,"55411":21906,"55412":21924,"55413":21885,"55414":21900,"55415":21926,"55416":21887,"55417":21909,"55418":21921,"55419":21902,"55420":22284,"55421":22569,"55422":22583,"55457":22553,"55458":22558,"55459":22567,"55460":22563,"55461":22568,"55462":22517,"55463":22600,"55464":22565,"55465":22556,"55466":22555,"55467":22579,"55468":22591,"55469":22582,"55470":22574,"55471":22585,"55472":22584,"55473":22573,"55474":22572,"55475":22587,"55476":22881,"55477":23215,"55478":23188,"55479":23199,"55480":23162,"55481":23202,"55482":23198,"55483":23160,"55484":23206,"55485":23164,"55486":23205,"55487":23212,"55488":23189,"55489":23214,"55490":23095,"55491":23172,"55492":23178,"55493":23191,"55494":23171,"55495":23179,"55496":23209,"55497":23163,"55498":23165,"55499":23180,"55500":23196,"55501":23183,"55502":23187,"55503":23197,"55504":23530,"55505":23501,"55506":23499,"55507":23508,"55508":23505,"55509":23498,"55510":23502,"55511":23564,"55512":23600,"55513":23863,"55514":23875,"55515":23915,"55516":23873,"55517":23883,"55518":23871,"55519":23861,"55520":23889,"55521":23886,"55522":23893,"55523":23859,"55524":23866,"55525":23890,"55526":23869,"55527":23857,"55528":23897,"55529":23874,"55530":23865,"55531":23881,"55532":23864,"55533":23868,"55534":23858,"55535":23862,"55536":23872,"55537":23877,"55538":24132,"55539":24129,"55540":24408,"55541":24486,"55542":24485,"55543":24491,"55544":24777,"55545":24761,"55546":24780,"55547":24802,"55548":24782,"55549":24772,"55550":24852,"55616":24818,"55617":24842,"55618":24854,"55619":24837,"55620":24821,"55621":24851,"55622":24824,"55623":24828,"55624":24830,"55625":24769,"55626":24835,"55627":24856,"55628":24861,"55629":24848,"55630":24831,"55631":24836,"55632":24843,"55633":25162,"55634":25492,"55635":25521,"55636":25520,"55637":25550,"55638":25573,"55639":25576,"55640":25583,"55641":25539,"55642":25757,"55643":25587,"55644":25546,"55645":25568,"55646":25590,"55647":25557,"55648":25586,"55649":25589,"55650":25697,"55651":25567,"55652":25534,"55653":25565,"55654":25564,"55655":25540,"55656":25560,"55657":25555,"55658":25538,"55659":25543,"55660":25548,"55661":25547,"55662":25544,"55663":25584,"55664":25559,"55665":25561,"55666":25906,"55667":25959,"55668":25962,"55669":25956,"55670":25948,"55671":25960,"55672":25957,"55673":25996,"55674":26013,"55675":26014,"55676":26030,"55677":26064,"55678":26066,"55713":26236,"55714":26220,"55715":26235,"55716":26240,"55717":26225,"55718":26233,"55719":26218,"55720":26226,"55721":26369,"55722":26892,"55723":26835,"55724":26884,"55725":26844,"55726":26922,"55727":26860,"55728":26858,"55729":26865,"55730":26895,"55731":26838,"55732":26871,"55733":26859,"55734":26852,"55735":26870,"55736":26899,"55737":26896,"55738":26867,"55739":26849,"55740":26887,"55741":26828,"55742":26888,"55743":26992,"55744":26804,"55745":26897,"55746":26863,"55747":26822,"55748":26900,"55749":26872,"55750":26832,"55751":26877,"55752":26876,"55753":26856,"55754":26891,"55755":26890,"55756":26903,"55757":26830,"55758":26824,"55759":26845,"55760":26846,"55761":26854,"55762":26868,"55763":26833,"55764":26886,"55765":26836,"55766":26857,"55767":26901,"55768":26917,"55769":26823,"55770":27449,"55771":27451,"55772":27455,"55773":27452,"55774":27540,"55775":27543,"55776":27545,"55777":27541,"55778":27581,"55779":27632,"55780":27634,"55781":27635,"55782":27696,"55783":28156,"55784":28230,"55785":28231,"55786":28191,"55787":28233,"55788":28296,"55789":28220,"55790":28221,"55791":28229,"55792":28258,"55793":28203,"55794":28223,"55795":28225,"55796":28253,"55797":28275,"55798":28188,"55799":28211,"55800":28235,"55801":28224,"55802":28241,"55803":28219,"55804":28163,"55805":28206,"55806":28254,"55872":28264,"55873":28252,"55874":28257,"55875":28209,"55876":28200,"55877":28256,"55878":28273,"55879":28267,"55880":28217,"55881":28194,"55882":28208,"55883":28243,"55884":28261,"55885":28199,"55886":28280,"55887":28260,"55888":28279,"55889":28245,"55890":28281,"55891":28242,"55892":28262,"55893":28213,"55894":28214,"55895":28250,"55896":28960,"55897":28958,"55898":28975,"55899":28923,"55900":28974,"55901":28977,"55902":28963,"55903":28965,"55904":28962,"55905":28978,"55906":28959,"55907":28968,"55908":28986,"55909":28955,"55910":29259,"55911":29274,"55912":29320,"55913":29321,"55914":29318,"55915":29317,"55916":29323,"55917":29458,"55918":29451,"55919":29488,"55920":29474,"55921":29489,"55922":29491,"55923":29479,"55924":29490,"55925":29485,"55926":29478,"55927":29475,"55928":29493,"55929":29452,"55930":29742,"55931":29740,"55932":29744,"55933":29739,"55934":29718,"55969":29722,"55970":29729,"55971":29741,"55972":29745,"55973":29732,"55974":29731,"55975":29725,"55976":29737,"55977":29728,"55978":29746,"55979":29947,"55980":29999,"55981":30063,"55982":30060,"55983":30183,"55984":30170,"55985":30177,"55986":30182,"55987":30173,"55988":30175,"55989":30180,"55990":30167,"55991":30357,"55992":30354,"55993":30426,"55994":30534,"55995":30535,"55996":30532,"55997":30541,"55998":30533,"55999":30538,"56000":30542,"56001":30539,"56002":30540,"56003":30686,"56004":30700,"56005":30816,"56006":30820,"56007":30821,"56008":30812,"56009":30829,"56010":30833,"56011":30826,"56012":30830,"56013":30832,"56014":30825,"56015":30824,"56016":30814,"56017":30818,"56018":31092,"56019":31091,"56020":31090,"56021":31088,"56022":31234,"56023":31242,"56024":31235,"56025":31244,"56026":31236,"56027":31385,"56028":31462,"56029":31460,"56030":31562,"56031":31547,"56032":31556,"56033":31560,"56034":31564,"56035":31566,"56036":31552,"56037":31576,"56038":31557,"56039":31906,"56040":31902,"56041":31912,"56042":31905,"56043":32088,"56044":32111,"56045":32099,"56046":32083,"56047":32086,"56048":32103,"56049":32106,"56050":32079,"56051":32109,"56052":32092,"56053":32107,"56054":32082,"56055":32084,"56056":32105,"56057":32081,"56058":32095,"56059":32078,"56060":32574,"56061":32575,"56062":32613,"56128":32614,"56129":32674,"56130":32672,"56131":32673,"56132":32727,"56133":32849,"56134":32847,"56135":32848,"56136":33022,"56137":32980,"56138":33091,"56139":33098,"56140":33106,"56141":33103,"56142":33095,"56143":33085,"56144":33101,"56145":33082,"56146":33254,"56147":33262,"56148":33271,"56149":33272,"56150":33273,"56151":33284,"56152":33340,"56153":33341,"56154":33343,"56155":33397,"56156":33595,"56157":33743,"56158":33785,"56159":33827,"56160":33728,"56161":33768,"56162":33810,"56163":33767,"56164":33764,"56165":33788,"56166":33782,"56167":33808,"56168":33734,"56169":33736,"56170":33771,"56171":33763,"56172":33727,"56173":33793,"56174":33757,"56175":33765,"56176":33752,"56177":33791,"56178":33761,"56179":33739,"56180":33742,"56181":33750,"56182":33781,"56183":33737,"56184":33801,"56185":33807,"56186":33758,"56187":33809,"56188":33798,"56189":33730,"56190":33779,"56225":33749,"56226":33786,"56227":33735,"56228":33745,"56229":33770,"56230":33811,"56231":33731,"56232":33772,"56233":33774,"56234":33732,"56235":33787,"56236":33751,"56237":33762,"56238":33819,"56239":33755,"56240":33790,"56241":34520,"56242":34530,"56243":34534,"56244":34515,"56245":34531,"56246":34522,"56247":34538,"56248":34525,"56249":34539,"56250":34524,"56251":34540,"56252":34537,"56253":34519,"56254":34536,"56255":34513,"56256":34888,"56257":34902,"56258":34901,"56259":35002,"56260":35031,"56261":35001,"56262":35000,"56263":35008,"56264":35006,"56265":34998,"56266":35004,"56267":34999,"56268":35005,"56269":34994,"56270":35073,"56271":35017,"56272":35221,"56273":35224,"56274":35223,"56275":35293,"56276":35290,"56277":35291,"56278":35406,"56279":35405,"56280":35385,"56281":35417,"56282":35392,"56283":35415,"56284":35416,"56285":35396,"56286":35397,"56287":35410,"56288":35400,"56289":35409,"56290":35402,"56291":35404,"56292":35407,"56293":35935,"56294":35969,"56295":35968,"56296":36026,"56297":36030,"56298":36016,"56299":36025,"56300":36021,"56301":36228,"56302":36224,"56303":36233,"56304":36312,"56305":36307,"56306":36301,"56307":36295,"56308":36310,"56309":36316,"56310":36303,"56311":36309,"56312":36313,"56313":36296,"56314":36311,"56315":36293,"56316":36591,"56317":36599,"56318":36602,"56384":36601,"56385":36582,"56386":36590,"56387":36581,"56388":36597,"56389":36583,"56390":36584,"56391":36598,"56392":36587,"56393":36593,"56394":36588,"56395":36596,"56396":36585,"56397":36909,"56398":36916,"56399":36911,"56400":37126,"56401":37164,"56402":37124,"56403":37119,"56404":37116,"56405":37128,"56406":37113,"56407":37115,"56408":37121,"56409":37120,"56410":37127,"56411":37125,"56412":37123,"56413":37217,"56414":37220,"56415":37215,"56416":37218,"56417":37216,"56418":37377,"56419":37386,"56420":37413,"56421":37379,"56422":37402,"56423":37414,"56424":37391,"56425":37388,"56426":37376,"56427":37394,"56428":37375,"56429":37373,"56430":37382,"56431":37380,"56432":37415,"56433":37378,"56434":37404,"56435":37412,"56436":37401,"56437":37399,"56438":37381,"56439":37398,"56440":38267,"56441":38285,"56442":38284,"56443":38288,"56444":38535,"56445":38526,"56446":38536,"56481":38537,"56482":38531,"56483":38528,"56484":38594,"56485":38600,"56486":38595,"56487":38641,"56488":38640,"56489":38764,"56490":38768,"56491":38766,"56492":38919,"56493":39081,"56494":39147,"56495":40166,"56496":40697,"56497":20099,"56498":20100,"56499":20150,"56500":20669,"56501":20671,"56502":20678,"56503":20654,"56504":20676,"56505":20682,"56506":20660,"56507":20680,"56508":20674,"56509":20656,"56510":20673,"56511":20666,"56512":20657,"56513":20683,"56514":20681,"56515":20662,"56516":20664,"56517":20951,"56518":21114,"56519":21112,"56520":21115,"56521":21116,"56522":21955,"56523":21979,"56524":21964,"56525":21968,"56526":21963,"56527":21962,"56528":21981,"56529":21952,"56530":21972,"56531":21956,"56532":21993,"56533":21951,"56534":21970,"56535":21901,"56536":21967,"56537":21973,"56538":21986,"56539":21974,"56540":21960,"56541":22002,"56542":21965,"56543":21977,"56544":21954,"56545":22292,"56546":22611,"56547":22632,"56548":22628,"56549":22607,"56550":22605,"56551":22601,"56552":22639,"56553":22613,"56554":22606,"56555":22621,"56556":22617,"56557":22629,"56558":22619,"56559":22589,"56560":22627,"56561":22641,"56562":22780,"56563":23239,"56564":23236,"56565":23243,"56566":23226,"56567":23224,"56568":23217,"56569":23221,"56570":23216,"56571":23231,"56572":23240,"56573":23227,"56574":23238,"56640":23223,"56641":23232,"56642":23242,"56643":23220,"56644":23222,"56645":23245,"56646":23225,"56647":23184,"56648":23510,"56649":23512,"56650":23513,"56651":23583,"56652":23603,"56653":23921,"56654":23907,"56655":23882,"56656":23909,"56657":23922,"56658":23916,"56659":23902,"56660":23912,"56661":23911,"56662":23906,"56663":24048,"56664":24143,"56665":24142,"56666":24138,"56667":24141,"56668":24139,"56669":24261,"56670":24268,"56671":24262,"56672":24267,"56673":24263,"56674":24384,"56675":24495,"56676":24493,"56677":24823,"56678":24905,"56679":24906,"56680":24875,"56681":24901,"56682":24886,"56683":24882,"56684":24878,"56685":24902,"56686":24879,"56687":24911,"56688":24873,"56689":24896,"56690":25120,"56691":37224,"56692":25123,"56693":25125,"56694":25124,"56695":25541,"56696":25585,"56697":25579,"56698":25616,"56699":25618,"56700":25609,"56701":25632,"56702":25636,"56737":25651,"56738":25667,"56739":25631,"56740":25621,"56741":25624,"56742":25657,"56743":25655,"56744":25634,"56745":25635,"56746":25612,"56747":25638,"56748":25648,"56749":25640,"56750":25665,"56751":25653,"56752":25647,"56753":25610,"56754":25626,"56755":25664,"56756":25637,"56757":25639,"56758":25611,"56759":25575,"56760":25627,"56761":25646,"56762":25633,"56763":25614,"56764":25967,"56765":26002,"56766":26067,"56767":26246,"56768":26252,"56769":26261,"56770":26256,"56771":26251,"56772":26250,"56773":26265,"56774":26260,"56775":26232,"56776":26400,"56777":26982,"56778":26975,"56779":26936,"56780":26958,"56781":26978,"56782":26993,"56783":26943,"56784":26949,"56785":26986,"56786":26937,"56787":26946,"56788":26967,"56789":26969,"56790":27002,"56791":26952,"56792":26953,"56793":26933,"56794":26988,"56795":26931,"56796":26941,"56797":26981,"56798":26864,"56799":27000,"56800":26932,"56801":26985,"56802":26944,"56803":26991,"56804":26948,"56805":26998,"56806":26968,"56807":26945,"56808":26996,"56809":26956,"56810":26939,"56811":26955,"56812":26935,"56813":26972,"56814":26959,"56815":26961,"56816":26930,"56817":26962,"56818":26927,"56819":27003,"56820":26940,"56821":27462,"56822":27461,"56823":27459,"56824":27458,"56825":27464,"56826":27457,"56827":27547,"56828":64013,"56829":27643,"56830":27644,"56896":27641,"56897":27639,"56898":27640,"56899":28315,"56900":28374,"56901":28360,"56902":28303,"56903":28352,"56904":28319,"56905":28307,"56906":28308,"56907":28320,"56908":28337,"56909":28345,"56910":28358,"56911":28370,"56912":28349,"56913":28353,"56914":28318,"56915":28361,"56916":28343,"56917":28336,"56918":28365,"56919":28326,"56920":28367,"56921":28338,"56922":28350,"56923":28355,"56924":28380,"56925":28376,"56926":28313,"56927":28306,"56928":28302,"56929":28301,"56930":28324,"56931":28321,"56932":28351,"56933":28339,"56934":28368,"56935":28362,"56936":28311,"56937":28334,"56938":28323,"56939":28999,"56940":29012,"56941":29010,"56942":29027,"56943":29024,"56944":28993,"56945":29021,"56946":29026,"56947":29042,"56948":29048,"56949":29034,"56950":29025,"56951":28994,"56952":29016,"56953":28995,"56954":29003,"56955":29040,"56956":29023,"56957":29008,"56958":29011,"56993":28996,"56994":29005,"56995":29018,"56996":29263,"56997":29325,"56998":29324,"56999":29329,"57000":29328,"57001":29326,"57002":29500,"57003":29506,"57004":29499,"57005":29498,"57006":29504,"57007":29514,"57008":29513,"57009":29764,"57010":29770,"57011":29771,"57012":29778,"57013":29777,"57014":29783,"57015":29760,"57016":29775,"57017":29776,"57018":29774,"57019":29762,"57020":29766,"57021":29773,"57022":29780,"57023":29921,"57024":29951,"57025":29950,"57026":29949,"57027":29981,"57028":30073,"57029":30071,"57030":27011,"57031":30191,"57032":30223,"57033":30211,"57034":30199,"57035":30206,"57036":30204,"57037":30201,"57038":30200,"57039":30224,"57040":30203,"57041":30198,"57042":30189,"57043":30197,"57044":30205,"57045":30361,"57046":30389,"57047":30429,"57048":30549,"57049":30559,"57050":30560,"57051":30546,"57052":30550,"57053":30554,"57054":30569,"57055":30567,"57056":30548,"57057":30553,"57058":30573,"57059":30688,"57060":30855,"57061":30874,"57062":30868,"57063":30863,"57064":30852,"57065":30869,"57066":30853,"57067":30854,"57068":30881,"57069":30851,"57070":30841,"57071":30873,"57072":30848,"57073":30870,"57074":30843,"57075":31100,"57076":31106,"57077":31101,"57078":31097,"57079":31249,"57080":31256,"57081":31257,"57082":31250,"57083":31255,"57084":31253,"57085":31266,"57086":31251,"57152":31259,"57153":31248,"57154":31395,"57155":31394,"57156":31390,"57157":31467,"57158":31590,"57159":31588,"57160":31597,"57161":31604,"57162":31593,"57163":31602,"57164":31589,"57165":31603,"57166":31601,"57167":31600,"57168":31585,"57169":31608,"57170":31606,"57171":31587,"57172":31922,"57173":31924,"57174":31919,"57175":32136,"57176":32134,"57177":32128,"57178":32141,"57179":32127,"57180":32133,"57181":32122,"57182":32142,"57183":32123,"57184":32131,"57185":32124,"57186":32140,"57187":32148,"57188":32132,"57189":32125,"57190":32146,"57191":32621,"57192":32619,"57193":32615,"57194":32616,"57195":32620,"57196":32678,"57197":32677,"57198":32679,"57199":32731,"57200":32732,"57201":32801,"57202":33124,"57203":33120,"57204":33143,"57205":33116,"57206":33129,"57207":33115,"57208":33122,"57209":33138,"57210":26401,"57211":33118,"57212":33142,"57213":33127,"57214":33135,"57249":33092,"57250":33121,"57251":33309,"57252":33353,"57253":33348,"57254":33344,"57255":33346,"57256":33349,"57257":34033,"57258":33855,"57259":33878,"57260":33910,"57261":33913,"57262":33935,"57263":33933,"57264":33893,"57265":33873,"57266":33856,"57267":33926,"57268":33895,"57269":33840,"57270":33869,"57271":33917,"57272":33882,"57273":33881,"57274":33908,"57275":33907,"57276":33885,"57277":34055,"57278":33886,"57279":33847,"57280":33850,"57281":33844,"57282":33914,"57283":33859,"57284":33912,"57285":33842,"57286":33861,"57287":33833,"57288":33753,"57289":33867,"57290":33839,"57291":33858,"57292":33837,"57293":33887,"57294":33904,"57295":33849,"57296":33870,"57297":33868,"57298":33874,"57299":33903,"57300":33989,"57301":33934,"57302":33851,"57303":33863,"57304":33846,"57305":33843,"57306":33896,"57307":33918,"57308":33860,"57309":33835,"57310":33888,"57311":33876,"57312":33902,"57313":33872,"57314":34571,"57315":34564,"57316":34551,"57317":34572,"57318":34554,"57319":34518,"57320":34549,"57321":34637,"57322":34552,"57323":34574,"57324":34569,"57325":34561,"57326":34550,"57327":34573,"57328":34565,"57329":35030,"57330":35019,"57331":35021,"57332":35022,"57333":35038,"57334":35035,"57335":35034,"57336":35020,"57337":35024,"57338":35205,"57339":35227,"57340":35295,"57341":35301,"57342":35300,"57408":35297,"57409":35296,"57410":35298,"57411":35292,"57412":35302,"57413":35446,"57414":35462,"57415":35455,"57416":35425,"57417":35391,"57418":35447,"57419":35458,"57420":35460,"57421":35445,"57422":35459,"57423":35457,"57424":35444,"57425":35450,"57426":35900,"57427":35915,"57428":35914,"57429":35941,"57430":35940,"57431":35942,"57432":35974,"57433":35972,"57434":35973,"57435":36044,"57436":36200,"57437":36201,"57438":36241,"57439":36236,"57440":36238,"57441":36239,"57442":36237,"57443":36243,"57444":36244,"57445":36240,"57446":36242,"57447":36336,"57448":36320,"57449":36332,"57450":36337,"57451":36334,"57452":36304,"57453":36329,"57454":36323,"57455":36322,"57456":36327,"57457":36338,"57458":36331,"57459":36340,"57460":36614,"57461":36607,"57462":36609,"57463":36608,"57464":36613,"57465":36615,"57466":36616,"57467":36610,"57468":36619,"57469":36946,"57470":36927,"57505":36932,"57506":36937,"57507":36925,"57508":37136,"57509":37133,"57510":37135,"57511":37137,"57512":37142,"57513":37140,"57514":37131,"57515":37134,"57516":37230,"57517":37231,"57518":37448,"57519":37458,"57520":37424,"57521":37434,"57522":37478,"57523":37427,"57524":37477,"57525":37470,"57526":37507,"57527":37422,"57528":37450,"57529":37446,"57530":37485,"57531":37484,"57532":37455,"57533":37472,"57534":37479,"57535":37487,"57536":37430,"57537":37473,"57538":37488,"57539":37425,"57540":37460,"57541":37475,"57542":37456,"57543":37490,"57544":37454,"57545":37459,"57546":37452,"57547":37462,"57548":37426,"57549":38303,"57550":38300,"57551":38302,"57552":38299,"57553":38546,"57554":38547,"57555":38545,"57556":38551,"57557":38606,"57558":38650,"57559":38653,"57560":38648,"57561":38645,"57562":38771,"57563":38775,"57564":38776,"57565":38770,"57566":38927,"57567":38925,"57568":38926,"57569":39084,"57570":39158,"57571":39161,"57572":39343,"57573":39346,"57574":39344,"57575":39349,"57576":39597,"57577":39595,"57578":39771,"57579":40170,"57580":40173,"57581":40167,"57582":40576,"57583":40701,"57584":20710,"57585":20692,"57586":20695,"57587":20712,"57588":20723,"57589":20699,"57590":20714,"57591":20701,"57592":20708,"57593":20691,"57594":20716,"57595":20720,"57596":20719,"57597":20707,"57598":20704,"57664":20952,"57665":21120,"57666":21121,"57667":21225,"57668":21227,"57669":21296,"57670":21420,"57671":22055,"57672":22037,"57673":22028,"57674":22034,"57675":22012,"57676":22031,"57677":22044,"57678":22017,"57679":22035,"57680":22018,"57681":22010,"57682":22045,"57683":22020,"57684":22015,"57685":22009,"57686":22665,"57687":22652,"57688":22672,"57689":22680,"57690":22662,"57691":22657,"57692":22655,"57693":22644,"57694":22667,"57695":22650,"57696":22663,"57697":22673,"57698":22670,"57699":22646,"57700":22658,"57701":22664,"57702":22651,"57703":22676,"57704":22671,"57705":22782,"57706":22891,"57707":23260,"57708":23278,"57709":23269,"57710":23253,"57711":23274,"57712":23258,"57713":23277,"57714":23275,"57715":23283,"57716":23266,"57717":23264,"57718":23259,"57719":23276,"57720":23262,"57721":23261,"57722":23257,"57723":23272,"57724":23263,"57725":23415,"57726":23520,"57761":23523,"57762":23651,"57763":23938,"57764":23936,"57765":23933,"57766":23942,"57767":23930,"57768":23937,"57769":23927,"57770":23946,"57771":23945,"57772":23944,"57773":23934,"57774":23932,"57775":23949,"57776":23929,"57777":23935,"57778":24152,"57779":24153,"57780":24147,"57781":24280,"57782":24273,"57783":24279,"57784":24270,"57785":24284,"57786":24277,"57787":24281,"57788":24274,"57789":24276,"57790":24388,"57791":24387,"57792":24431,"57793":24502,"57794":24876,"57795":24872,"57796":24897,"57797":24926,"57798":24945,"57799":24947,"57800":24914,"57801":24915,"57802":24946,"57803":24940,"57804":24960,"57805":24948,"57806":24916,"57807":24954,"57808":24923,"57809":24933,"57810":24891,"57811":24938,"57812":24929,"57813":24918,"57814":25129,"57815":25127,"57816":25131,"57817":25643,"57818":25677,"57819":25691,"57820":25693,"57821":25716,"57822":25718,"57823":25714,"57824":25715,"57825":25725,"57826":25717,"57827":25702,"57828":25766,"57829":25678,"57830":25730,"57831":25694,"57832":25692,"57833":25675,"57834":25683,"57835":25696,"57836":25680,"57837":25727,"57838":25663,"57839":25708,"57840":25707,"57841":25689,"57842":25701,"57843":25719,"57844":25971,"57845":26016,"57846":26273,"57847":26272,"57848":26271,"57849":26373,"57850":26372,"57851":26402,"57852":27057,"57853":27062,"57854":27081,"57920":27040,"57921":27086,"57922":27030,"57923":27056,"57924":27052,"57925":27068,"57926":27025,"57927":27033,"57928":27022,"57929":27047,"57930":27021,"57931":27049,"57932":27070,"57933":27055,"57934":27071,"57935":27076,"57936":27069,"57937":27044,"57938":27092,"57939":27065,"57940":27082,"57941":27034,"57942":27087,"57943":27059,"57944":27027,"57945":27050,"57946":27041,"57947":27038,"57948":27097,"57949":27031,"57950":27024,"57951":27074,"57952":27061,"57953":27045,"57954":27078,"57955":27466,"57956":27469,"57957":27467,"57958":27550,"57959":27551,"57960":27552,"57961":27587,"57962":27588,"57963":27646,"57964":28366,"57965":28405,"57966":28401,"57967":28419,"57968":28453,"57969":28408,"57970":28471,"57971":28411,"57972":28462,"57973":28425,"57974":28494,"57975":28441,"57976":28442,"57977":28455,"57978":28440,"57979":28475,"57980":28434,"57981":28397,"57982":28426,"58017":28470,"58018":28531,"58019":28409,"58020":28398,"58021":28461,"58022":28480,"58023":28464,"58024":28476,"58025":28469,"58026":28395,"58027":28423,"58028":28430,"58029":28483,"58030":28421,"58031":28413,"58032":28406,"58033":28473,"58034":28444,"58035":28412,"58036":28474,"58037":28447,"58038":28429,"58039":28446,"58040":28424,"58041":28449,"58042":29063,"58043":29072,"58044":29065,"58045":29056,"58046":29061,"58047":29058,"58048":29071,"58049":29051,"58050":29062,"58051":29057,"58052":29079,"58053":29252,"58054":29267,"58055":29335,"58056":29333,"58057":29331,"58058":29507,"58059":29517,"58060":29521,"58061":29516,"58062":29794,"58063":29811,"58064":29809,"58065":29813,"58066":29810,"58067":29799,"58068":29806,"58069":29952,"58070":29954,"58071":29955,"58072":30077,"58073":30096,"58074":30230,"58075":30216,"58076":30220,"58077":30229,"58078":30225,"58079":30218,"58080":30228,"58081":30392,"58082":30593,"58083":30588,"58084":30597,"58085":30594,"58086":30574,"58087":30592,"58088":30575,"58089":30590,"58090":30595,"58091":30898,"58092":30890,"58093":30900,"58094":30893,"58095":30888,"58096":30846,"58097":30891,"58098":30878,"58099":30885,"58100":30880,"58101":30892,"58102":30882,"58103":30884,"58104":31128,"58105":31114,"58106":31115,"58107":31126,"58108":31125,"58109":31124,"58110":31123,"58176":31127,"58177":31112,"58178":31122,"58179":31120,"58180":31275,"58181":31306,"58182":31280,"58183":31279,"58184":31272,"58185":31270,"58186":31400,"58187":31403,"58188":31404,"58189":31470,"58190":31624,"58191":31644,"58192":31626,"58193":31633,"58194":31632,"58195":31638,"58196":31629,"58197":31628,"58198":31643,"58199":31630,"58200":31621,"58201":31640,"58202":21124,"58203":31641,"58204":31652,"58205":31618,"58206":31931,"58207":31935,"58208":31932,"58209":31930,"58210":32167,"58211":32183,"58212":32194,"58213":32163,"58214":32170,"58215":32193,"58216":32192,"58217":32197,"58218":32157,"58219":32206,"58220":32196,"58221":32198,"58222":32203,"58223":32204,"58224":32175,"58225":32185,"58226":32150,"58227":32188,"58228":32159,"58229":32166,"58230":32174,"58231":32169,"58232":32161,"58233":32201,"58234":32627,"58235":32738,"58236":32739,"58237":32741,"58238":32734,"58273":32804,"58274":32861,"58275":32860,"58276":33161,"58277":33158,"58278":33155,"58279":33159,"58280":33165,"58281":33164,"58282":33163,"58283":33301,"58284":33943,"58285":33956,"58286":33953,"58287":33951,"58288":33978,"58289":33998,"58290":33986,"58291":33964,"58292":33966,"58293":33963,"58294":33977,"58295":33972,"58296":33985,"58297":33997,"58298":33962,"58299":33946,"58300":33969,"58301":34000,"58302":33949,"58303":33959,"58304":33979,"58305":33954,"58306":33940,"58307":33991,"58308":33996,"58309":33947,"58310":33961,"58311":33967,"58312":33960,"58313":34006,"58314":33944,"58315":33974,"58316":33999,"58317":33952,"58318":34007,"58319":34004,"58320":34002,"58321":34011,"58322":33968,"58323":33937,"58324":34401,"58325":34611,"58326":34595,"58327":34600,"58328":34667,"58329":34624,"58330":34606,"58331":34590,"58332":34593,"58333":34585,"58334":34587,"58335":34627,"58336":34604,"58337":34625,"58338":34622,"58339":34630,"58340":34592,"58341":34610,"58342":34602,"58343":34605,"58344":34620,"58345":34578,"58346":34618,"58347":34609,"58348":34613,"58349":34626,"58350":34598,"58351":34599,"58352":34616,"58353":34596,"58354":34586,"58355":34608,"58356":34577,"58357":35063,"58358":35047,"58359":35057,"58360":35058,"58361":35066,"58362":35070,"58363":35054,"58364":35068,"58365":35062,"58366":35067,"58432":35056,"58433":35052,"58434":35051,"58435":35229,"58436":35233,"58437":35231,"58438":35230,"58439":35305,"58440":35307,"58441":35304,"58442":35499,"58443":35481,"58444":35467,"58445":35474,"58446":35471,"58447":35478,"58448":35901,"58449":35944,"58450":35945,"58451":36053,"58452":36047,"58453":36055,"58454":36246,"58455":36361,"58456":36354,"58457":36351,"58458":36365,"58459":36349,"58460":36362,"58461":36355,"58462":36359,"58463":36358,"58464":36357,"58465":36350,"58466":36352,"58467":36356,"58468":36624,"58469":36625,"58470":36622,"58471":36621,"58472":37155,"58473":37148,"58474":37152,"58475":37154,"58476":37151,"58477":37149,"58478":37146,"58479":37156,"58480":37153,"58481":37147,"58482":37242,"58483":37234,"58484":37241,"58485":37235,"58486":37541,"58487":37540,"58488":37494,"58489":37531,"58490":37498,"58491":37536,"58492":37524,"58493":37546,"58494":37517,"58529":37542,"58530":37530,"58531":37547,"58532":37497,"58533":37527,"58534":37503,"58535":37539,"58536":37614,"58537":37518,"58538":37506,"58539":37525,"58540":37538,"58541":37501,"58542":37512,"58543":37537,"58544":37514,"58545":37510,"58546":37516,"58547":37529,"58548":37543,"58549":37502,"58550":37511,"58551":37545,"58552":37533,"58553":37515,"58554":37421,"58555":38558,"58556":38561,"58557":38655,"58558":38744,"58559":38781,"58560":38778,"58561":38782,"58562":38787,"58563":38784,"58564":38786,"58565":38779,"58566":38788,"58567":38785,"58568":38783,"58569":38862,"58570":38861,"58571":38934,"58572":39085,"58573":39086,"58574":39170,"58575":39168,"58576":39175,"58577":39325,"58578":39324,"58579":39363,"58580":39353,"58581":39355,"58582":39354,"58583":39362,"58584":39357,"58585":39367,"58586":39601,"58587":39651,"58588":39655,"58589":39742,"58590":39743,"58591":39776,"58592":39777,"58593":39775,"58594":40177,"58595":40178,"58596":40181,"58597":40615,"58598":20735,"58599":20739,"58600":20784,"58601":20728,"58602":20742,"58603":20743,"58604":20726,"58605":20734,"58606":20747,"58607":20748,"58608":20733,"58609":20746,"58610":21131,"58611":21132,"58612":21233,"58613":21231,"58614":22088,"58615":22082,"58616":22092,"58617":22069,"58618":22081,"58619":22090,"58620":22089,"58621":22086,"58622":22104,"58688":22106,"58689":22080,"58690":22067,"58691":22077,"58692":22060,"58693":22078,"58694":22072,"58695":22058,"58696":22074,"58697":22298,"58698":22699,"58699":22685,"58700":22705,"58701":22688,"58702":22691,"58703":22703,"58704":22700,"58705":22693,"58706":22689,"58707":22783,"58708":23295,"58709":23284,"58710":23293,"58711":23287,"58712":23286,"58713":23299,"58714":23288,"58715":23298,"58716":23289,"58717":23297,"58718":23303,"58719":23301,"58720":23311,"58721":23655,"58722":23961,"58723":23959,"58724":23967,"58725":23954,"58726":23970,"58727":23955,"58728":23957,"58729":23968,"58730":23964,"58731":23969,"58732":23962,"58733":23966,"58734":24169,"58735":24157,"58736":24160,"58737":24156,"58738":32243,"58739":24283,"58740":24286,"58741":24289,"58742":24393,"58743":24498,"58744":24971,"58745":24963,"58746":24953,"58747":25009,"58748":25008,"58749":24994,"58750":24969,"58785":24987,"58786":24979,"58787":25007,"58788":25005,"58789":24991,"58790":24978,"58791":25002,"58792":24993,"58793":24973,"58794":24934,"58795":25011,"58796":25133,"58797":25710,"58798":25712,"58799":25750,"58800":25760,"58801":25733,"58802":25751,"58803":25756,"58804":25743,"58805":25739,"58806":25738,"58807":25740,"58808":25763,"58809":25759,"58810":25704,"58811":25777,"58812":25752,"58813":25974,"58814":25978,"58815":25977,"58816":25979,"58817":26034,"58818":26035,"58819":26293,"58820":26288,"58821":26281,"58822":26290,"58823":26295,"58824":26282,"58825":26287,"58826":27136,"58827":27142,"58828":27159,"58829":27109,"58830":27128,"58831":27157,"58832":27121,"58833":27108,"58834":27168,"58835":27135,"58836":27116,"58837":27106,"58838":27163,"58839":27165,"58840":27134,"58841":27175,"58842":27122,"58843":27118,"58844":27156,"58845":27127,"58846":27111,"58847":27200,"58848":27144,"58849":27110,"58850":27131,"58851":27149,"58852":27132,"58853":27115,"58854":27145,"58855":27140,"58856":27160,"58857":27173,"58858":27151,"58859":27126,"58860":27174,"58861":27143,"58862":27124,"58863":27158,"58864":27473,"58865":27557,"58866":27555,"58867":27554,"58868":27558,"58869":27649,"58870":27648,"58871":27647,"58872":27650,"58873":28481,"58874":28454,"58875":28542,"58876":28551,"58877":28614,"58878":28562,"58944":28557,"58945":28553,"58946":28556,"58947":28514,"58948":28495,"58949":28549,"58950":28506,"58951":28566,"58952":28534,"58953":28524,"58954":28546,"58955":28501,"58956":28530,"58957":28498,"58958":28496,"58959":28503,"58960":28564,"58961":28563,"58962":28509,"58963":28416,"58964":28513,"58965":28523,"58966":28541,"58967":28519,"58968":28560,"58969":28499,"58970":28555,"58971":28521,"58972":28543,"58973":28565,"58974":28515,"58975":28535,"58976":28522,"58977":28539,"58978":29106,"58979":29103,"58980":29083,"58981":29104,"58982":29088,"58983":29082,"58984":29097,"58985":29109,"58986":29085,"58987":29093,"58988":29086,"58989":29092,"58990":29089,"58991":29098,"58992":29084,"58993":29095,"58994":29107,"58995":29336,"58996":29338,"58997":29528,"58998":29522,"58999":29534,"59000":29535,"59001":29536,"59002":29533,"59003":29531,"59004":29537,"59005":29530,"59006":29529,"59041":29538,"59042":29831,"59043":29833,"59044":29834,"59045":29830,"59046":29825,"59047":29821,"59048":29829,"59049":29832,"59050":29820,"59051":29817,"59052":29960,"59053":29959,"59054":30078,"59055":30245,"59056":30238,"59057":30233,"59058":30237,"59059":30236,"59060":30243,"59061":30234,"59062":30248,"59063":30235,"59064":30364,"59065":30365,"59066":30366,"59067":30363,"59068":30605,"59069":30607,"59070":30601,"59071":30600,"59072":30925,"59073":30907,"59074":30927,"59075":30924,"59076":30929,"59077":30926,"59078":30932,"59079":30920,"59080":30915,"59081":30916,"59082":30921,"59083":31130,"59084":31137,"59085":31136,"59086":31132,"59087":31138,"59088":31131,"59089":27510,"59090":31289,"59091":31410,"59092":31412,"59093":31411,"59094":31671,"59095":31691,"59096":31678,"59097":31660,"59098":31694,"59099":31663,"59100":31673,"59101":31690,"59102":31669,"59103":31941,"59104":31944,"59105":31948,"59106":31947,"59107":32247,"59108":32219,"59109":32234,"59110":32231,"59111":32215,"59112":32225,"59113":32259,"59114":32250,"59115":32230,"59116":32246,"59117":32241,"59118":32240,"59119":32238,"59120":32223,"59121":32630,"59122":32684,"59123":32688,"59124":32685,"59125":32749,"59126":32747,"59127":32746,"59128":32748,"59129":32742,"59130":32744,"59131":32868,"59132":32871,"59133":33187,"59134":33183,"59200":33182,"59201":33173,"59202":33186,"59203":33177,"59204":33175,"59205":33302,"59206":33359,"59207":33363,"59208":33362,"59209":33360,"59210":33358,"59211":33361,"59212":34084,"59213":34107,"59214":34063,"59215":34048,"59216":34089,"59217":34062,"59218":34057,"59219":34061,"59220":34079,"59221":34058,"59222":34087,"59223":34076,"59224":34043,"59225":34091,"59226":34042,"59227":34056,"59228":34060,"59229":34036,"59230":34090,"59231":34034,"59232":34069,"59233":34039,"59234":34027,"59235":34035,"59236":34044,"59237":34066,"59238":34026,"59239":34025,"59240":34070,"59241":34046,"59242":34088,"59243":34077,"59244":34094,"59245":34050,"59246":34045,"59247":34078,"59248":34038,"59249":34097,"59250":34086,"59251":34023,"59252":34024,"59253":34032,"59254":34031,"59255":34041,"59256":34072,"59257":34080,"59258":34096,"59259":34059,"59260":34073,"59261":34095,"59262":34402,"59297":34646,"59298":34659,"59299":34660,"59300":34679,"59301":34785,"59302":34675,"59303":34648,"59304":34644,"59305":34651,"59306":34642,"59307":34657,"59308":34650,"59309":34641,"59310":34654,"59311":34669,"59312":34666,"59313":34640,"59314":34638,"59315":34655,"59316":34653,"59317":34671,"59318":34668,"59319":34682,"59320":34670,"59321":34652,"59322":34661,"59323":34639,"59324":34683,"59325":34677,"59326":34658,"59327":34663,"59328":34665,"59329":34906,"59330":35077,"59331":35084,"59332":35092,"59333":35083,"59334":35095,"59335":35096,"59336":35097,"59337":35078,"59338":35094,"59339":35089,"59340":35086,"59341":35081,"59342":35234,"59343":35236,"59344":35235,"59345":35309,"59346":35312,"59347":35308,"59348":35535,"59349":35526,"59350":35512,"59351":35539,"59352":35537,"59353":35540,"59354":35541,"59355":35515,"59356":35543,"59357":35518,"59358":35520,"59359":35525,"59360":35544,"59361":35523,"59362":35514,"59363":35517,"59364":35545,"59365":35902,"59366":35917,"59367":35983,"59368":36069,"59369":36063,"59370":36057,"59371":36072,"59372":36058,"59373":36061,"59374":36071,"59375":36256,"59376":36252,"59377":36257,"59378":36251,"59379":36384,"59380":36387,"59381":36389,"59382":36388,"59383":36398,"59384":36373,"59385":36379,"59386":36374,"59387":36369,"59388":36377,"59389":36390,"59390":36391,"59456":36372,"59457":36370,"59458":36376,"59459":36371,"59460":36380,"59461":36375,"59462":36378,"59463":36652,"59464":36644,"59465":36632,"59466":36634,"59467":36640,"59468":36643,"59469":36630,"59470":36631,"59471":36979,"59472":36976,"59473":36975,"59474":36967,"59475":36971,"59476":37167,"59477":37163,"59478":37161,"59479":37162,"59480":37170,"59481":37158,"59482":37166,"59483":37253,"59484":37254,"59485":37258,"59486":37249,"59487":37250,"59488":37252,"59489":37248,"59490":37584,"59491":37571,"59492":37572,"59493":37568,"59494":37593,"59495":37558,"59496":37583,"59497":37617,"59498":37599,"59499":37592,"59500":37609,"59501":37591,"59502":37597,"59503":37580,"59504":37615,"59505":37570,"59506":37608,"59507":37578,"59508":37576,"59509":37582,"59510":37606,"59511":37581,"59512":37589,"59513":37577,"59514":37600,"59515":37598,"59516":37607,"59517":37585,"59518":37587,"59553":37557,"59554":37601,"59555":37574,"59556":37556,"59557":38268,"59558":38316,"59559":38315,"59560":38318,"59561":38320,"59562":38564,"59563":38562,"59564":38611,"59565":38661,"59566":38664,"59567":38658,"59568":38746,"59569":38794,"59570":38798,"59571":38792,"59572":38864,"59573":38863,"59574":38942,"59575":38941,"59576":38950,"59577":38953,"59578":38952,"59579":38944,"59580":38939,"59581":38951,"59582":39090,"59583":39176,"59584":39162,"59585":39185,"59586":39188,"59587":39190,"59588":39191,"59589":39189,"59590":39388,"59591":39373,"59592":39375,"59593":39379,"59594":39380,"59595":39374,"59596":39369,"59597":39382,"59598":39384,"59599":39371,"59600":39383,"59601":39372,"59602":39603,"59603":39660,"59604":39659,"59605":39667,"59606":39666,"59607":39665,"59608":39750,"59609":39747,"59610":39783,"59611":39796,"59612":39793,"59613":39782,"59614":39798,"59615":39797,"59616":39792,"59617":39784,"59618":39780,"59619":39788,"59620":40188,"59621":40186,"59622":40189,"59623":40191,"59624":40183,"59625":40199,"59626":40192,"59627":40185,"59628":40187,"59629":40200,"59630":40197,"59631":40196,"59632":40579,"59633":40659,"59634":40719,"59635":40720,"59636":20764,"59637":20755,"59638":20759,"59639":20762,"59640":20753,"59641":20958,"59642":21300,"59643":21473,"59644":22128,"59645":22112,"59646":22126,"59712":22131,"59713":22118,"59714":22115,"59715":22125,"59716":22130,"59717":22110,"59718":22135,"59719":22300,"59720":22299,"59721":22728,"59722":22717,"59723":22729,"59724":22719,"59725":22714,"59726":22722,"59727":22716,"59728":22726,"59729":23319,"59730":23321,"59731":23323,"59732":23329,"59733":23316,"59734":23315,"59735":23312,"59736":23318,"59737":23336,"59738":23322,"59739":23328,"59740":23326,"59741":23535,"59742":23980,"59743":23985,"59744":23977,"59745":23975,"59746":23989,"59747":23984,"59748":23982,"59749":23978,"59750":23976,"59751":23986,"59752":23981,"59753":23983,"59754":23988,"59755":24167,"59756":24168,"59757":24166,"59758":24175,"59759":24297,"59760":24295,"59761":24294,"59762":24296,"59763":24293,"59764":24395,"59765":24508,"59766":24989,"59767":25000,"59768":24982,"59769":25029,"59770":25012,"59771":25030,"59772":25025,"59773":25036,"59774":25018,"59809":25023,"59810":25016,"59811":24972,"59812":25815,"59813":25814,"59814":25808,"59815":25807,"59816":25801,"59817":25789,"59818":25737,"59819":25795,"59820":25819,"59821":25843,"59822":25817,"59823":25907,"59824":25983,"59825":25980,"59826":26018,"59827":26312,"59828":26302,"59829":26304,"59830":26314,"59831":26315,"59832":26319,"59833":26301,"59834":26299,"59835":26298,"59836":26316,"59837":26403,"59838":27188,"59839":27238,"59840":27209,"59841":27239,"59842":27186,"59843":27240,"59844":27198,"59845":27229,"59846":27245,"59847":27254,"59848":27227,"59849":27217,"59850":27176,"59851":27226,"59852":27195,"59853":27199,"59854":27201,"59855":27242,"59856":27236,"59857":27216,"59858":27215,"59859":27220,"59860":27247,"59861":27241,"59862":27232,"59863":27196,"59864":27230,"59865":27222,"59866":27221,"59867":27213,"59868":27214,"59869":27206,"59870":27477,"59871":27476,"59872":27478,"59873":27559,"59874":27562,"59875":27563,"59876":27592,"59877":27591,"59878":27652,"59879":27651,"59880":27654,"59881":28589,"59882":28619,"59883":28579,"59884":28615,"59885":28604,"59886":28622,"59887":28616,"59888":28510,"59889":28612,"59890":28605,"59891":28574,"59892":28618,"59893":28584,"59894":28676,"59895":28581,"59896":28590,"59897":28602,"59898":28588,"59899":28586,"59900":28623,"59901":28607,"59902":28600,"59968":28578,"59969":28617,"59970":28587,"59971":28621,"59972":28591,"59973":28594,"59974":28592,"59975":29125,"59976":29122,"59977":29119,"59978":29112,"59979":29142,"59980":29120,"59981":29121,"59982":29131,"59983":29140,"59984":29130,"59985":29127,"59986":29135,"59987":29117,"59988":29144,"59989":29116,"59990":29126,"59991":29146,"59992":29147,"59993":29341,"59994":29342,"59995":29545,"59996":29542,"59997":29543,"59998":29548,"59999":29541,"60000":29547,"60001":29546,"60002":29823,"60003":29850,"60004":29856,"60005":29844,"60006":29842,"60007":29845,"60008":29857,"60009":29963,"60010":30080,"60011":30255,"60012":30253,"60013":30257,"60014":30269,"60015":30259,"60016":30268,"60017":30261,"60018":30258,"60019":30256,"60020":30395,"60021":30438,"60022":30618,"60023":30621,"60024":30625,"60025":30620,"60026":30619,"60027":30626,"60028":30627,"60029":30613,"60030":30617,"60065":30615,"60066":30941,"60067":30953,"60068":30949,"60069":30954,"60070":30942,"60071":30947,"60072":30939,"60073":30945,"60074":30946,"60075":30957,"60076":30943,"60077":30944,"60078":31140,"60079":31300,"60080":31304,"60081":31303,"60082":31414,"60083":31416,"60084":31413,"60085":31409,"60086":31415,"60087":31710,"60088":31715,"60089":31719,"60090":31709,"60091":31701,"60092":31717,"60093":31706,"60094":31720,"60095":31737,"60096":31700,"60097":31722,"60098":31714,"60099":31708,"60100":31723,"60101":31704,"60102":31711,"60103":31954,"60104":31956,"60105":31959,"60106":31952,"60107":31953,"60108":32274,"60109":32289,"60110":32279,"60111":32268,"60112":32287,"60113":32288,"60114":32275,"60115":32270,"60116":32284,"60117":32277,"60118":32282,"60119":32290,"60120":32267,"60121":32271,"60122":32278,"60123":32269,"60124":32276,"60125":32293,"60126":32292,"60127":32579,"60128":32635,"60129":32636,"60130":32634,"60131":32689,"60132":32751,"60133":32810,"60134":32809,"60135":32876,"60136":33201,"60137":33190,"60138":33198,"60139":33209,"60140":33205,"60141":33195,"60142":33200,"60143":33196,"60144":33204,"60145":33202,"60146":33207,"60147":33191,"60148":33266,"60149":33365,"60150":33366,"60151":33367,"60152":34134,"60153":34117,"60154":34155,"60155":34125,"60156":34131,"60157":34145,"60158":34136,"60224":34112,"60225":34118,"60226":34148,"60227":34113,"60228":34146,"60229":34116,"60230":34129,"60231":34119,"60232":34147,"60233":34110,"60234":34139,"60235":34161,"60236":34126,"60237":34158,"60238":34165,"60239":34133,"60240":34151,"60241":34144,"60242":34188,"60243":34150,"60244":34141,"60245":34132,"60246":34149,"60247":34156,"60248":34403,"60249":34405,"60250":34404,"60251":34715,"60252":34703,"60253":34711,"60254":34707,"60255":34706,"60256":34696,"60257":34689,"60258":34710,"60259":34712,"60260":34681,"60261":34695,"60262":34723,"60263":34693,"60264":34704,"60265":34705,"60266":34717,"60267":34692,"60268":34708,"60269":34716,"60270":34714,"60271":34697,"60272":35102,"60273":35110,"60274":35120,"60275":35117,"60276":35118,"60277":35111,"60278":35121,"60279":35106,"60280":35113,"60281":35107,"60282":35119,"60283":35116,"60284":35103,"60285":35313,"60286":35552,"60321":35554,"60322":35570,"60323":35572,"60324":35573,"60325":35549,"60326":35604,"60327":35556,"60328":35551,"60329":35568,"60330":35528,"60331":35550,"60332":35553,"60333":35560,"60334":35583,"60335":35567,"60336":35579,"60337":35985,"60338":35986,"60339":35984,"60340":36085,"60341":36078,"60342":36081,"60343":36080,"60344":36083,"60345":36204,"60346":36206,"60347":36261,"60348":36263,"60349":36403,"60350":36414,"60351":36408,"60352":36416,"60353":36421,"60354":36406,"60355":36412,"60356":36413,"60357":36417,"60358":36400,"60359":36415,"60360":36541,"60361":36662,"60362":36654,"60363":36661,"60364":36658,"60365":36665,"60366":36663,"60367":36660,"60368":36982,"60369":36985,"60370":36987,"60371":36998,"60372":37114,"60373":37171,"60374":37173,"60375":37174,"60376":37267,"60377":37264,"60378":37265,"60379":37261,"60380":37263,"60381":37671,"60382":37662,"60383":37640,"60384":37663,"60385":37638,"60386":37647,"60387":37754,"60388":37688,"60389":37692,"60390":37659,"60391":37667,"60392":37650,"60393":37633,"60394":37702,"60395":37677,"60396":37646,"60397":37645,"60398":37579,"60399":37661,"60400":37626,"60401":37669,"60402":37651,"60403":37625,"60404":37623,"60405":37684,"60406":37634,"60407":37668,"60408":37631,"60409":37673,"60410":37689,"60411":37685,"60412":37674,"60413":37652,"60414":37644,"60480":37643,"60481":37630,"60482":37641,"60483":37632,"60484":37627,"60485":37654,"60486":38332,"60487":38349,"60488":38334,"60489":38329,"60490":38330,"60491":38326,"60492":38335,"60493":38325,"60494":38333,"60495":38569,"60496":38612,"60497":38667,"60498":38674,"60499":38672,"60500":38809,"60501":38807,"60502":38804,"60503":38896,"60504":38904,"60505":38965,"60506":38959,"60507":38962,"60508":39204,"60509":39199,"60510":39207,"60511":39209,"60512":39326,"60513":39406,"60514":39404,"60515":39397,"60516":39396,"60517":39408,"60518":39395,"60519":39402,"60520":39401,"60521":39399,"60522":39609,"60523":39615,"60524":39604,"60525":39611,"60526":39670,"60527":39674,"60528":39673,"60529":39671,"60530":39731,"60531":39808,"60532":39813,"60533":39815,"60534":39804,"60535":39806,"60536":39803,"60537":39810,"60538":39827,"60539":39826,"60540":39824,"60541":39802,"60542":39829,"60577":39805,"60578":39816,"60579":40229,"60580":40215,"60581":40224,"60582":40222,"60583":40212,"60584":40233,"60585":40221,"60586":40216,"60587":40226,"60588":40208,"60589":40217,"60590":40223,"60591":40584,"60592":40582,"60593":40583,"60594":40622,"60595":40621,"60596":40661,"60597":40662,"60598":40698,"60599":40722,"60600":40765,"60601":20774,"60602":20773,"60603":20770,"60604":20772,"60605":20768,"60606":20777,"60607":21236,"60608":22163,"60609":22156,"60610":22157,"60611":22150,"60612":22148,"60613":22147,"60614":22142,"60615":22146,"60616":22143,"60617":22145,"60618":22742,"60619":22740,"60620":22735,"60621":22738,"60622":23341,"60623":23333,"60624":23346,"60625":23331,"60626":23340,"60627":23335,"60628":23334,"60629":23343,"60630":23342,"60631":23419,"60632":23537,"60633":23538,"60634":23991,"60635":24172,"60636":24170,"60637":24510,"60638":24507,"60639":25027,"60640":25013,"60641":25020,"60642":25063,"60643":25056,"60644":25061,"60645":25060,"60646":25064,"60647":25054,"60648":25839,"60649":25833,"60650":25827,"60651":25835,"60652":25828,"60653":25832,"60654":25985,"60655":25984,"60656":26038,"60657":26074,"60658":26322,"60659":27277,"60660":27286,"60661":27265,"60662":27301,"60663":27273,"60664":27295,"60665":27291,"60666":27297,"60667":27294,"60668":27271,"60669":27283,"60670":27278,"60736":27285,"60737":27267,"60738":27304,"60739":27300,"60740":27281,"60741":27263,"60742":27302,"60743":27290,"60744":27269,"60745":27276,"60746":27282,"60747":27483,"60748":27565,"60749":27657,"60750":28620,"60751":28585,"60752":28660,"60753":28628,"60754":28643,"60755":28636,"60756":28653,"60757":28647,"60758":28646,"60759":28638,"60760":28658,"60761":28637,"60762":28642,"60763":28648,"60764":29153,"60765":29169,"60766":29160,"60767":29170,"60768":29156,"60769":29168,"60770":29154,"60771":29555,"60772":29550,"60773":29551,"60774":29847,"60775":29874,"60776":29867,"60777":29840,"60778":29866,"60779":29869,"60780":29873,"60781":29861,"60782":29871,"60783":29968,"60784":29969,"60785":29970,"60786":29967,"60787":30084,"60788":30275,"60789":30280,"60790":30281,"60791":30279,"60792":30372,"60793":30441,"60794":30645,"60795":30635,"60796":30642,"60797":30647,"60798":30646,"60833":30644,"60834":30641,"60835":30632,"60836":30704,"60837":30963,"60838":30973,"60839":30978,"60840":30971,"60841":30972,"60842":30962,"60843":30981,"60844":30969,"60845":30974,"60846":30980,"60847":31147,"60848":31144,"60849":31324,"60850":31323,"60851":31318,"60852":31320,"60853":31316,"60854":31322,"60855":31422,"60856":31424,"60857":31425,"60858":31749,"60859":31759,"60860":31730,"60861":31744,"60862":31743,"60863":31739,"60864":31758,"60865":31732,"60866":31755,"60867":31731,"60868":31746,"60869":31753,"60870":31747,"60871":31745,"60872":31736,"60873":31741,"60874":31750,"60875":31728,"60876":31729,"60877":31760,"60878":31754,"60879":31976,"60880":32301,"60881":32316,"60882":32322,"60883":32307,"60884":38984,"60885":32312,"60886":32298,"60887":32329,"60888":32320,"60889":32327,"60890":32297,"60891":32332,"60892":32304,"60893":32315,"60894":32310,"60895":32324,"60896":32314,"60897":32581,"60898":32639,"60899":32638,"60900":32637,"60901":32756,"60902":32754,"60903":32812,"60904":33211,"60905":33220,"60906":33228,"60907":33226,"60908":33221,"60909":33223,"60910":33212,"60911":33257,"60912":33371,"60913":33370,"60914":33372,"60915":34179,"60916":34176,"60917":34191,"60918":34215,"60919":34197,"60920":34208,"60921":34187,"60922":34211,"60923":34171,"60924":34212,"60925":34202,"60926":34206,"60992":34167,"60993":34172,"60994":34185,"60995":34209,"60996":34170,"60997":34168,"60998":34135,"60999":34190,"61000":34198,"61001":34182,"61002":34189,"61003":34201,"61004":34205,"61005":34177,"61006":34210,"61007":34178,"61008":34184,"61009":34181,"61010":34169,"61011":34166,"61012":34200,"61013":34192,"61014":34207,"61015":34408,"61016":34750,"61017":34730,"61018":34733,"61019":34757,"61020":34736,"61021":34732,"61022":34745,"61023":34741,"61024":34748,"61025":34734,"61026":34761,"61027":34755,"61028":34754,"61029":34764,"61030":34743,"61031":34735,"61032":34756,"61033":34762,"61034":34740,"61035":34742,"61036":34751,"61037":34744,"61038":34749,"61039":34782,"61040":34738,"61041":35125,"61042":35123,"61043":35132,"61044":35134,"61045":35137,"61046":35154,"61047":35127,"61048":35138,"61049":35245,"61050":35247,"61051":35246,"61052":35314,"61053":35315,"61054":35614,"61089":35608,"61090":35606,"61091":35601,"61092":35589,"61093":35595,"61094":35618,"61095":35599,"61096":35602,"61097":35605,"61098":35591,"61099":35597,"61100":35592,"61101":35590,"61102":35612,"61103":35603,"61104":35610,"61105":35919,"61106":35952,"61107":35954,"61108":35953,"61109":35951,"61110":35989,"61111":35988,"61112":36089,"61113":36207,"61114":36430,"61115":36429,"61116":36435,"61117":36432,"61118":36428,"61119":36423,"61120":36675,"61121":36672,"61122":36997,"61123":36990,"61124":37176,"61125":37274,"61126":37282,"61127":37275,"61128":37273,"61129":37279,"61130":37281,"61131":37277,"61132":37280,"61133":37793,"61134":37763,"61135":37807,"61136":37732,"61137":37718,"61138":37703,"61139":37756,"61140":37720,"61141":37724,"61142":37750,"61143":37705,"61144":37712,"61145":37713,"61146":37728,"61147":37741,"61148":37775,"61149":37708,"61150":37738,"61151":37753,"61152":37719,"61153":37717,"61154":37714,"61155":37711,"61156":37745,"61157":37751,"61158":37755,"61159":37729,"61160":37726,"61161":37731,"61162":37735,"61163":37760,"61164":37710,"61165":37721,"61166":38343,"61167":38336,"61168":38345,"61169":38339,"61170":38341,"61171":38327,"61172":38574,"61173":38576,"61174":38572,"61175":38688,"61176":38687,"61177":38680,"61178":38685,"61179":38681,"61180":38810,"61181":38817,"61182":38812,"61248":38814,"61249":38813,"61250":38869,"61251":38868,"61252":38897,"61253":38977,"61254":38980,"61255":38986,"61256":38985,"61257":38981,"61258":38979,"61259":39205,"61260":39211,"61261":39212,"61262":39210,"61263":39219,"61264":39218,"61265":39215,"61266":39213,"61267":39217,"61268":39216,"61269":39320,"61270":39331,"61271":39329,"61272":39426,"61273":39418,"61274":39412,"61275":39415,"61276":39417,"61277":39416,"61278":39414,"61279":39419,"61280":39421,"61281":39422,"61282":39420,"61283":39427,"61284":39614,"61285":39678,"61286":39677,"61287":39681,"61288":39676,"61289":39752,"61290":39834,"61291":39848,"61292":39838,"61293":39835,"61294":39846,"61295":39841,"61296":39845,"61297":39844,"61298":39814,"61299":39842,"61300":39840,"61301":39855,"61302":40243,"61303":40257,"61304":40295,"61305":40246,"61306":40238,"61307":40239,"61308":40241,"61309":40248,"61310":40240,"61345":40261,"61346":40258,"61347":40259,"61348":40254,"61349":40247,"61350":40256,"61351":40253,"61352":32757,"61353":40237,"61354":40586,"61355":40585,"61356":40589,"61357":40624,"61358":40648,"61359":40666,"61360":40699,"61361":40703,"61362":40740,"61363":40739,"61364":40738,"61365":40788,"61366":40864,"61367":20785,"61368":20781,"61369":20782,"61370":22168,"61371":22172,"61372":22167,"61373":22170,"61374":22173,"61375":22169,"61376":22896,"61377":23356,"61378":23657,"61379":23658,"61380":24000,"61381":24173,"61382":24174,"61383":25048,"61384":25055,"61385":25069,"61386":25070,"61387":25073,"61388":25066,"61389":25072,"61390":25067,"61391":25046,"61392":25065,"61393":25855,"61394":25860,"61395":25853,"61396":25848,"61397":25857,"61398":25859,"61399":25852,"61400":26004,"61401":26075,"61402":26330,"61403":26331,"61404":26328,"61405":27333,"61406":27321,"61407":27325,"61408":27361,"61409":27334,"61410":27322,"61411":27318,"61412":27319,"61413":27335,"61414":27316,"61415":27309,"61416":27486,"61417":27593,"61418":27659,"61419":28679,"61420":28684,"61421":28685,"61422":28673,"61423":28677,"61424":28692,"61425":28686,"61426":28671,"61427":28672,"61428":28667,"61429":28710,"61430":28668,"61431":28663,"61432":28682,"61433":29185,"61434":29183,"61435":29177,"61436":29187,"61437":29181,"61438":29558,"61504":29880,"61505":29888,"61506":29877,"61507":29889,"61508":29886,"61509":29878,"61510":29883,"61511":29890,"61512":29972,"61513":29971,"61514":30300,"61515":30308,"61516":30297,"61517":30288,"61518":30291,"61519":30295,"61520":30298,"61521":30374,"61522":30397,"61523":30444,"61524":30658,"61525":30650,"61526":30975,"61527":30988,"61528":30995,"61529":30996,"61530":30985,"61531":30992,"61532":30994,"61533":30993,"61534":31149,"61535":31148,"61536":31327,"61537":31772,"61538":31785,"61539":31769,"61540":31776,"61541":31775,"61542":31789,"61543":31773,"61544":31782,"61545":31784,"61546":31778,"61547":31781,"61548":31792,"61549":32348,"61550":32336,"61551":32342,"61552":32355,"61553":32344,"61554":32354,"61555":32351,"61556":32337,"61557":32352,"61558":32343,"61559":32339,"61560":32693,"61561":32691,"61562":32759,"61563":32760,"61564":32885,"61565":33233,"61566":33234,"61601":33232,"61602":33375,"61603":33374,"61604":34228,"61605":34246,"61606":34240,"61607":34243,"61608":34242,"61609":34227,"61610":34229,"61611":34237,"61612":34247,"61613":34244,"61614":34239,"61615":34251,"61616":34254,"61617":34248,"61618":34245,"61619":34225,"61620":34230,"61621":34258,"61622":34340,"61623":34232,"61624":34231,"61625":34238,"61626":34409,"61627":34791,"61628":34790,"61629":34786,"61630":34779,"61631":34795,"61632":34794,"61633":34789,"61634":34783,"61635":34803,"61636":34788,"61637":34772,"61638":34780,"61639":34771,"61640":34797,"61641":34776,"61642":34787,"61643":34724,"61644":34775,"61645":34777,"61646":34817,"61647":34804,"61648":34792,"61649":34781,"61650":35155,"61651":35147,"61652":35151,"61653":35148,"61654":35142,"61655":35152,"61656":35153,"61657":35145,"61658":35626,"61659":35623,"61660":35619,"61661":35635,"61662":35632,"61663":35637,"61664":35655,"61665":35631,"61666":35644,"61667":35646,"61668":35633,"61669":35621,"61670":35639,"61671":35622,"61672":35638,"61673":35630,"61674":35620,"61675":35643,"61676":35645,"61677":35642,"61678":35906,"61679":35957,"61680":35993,"61681":35992,"61682":35991,"61683":36094,"61684":36100,"61685":36098,"61686":36096,"61687":36444,"61688":36450,"61689":36448,"61690":36439,"61691":36438,"61692":36446,"61693":36453,"61694":36455,"61760":36443,"61761":36442,"61762":36449,"61763":36445,"61764":36457,"61765":36436,"61766":36678,"61767":36679,"61768":36680,"61769":36683,"61770":37160,"61771":37178,"61772":37179,"61773":37182,"61774":37288,"61775":37285,"61776":37287,"61777":37295,"61778":37290,"61779":37813,"61780":37772,"61781":37778,"61782":37815,"61783":37787,"61784":37789,"61785":37769,"61786":37799,"61787":37774,"61788":37802,"61789":37790,"61790":37798,"61791":37781,"61792":37768,"61793":37785,"61794":37791,"61795":37773,"61796":37809,"61797":37777,"61798":37810,"61799":37796,"61800":37800,"61801":37812,"61802":37795,"61803":37797,"61804":38354,"61805":38355,"61806":38353,"61807":38579,"61808":38615,"61809":38618,"61810":24002,"61811":38623,"61812":38616,"61813":38621,"61814":38691,"61815":38690,"61816":38693,"61817":38828,"61818":38830,"61819":38824,"61820":38827,"61821":38820,"61822":38826,"61857":38818,"61858":38821,"61859":38871,"61860":38873,"61861":38870,"61862":38872,"61863":38906,"61864":38992,"61865":38993,"61866":38994,"61867":39096,"61868":39233,"61869":39228,"61870":39226,"61871":39439,"61872":39435,"61873":39433,"61874":39437,"61875":39428,"61876":39441,"61877":39434,"61878":39429,"61879":39431,"61880":39430,"61881":39616,"61882":39644,"61883":39688,"61884":39684,"61885":39685,"61886":39721,"61887":39733,"61888":39754,"61889":39756,"61890":39755,"61891":39879,"61892":39878,"61893":39875,"61894":39871,"61895":39873,"61896":39861,"61897":39864,"61898":39891,"61899":39862,"61900":39876,"61901":39865,"61902":39869,"61903":40284,"61904":40275,"61905":40271,"61906":40266,"61907":40283,"61908":40267,"61909":40281,"61910":40278,"61911":40268,"61912":40279,"61913":40274,"61914":40276,"61915":40287,"61916":40280,"61917":40282,"61918":40590,"61919":40588,"61920":40671,"61921":40705,"61922":40704,"61923":40726,"61924":40741,"61925":40747,"61926":40746,"61927":40745,"61928":40744,"61929":40780,"61930":40789,"61931":20788,"61932":20789,"61933":21142,"61934":21239,"61935":21428,"61936":22187,"61937":22189,"61938":22182,"61939":22183,"61940":22186,"61941":22188,"61942":22746,"61943":22749,"61944":22747,"61945":22802,"61946":23357,"61947":23358,"61948":23359,"61949":24003,"61950":24176,"62016":24511,"62017":25083,"62018":25863,"62019":25872,"62020":25869,"62021":25865,"62022":25868,"62023":25870,"62024":25988,"62025":26078,"62026":26077,"62027":26334,"62028":27367,"62029":27360,"62030":27340,"62031":27345,"62032":27353,"62033":27339,"62034":27359,"62035":27356,"62036":27344,"62037":27371,"62038":27343,"62039":27341,"62040":27358,"62041":27488,"62042":27568,"62043":27660,"62044":28697,"62045":28711,"62046":28704,"62047":28694,"62048":28715,"62049":28705,"62050":28706,"62051":28707,"62052":28713,"62053":28695,"62054":28708,"62055":28700,"62056":28714,"62057":29196,"62058":29194,"62059":29191,"62060":29186,"62061":29189,"62062":29349,"62063":29350,"62064":29348,"62065":29347,"62066":29345,"62067":29899,"62068":29893,"62069":29879,"62070":29891,"62071":29974,"62072":30304,"62073":30665,"62074":30666,"62075":30660,"62076":30705,"62077":31005,"62078":31003,"62113":31009,"62114":31004,"62115":30999,"62116":31006,"62117":31152,"62118":31335,"62119":31336,"62120":31795,"62121":31804,"62122":31801,"62123":31788,"62124":31803,"62125":31980,"62126":31978,"62127":32374,"62128":32373,"62129":32376,"62130":32368,"62131":32375,"62132":32367,"62133":32378,"62134":32370,"62135":32372,"62136":32360,"62137":32587,"62138":32586,"62139":32643,"62140":32646,"62141":32695,"62142":32765,"62143":32766,"62144":32888,"62145":33239,"62146":33237,"62147":33380,"62148":33377,"62149":33379,"62150":34283,"62151":34289,"62152":34285,"62153":34265,"62154":34273,"62155":34280,"62156":34266,"62157":34263,"62158":34284,"62159":34290,"62160":34296,"62161":34264,"62162":34271,"62163":34275,"62164":34268,"62165":34257,"62166":34288,"62167":34278,"62168":34287,"62169":34270,"62170":34274,"62171":34816,"62172":34810,"62173":34819,"62174":34806,"62175":34807,"62176":34825,"62177":34828,"62178":34827,"62179":34822,"62180":34812,"62181":34824,"62182":34815,"62183":34826,"62184":34818,"62185":35170,"62186":35162,"62187":35163,"62188":35159,"62189":35169,"62190":35164,"62191":35160,"62192":35165,"62193":35161,"62194":35208,"62195":35255,"62196":35254,"62197":35318,"62198":35664,"62199":35656,"62200":35658,"62201":35648,"62202":35667,"62203":35670,"62204":35668,"62205":35659,"62206":35669,"62272":35665,"62273":35650,"62274":35666,"62275":35671,"62276":35907,"62277":35959,"62278":35958,"62279":35994,"62280":36102,"62281":36103,"62282":36105,"62283":36268,"62284":36266,"62285":36269,"62286":36267,"62287":36461,"62288":36472,"62289":36467,"62290":36458,"62291":36463,"62292":36475,"62293":36546,"62294":36690,"62295":36689,"62296":36687,"62297":36688,"62298":36691,"62299":36788,"62300":37184,"62301":37183,"62302":37296,"62303":37293,"62304":37854,"62305":37831,"62306":37839,"62307":37826,"62308":37850,"62309":37840,"62310":37881,"62311":37868,"62312":37836,"62313":37849,"62314":37801,"62315":37862,"62316":37834,"62317":37844,"62318":37870,"62319":37859,"62320":37845,"62321":37828,"62322":37838,"62323":37824,"62324":37842,"62325":37863,"62326":38269,"62327":38362,"62328":38363,"62329":38625,"62330":38697,"62331":38699,"62332":38700,"62333":38696,"62334":38694,"62369":38835,"62370":38839,"62371":38838,"62372":38877,"62373":38878,"62374":38879,"62375":39004,"62376":39001,"62377":39005,"62378":38999,"62379":39103,"62380":39101,"62381":39099,"62382":39102,"62383":39240,"62384":39239,"62385":39235,"62386":39334,"62387":39335,"62388":39450,"62389":39445,"62390":39461,"62391":39453,"62392":39460,"62393":39451,"62394":39458,"62395":39456,"62396":39463,"62397":39459,"62398":39454,"62399":39452,"62400":39444,"62401":39618,"62402":39691,"62403":39690,"62404":39694,"62405":39692,"62406":39735,"62407":39914,"62408":39915,"62409":39904,"62410":39902,"62411":39908,"62412":39910,"62413":39906,"62414":39920,"62415":39892,"62416":39895,"62417":39916,"62418":39900,"62419":39897,"62420":39909,"62421":39893,"62422":39905,"62423":39898,"62424":40311,"62425":40321,"62426":40330,"62427":40324,"62428":40328,"62429":40305,"62430":40320,"62431":40312,"62432":40326,"62433":40331,"62434":40332,"62435":40317,"62436":40299,"62437":40308,"62438":40309,"62439":40304,"62440":40297,"62441":40325,"62442":40307,"62443":40315,"62444":40322,"62445":40303,"62446":40313,"62447":40319,"62448":40327,"62449":40296,"62450":40596,"62451":40593,"62452":40640,"62453":40700,"62454":40749,"62455":40768,"62456":40769,"62457":40781,"62458":40790,"62459":40791,"62460":40792,"62461":21303,"62462":22194,"62528":22197,"62529":22195,"62530":22755,"62531":23365,"62532":24006,"62533":24007,"62534":24302,"62535":24303,"62536":24512,"62537":24513,"62538":25081,"62539":25879,"62540":25878,"62541":25877,"62542":25875,"62543":26079,"62544":26344,"62545":26339,"62546":26340,"62547":27379,"62548":27376,"62549":27370,"62550":27368,"62551":27385,"62552":27377,"62553":27374,"62554":27375,"62555":28732,"62556":28725,"62557":28719,"62558":28727,"62559":28724,"62560":28721,"62561":28738,"62562":28728,"62563":28735,"62564":28730,"62565":28729,"62566":28736,"62567":28731,"62568":28723,"62569":28737,"62570":29203,"62571":29204,"62572":29352,"62573":29565,"62574":29564,"62575":29882,"62576":30379,"62577":30378,"62578":30398,"62579":30445,"62580":30668,"62581":30670,"62582":30671,"62583":30669,"62584":30706,"62585":31013,"62586":31011,"62587":31015,"62588":31016,"62589":31012,"62590":31017,"62625":31154,"62626":31342,"62627":31340,"62628":31341,"62629":31479,"62630":31817,"62631":31816,"62632":31818,"62633":31815,"62634":31813,"62635":31982,"62636":32379,"62637":32382,"62638":32385,"62639":32384,"62640":32698,"62641":32767,"62642":32889,"62643":33243,"62644":33241,"62645":33291,"62646":33384,"62647":33385,"62648":34338,"62649":34303,"62650":34305,"62651":34302,"62652":34331,"62653":34304,"62654":34294,"62655":34308,"62656":34313,"62657":34309,"62658":34316,"62659":34301,"62660":34841,"62661":34832,"62662":34833,"62663":34839,"62664":34835,"62665":34838,"62666":35171,"62667":35174,"62668":35257,"62669":35319,"62670":35680,"62671":35690,"62672":35677,"62673":35688,"62674":35683,"62675":35685,"62676":35687,"62677":35693,"62678":36270,"62679":36486,"62680":36488,"62681":36484,"62682":36697,"62683":36694,"62684":36695,"62685":36693,"62686":36696,"62687":36698,"62688":37005,"62689":37187,"62690":37185,"62691":37303,"62692":37301,"62693":37298,"62694":37299,"62695":37899,"62696":37907,"62697":37883,"62698":37920,"62699":37903,"62700":37908,"62701":37886,"62702":37909,"62703":37904,"62704":37928,"62705":37913,"62706":37901,"62707":37877,"62708":37888,"62709":37879,"62710":37895,"62711":37902,"62712":37910,"62713":37906,"62714":37882,"62715":37897,"62716":37880,"62717":37898,"62718":37887,"62784":37884,"62785":37900,"62786":37878,"62787":37905,"62788":37894,"62789":38366,"62790":38368,"62791":38367,"62792":38702,"62793":38703,"62794":38841,"62795":38843,"62796":38909,"62797":38910,"62798":39008,"62799":39010,"62800":39011,"62801":39007,"62802":39105,"62803":39106,"62804":39248,"62805":39246,"62806":39257,"62807":39244,"62808":39243,"62809":39251,"62810":39474,"62811":39476,"62812":39473,"62813":39468,"62814":39466,"62815":39478,"62816":39465,"62817":39470,"62818":39480,"62819":39469,"62820":39623,"62821":39626,"62822":39622,"62823":39696,"62824":39698,"62825":39697,"62826":39947,"62827":39944,"62828":39927,"62829":39941,"62830":39954,"62831":39928,"62832":40000,"62833":39943,"62834":39950,"62835":39942,"62836":39959,"62837":39956,"62838":39945,"62839":40351,"62840":40345,"62841":40356,"62842":40349,"62843":40338,"62844":40344,"62845":40336,"62846":40347,"62881":40352,"62882":40340,"62883":40348,"62884":40362,"62885":40343,"62886":40353,"62887":40346,"62888":40354,"62889":40360,"62890":40350,"62891":40355,"62892":40383,"62893":40361,"62894":40342,"62895":40358,"62896":40359,"62897":40601,"62898":40603,"62899":40602,"62900":40677,"62901":40676,"62902":40679,"62903":40678,"62904":40752,"62905":40750,"62906":40795,"62907":40800,"62908":40798,"62909":40797,"62910":40793,"62911":40849,"62912":20794,"62913":20793,"62914":21144,"62915":21143,"62916":22211,"62917":22205,"62918":22206,"62919":23368,"62920":23367,"62921":24011,"62922":24015,"62923":24305,"62924":25085,"62925":25883,"62926":27394,"62927":27388,"62928":27395,"62929":27384,"62930":27392,"62931":28739,"62932":28740,"62933":28746,"62934":28744,"62935":28745,"62936":28741,"62937":28742,"62938":29213,"62939":29210,"62940":29209,"62941":29566,"62942":29975,"62943":30314,"62944":30672,"62945":31021,"62946":31025,"62947":31023,"62948":31828,"62949":31827,"62950":31986,"62951":32394,"62952":32391,"62953":32392,"62954":32395,"62955":32390,"62956":32397,"62957":32589,"62958":32699,"62959":32816,"62960":33245,"62961":34328,"62962":34346,"62963":34342,"62964":34335,"62965":34339,"62966":34332,"62967":34329,"62968":34343,"62969":34350,"62970":34337,"62971":34336,"62972":34345,"62973":34334,"62974":34341,"63040":34857,"63041":34845,"63042":34843,"63043":34848,"63044":34852,"63045":34844,"63046":34859,"63047":34890,"63048":35181,"63049":35177,"63050":35182,"63051":35179,"63052":35322,"63053":35705,"63054":35704,"63055":35653,"63056":35706,"63057":35707,"63058":36112,"63059":36116,"63060":36271,"63061":36494,"63062":36492,"63063":36702,"63064":36699,"63065":36701,"63066":37190,"63067":37188,"63068":37189,"63069":37305,"63070":37951,"63071":37947,"63072":37942,"63073":37929,"63074":37949,"63075":37948,"63076":37936,"63077":37945,"63078":37930,"63079":37943,"63080":37932,"63081":37952,"63082":37937,"63083":38373,"63084":38372,"63085":38371,"63086":38709,"63087":38714,"63088":38847,"63089":38881,"63090":39012,"63091":39113,"63092":39110,"63093":39104,"63094":39256,"63095":39254,"63096":39481,"63097":39485,"63098":39494,"63099":39492,"63100":39490,"63101":39489,"63102":39482,"63137":39487,"63138":39629,"63139":39701,"63140":39703,"63141":39704,"63142":39702,"63143":39738,"63144":39762,"63145":39979,"63146":39965,"63147":39964,"63148":39980,"63149":39971,"63150":39976,"63151":39977,"63152":39972,"63153":39969,"63154":40375,"63155":40374,"63156":40380,"63157":40385,"63158":40391,"63159":40394,"63160":40399,"63161":40382,"63162":40389,"63163":40387,"63164":40379,"63165":40373,"63166":40398,"63167":40377,"63168":40378,"63169":40364,"63170":40392,"63171":40369,"63172":40365,"63173":40396,"63174":40371,"63175":40397,"63176":40370,"63177":40570,"63178":40604,"63179":40683,"63180":40686,"63181":40685,"63182":40731,"63183":40728,"63184":40730,"63185":40753,"63186":40782,"63187":40805,"63188":40804,"63189":40850,"63190":20153,"63191":22214,"63192":22213,"63193":22219,"63194":22897,"63195":23371,"63196":23372,"63197":24021,"63198":24017,"63199":24306,"63200":25889,"63201":25888,"63202":25894,"63203":25890,"63204":27403,"63205":27400,"63206":27401,"63207":27661,"63208":28757,"63209":28758,"63210":28759,"63211":28754,"63212":29214,"63213":29215,"63214":29353,"63215":29567,"63216":29912,"63217":29909,"63218":29913,"63219":29911,"63220":30317,"63221":30381,"63222":31029,"63223":31156,"63224":31344,"63225":31345,"63226":31831,"63227":31836,"63228":31833,"63229":31835,"63230":31834,"63296":31988,"63297":31985,"63298":32401,"63299":32591,"63300":32647,"63301":33246,"63302":33387,"63303":34356,"63304":34357,"63305":34355,"63306":34348,"63307":34354,"63308":34358,"63309":34860,"63310":34856,"63311":34854,"63312":34858,"63313":34853,"63314":35185,"63315":35263,"63316":35262,"63317":35323,"63318":35710,"63319":35716,"63320":35714,"63321":35718,"63322":35717,"63323":35711,"63324":36117,"63325":36501,"63326":36500,"63327":36506,"63328":36498,"63329":36496,"63330":36502,"63331":36503,"63332":36704,"63333":36706,"63334":37191,"63335":37964,"63336":37968,"63337":37962,"63338":37963,"63339":37967,"63340":37959,"63341":37957,"63342":37960,"63343":37961,"63344":37958,"63345":38719,"63346":38883,"63347":39018,"63348":39017,"63349":39115,"63350":39252,"63351":39259,"63352":39502,"63353":39507,"63354":39508,"63355":39500,"63356":39503,"63357":39496,"63358":39498,"63393":39497,"63394":39506,"63395":39504,"63396":39632,"63397":39705,"63398":39723,"63399":39739,"63400":39766,"63401":39765,"63402":40006,"63403":40008,"63404":39999,"63405":40004,"63406":39993,"63407":39987,"63408":40001,"63409":39996,"63410":39991,"63411":39988,"63412":39986,"63413":39997,"63414":39990,"63415":40411,"63416":40402,"63417":40414,"63418":40410,"63419":40395,"63420":40400,"63421":40412,"63422":40401,"63423":40415,"63424":40425,"63425":40409,"63426":40408,"63427":40406,"63428":40437,"63429":40405,"63430":40413,"63431":40630,"63432":40688,"63433":40757,"63434":40755,"63435":40754,"63436":40770,"63437":40811,"63438":40853,"63439":40866,"63440":20797,"63441":21145,"63442":22760,"63443":22759,"63444":22898,"63445":23373,"63446":24024,"63447":34863,"63448":24399,"63449":25089,"63450":25091,"63451":25092,"63452":25897,"63453":25893,"63454":26006,"63455":26347,"63456":27409,"63457":27410,"63458":27407,"63459":27594,"63460":28763,"63461":28762,"63462":29218,"63463":29570,"63464":29569,"63465":29571,"63466":30320,"63467":30676,"63468":31847,"63469":31846,"63470":32405,"63471":33388,"63472":34362,"63473":34368,"63474":34361,"63475":34364,"63476":34353,"63477":34363,"63478":34366,"63479":34864,"63480":34866,"63481":34862,"63482":34867,"63483":35190,"63484":35188,"63485":35187,"63486":35326,"63552":35724,"63553":35726,"63554":35723,"63555":35720,"63556":35909,"63557":36121,"63558":36504,"63559":36708,"63560":36707,"63561":37308,"63562":37986,"63563":37973,"63564":37981,"63565":37975,"63566":37982,"63567":38852,"63568":38853,"63569":38912,"63570":39510,"63571":39513,"63572":39710,"63573":39711,"63574":39712,"63575":40018,"63576":40024,"63577":40016,"63578":40010,"63579":40013,"63580":40011,"63581":40021,"63582":40025,"63583":40012,"63584":40014,"63585":40443,"63586":40439,"63587":40431,"63588":40419,"63589":40427,"63590":40440,"63591":40420,"63592":40438,"63593":40417,"63594":40430,"63595":40422,"63596":40434,"63597":40432,"63598":40418,"63599":40428,"63600":40436,"63601":40435,"63602":40424,"63603":40429,"63604":40642,"63605":40656,"63606":40690,"63607":40691,"63608":40710,"63609":40732,"63610":40760,"63611":40759,"63612":40758,"63613":40771,"63614":40783,"63649":40817,"63650":40816,"63651":40814,"63652":40815,"63653":22227,"63654":22221,"63655":23374,"63656":23661,"63657":25901,"63658":26349,"63659":26350,"63660":27411,"63661":28767,"63662":28769,"63663":28765,"63664":28768,"63665":29219,"63666":29915,"63667":29925,"63668":30677,"63669":31032,"63670":31159,"63671":31158,"63672":31850,"63673":32407,"63674":32649,"63675":33389,"63676":34371,"63677":34872,"63678":34871,"63679":34869,"63680":34891,"63681":35732,"63682":35733,"63683":36510,"63684":36511,"63685":36512,"63686":36509,"63687":37310,"63688":37309,"63689":37314,"63690":37995,"63691":37992,"63692":37993,"63693":38629,"63694":38726,"63695":38723,"63696":38727,"63697":38855,"63698":38885,"63699":39518,"63700":39637,"63701":39769,"63702":40035,"63703":40039,"63704":40038,"63705":40034,"63706":40030,"63707":40032,"63708":40450,"63709":40446,"63710":40455,"63711":40451,"63712":40454,"63713":40453,"63714":40448,"63715":40449,"63716":40457,"63717":40447,"63718":40445,"63719":40452,"63720":40608,"63721":40734,"63722":40774,"63723":40820,"63724":40821,"63725":40822,"63726":22228,"63727":25902,"63728":26040,"63729":27416,"63730":27417,"63731":27415,"63732":27418,"63733":28770,"63734":29222,"63735":29354,"63736":30680,"63737":30681,"63738":31033,"63739":31849,"63740":31851,"63741":31990,"63742":32410,"63808":32408,"63809":32411,"63810":32409,"63811":33248,"63812":33249,"63813":34374,"63814":34375,"63815":34376,"63816":35193,"63817":35194,"63818":35196,"63819":35195,"63820":35327,"63821":35736,"63822":35737,"63823":36517,"63824":36516,"63825":36515,"63826":37998,"63827":37997,"63828":37999,"63829":38001,"63830":38003,"63831":38729,"63832":39026,"63833":39263,"63834":40040,"63835":40046,"63836":40045,"63837":40459,"63838":40461,"63839":40464,"63840":40463,"63841":40466,"63842":40465,"63843":40609,"63844":40693,"63845":40713,"63846":40775,"63847":40824,"63848":40827,"63849":40826,"63850":40825,"63851":22302,"63852":28774,"63853":31855,"63854":34876,"63855":36274,"63856":36518,"63857":37315,"63858":38004,"63859":38008,"63860":38006,"63861":38005,"63862":39520,"63863":40052,"63864":40051,"63865":40049,"63866":40053,"63867":40468,"63868":40467,"63869":40694,"63870":40714,"63905":40868,"63906":28776,"63907":28773,"63908":31991,"63909":34410,"63910":34878,"63911":34877,"63912":34879,"63913":35742,"63914":35996,"63915":36521,"63916":36553,"63917":38731,"63918":39027,"63919":39028,"63920":39116,"63921":39265,"63922":39339,"63923":39524,"63924":39526,"63925":39527,"63926":39716,"63927":40469,"63928":40471,"63929":40776,"63930":25095,"63931":27422,"63932":29223,"63933":34380,"63934":36520,"63935":38018,"63936":38016,"63937":38017,"63938":39529,"63939":39528,"63940":39726,"63941":40473,"63942":29225,"63943":34379,"63944":35743,"63945":38019,"63946":40057,"63947":40631,"63948":30325,"63949":39531,"63950":40058,"63951":40477,"63952":28777,"63953":28778,"63954":40612,"63955":40830,"63956":40777,"63957":40856,"63958":30849,"63959":37561,"63960":35023,"63961":22715,"63962":24658,"63963":31911,"63964":23290,"63965":9556,"63966":9574,"63967":9559,"63968":9568,"63969":9580,"63970":9571,"63971":9562,"63972":9577,"63973":9565,"63974":9554,"63975":9572,"63976":9557,"63977":9566,"63978":9578,"63979":9569,"63980":9560,"63981":9575,"63982":9563,"63983":9555,"63984":9573,"63985":9558,"63986":9567,"63987":9579,"63988":9570,"63989":9561,"63990":9576,"63991":9564,"63992":9553,"63993":9552,"63994":9581,"63995":9582,"63996":9584,"63997":9583,"63998":9619,"64064":57344,"64065":57345,"64066":57346,"64067":57347,"64068":57348,"64069":57349,"64070":57350,"64071":57351,"64072":57352,"64073":57353,"64074":57354,"64075":57355,"64076":57356,"64077":57357,"64078":57358,"64079":57359,"64080":57360,"64081":57361,"64082":57362,"64083":57363,"64084":57364,"64085":57365,"64086":57366,"64087":57367,"64088":57368,"64089":57369,"64090":57370,"64091":57371,"64092":57372,"64093":57373,"64094":57374,"64095":57375,"64096":57376,"64097":57377,"64098":57378,"64099":57379,"64100":29234,"64101":29244,"64102":29286,"64103":29314,"64104":29327,"64105":29343,"64106":29357,"64107":29361,"64108":29368,"64109":29374,"64110":29389,"64111":29403,"64112":29476,"64113":29487,"64114":29496,"64115":29497,"64116":29629,"64117":29646,"64118":29681,"64119":29814,"64120":29858,"64121":29953,"64122":29977,"64123":29987,"64124":30012,"64125":30020,"64126":30025,"64161":30029,"64162":30061,"64163":30082,"64164":30083,"64165":30089,"64166":30124,"64167":30166,"64168":30185,"64169":30272,"64170":30285,"64171":30292,"64172":30312,"64173":30336,"64174":30339,"64175":30352,"64176":30391,"64177":30393,"64178":30477,"64179":30494,"64180":30531,"64181":30744,"64182":30748,"64183":30777,"64184":30780,"64185":30791,"64186":30806,"64187":30842,"64188":30901,"64189":30905,"64190":30918,"64191":30937,"64192":30983,"64193":31024,"64194":31028,"64195":31035,"64196":31104,"64197":31133,"64198":31171,"64199":31201,"64200":31238,"64201":31246,"64202":31299,"64203":31312,"64204":31427,"64205":31442,"64206":31458,"64207":31463,"64208":31480,"64209":31542,"64210":31586,"64211":31596,"64212":31610,"64213":31611,"64214":31642,"64215":31646,"64216":31647,"64217":31650,"64218":31655,"64219":31734,"64220":31762,"64221":31764,"64222":31823,"64223":31830,"64224":31832,"64225":31915,"64226":31994,"64227":32072,"64228":32075,"64229":32119,"64230":32212,"64231":32213,"64232":32214,"64233":32228,"64234":32333,"64235":32349,"64236":32383,"64237":32393,"64238":32398,"64239":32402,"64240":32468,"64241":32497,"64242":32530,"64243":32560,"64244":32625,"64245":32642,"64246":32686,"64247":32710,"64248":32800,"64249":32802,"64250":32805,"64251":32817,"64252":32863,"64253":32872,"64254":32940,"64320":32951,"64321":20890,"64322":21526,"64323":21524,"64324":13535,"64325":19581,"64326":25283,"64327":57508,"64328":57509,"64329":57510,"64330":21707,"64331":57512,"64332":21948,"64333":32950,"64334":20903,"64335":57516,"64336":57517,"64337":57518,"64338":21779,"64339":33318,"64340":57521,"64341":21790,"64342":21982,"64343":25529,"64344":26776,"64345":57526,"64346":21762,"64347":21865,"64348":30132,"64349":25596,"64350":40580,"64351":37418,"64352":57533,"64353":57534,"64354":57535,"64355":35015,"64356":24734,"64357":22053,"64358":28997,"64359":23282,"64360":57541,"64361":21135,"64362":22095,"64363":30611,"64364":34694,"64365":36397,"64366":33206,"64367":13822,"64368":29174,"64369":57550,"64370":34820,"64371":37765,"64372":57553,"64373":57554,"64374":30310,"64375":57556,"64376":40050,"64377":57558,"64378":25294,"64379":57560,"64380":40598,"64381":18825,"64382":31955,"64417":36570,"64418":40619,"64419":25831,"64420":57567,"64421":33450,"64422":26471,"64423":28018,"64424":30982,"64425":31172,"64426":32590,"64427":34798,"64428":57575,"64429":33726,"64430":34351,"64431":35237,"64432":17935,"64433":57580,"64434":39112,"64435":39232,"64436":39245,"64437":39436,"64438":39639,"64439":40600,"64440":40742,"64441":57588,"64442":20227,"64443":57590,"64444":20281,"64445":20274,"64446":20395,"64447":20566,"64448":57595,"64449":20526,"64450":20646,"64451":20697,"64452":20750,"64453":20717,"64454":20737,"64455":20980,"64456":21023,"64457":21088,"64458":21079,"64459":21146,"64460":21201,"64461":21216,"64462":21217,"64463":20947,"64464":20959,"64465":30022,"64466":20990,"64467":21298,"64468":21292,"64469":21299,"64470":21419,"64471":21418,"64472":40846,"64473":21609,"64474":21660,"64475":21466,"64476":27338,"64477":21875,"64478":57625,"64479":13782,"64480":57627,"64481":22033,"64482":22093,"64483":57630,"64484":22100,"64485":13811,"64486":57633,"64487":22342,"64488":22394,"64489":22375,"64490":22586,"64491":22502,"64492":22493,"64493":22592,"64494":57641,"64495":22566,"64496":22748,"64497":22967,"64498":23001,"64499":23584,"64500":57647,"64501":23761,"64502":23785,"64503":23878,"64504":23950,"64505":57652,"64506":24053,"64507":24075,"64508":24082,"64509":24110,"64510":24158,"64576":57658,"64577":24397,"64578":31357,"64579":23491,"64580":31419,"64581":57663,"64582":57664,"64583":24484,"64584":24506,"64585":24508,"64586":57668,"64587":24695,"64588":24740,"64589":24755,"64590":24829,"64591":24880,"64592":57674,"64593":24988,"64594":24921,"64595":24957,"64596":24924,"64597":25471,"64598":25058,"64599":28885,"64600":25145,"64601":25192,"64602":25221,"64603":25218,"64604":25254,"64605":25301,"64606":25444,"64607":25397,"64608":25744,"64609":14940,"64610":26184,"64611":26215,"64612":26398,"64613":26627,"64614":26540,"64615":26617,"64616":26806,"64617":26924,"64618":26881,"64619":26880,"64620":26826,"64621":26995,"64622":27008,"64623":26942,"64624":57706,"64625":27058,"64626":27072,"64627":27018,"64628":27130,"64629":27113,"64630":27314,"64631":27218,"64632":27293,"64633":27421,"64634":27474,"64635":27642,"64636":15569,"64637":27854,"64638":28239,"64673":28089,"64674":28484,"64675":57723,"64676":28634,"64677":28801,"64678":31180,"64679":28980,"64680":15820,"64681":29046,"64682":57730,"64683":57731,"64684":29205,"64685":29264,"64686":29319,"64687":29484,"64688":29362,"64689":29410,"64690":29442,"64691":29512,"64692":29480,"64693":29519,"64694":29553,"64695":25989,"64696":57744,"64697":29789,"64698":29800,"64699":29982,"64700":30035,"64701":30074,"64702":30369,"64703":30412,"64704":30500,"64705":30507,"64706":16485,"64707":30803,"64708":30931,"64709":30936,"64710":40318,"64711":30895,"64712":57760,"64713":24898,"64714":31145,"64715":39994,"64716":31188,"64717":57765,"64718":31277,"64719":31294,"64720":31305,"64721":31453,"64722":31450,"64723":30147,"64724":30215,"64725":30210,"64726":57774,"64727":30311,"64728":30319,"64729":22048,"64730":35431,"64731":40727,"64732":31519,"64733":31634,"64734":31651,"64735":31695,"64736":57784,"64737":31740,"64738":31810,"64739":31825,"64740":31837,"64741":31856,"64742":31870,"64743":31878,"64744":31875,"64745":31916,"64746":31943,"64747":31938,"64748":57796,"64749":31962,"64750":57798,"64751":32077,"64752":32090,"64753":32245,"64754":32295,"64755":32366,"64756":40597,"64757":21107,"64758":32797,"64759":32866,"64760":32867,"64761":32870,"64762":32859,"64763":32934,"64764":33027,"64765":40577,"64766":33224,"64832":57815,"64833":36768,"64834":33270,"64835":33306,"64836":57819,"64837":34673,"64838":34729,"64839":34700,"64840":40606,"64841":34753,"64842":40476,"64843":57826,"64844":34774,"64845":34805,"64846":34831,"64847":34840,"64848":34861,"64849":34882,"64850":34885,"64851":39989,"64852":34926,"64853":34986,"64854":34976,"64855":25245,"64856":35139,"64857":35149,"64858":29042,"64859":34910,"64860":57843,"64861":33533,"64862":17591,"64863":33488,"64864":33669,"64865":40194,"64866":40809,"64867":33824,"64868":57851,"64869":34010,"64870":33965,"64871":17659,"64872":34123,"64873":57856,"64874":34306,"64875":34320,"64876":25553,"64877":35209,"64878":35210,"64879":35220,"64880":40005,"64881":35260,"64882":35454,"64883":35401,"64884":35596,"64885":35651,"64886":35713,"64887":35660,"64888":57871,"64889":36013,"64890":36075,"64891":36087,"64892":36108,"64893":36226,"64894":36262,"64929":36308,"64930":36392,"64931":36431,"64932":36471,"64933":36469,"64934":36519,"64935":36633,"64936":57885,"64937":36700,"64938":40260,"64939":37060,"64940":37201,"64941":57890,"64942":37212,"64943":37209,"64944":37223,"64945":37244,"64946":37262,"64947":37307,"64948":40616,"64949":36950,"64950":36940,"64951":37374,"64952":37474,"64953":37566,"64954":37739,"64955":37742,"64956":37818,"64957":37927,"64958":38295,"64959":38311,"64960":57909,"64961":38456,"64962":57911,"64963":38531,"64964":38550,"64965":38529,"64966":38589,"64967":38659,"64968":38689,"64969":38705,"64970":38751,"64971":38815,"64972":38836,"64973":38840,"64974":38842,"64975":38846,"64976":38856,"64977":40639,"64978":38943,"64979":38958,"64980":40869,"64981":38983,"64982":38987,"64983":39014,"64984":39020,"64985":39092,"64986":40794,"64987":39132,"64988":39142,"64989":39234,"64990":39225,"64991":39227,"64992":40787,"64993":39242,"64994":40773,"64995":19326,"64996":39386,"64997":31432,"64998":39610,"64999":39613,"65000":40706,"65001":39722,"65002":57951,"65003":39725,"65004":39650,"65005":39682,"65006":39679,"65007":19463,"65008":39689,"65009":19460,"65010":19515,"65011":39823,"65012":39837,"65013":39856,"65014":39948,"65015":39957,"65016":39946,"65017":39935,"65018":39982,"65019":33000,"65020":33001,"65021":33004,"65022":33038,"65088":27705,"65089":20074,"65090":38465,"65091":22770,"65092":31074,"65093":26658,"65094":57978,"65095":57979,"65096":33031,"65097":22487,"65098":17642,"65099":25653,"65100":34100,"65101":16607,"65102":57986,"65103":26906,"65104":39938,"65105":30129,"65106":33747,"65107":29041,"65108":27147,"65109":57993,"65110":27258,"65111":39668,"65112":57996,"65113":57997,"65114":30649,"65115":25904,"65116":28054,"65117":22071,"65118":26405,"65119":27179,"65120":32093,"65121":36961,"65122":20120,"65123":31910,"65124":31545,"65125":58009,"65126":22901,"65127":14023,"65128":28799,"65129":58013,"65130":28299,"65131":58015,"65132":58016,"65133":38749,"65134":37584,"65135":22356,"65136":58020,"65137":16089,"65138":58022,"65139":58023,"65140":24985,"65141":29792,"65142":28991,"65143":31022,"65144":23190,"65145":37704,"65146":26254,"65147":20477,"65148":37697,"65149":13908,"65150":23925,"65185":28702,"65186":25979,"65187":28813,"65188":24269,"65189":58039,"65190":24743,"65191":31408,"65192":24419,"65193":58043,"65194":29687,"65195":58045,"65196":29800,"65197":30132,"65198":58048,"65199":39785,"65200":189,"65201":8531,"65202":8532,"65203":188,"65204":190,"65205":8533,"65206":8534,"65207":8535,"65208":8536,"65209":8537,"65210":8538,"65211":34450,"65212":34464,"65213":34477,"65214":34482,"65215":34725,"65216":34737,"65217":8539,"65218":8540,"65219":8541,"65220":8542,"65221":34778,"65222":34895,"65223":34912,"65224":34951,"65225":34959,"65226":34960,"65227":35046,"65228":35071,"65229":35072,"65230":35108,"65231":35143,"65232":35156,"65233":35173,"65234":35200,"65235":35217,"65236":35356,"65237":35369,"65238":35371,"65239":35384,"65240":35389,"65241":8978,"65242":35472,"65243":35476,"65244":35484,"65245":35497,"65246":35503,"65247":35508,"65248":35562,"65249":35615,"65250":8240,"65251":35647,"65252":35661,"65253":35678,"65254":35682,"65255":35689,"65256":35739,"65257":35921,"65258":35995,"65259":35999,"65260":36052,"65261":36054,"65262":33042,"65263":33073,"65264":33078,"65265":33119,"65266":33133,"65267":33149,"65268":33171,"65269":33194,"65270":33208,"65271":33217,"65272":33321,"65273":33325,"65274":33326,"65275":33342,"65276":33378,"65277":33386,"65278":33416,"NaN":null}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/encodings/table/gbk.js
-@@ -0,0 +1 @@
-+module.exports={33088:19970,33089:19972,33090:19973,33091:19974,33092:19983,33093:19986,33094:19991,33095:19999,33096:20000,33097:20001,33098:20003,33099:20006,33100:20009,33101:20014,33102:20015,33103:20017,33104:20019,33105:20021,33106:20023,33107:20028,33108:20032,33109:20033,33110:20034,33111:20036,33112:20038,33113:20042,33114:20049,33115:20053,33116:20055,33117:20058,33118:20059,33119:20066,33120:20067,33121:20068,33122:20069,33123:20071,33124:20072,33125:20074,33126:20075,33127:20076,33128:20077,33129:20078,33130:20079,33131:20082,33132:20084,33133:20085,33134:20086,33135:20087,33136:20088,33137:20089,33138:20090,33139:20091,33140:20092,33141:20093,33142:20095,33143:20096,33144:20097,33145:20098,33146:20099,33147:20100,33148:20101,33149:20103,33150:20106,33152:20112,33153:20118,33154:20119,33155:20121,33156:20124,33157:20125,33158:20126,33159:20131,33160:20138,33161:20143,33162:20144,33163:20145,33164:20148,33165:20150,33166:20151,33167:20152,33168:20153,33169:20156,33170:20157,33171:20158,33172:20168,33173:20172,33174:20175,33175:20176,33176:20178,33177:20186,33178:20187,33179:20188,33180:20192,33181:20194,33182:20198,33183:20199,33184:20201,33185:20205,33186:20206,33187:20207,33188:20209,33189:20212,33190:20216,33191:20217,33192:20218,33193:20220,33194:20222,33195:20224,33196:20226,33197:20227,33198:20228,33199:20229,33200:20230,33201:20231,33202:20232,33203:20235,33204:20236,33205:20242,33206:20243,33207:20244,33208:20245,33209:20246,33210:20252,33211:20253,33212:20257,33213:20259,33214:20264,33215:20265,33216:20268,33217:20269,33218:20270,33219:20273,33220:20275,33221:20277,33222:20279,33223:20281,33224:20283,33225:20286,33226:20287,33227:20288,33228:20289,33229:20290,33230:20292,33231:20293,33232:20295,33233:20296,33234:20297,33235:20298,33236:20299,33237:20300,33238:20306,33239:20308,33240:20310,33241:20321,33242:20322,33243:20326,33244:20328,33245:20330,33246:20331,33247:20333,33248:20334,33249:20337,33250:20338,33251:20341,33252:20343,33253:20344,33254:20345,33255:20346,33256:20349,33257:20352,33258:20353,33259:20354,33260:20357,33261:20358,33262:20359,33263:20362,33264:20364,33265:20366,33266:20368,33267:20370,33268:20371,33269:20373,33270:20374,33271:20376,33272:20377,33273:20378,33274:20380,33275:20382,33276:20383,33277:20385,33278:20386,33344:20388,33345:20395,33346:20397,33347:20400,33348:20401,33349:20402,33350:20403,33351:20404,33352:20406,33353:20407,33354:20408,33355:20409,33356:20410,33357:20411,33358:20412,33359:20413,33360:20414,33361:20416,33362:20417,33363:20418,33364:20422,33365:20423,33366:20424,33367:20425,33368:20427,33369:20428,33370:20429,33371:20434,33372:20435,33373:20436,33374:20437,33375:20438,33376:20441,33377:20443,33378:20448,33379:20450,33380:20452,33381:20453,33382:20455,33383:20459,33384:20460,33385:20464,33386:20466,33387:20468,33388:20469,33389:20470,33390:20471,33391:20473,33392:20475,33393:20476,33394:20477,33395:20479,33396:20480,33397:20481,33398:20482,33399:20483,33400:20484,33401:20485,33402:20486,33403:20487,33404:20488,33405:20489,33406:20490,33408:20491,33409:20494,33410:20496,33411:20497,33412:20499,33413:20501,33414:20502,33415:20503,33416:20507,33417:20509,33418:20510,33419:20512,33420:20514,33421:20515,33422:20516,33423:20519,33424:20523,33425:20527,33426:20528,33427:20529,33428:20530,33429:20531,33430:20532,33431:20533,33432:20534,33433:20535,33434:20536,33435:20537,33436:20539,33437:20541,33438:20543,33439:20544,33440:20545,33441:20546,33442:20548,33443:20549,33444:20550,33445:20553,33446:20554,33447:20555,33448:20557,33449:20560,33450:20561,33451:20562,33452:20563,33453:20564,33454:20566,33455:20567,33456:20568,33457:20569,33458:20571,33459:20573,33460:20574,33461:20575,33462:20576,33463:20577,33464:20578,33465:20579,33466:20580,33467:20582,33468:20583,33469:20584,33470:20585,33471:20586,33472:20587,33473:20589,33474:20590,33475:20591,33476:20592,33477:20593,33478:20594,33479:20595,33480:20596,33481:20597,33482:20600,33483:20601,33484:20602,33485:20604,33486:20605,33487:20609,33488:20610,33489:20611,33490:20612,33491:20614,33492:20615,33493:20617,33494:20618,33495:20619,33496:20620,33497:20622,33498:20623,33499:20624,33500:20625,33501:20626,33502:20627,33503:20628,33504:20629,33505:20630,33506:20631,33507:20632,33508:20633,33509:20634,33510:20635,33511:20636,33512:20637,33513:20638,33514:20639,33515:20640,33516:20641,33517:20642,33518:20644,33519:20646,33520:20650,33521:20651,33522:20653,33523:20654,33524:20655,33525:20656,33526:20657,33527:20659,33528:20660,33529:20661,33530:20662,33531:20663,33532:20664,33533:20665,33534:20668,33600:20669,33601:20670,33602:20671,33603:20672,33604:20673,33605:20674,33606:20675,33607:20676,33608:20677,33609:20678,33610:20679,33611:20680,33612:20681,33613:20682,33614:20683,33615:20684,33616:20685,33617:20686,33618:20688,33619:20689,33620:20690,33621:20691,33622:20692,33623:20693,33624:20695,33625:20696,33626:20697,33627:20699,33628:20700,33629:20701,33630:20702,33631:20703,33632:20704,33633:20705,33634:20706,33635:20707,33636:20708,33637:20709,33638:20712,33639:20713,33640:20714,33641:20715,33642:20719,33643:20720,33644:20721,33645:20722,33646:20724,33647:20726,33648:20727,33649:20728,33650:20729,33651:20730,33652:20732,33653:20733,33654:20734,33655:20735,33656:20736,33657:20737,33658:20738,33659:20739,33660:20740,33661:20741,33662:20744,33664:20745,33665:20746,33666:20748,33667:20749,33668:20750,33669:20751,33670:20752,33671:20753,33672:20755,33673:20756,33674:20757,33675:20758,33676:20759,33677:20760,33678:20761,33679:20762,33680:20763,33681:20764,33682:20765,33683:20766,33684:20767,33685:20768,33686:20770,33687:20771,33688:20772,33689:20773,33690:20774,33691:20775,33692:20776,33693:20777,33694:20778,33695:20779,33696:20780,33697:20781,33698:20782,33699:20783,33700:20784,33701:20785,33702:20786,33703:20787,33704:20788,33705:20789,33706:20790,33707:20791,33708:20792,33709:20793,33710:20794,33711:20795,33712:20796,33713:20797,33714:20798,33715:20802,33716:20807,33717:20810,33718:20812,33719:20814,33720:20815,33721:20816,33722:20818,33723:20819,33724:20823,33725:20824,33726:20825,33727:20827,33728:20829,33729:20830,33730:20831,33731:20832,33732:20833,33733:20835,33734:20836,33735:20838,33736:20839,33737:20841,33738:20842,33739:20847,33740:20850,33741:20858,33742:20862,33743:20863,33744:20867,33745:20868,33746:20870,33747:20871,33748:20874,33749:20875,33750:20878,33751:20879,33752:20880,33753:20881,33754:20883,33755:20884,33756:20888,33757:20890,33758:20893,33759:20894,33760:20895,33761:20897,33762:20899,33763:20902,33764:20903,33765:20904,33766:20905,33767:20906,33768:20909,33769:20910,33770:20916,33771:20920,33772:20921,33773:20922,33774:20926,33775:20927,33776:20929,33777:20930,33778:20931,33779:20933,33780:20936,33781:20938,33782:20941,33783:20942,33784:20944,33785:20946,33786:20947,33787:20948,33788:20949,33789:20950,33790:20951,33856:20952,33857:20953,33858:20954,33859:20956,33860:20958,33861:20959,33862:20962,33863:20963,33864:20965,33865:20966,33866:20967,33867:20968,33868:20969,33869:20970,33870:20972,33871:20974,33872:20977,33873:20978,33874:20980,33875:20983,33876:20990,33877:20996,33878:20997,33879:21001,33880:21003,33881:21004,33882:21007,33883:21008,33884:21011,33885:21012,33886:21013,33887:21020,33888:21022,33889:21023,33890:21025,33891:21026,33892:21027,33893:21029,33894:21030,33895:21031,33896:21034,33897:21036,33898:21039,33899:21041,33900:21042,33901:21044,33902:21045,33903:21052,33904:21054,33905:21060,33906:21061,33907:21062,33908:21063,33909:21064,33910:21065,33911:21067,33912:21070,33913:21071,33914:21074,33915:21075,33916:21077,33917:21079,33918:21080,33920:21081,33921:21082,33922:21083,33923:21085,33924:21087,33925:21088,33926:21090,33927:21091,33928:21092,33929:21094,33930:21096,33931:21099,33932:21100,33933:21101,33934:21102,33935:21104,33936:21105,33937:21107,33938:21108,33939:21109,33940:21110,33941:21111,33942:21112,33943:21113,33944:21114,33945:21115,33946:21116,33947:21118,33948:21120,33949:21123,33950:21124,33951:21125,33952:21126,33953:21127,33954:21129,33955:21130,33956:21131,33957:21132,33958:21133,33959:21134,33960:21135,33961:21137,33962:21138,33963:21140,33964:21141,33965:21142,33966:21143,33967:21144,33968:21145,33969:21146,33970:21148,33971:21156,33972:21157,33973:21158,33974:21159,33975:21166,33976:21167,33977:21168,33978:21172,33979:21173,33980:21174,33981:21175,33982:21176,33983:21177,33984:21178,33985:21179,33986:21180,33987:21181,33988:21184,33989:21185,33990:21186,33991:21188,33992:21189,33993:21190,33994:21192,33995:21194,33996:21196,33997:21197,33998:21198,33999:21199,34000:21201,34001:21203,34002:21204,34003:21205,34004:21207,34005:21209,34006:21210,34007:21211,34008:21212,34009:21213,34010:21214,34011:21216,34012:21217,34013:21218,34014:21219,34015:21221,34016:21222,34017:21223,34018:21224,34019:21225,34020:21226,34021:21227,34022:21228,34023:21229,34024:21230,34025:21231,34026:21233,34027:21234,34028:21235,34029:21236,34030:21237,34031:21238,34032:21239,34033:21240,34034:21243,34035:21244,34036:21245,34037:21249,34038:21250,34039:21251,34040:21252,34041:21255,34042:21257,34043:21258,34044:21259,34045:21260,34046:21262,34112:21265,34113:21266,34114:21267,34115:21268,34116:21272,34117:21275,34118:21276,34119:21278,34120:21279,34121:21282,34122:21284,34123:21285,34124:21287,34125:21288,34126:21289,34127:21291,34128:21292,34129:21293,34130:21295,34131:21296,34132:21297,34133:21298,34134:21299,34135:21300,34136:21301,34137:21302,34138:21303,34139:21304,34140:21308,34141:21309,34142:21312,34143:21314,34144:21316,34145:21318,34146:21323,34147:21324,34148:21325,34149:21328,34150:21332,34151:21336,34152:21337,34153:21339,34154:21341,34155:21349,34156:21352,34157:21354,34158:21356,34159:21357,34160:21362,34161:21366,34162:21369,34163:21371,34164:21372,34165:21373,34166:21374,34167:21376,34168:21377,34169:21379,34170:21383,34171:21384,34172:21386,34173:21390,34174:21391,34176:21392,34177:21393,34178:21394,34179:21395,34180:21396,34181:21398,34182:21399,34183:21401,34184:21403,34185:21404,34186:21406,34187:21408,34188:21409,34189:21412,34190:21415,34191:21418,34192:21419,34193:21420,34194:21421,34195:21423,34196:21424,34197:21425,34198:21426,34199:21427,34200:21428,34201:21429,34202:21431,34203:21432,34204:21433,34205:21434,34206:21436,34207:21437,34208:21438,34209:21440,34210:21443,34211:21444,34212:21445,34213:21446,34214:21447,34215:21454,34216:21455,34217:21456,34218:21458,34219:21459,34220:21461,34221:21466,34222:21468,34223:21469,34224:21470,34225:21473,34226:21474,34227:21479,34228:21492,34229:21498,34230:21502,34231:21503,34232:21504,34233:21506,34234:21509,34235:21511,34236:21515,34237:21524,34238:21528,34239:21529,34240:21530,34241:21532,34242:21538,34243:21540,34244:21541,34245:21546,34246:21552,34247:21555,34248:21558,34249:21559,34250:21562,34251:21565,34252:21567,34253:21569,34254:21570,34255:21572,34256:21573,34257:21575,34258:21577,34259:21580,34260:21581,34261:21582,34262:21583,34263:21585,34264:21594,34265:21597,34266:21598,34267:21599,34268:21600,34269:21601,34270:21603,34271:21605,34272:21607,34273:21609,34274:21610,34275:21611,34276:21612,34277:21613,34278:21614,34279:21615,34280:21616,34281:21620,34282:21625,34283:21626,34284:21630,34285:21631,34286:21633,34287:21635,34288:21637,34289:21639,34290:21640,34291:21641,34292:21642,34293:21645,34294:21649,34295:21651,34296:21655,34297:21656,34298:21660,34299:21662,34300:21663,34301:21664,34302:21665,34368:21666,34369:21669,34370:21678,34371:21680,34372:21682,34373:21685,34374:21686,34375:21687,34376:21689,34377:21690,34378:21692,34379:21694,34380:21699,34381:21701,34382:21706,34383:21707,34384:21718,34385:21720,34386:21723,34387:21728,34388:21729,34389:21730,34390:21731,34391:21732,34392:21739,34393:21740,34394:21743,34395:21744,34396:21745,34397:21748,34398:21749,34399:21750,34400:21751,34401:21752,34402:21753,34403:21755,34404:21758,34405:21760,34406:21762,34407:21763,34408:21764,34409:21765,34410:21768,34411:21770,34412:21771,34413:21772,34414:21773,34415:21774,34416:21778,34417:21779,34418:21781,34419:21782,34420:21783,34421:21784,34422:21785,34423:21786,34424:21788,34425:21789,34426:21790,34427:21791,34428:21793,34429:21797,34430:21798,34432:21800,34433:21801,34434:21803,34435:21805,34436:21810,34437:21812,34438:21813,34439:21814,34440:21816,34441:21817,34442:21818,34443:21819,34444:21821,34445:21824,34446:21826,34447:21829,34448:21831,34449:21832,34450:21835,34451:21836,34452:21837,34453:21838,34454:21839,34455:21841,34456:21842,34457:21843,34458:21844,34459:21847,34460:21848,34461:21849,34462:21850,34463:21851,34464:21853,34465:21854,34466:21855,34467:21856,34468:21858,34469:21859,34470:21864,34471:21865,34472:21867,34473:21871,34474:21872,34475:21873,34476:21874,34477:21875,34478:21876,34479:21881,34480:21882,34481:21885,34482:21887,34483:21893,34484:21894,34485:21900,34486:21901,34487:21902,34488:21904,34489:21906,34490:21907,34491:21909,34492:21910,34493:21911,34494:21914,34495:21915,34496:21918,34497:21920,34498:21921,34499:21922,34500:21923,34501:21924,34502:21925,34503:21926,34504:21928,34505:21929,34506:21930,34507:21931,34508:21932,34509:21933,34510:21934,34511:21935,34512:21936,34513:21938,34514:21940,34515:21942,34516:21944,34517:21946,34518:21948,34519:21951,34520:21952,34521:21953,34522:21954,34523:21955,34524:21958,34525:21959,34526:21960,34527:21962,34528:21963,34529:21966,34530:21967,34531:21968,34532:21973,34533:21975,34534:21976,34535:21977,34536:21978,34537:21979,34538:21982,34539:21984,34540:21986,34541:21991,34542:21993,34543:21997,34544:21998,34545:22000,34546:22001,34547:22004,34548:22006,34549:22008,34550:22009,34551:22010,34552:22011,34553:22012,34554:22015,34555:22018,34556:22019,34557:22020,34558:22021,34624:22022,34625:22023,34626:22026,34627:22027,34628:22029,34629:22032,34630:22033,34631:22034,34632:22035,34633:22036,34634:22037,34635:22038,34636:22039,34637:22041,34638:22042,34639:22044,34640:22045,34641:22048,34642:22049,34643:22050,34644:22053,34645:22054,34646:22056,34647:22057,34648:22058,34649:22059,34650:22062,34651:22063,34652:22064,34653:22067,34654:22069,34655:22071,34656:22072,34657:22074,34658:22076,34659:22077,34660:22078,34661:22080,34662:22081,34663:22082,34664:22083,34665:22084,34666:22085,34667:22086,34668:22087,34669:22088,34670:22089,34671:22090,34672:22091,34673:22095,34674:22096,34675:22097,34676:22098,34677:22099,34678:22101,34679:22102,34680:22106,34681:22107,34682:22109,34683:22110,34684:22111,34685:22112,34686:22113,34688:22115,34689:22117,34690:22118,34691:22119,34692:22125,34693:22126,34694:22127,34695:22128,34696:22130,34697:22131,34698:22132,34699:22133,34700:22135,34701:22136,34702:22137,34703:22138,34704:22141,34705:22142,34706:22143,34707:22144,34708:22145,34709:22146,34710:22147,34711:22148,34712:22151,34713:22152,34714:22153,34715:22154,34716:22155,34717:22156,34718:22157,34719:22160,34720:22161,34721:22162,34722:22164,34723:22165,34724:22166,34725:22167,34726:22168,34727:22169,34728:22170,34729:22171,34730:22172,34731:22173,34732:22174,34733:22175,34734:22176,34735:22177,34736:22178,34737:22180,34738:22181,34739:22182,34740:22183,34741:22184,34742:22185,34743:22186,34744:22187,34745:22188,34746:22189,34747:22190,34748:22192,34749:22193,34750:22194,34751:22195,34752:22196,34753:22197,34754:22198,34755:22200,34756:22201,34757:22202,34758:22203,34759:22205,34760:22206,34761:22207,34762:22208,34763:22209,34764:22210,34765:22211,34766:22212,34767:22213,34768:22214,34769:22215,34770:22216,34771:22217,34772:22219,34773:22220,34774:22221,34775:22222,34776:22223,34777:22224,34778:22225,34779:22226,34780:22227,34781:22229,34782:22230,34783:22232,34784:22233,34785:22236,34786:22243,34787:22245,34788:22246,34789:22247,34790:22248,34791:22249,34792:22250,34793:22252,34794:22254,34795:22255,34796:22258,34797:22259,34798:22262,34799:22263,34800:22264,34801:22267,34802:22268,34803:22272,34804:22273,34805:22274,34806:22277,34807:22279,34808:22283,34809:22284,34810:22285,34811:22286,34812:22287,34813:22288,34814:22289,34880:22290,34881:22291,34882:22292,34883:22293,34884:22294,34885:22295,34886:22296,34887:22297,34888:22298,34889:22299,34890:22301,34891:22302,34892:22304,34893:22305,34894:22306,34895:22308,34896:22309,34897:22310,34898:22311,34899:22315,34900:22321,34901:22322,34902:22324,34903:22325,34904:22326,34905:22327,34906:22328,34907:22332,34908:22333,34909:22335,34910:22337,34911:22339,34912:22340,34913:22341,34914:22342,34915:22344,34916:22345,34917:22347,34918:22354,34919:22355,34920:22356,34921:22357,34922:22358,34923:22360,34924:22361,34925:22370,34926:22371,34927:22373,34928:22375,34929:22380,34930:22382,34931:22384,34932:22385,34933:22386,34934:22388,34935:22389,34936:22392,34937:22393,34938:22394,34939:22397,34940:22398,34941:22399,34942:22400,34944:22401,34945:22407,34946:22408,34947:22409,34948:22410,34949:22413,34950:22414,34951:22415,34952:22416,34953:22417,34954:22420,34955:22421,34956:22422,34957:22423,34958:22424,34959:22425,34960:22426,34961:22428,34962:22429,34963:22430,34964:22431,34965:22437,34966:22440,34967:22442,34968:22444,34969:22447,34970:22448,34971:22449,34972:22451,34973:22453,34974:22454,34975:22455,34976:22457,34977:22458,34978:22459,34979:22460,34980:22461,34981:22462,34982:22463,34983:22464,34984:22465,34985:22468,34986:22469,34987:22470,34988:22471,34989:22472,34990:22473,34991:22474,34992:22476,34993:22477,34994:22480,34995:22481,34996:22483,34997:22486,34998:22487,34999:22491,35000:22492,35001:22494,35002:22497,35003:22498,35004:22499,35005:22501,35006:22502,35007:22503,35008:22504,35009:22505,35010:22506,35011:22507,35012:22508,35013:22510,35014:22512,35015:22513,35016:22514,35017:22515,35018:22517,35019:22518,35020:22519,35021:22523,35022:22524,35023:22526,35024:22527,35025:22529,35026:22531,35027:22532,35028:22533,35029:22536,35030:22537,35031:22538,35032:22540,35033:22542,35034:22543,35035:22544,35036:22546,35037:22547,35038:22548,35039:22550,35040:22551,35041:22552,35042:22554,35043:22555,35044:22556,35045:22557,35046:22559,35047:22562,35048:22563,35049:22565,35050:22566,35051:22567,35052:22568,35053:22569,35054:22571,35055:22572,35056:22573,35057:22574,35058:22575,35059:22577,35060:22578,35061:22579,35062:22580,35063:22582,35064:22583,35065:22584,35066:22585,35067:22586,35068:22587,35069:22588,35070:22589,35136:22590,35137:22591,35138:22592,35139:22593,35140:22594,35141:22595,35142:22597,35143:22598,35144:22599,35145:22600,35146:22601,35147:22602,35148:22603,35149:22606,35150:22607,35151:22608,35152:22610,35153:22611,35154:22613,35155:22614,35156:22615,35157:22617,35158:22618,35159:22619,35160:22620,35161:22621,35162:22623,35163:22624,35164:22625,35165:22626,35166:22627,35167:22628,35168:22630,35169:22631,35170:22632,35171:22633,35172:22634,35173:22637,35174:22638,35175:22639,35176:22640,35177:22641,35178:22642,35179:22643,35180:22644,35181:22645,35182:22646,35183:22647,35184:22648,35185:22649,35186:22650,35187:22651,35188:22652,35189:22653,35190:22655,35191:22658,35192:22660,35193:22662,35194:22663,35195:22664,35196:22666,35197:22667,35198:22668,35200:22669,35201:22670,35202:22671,35203:22672,35204:22673,35205:22676,35206:22677,35207:22678,35208:22679,35209:22680,35210:22683,35211:22684,35212:22685,35213:22688,35214:22689,35215:22690,35216:22691,35217:22692,35218:22693,35219:22694,35220:22695,35221:22698,35222:22699,35223:22700,35224:22701,35225:22702,35226:22703,35227:22704,35228:22705,35229:22706,35230:22707,35231:22708,35232:22709,35233:22710,35234:22711,35235:22712,35236:22713,35237:22714,35238:22715,35239:22717,35240:22718,35241:22719,35242:22720,35243:22722,35244:22723,35245:22724,35246:22726,35247:22727,35248:22728,35249:22729,35250:22730,35251:22731,35252:22732,35253:22733,35254:22734,35255:22735,35256:22736,35257:22738,35258:22739,35259:22740,35260:22742,35261:22743,35262:22744,35263:22745,35264:22746,35265:22747,35266:22748,35267:22749,35268:22750,35269:22751,35270:22752,35271:22753,35272:22754,35273:22755,35274:22757,35275:22758,35276:22759,35277:22760,35278:22761,35279:22762,35280:22765,35281:22767,35282:22769,35283:22770,35284:22772,35285:22773,35286:22775,35287:22776,35288:22778,35289:22779,35290:22780,35291:22781,35292:22782,35293:22783,35294:22784,35295:22785,35296:22787,35297:22789,35298:22790,35299:22792,35300:22793,35301:22794,35302:22795,35303:22796,35304:22798,35305:22800,35306:22801,35307:22802,35308:22803,35309:22807,35310:22808,35311:22811,35312:22813,35313:22814,35314:22816,35315:22817,35316:22818,35317:22819,35318:22822,35319:22824,35320:22828,35321:22832,35322:22834,35323:22835,35324:22837,35325:22838,35326:22843,35392:22845,35393:22846,35394:22847,35395:22848,35396:22851,35397:22853,35398:22854,35399:22858,35400:22860,35401:22861,35402:22864,35403:22866,35404:22867,35405:22873,35406:22875,35407:22876,35408:22877,35409:22878,35410:22879,35411:22881,35412:22883,35413:22884,35414:22886,35415:22887,35416:22888,35417:22889,35418:22890,35419:22891,35420:22892,35421:22893,35422:22894,35423:22895,35424:22896,35425:22897,35426:22898,35427:22901,35428:22903,35429:22906,35430:22907,35431:22908,35432:22910,35433:22911,35434:22912,35435:22917,35436:22921,35437:22923,35438:22924,35439:22926,35440:22927,35441:22928,35442:22929,35443:22932,35444:22933,35445:22936,35446:22938,35447:22939,35448:22940,35449:22941,35450:22943,35451:22944,35452:22945,35453:22946,35454:22950,35456:22951,35457:22956,35458:22957,35459:22960,35460:22961,35461:22963,35462:22964,35463:22965,35464:22966,35465:22967,35466:22968,35467:22970,35468:22972,35469:22973,35470:22975,35471:22976,35472:22977,35473:22978,35474:22979,35475:22980,35476:22981,35477:22983,35478:22984,35479:22985,35480:22988,35481:22989,35482:22990,35483:22991,35484:22997,35485:22998,35486:23001,35487:23003,35488:23006,35489:23007,35490:23008,35491:23009,35492:23010,35493:23012,35494:23014,35495:23015,35496:23017,35497:23018,35498:23019,35499:23021,35500:23022,35501:23023,35502:23024,35503:23025,35504:23026,35505:23027,35506:23028,35507:23029,35508:23030,35509:23031,35510:23032,35511:23034,35512:23036,35513:23037,35514:23038,35515:23040,35516:23042,35517:23050,35518:23051,35519:23053,35520:23054,35521:23055,35522:23056,35523:23058,35524:23060,35525:23061,35526:23062,35527:23063,35528:23065,35529:23066,35530:23067,35531:23069,35532:23070,35533:23073,35534:23074,35535:23076,35536:23078,35537:23079,35538:23080,35539:23082,35540:23083,35541:23084,35542:23085,35543:23086,35544:23087,35545:23088,35546:23091,35547:23093,35548:23095,35549:23096,35550:23097,35551:23098,35552:23099,35553:23101,35554:23102,35555:23103,35556:23105,35557:23106,35558:23107,35559:23108,35560:23109,35561:23111,35562:23112,35563:23115,35564:23116,35565:23117,35566:23118,35567:23119,35568:23120,35569:23121,35570:23122,35571:23123,35572:23124,35573:23126,35574:23127,35575:23128,35576:23129,35577:23131,35578:23132,35579:23133,35580:23134,35581:23135,35582:23136,35648:23137,35649:23139,35650:23140,35651:23141,35652:23142,35653:23144,35654:23145,35655:23147,35656:23148,35657:23149,35658:23150,35659:23151,35660:23152,35661:23153,35662:23154,35663:23155,35664:23160,35665:23161,35666:23163,35667:23164,35668:23165,35669:23166,35670:23168,35671:23169,35672:23170,35673:23171,35674:23172,35675:23173,35676:23174,35677:23175,35678:23176,35679:23177,35680:23178,35681:23179,35682:23180,35683:23181,35684:23182,35685:23183,35686:23184,35687:23185,35688:23187,35689:23188,35690:23189,35691:23190,35692:23191,35693:23192,35694:23193,35695:23196,35696:23197,35697:23198,35698:23199,35699:23200,35700:23201,35701:23202,35702:23203,35703:23204,35704:23205,35705:23206,35706:23207,35707:23208,35708:23209,35709:23211,35710:23212,35712:23213,35713:23214,35714:23215,35715:23216,35716:23217,35717:23220,35718:23222,35719:23223,35720:23225,35721:23226,35722:23227,35723:23228,35724:23229,35725:23231,35726:23232,35727:23235,35728:23236,35729:23237,35730:23238,35731:23239,35732:23240,35733:23242,35734:23243,35735:23245,35736:23246,35737:23247,35738:23248,35739:23249,35740:23251,35741:23253,35742:23255,35743:23257,35744:23258,35745:23259,35746:23261,35747:23262,35748:23263,35749:23266,35750:23268,35751:23269,35752:23271,35753:23272,35754:23274,35755:23276,35756:23277,35757:23278,35758:23279,35759:23280,35760:23282,35761:23283,35762:23284,35763:23285,35764:23286,35765:23287,35766:23288,35767:23289,35768:23290,35769:23291,35770:23292,35771:23293,35772:23294,35773:23295,35774:23296,35775:23297,35776:23298,35777:23299,35778:23300,35779:23301,35780:23302,35781:23303,35782:23304,35783:23306,35784:23307,35785:23308,35786:23309,35787:23310,35788:23311,35789:23312,35790:23313,35791:23314,35792:23315,35793:23316,35794:23317,35795:23320,35796:23321,35797:23322,35798:23323,35799:23324,35800:23325,35801:23326,35802:23327,35803:23328,35804:23329,35805:23330,35806:23331,35807:23332,35808:23333,35809:23334,35810:23335,35811:23336,35812:23337,35813:23338,35814:23339,35815:23340,35816:23341,35817:23342,35818:23343,35819:23344,35820:23345,35821:23347,35822:23349,35823:23350,35824:23352,35825:23353,35826:23354,35827:23355,35828:23356,35829:23357,35830:23358,35831:23359,35832:23361,35833:23362,35834:23363,35835:23364,35836:23365,35837:23366,35838:23367,35904:23368,35905:23369,35906:23370,35907:23371,35908:23372,35909:23373,35910:23374,35911:23375,35912:23378,35913:23382,35914:23390,35915:23392,35916:23393,35917:23399,35918:23400,35919:23403,35920:23405,35921:23406,35922:23407,35923:23410,35924:23412,35925:23414,35926:23415,35927:23416,35928:23417,35929:23419,35930:23420,35931:23422,35932:23423,35933:23426,35934:23430,35935:23434,35936:23437,35937:23438,35938:23440,35939:23441,35940:23442,35941:23444,35942:23446,35943:23455,35944:23463,35945:23464,35946:23465,35947:23468,35948:23469,35949:23470,35950:23471,35951:23473,35952:23474,35953:23479,35954:23482,35955:23483,35956:23484,35957:23488,35958:23489,35959:23491,35960:23496,35961:23497,35962:23498,35963:23499,35964:23501,35965:23502,35966:23503,35968:23505,35969:23508,35970:23509,35971:23510,35972:23511,35973:23512,35974:23513,35975:23514,35976:23515,35977:23516,35978:23520,35979:23522,35980:23523,35981:23526,35982:23527,35983:23529,35984:23530,35985:23531,35986:23532,35987:23533,35988:23535,35989:23537,35990:23538,35991:23539,35992:23540,35993:23541,35994:23542,35995:23543,35996:23549,35997:23550,35998:23552,35999:23554,36000:23555,36001:23557,36002:23559,36003:23560,36004:23563,36005:23564,36006:23565,36007:23566,36008:23568,36009:23570,36010:23571,36011:23575,36012:23577,36013:23579,36014:23582,36015:23583,36016:23584,36017:23585,36018:23587,36019:23590,36020:23592,36021:23593,36022:23594,36023:23595,36024:23597,36025:23598,36026:23599,36027:23600,36028:23602,36029:23603,36030:23605,36031:23606,36032:23607,36033:23619,36034:23620,36035:23622,36036:23623,36037:23628,36038:23629,36039:23634,36040:23635,36041:23636,36042:23638,36043:23639,36044:23640,36045:23642,36046:23643,36047:23644,36048:23645,36049:23647,36050:23650,36051:23652,36052:23655,36053:23656,36054:23657,36055:23658,36056:23659,36057:23660,36058:23661,36059:23664,36060:23666,36061:23667,36062:23668,36063:23669,36064:23670,36065:23671,36066:23672,36067:23675,36068:23676,36069:23677,36070:23678,36071:23680,36072:23683,36073:23684,36074:23685,36075:23686,36076:23687,36077:23689,36078:23690,36079:23691,36080:23694,36081:23695,36082:23698,36083:23699,36084:23701,36085:23709,36086:23710,36087:23711,36088:23712,36089:23713,36090:23716,36091:23717,36092:23718,36093:23719,36094:23720,36160:23722,36161:23726,36162:23727,36163:23728,36164:23730,36165:23732,36166:23734,36167:23737,36168:23738,36169:23739,36170:23740,36171:23742,36172:23744,36173:23746,36174:23747,36175:23749,36176:23750,36177:23751,36178:23752,36179:23753,36180:23754,36181:23756,36182:23757,36183:23758,36184:23759,36185:23760,36186:23761,36187:23763,36188:23764,36189:23765,36190:23766,36191:23767,36192:23768,36193:23770,36194:23771,36195:23772,36196:23773,36197:23774,36198:23775,36199:23776,36200:23778,36201:23779,36202:23783,36203:23785,36204:23787,36205:23788,36206:23790,36207:23791,36208:23793,36209:23794,36210:23795,36211:23796,36212:23797,36213:23798,36214:23799,36215:23800,36216:23801,36217:23802,36218:23804,36219:23805,36220:23806,36221:23807,36222:23808,36224:23809,36225:23812,36226:23813,36227:23816,36228:23817,36229:23818,36230:23819,36231:23820,36232:23821,36233:23823,36234:23824,36235:23825,36236:23826,36237:23827,36238:23829,36239:23831,36240:23832,36241:23833,36242:23834,36243:23836,36244:23837,36245:23839,36246:23840,36247:23841,36248:23842,36249:23843,36250:23845,36251:23848,36252:23850,36253:23851,36254:23852,36255:23855,36256:23856,36257:23857,36258:23858,36259:23859,36260:23861,36261:23862,36262:23863,36263:23864,36264:23865,36265:23866,36266:23867,36267:23868,36268:23871,36269:23872,36270:23873,36271:23874,36272:23875,36273:23876,36274:23877,36275:23878,36276:23880,36277:23881,36278:23885,36279:23886,36280:23887,36281:23888,36282:23889,36283:23890,36284:23891,36285:23892,36286:23893,36287:23894,36288:23895,36289:23897,36290:23898,36291:23900,36292:23902,36293:23903,36294:23904,36295:23905,36296:23906,36297:23907,36298:23908,36299:23909,36300:23910,36301:23911,36302:23912,36303:23914,36304:23917,36305:23918,36306:23920,36307:23921,36308:23922,36309:23923,36310:23925,36311:23926,36312:23927,36313:23928,36314:23929,36315:23930,36316:23931,36317:23932,36318:23933,36319:23934,36320:23935,36321:23936,36322:23937,36323:23939,36324:23940,36325:23941,36326:23942,36327:23943,36328:23944,36329:23945,36330:23946,36331:23947,36332:23948,36333:23949,36334:23950,36335:23951,36336:23952,36337:23953,36338:23954,36339:23955,36340:23956,36341:23957,36342:23958,36343:23959,36344:23960,36345:23962,36346:23963,36347:23964,36348:23966,36349:23967,36350:23968,36416:23969,36417:23970,36418:23971,36419:23972,36420:23973,36421:23974,36422:23975,36423:23976,36424:23977,36425:23978,36426:23979,36427:23980,36428:23981,36429:23982,36430:23983,36431:23984,36432:23985,36433:23986,36434:23987,36435:23988,36436:23989,36437:23990,36438:23992,36439:23993,36440:23994,36441:23995,36442:23996,36443:23997,36444:23998,36445:23999,36446:24000,36447:24001,36448:24002,36449:24003,36450:24004,36451:24006,36452:24007,36453:24008,36454:24009,36455:24010,36456:24011,36457:24012,36458:24014,36459:24015,36460:24016,36461:24017,36462:24018,36463:24019,36464:24020,36465:24021,36466:24022,36467:24023,36468:24024,36469:24025,36470:24026,36471:24028,36472:24031,36473:24032,36474:24035,36475:24036,36476:24042,36477:24044,36478:24045,36480:24048,36481:24053,36482:24054,36483:24056,36484:24057,36485:24058,36486:24059,36487:24060,36488:24063,36489:24064,36490:24068,36491:24071,36492:24073,36493:24074,36494:24075,36495:24077,36496:24078,36497:24082,36498:24083,36499:24087,36500:24094,36501:24095,36502:24096,36503:24097,36504:24098,36505:24099,36506:24100,36507:24101,36508:24104,36509:24105,36510:24106,36511:24107,36512:24108,36513:24111,36514:24112,36515:24114,36516:24115,36517:24116,36518:24117,36519:24118,36520:24121,36521:24122,36522:24126,36523:24127,36524:24128,36525:24129,36526:24131,36527:24134,36528:24135,36529:24136,36530:24137,36531:24138,36532:24139,36533:24141,36534:24142,36535:24143,36536:24144,36537:24145,36538:24146,36539:24147,36540:24150,36541:24151,36542:24152,36543:24153,36544:24154,36545:24156,36546:24157,36547:24159,36548:24160,36549:24163,36550:24164,36551:24165,36552:24166,36553:24167,36554:24168,36555:24169,36556:24170,36557:24171,36558:24172,36559:24173,36560:24174,36561:24175,36562:24176,36563:24177,36564:24181,36565:24183,36566:24185,36567:24190,36568:24193,36569:24194,36570:24195,36571:24197,36572:24200,36573:24201,36574:24204,36575:24205,36576:24206,36577:24210,36578:24216,36579:24219,36580:24221,36581:24225,36582:24226,36583:24227,36584:24228,36585:24232,36586:24233,36587:24234,36588:24235,36589:24236,36590:24238,36591:24239,36592:24240,36593:24241,36594:24242,36595:24244,36596:24250,36597:24251,36598:24252,36599:24253,36600:24255,36601:24256,36602:24257,36603:24258,36604:24259,36605:24260,36606:24261,36672:24262,36673:24263,36674:24264,36675:24267,36676:24268,36677:24269,36678:24270,36679:24271,36680:24272,36681:24276,36682:24277,36683:24279,36684:24280,36685:24281,36686:24282,36687:24284,36688:24285,36689:24286,36690:24287,36691:24288,36692:24289,36693:24290,36694:24291,36695:24292,36696:24293,36697:24294,36698:24295,36699:24297,36700:24299,36701:24300,36702:24301,36703:24302,36704:24303,36705:24304,36706:24305,36707:24306,36708:24307,36709:24309,36710:24312,36711:24313,36712:24315,36713:24316,36714:24317,36715:24325,36716:24326,36717:24327,36718:24329,36719:24332,36720:24333,36721:24334,36722:24336,36723:24338,36724:24340,36725:24342,36726:24345,36727:24346,36728:24348,36729:24349,36730:24350,36731:24353,36732:24354,36733:24355,36734:24356,36736:24360,36737:24363,36738:24364,36739:24366,36740:24368,36741:24370,36742:24371,36743:24372,36744:24373,36745:24374,36746:24375,36747:24376,36748:24379,36749:24381,36750:24382,36751:24383,36752:24385,36753:24386,36754:24387,36755:24388,36756:24389,36757:24390,36758:24391,36759:24392,36760:24393,36761:24394,36762:24395,36763:24396,36764:24397,36765:24398,36766:24399,36767:24401,36768:24404,36769:24409,36770:24410,36771:24411,36772:24412,36773:24414,36774:24415,36775:24416,36776:24419,36777:24421,36778:24423,36779:24424,36780:24427,36781:24430,36782:24431,36783:24434,36784:24436,36785:24437,36786:24438,36787:24440,36788:24442,36789:24445,36790:24446,36791:24447,36792:24451,36793:24454,36794:24461,36795:24462,36796:24463,36797:24465,36798:24467,36799:24468,36800:24470,36801:24474,36802:24475,36803:24477,36804:24478,36805:24479,36806:24480,36807:24482,36808:24483,36809:24484,36810:24485,36811:24486,36812:24487,36813:24489,36814:24491,36815:24492,36816:24495,36817:24496,36818:24497,36819:24498,36820:24499,36821:24500,36822:24502,36823:24504,36824:24505,36825:24506,36826:24507,36827:24510,36828:24511,36829:24512,36830:24513,36831:24514,36832:24519,36833:24520,36834:24522,36835:24523,36836:24526,36837:24531,36838:24532,36839:24533,36840:24538,36841:24539,36842:24540,36843:24542,36844:24543,36845:24546,36846:24547,36847:24549,36848:24550,36849:24552,36850:24553,36851:24556,36852:24559,36853:24560,36854:24562,36855:24563,36856:24564,36857:24566,36858:24567,36859:24569,36860:24570,36861:24572,36862:24583,36928:24584,36929:24585,36930:24587,36931:24588,36932:24592,36933:24593,36934:24595,36935:24599,36936:24600,36937:24602,36938:24606,36939:24607,36940:24610,36941:24611,36942:24612,36943:24620,36944:24621,36945:24622,36946:24624,36947:24625,36948:24626,36949:24627,36950:24628,36951:24630,36952:24631,36953:24632,36954:24633,36955:24634,36956:24637,36957:24638,36958:24640,36959:24644,36960:24645,36961:24646,36962:24647,36963:24648,36964:24649,36965:24650,36966:24652,36967:24654,36968:24655,36969:24657,36970:24659,36971:24660,36972:24662,36973:24663,36974:24664,36975:24667,36976:24668,36977:24670,36978:24671,36979:24672,36980:24673,36981:24677,36982:24678,36983:24686,36984:24689,36985:24690,36986:24692,36987:24693,36988:24695,36989:24702,36990:24704,36992:24705,36993:24706,36994:24709,36995:24710,36996:24711,36997:24712,36998:24714,36999:24715,37000:24718,37001:24719,37002:24720,37003:24721,37004:24723,37005:24725,37006:24727,37007:24728,37008:24729,37009:24732,37010:24734,37011:24737,37012:24738,37013:24740,37014:24741,37015:24743,37016:24745,37017:24746,37018:24750,37019:24752,37020:24755,37021:24757,37022:24758,37023:24759,37024:24761,37025:24762,37026:24765,37027:24766,37028:24767,37029:24768,37030:24769,37031:24770,37032:24771,37033:24772,37034:24775,37035:24776,37036:24777,37037:24780,37038:24781,37039:24782,37040:24783,37041:24784,37042:24786,37043:24787,37044:24788,37045:24790,37046:24791,37047:24793,37048:24795,37049:24798,37050:24801,37051:24802,37052:24803,37053:24804,37054:24805,37055:24810,37056:24817,37057:24818,37058:24821,37059:24823,37060:24824,37061:24827,37062:24828,37063:24829,37064:24830,37065:24831,37066:24834,37067:24835,37068:24836,37069:24837,37070:24839,37071:24842,37072:24843,37073:24844,37074:24848,37075:24849,37076:24850,37077:24851,37078:24852,37079:24854,37080:24855,37081:24856,37082:24857,37083:24859,37084:24860,37085:24861,37086:24862,37087:24865,37088:24866,37089:24869,37090:24872,37091:24873,37092:24874,37093:24876,37094:24877,37095:24878,37096:24879,37097:24880,37098:24881,37099:24882,37100:24883,37101:24884,37102:24885,37103:24886,37104:24887,37105:24888,37106:24889,37107:24890,37108:24891,37109:24892,37110:24893,37111:24894,37112:24896,37113:24897,37114:24898,37115:24899,37116:24900,37117:24901,37118:24902,37184:24903,37185:24905,37186:24907,37187:24909,37188:24911,37189:24912,37190:24914,37191:24915,37192:24916,37193:24918,37194:24919,37195:24920,37196:24921,37197:24922,37198:24923,37199:24924,37200:24926,37201:24927,37202:24928,37203:24929,37204:24931,37205:24932,37206:24933,37207:24934,37208:24937,37209:24938,37210:24939,37211:24940,37212:24941,37213:24942,37214:24943,37215:24945,37216:24946,37217:24947,37218:24948,37219:24950,37220:24952,37221:24953,37222:24954,37223:24955,37224:24956,37225:24957,37226:24958,37227:24959,37228:24960,37229:24961,37230:24962,37231:24963,37232:24964,37233:24965,37234:24966,37235:24967,37236:24968,37237:24969,37238:24970,37239:24972,37240:24973,37241:24975,37242:24976,37243:24977,37244:24978,37245:24979,37246:24981,37248:24982,37249:24983,37250:24984,37251:24985,37252:24986,37253:24987,37254:24988,37255:24990,37256:24991,37257:24992,37258:24993,37259:24994,37260:24995,37261:24996,37262:24997,37263:24998,37264:25002,37265:25003,37266:25005,37267:25006,37268:25007,37269:25008,37270:25009,37271:25010,37272:25011,37273:25012,37274:25013,37275:25014,37276:25016,37277:25017,37278:25018,37279:25019,37280:25020,37281:25021,37282:25023,37283:25024,37284:25025,37285:25027,37286:25028,37287:25029,37288:25030,37289:25031,37290:25033,37291:25036,37292:25037,37293:25038,37294:25039,37295:25040,37296:25043,37297:25045,37298:25046,37299:25047,37300:25048,37301:25049,37302:25050,37303:25051,37304:25052,37305:25053,37306:25054,37307:25055,37308:25056,37309:25057,37310:25058,37311:25059,37312:25060,37313:25061,37314:25063,37315:25064,37316:25065,37317:25066,37318:25067,37319:25068,37320:25069,37321:25070,37322:25071,37323:25072,37324:25073,37325:25074,37326:25075,37327:25076,37328:25078,37329:25079,37330:25080,37331:25081,37332:25082,37333:25083,37334:25084,37335:25085,37336:25086,37337:25088,37338:25089,37339:25090,37340:25091,37341:25092,37342:25093,37343:25095,37344:25097,37345:25107,37346:25108,37347:25113,37348:25116,37349:25117,37350:25118,37351:25120,37352:25123,37353:25126,37354:25127,37355:25128,37356:25129,37357:25131,37358:25133,37359:25135,37360:25136,37361:25137,37362:25138,37363:25141,37364:25142,37365:25144,37366:25145,37367:25146,37368:25147,37369:25148,37370:25154,37371:25156,37372:25157,37373:25158,37374:25162,37440:25167,37441:25168,37442:25173,37443:25174,37444:25175,37445:25177,37446:25178,37447:25180,37448:25181,37449:25182,37450:25183,37451:25184,37452:25185,37453:25186,37454:25188,37455:25189,37456:25192,37457:25201,37458:25202,37459:25204,37460:25205,37461:25207,37462:25208,37463:25210,37464:25211,37465:25213,37466:25217,37467:25218,37468:25219,37469:25221,37470:25222,37471:25223,37472:25224,37473:25227,37474:25228,37475:25229,37476:25230,37477:25231,37478:25232,37479:25236,37480:25241,37481:25244,37482:25245,37483:25246,37484:25251,37485:25254,37486:25255,37487:25257,37488:25258,37489:25261,37490:25262,37491:25263,37492:25264,37493:25266,37494:25267,37495:25268,37496:25270,37497:25271,37498:25272,37499:25274,37500:25278,37501:25280,37502:25281,37504:25283,37505:25291,37506:25295,37507:25297,37508:25301,37509:25309,37510:25310,37511:25312,37512:25313,37513:25316,37514:25322,37515:25323,37516:25328,37517:25330,37518:25333,37519:25336,37520:25337,37521:25338,37522:25339,37523:25344,37524:25347,37525:25348,37526:25349,37527:25350,37528:25354,37529:25355,37530:25356,37531:25357,37532:25359,37533:25360,37534:25362,37535:25363,37536:25364,37537:25365,37538:25367,37539:25368,37540:25369,37541:25372,37542:25382,37543:25383,37544:25385,37545:25388,37546:25389,37547:25390,37548:25392,37549:25393,37550:25395,37551:25396,37552:25397,37553:25398,37554:25399,37555:25400,37556:25403,37557:25404,37558:25406,37559:25407,37560:25408,37561:25409,37562:25412,37563:25415,37564:25416,37565:25418,37566:25425,37567:25426,37568:25427,37569:25428,37570:25430,37571:25431,37572:25432,37573:25433,37574:25434,37575:25435,37576:25436,37577:25437,37578:25440,37579:25444,37580:25445,37581:25446,37582:25448,37583:25450,37584:25451,37585:25452,37586:25455,37587:25456,37588:25458,37589:25459,37590:25460,37591:25461,37592:25464,37593:25465,37594:25468,37595:25469,37596:25470,37597:25471,37598:25473,37599:25475,37600:25476,37601:25477,37602:25478,37603:25483,37604:25485,37605:25489,37606:25491,37607:25492,37608:25493,37609:25495,37610:25497,37611:25498,37612:25499,37613:25500,37614:25501,37615:25502,37616:25503,37617:25505,37618:25508,37619:25510,37620:25515,37621:25519,37622:25521,37623:25522,37624:25525,37625:25526,37626:25529,37627:25531,37628:25533,37629:25535,37630:25536,37696:25537,37697:25538,37698:25539,37699:25541,37700:25543,37701:25544,37702:25546,37703:25547,37704:25548,37705:25553,37706:25555,37707:25556,37708:25557,37709:25559,37710:25560,37711:25561,37712:25562,37713:25563,37714:25564,37715:25565,37716:25567,37717:25570,37718:25572,37719:25573,37720:25574,37721:25575,37722:25576,37723:25579,37724:25580,37725:25582,37726:25583,37727:25584,37728:25585,37729:25587,37730:25589,37731:25591,37732:25593,37733:25594,37734:25595,37735:25596,37736:25598,37737:25603,37738:25604,37739:25606,37740:25607,37741:25608,37742:25609,37743:25610,37744:25613,37745:25614,37746:25617,37747:25618,37748:25621,37749:25622,37750:25623,37751:25624,37752:25625,37753:25626,37754:25629,37755:25631,37756:25634,37757:25635,37758:25636,37760:25637,37761:25639,37762:25640,37763:25641,37764:25643,37765:25646,37766:25647,37767:25648,37768:25649,37769:25650,37770:25651,37771:25653,37772:25654,37773:25655,37774:25656,37775:25657,37776:25659,37777:25660,37778:25662,37779:25664,37780:25666,37781:25667,37782:25673,37783:25675,37784:25676,37785:25677,37786:25678,37787:25679,37788:25680,37789:25681,37790:25683,37791:25685,37792:25686,37793:25687,37794:25689,37795:25690,37796:25691,37797:25692,37798:25693,37799:25695,37800:25696,37801:25697,37802:25698,37803:25699,37804:25700,37805:25701,37806:25702,37807:25704,37808:25706,37809:25707,37810:25708,37811:25710,37812:25711,37813:25712,37814:25713,37815:25714,37816:25715,37817:25716,37818:25717,37819:25718,37820:25719,37821:25723,37822:25724,37823:25725,37824:25726,37825:25727,37826:25728,37827:25729,37828:25731,37829:25734,37830:25736,37831:25737,37832:25738,37833:25739,37834:25740,37835:25741,37836:25742,37837:25743,37838:25744,37839:25747,37840:25748,37841:25751,37842:25752,37843:25754,37844:25755,37845:25756,37846:25757,37847:25759,37848:25760,37849:25761,37850:25762,37851:25763,37852:25765,37853:25766,37854:25767,37855:25768,37856:25770,37857:25771,37858:25775,37859:25777,37860:25778,37861:25779,37862:25780,37863:25782,37864:25785,37865:25787,37866:25789,37867:25790,37868:25791,37869:25793,37870:25795,37871:25796,37872:25798,37873:25799,37874:25800,37875:25801,37876:25802,37877:25803,37878:25804,37879:25807,37880:25809,37881:25811,37882:25812,37883:25813,37884:25814,37885:25817,37886:25818,37952:25819,37953:25820,37954:25821,37955:25823,37956:25824,37957:25825,37958:25827,37959:25829,37960:25831,37961:25832,37962:25833,37963:25834,37964:25835,37965:25836,37966:25837,37967:25838,37968:25839,37969:25840,37970:25841,37971:25842,37972:25843,37973:25844,37974:25845,37975:25846,37976:25847,37977:25848,37978:25849,37979:25850,37980:25851,37981:25852,37982:25853,37983:25854,37984:25855,37985:25857,37986:25858,37987:25859,37988:25860,37989:25861,37990:25862,37991:25863,37992:25864,37993:25866,37994:25867,37995:25868,37996:25869,37997:25870,37998:25871,37999:25872,38000:25873,38001:25875,38002:25876,38003:25877,38004:25878,38005:25879,38006:25881,38007:25882,38008:25883,38009:25884,38010:25885,38011:25886,38012:25887,38013:25888,38014:25889,38016:25890,38017:25891,38018:25892,38019:25894,38020:25895,38021:25896,38022:25897,38023:25898,38024:25900,38025:25901,38026:25904,38027:25905,38028:25906,38029:25907,38030:25911,38031:25914,38032:25916,38033:25917,38034:25920,38035:25921,38036:25922,38037:25923,38038:25924,38039:25926,38040:25927,38041:25930,38042:25931,38043:25933,38044:25934,38045:25936,38046:25938,38047:25939,38048:25940,38049:25943,38050:25944,38051:25946,38052:25948,38053:25951,38054:25952,38055:25953,38056:25956,38057:25957,38058:25959,38059:25960,38060:25961,38061:25962,38062:25965,38063:25966,38064:25967,38065:25969,38066:25971,38067:25973,38068:25974,38069:25976,38070:25977,38071:25978,38072:25979,38073:25980,38074:25981,38075:25982,38076:25983,38077:25984,38078:25985,38079:25986,38080:25987,38081:25988,38082:25989,38083:25990,38084:25992,38085:25993,38086:25994,38087:25997,38088:25998,38089:25999,38090:26002,38091:26004,38092:26005,38093:26006,38094:26008,38095:26010,38096:26013,38097:26014,38098:26016,38099:26018,38100:26019,38101:26022,38102:26024,38103:26026,38104:26028,38105:26030,38106:26033,38107:26034,38108:26035,38109:26036,38110:26037,38111:26038,38112:26039,38113:26040,38114:26042,38115:26043,38116:26046,38117:26047,38118:26048,38119:26050,38120:26055,38121:26056,38122:26057,38123:26058,38124:26061,38125:26064,38126:26065,38127:26067,38128:26068,38129:26069,38130:26072,38131:26073,38132:26074,38133:26075,38134:26076,38135:26077,38136:26078,38137:26079,38138:26081,38139:26083,38140:26084,38141:26090,38142:26091,38208:26098,38209:26099,38210:26100,38211:26101,38212:26104,38213:26105,38214:26107,38215:26108,38216:26109,38217:26110,38218:26111,38219:26113,38220:26116,38221:26117,38222:26119,38223:26120,38224:26121,38225:26123,38226:26125,38227:26128,38228:26129,38229:26130,38230:26134,38231:26135,38232:26136,38233:26138,38234:26139,38235:26140,38236:26142,38237:26145,38238:26146,38239:26147,38240:26148,38241:26150,38242:26153,38243:26154,38244:26155,38245:26156,38246:26158,38247:26160,38248:26162,38249:26163,38250:26167,38251:26168,38252:26169,38253:26170,38254:26171,38255:26173,38256:26175,38257:26176,38258:26178,38259:26180,38260:26181,38261:26182,38262:26183,38263:26184,38264:26185,38265:26186,38266:26189,38267:26190,38268:26192,38269:26193,38270:26200,38272:26201,38273:26203,38274:26204,38275:26205,38276:26206,38277:26208,38278:26210,38279:26211,38280:26213,38281:26215,38282:26217,38283:26218,38284:26219,38285:26220,38286:26221,38287:26225,38288:26226,38289:26227,38290:26229,38291:26232,38292:26233,38293:26235,38294:26236,38295:26237,38296:26239,38297:26240,38298:26241,38299:26243,38300:26245,38301:26246,38302:26248,38303:26249,38304:26250,38305:26251,38306:26253,38307:26254,38308:26255,38309:26256,38310:26258,38311:26259,38312:26260,38313:26261,38314:26264,38315:26265,38316:26266,38317:26267,38318:26268,38319:26270,38320:26271,38321:26272,38322:26273,38323:26274,38324:26275,38325:26276,38326:26277,38327:26278,38328:26281,38329:26282,38330:26283,38331:26284,38332:26285,38333:26287,38334:26288,38335:26289,38336:26290,38337:26291,38338:26293,38339:26294,38340:26295,38341:26296,38342:26298,38343:26299,38344:26300,38345:26301,38346:26303,38347:26304,38348:26305,38349:26306,38350:26307,38351:26308,38352:26309,38353:26310,38354:26311,38355:26312,38356:26313,38357:26314,38358:26315,38359:26316,38360:26317,38361:26318,38362:26319,38363:26320,38364:26321,38365:26322,38366:26323,38367:26324,38368:26325,38369:26326,38370:26327,38371:26328,38372:26330,38373:26334,38374:26335,38375:26336,38376:26337,38377:26338,38378:26339,38379:26340,38380:26341,38381:26343,38382:26344,38383:26346,38384:26347,38385:26348,38386:26349,38387:26350,38388:26351,38389:26353,38390:26357,38391:26358,38392:26360,38393:26362,38394:26363,38395:26365,38396:26369,38397:26370,38398:26371,38464:26372,38465:26373,38466:26374,38467:26375,38468:26380,38469:26382,38470:26383,38471:26385,38472:26386,38473:26387,38474:26390,38475:26392,38476:26393,38477:26394,38478:26396,38479:26398,38480:26400,38481:26401,38482:26402,38483:26403,38484:26404,38485:26405,38486:26407,38487:26409,38488:26414,38489:26416,38490:26418,38491:26419,38492:26422,38493:26423,38494:26424,38495:26425,38496:26427,38497:26428,38498:26430,38499:26431,38500:26433,38501:26436,38502:26437,38503:26439,38504:26442,38505:26443,38506:26445,38507:26450,38508:26452,38509:26453,38510:26455,38511:26456,38512:26457,38513:26458,38514:26459,38515:26461,38516:26466,38517:26467,38518:26468,38519:26470,38520:26471,38521:26475,38522:26476,38523:26478,38524:26481,38525:26484,38526:26486,38528:26488,38529:26489,38530:26490,38531:26491,38532:26493,38533:26496,38534:26498,38535:26499,38536:26501,38537:26502,38538:26504,38539:26506,38540:26508,38541:26509,38542:26510,38543:26511,38544:26513,38545:26514,38546:26515,38547:26516,38548:26518,38549:26521,38550:26523,38551:26527,38552:26528,38553:26529,38554:26532,38555:26534,38556:26537,38557:26540,38558:26542,38559:26545,38560:26546,38561:26548,38562:26553,38563:26554,38564:26555,38565:26556,38566:26557,38567:26558,38568:26559,38569:26560,38570:26562,38571:26565,38572:26566,38573:26567,38574:26568,38575:26569,38576:26570,38577:26571,38578:26572,38579:26573,38580:26574,38581:26581,38582:26582,38583:26583,38584:26587,38585:26591,38586:26593,38587:26595,38588:26596,38589:26598,38590:26599,38591:26600,38592:26602,38593:26603,38594:26605,38595:26606,38596:26610,38597:26613,38598:26614,38599:26615,38600:26616,38601:26617,38602:26618,38603:26619,38604:26620,38605:26622,38606:26625,38607:26626,38608:26627,38609:26628,38610:26630,38611:26637,38612:26640,38613:26642,38614:26644,38615:26645,38616:26648,38617:26649,38618:26650,38619:26651,38620:26652,38621:26654,38622:26655,38623:26656,38624:26658,38625:26659,38626:26660,38627:26661,38628:26662,38629:26663,38630:26664,38631:26667,38632:26668,38633:26669,38634:26670,38635:26671,38636:26672,38637:26673,38638:26676,38639:26677,38640:26678,38641:26682,38642:26683,38643:26687,38644:26695,38645:26699,38646:26701,38647:26703,38648:26706,38649:26710,38650:26711,38651:26712,38652:26713,38653:26714,38654:26715,38720:26716,38721:26717,38722:26718,38723:26719,38724:26730,38725:26732,38726:26733,38727:26734,38728:26735,38729:26736,38730:26737,38731:26738,38732:26739,38733:26741,38734:26744,38735:26745,38736:26746,38737:26747,38738:26748,38739:26749,38740:26750,38741:26751,38742:26752,38743:26754,38744:26756,38745:26759,38746:26760,38747:26761,38748:26762,38749:26763,38750:26764,38751:26765,38752:26766,38753:26768,38754:26769,38755:26770,38756:26772,38757:26773,38758:26774,38759:26776,38760:26777,38761:26778,38762:26779,38763:26780,38764:26781,38765:26782,38766:26783,38767:26784,38768:26785,38769:26787,38770:26788,38771:26789,38772:26793,38773:26794,38774:26795,38775:26796,38776:26798,38777:26801,38778:26802,38779:26804,38780:26806,38781:26807,38782:26808,38784:26809,38785:26810,38786:26811,38787:26812,38788:26813,38789:26814,38790:26815,38791:26817,38792:26819,38793:26820,38794:26821,38795:26822,38796:26823,38797:26824,38798:26826,38799:26828,38800:26830,38801:26831,38802:26832,38803:26833,38804:26835,38805:26836,38806:26838,38807:26839,38808:26841,38809:26843,38810:26844,38811:26845,38812:26846,38813:26847,38814:26849,38815:26850,38816:26852,38817:26853,38818:26854,38819:26855,38820:26856,38821:26857,38822:26858,38823:26859,38824:26860,38825:26861,38826:26863,38827:26866,38828:26867,38829:26868,38830:26870,38831:26871,38832:26872,38833:26875,38834:26877,38835:26878,38836:26879,38837:26880,38838:26882,38839:26883,38840:26884,38841:26886,38842:26887,38843:26888,38844:26889,38845:26890,38846:26892,38847:26895,38848:26897,38849:26899,38850:26900,38851:26901,38852:26902,38853:26903,38854:26904,38855:26905,38856:26906,38857:26907,38858:26908,38859:26909,38860:26910,38861:26913,38862:26914,38863:26915,38864:26917,38865:26918,38866:26919,38867:26920,38868:26921,38869:26922,38870:26923,38871:26924,38872:26926,38873:26927,38874:26929,38875:26930,38876:26931,38877:26933,38878:26934,38879:26935,38880:26936,38881:26938,38882:26939,38883:26940,38884:26942,38885:26944,38886:26945,38887:26947,38888:26948,38889:26949,38890:26950,38891:26951,38892:26952,38893:26953,38894:26954,38895:26955,38896:26956,38897:26957,38898:26958,38899:26959,38900:26960,38901:26961,38902:26962,38903:26963,38904:26965,38905:26966,38906:26968,38907:26969,38908:26971,38909:26972,38910:26975,38976:26977,38977:26978,38978:26980,38979:26981,38980:26983,38981:26984,38982:26985,38983:26986,38984:26988,38985:26989,38986:26991,38987:26992,38988:26994,38989:26995,38990:26996,38991:26997,38992:26998,38993:27002,38994:27003,38995:27005,38996:27006,38997:27007,38998:27009,38999:27011,39000:27013,39001:27018,39002:27019,39003:27020,39004:27022,39005:27023,39006:27024,39007:27025,39008:27026,39009:27027,39010:27030,39011:27031,39012:27033,39013:27034,39014:27037,39015:27038,39016:27039,39017:27040,39018:27041,39019:27042,39020:27043,39021:27044,39022:27045,39023:27046,39024:27049,39025:27050,39026:27052,39027:27054,39028:27055,39029:27056,39030:27058,39031:27059,39032:27061,39033:27062,39034:27064,39035:27065,39036:27066,39037:27068,39038:27069,39040:27070,39041:27071,39042:27072,39043:27074,39044:27075,39045:27076,39046:27077,39047:27078,39048:27079,39049:27080,39050:27081,39051:27083,39052:27085,39053:27087,39054:27089,39055:27090,39056:27091,39057:27093,39058:27094,39059:27095,39060:27096,39061:27097,39062:27098,39063:27100,39064:27101,39065:27102,39066:27105,39067:27106,39068:27107,39069:27108,39070:27109,39071:27110,39072:27111,39073:27112,39074:27113,39075:27114,39076:27115,39077:27116,39078:27118,39079:27119,39080:27120,39081:27121,39082:27123,39083:27124,39084:27125,39085:27126,39086:27127,39087:27128,39088:27129,39089:27130,39090:27131,39091:27132,39092:27134,39093:27136,39094:27137,39095:27138,39096:27139,39097:27140,39098:27141,39099:27142,39100:27143,39101:27144,39102:27145,39103:27147,39104:27148,39105:27149,39106:27150,39107:27151,39108:27152,39109:27153,39110:27154,39111:27155,39112:27156,39113:27157,39114:27158,39115:27161,39116:27162,39117:27163,39118:27164,39119:27165,39120:27166,39121:27168,39122:27170,39123:27171,39124:27172,39125:27173,39126:27174,39127:27175,39128:27177,39129:27179,39130:27180,39131:27181,39132:27182,39133:27184,39134:27186,39135:27187,39136:27188,39137:27190,39138:27191,39139:27192,39140:27193,39141:27194,39142:27195,39143:27196,39144:27199,39145:27200,39146:27201,39147:27202,39148:27203,39149:27205,39150:27206,39151:27208,39152:27209,39153:27210,39154:27211,39155:27212,39156:27213,39157:27214,39158:27215,39159:27217,39160:27218,39161:27219,39162:27220,39163:27221,39164:27222,39165:27223,39166:27226,39232:27228,39233:27229,39234:27230,39235:27231,39236:27232,39237:27234,39238:27235,39239:27236,39240:27238,39241:27239,39242:27240,39243:27241,39244:27242,39245:27243,39246:27244,39247:27245,39248:27246,39249:27247,39250:27248,39251:27250,39252:27251,39253:27252,39254:27253,39255:27254,39256:27255,39257:27256,39258:27258,39259:27259,39260:27261,39261:27262,39262:27263,39263:27265,39264:27266,39265:27267,39266:27269,39267:27270,39268:27271,39269:27272,39270:27273,39271:27274,39272:27275,39273:27276,39274:27277,39275:27279,39276:27282,39277:27283,39278:27284,39279:27285,39280:27286,39281:27288,39282:27289,39283:27290,39284:27291,39285:27292,39286:27293,39287:27294,39288:27295,39289:27297,39290:27298,39291:27299,39292:27300,39293:27301,39294:27302,39296:27303,39297:27304,39298:27306,39299:27309,39300:27310,39301:27311,39302:27312,39303:27313,39304:27314,39305:27315,39306:27316,39307:27317,39308:27318,39309:27319,39310:27320,39311:27321,39312:27322,39313:27323,39314:27324,39315:27325,39316:27326,39317:27327,39318:27328,39319:27329,39320:27330,39321:27331,39322:27332,39323:27333,39324:27334,39325:27335,39326:27336,39327:27337,39328:27338,39329:27339,39330:27340,39331:27341,39332:27342,39333:27343,39334:27344,39335:27345,39336:27346,39337:27347,39338:27348,39339:27349,39340:27350,39341:27351,39342:27352,39343:27353,39344:27354,39345:27355,39346:27356,39347:27357,39348:27358,39349:27359,39350:27360,39351:27361,39352:27362,39353:27363,39354:27364,39355:27365,39356:27366,39357:27367,39358:27368,39359:27369,39360:27370,39361:27371,39362:27372,39363:27373,39364:27374,39365:27375,39366:27376,39367:27377,39368:27378,39369:27379,39370:27380,39371:27381,39372:27382,39373:27383,39374:27384,39375:27385,39376:27386,39377:27387,39378:27388,39379:27389,39380:27390,39381:27391,39382:27392,39383:27393,39384:27394,39385:27395,39386:27396,39387:27397,39388:27398,39389:27399,39390:27400,39391:27401,39392:27402,39393:27403,39394:27404,39395:27405,39396:27406,39397:27407,39398:27408,39399:27409,39400:27410,39401:27411,39402:27412,39403:27413,39404:27414,39405:27415,39406:27416,39407:27417,39408:27418,39409:27419,39410:27420,39411:27421,39412:27422,39413:27423,39414:27429,39415:27430,39416:27432,39417:27433,39418:27434,39419:27435,39420:27436,39421:27437,39422:27438,39488:27439,39489:27440,39490:27441,39491:27443,39492:27444,39493:27445,39494:27446,39495:27448,39496:27451,39497:27452,39498:27453,39499:27455,39500:27456,39501:27457,39502:27458,39503:27460,39504:27461,39505:27464,39506:27466,39507:27467,39508:27469,39509:27470,39510:27471,39511:27472,39512:27473,39513:27474,39514:27475,39515:27476,39516:27477,39517:27478,39518:27479,39519:27480,39520:27482,39521:27483,39522:27484,39523:27485,39524:27486,39525:27487,39526:27488,39527:27489,39528:27496,39529:27497,39530:27499,39531:27500,39532:27501,39533:27502,39534:27503,39535:27504,39536:27505,39537:27506,39538:27507,39539:27508,39540:27509,39541:27510,39542:27511,39543:27512,39544:27514,39545:27517,39546:27518,39547:27519,39548:27520,39549:27525,39550:27528,39552:27532,39553:27534,39554:27535,39555:27536,39556:27537,39557:27540,39558:27541,39559:27543,39560:27544,39561:27545,39562:27548,39563:27549,39564:27550,39565:27551,39566:27552,39567:27554,39568:27555,39569:27556,39570:27557,39571:27558,39572:27559,39573:27560,39574:27561,39575:27563,39576:27564,39577:27565,39578:27566,39579:27567,39580:27568,39581:27569,39582:27570,39583:27574,39584:27576,39585:27577,39586:27578,39587:27579,39588:27580,39589:27581,39590:27582,39591:27584,39592:27587,39593:27588,39594:27590,39595:27591,39596:27592,39597:27593,39598:27594,39599:27596,39600:27598,39601:27600,39602:27601,39603:27608,39604:27610,39605:27612,39606:27613,39607:27614,39608:27615,39609:27616,39610:27618,39611:27619,39612:27620,39613:27621,39614:27622,39615:27623,39616:27624,39617:27625,39618:27628,39619:27629,39620:27630,39621:27632,39622:27633,39623:27634,39624:27636,39625:27638,39626:27639,39627:27640,39628:27642,39629:27643,39630:27644,39631:27646,39632:27647,39633:27648,39634:27649,39635:27650,39636:27651,39637:27652,39638:27656,39639:27657,39640:27658,39641:27659,39642:27660,39643:27662,39644:27666,39645:27671,39646:27676,39647:27677,39648:27678,39649:27680,39650:27683,39651:27685,39652:27691,39653:27692,39654:27693,39655:27697,39656:27699,39657:27702,39658:27703,39659:27705,39660:27706,39661:27707,39662:27708,39663:27710,39664:27711,39665:27715,39666:27716,39667:27717,39668:27720,39669:27723,39670:27724,39671:27725,39672:27726,39673:27727,39674:27729,39675:27730,39676:27731,39677:27734,39678:27736,39744:27737,39745:27738,39746:27746,39747:27747,39748:27749,39749:27750,39750:27751,39751:27755,39752:27756,39753:27757,39754:27758,39755:27759,39756:27761,39757:27763,39758:27765,39759:27767,39760:27768,39761:27770,39762:27771,39763:27772,39764:27775,39765:27776,39766:27780,39767:27783,39768:27786,39769:27787,39770:27789,39771:27790,39772:27793,39773:27794,39774:27797,39775:27798,39776:27799,39777:27800,39778:27802,39779:27804,39780:27805,39781:27806,39782:27808,39783:27810,39784:27816,39785:27820,39786:27823,39787:27824,39788:27828,39789:27829,39790:27830,39791:27831,39792:27834,39793:27840,39794:27841,39795:27842,39796:27843,39797:27846,39798:27847,39799:27848,39800:27851,39801:27853,39802:27854,39803:27855,39804:27857,39805:27858,39806:27864,39808:27865,39809:27866,39810:27868,39811:27869,39812:27871,39813:27876,39814:27878,39815:27879,39816:27881,39817:27884,39818:27885,39819:27890,39820:27892,39821:27897,39822:27903,39823:27904,39824:27906,39825:27907,39826:27909,39827:27910,39828:27912,39829:27913,39830:27914,39831:27917,39832:27919,39833:27920,39834:27921,39835:27923,39836:27924,39837:27925,39838:27926,39839:27928,39840:27932,39841:27933,39842:27935,39843:27936,39844:27937,39845:27938,39846:27939,39847:27940,39848:27942,39849:27944,39850:27945,39851:27948,39852:27949,39853:27951,39854:27952,39855:27956,39856:27958,39857:27959,39858:27960,39859:27962,39860:27967,39861:27968,39862:27970,39863:27972,39864:27977,39865:27980,39866:27984,39867:27989,39868:27990,39869:27991,39870:27992,39871:27995,39872:27997,39873:27999,39874:28001,39875:28002,39876:28004,39877:28005,39878:28007,39879:28008,39880:28011,39881:28012,39882:28013,39883:28016,39884:28017,39885:28018,39886:28019,39887:28021,39888:28022,39889:28025,39890:28026,39891:28027,39892:28029,39893:28030,39894:28031,39895:28032,39896:28033,39897:28035,39898:28036,39899:28038,39900:28039,39901:28042,39902:28043,39903:28045,39904:28047,39905:28048,39906:28050,39907:28054,39908:28055,39909:28056,39910:28057,39911:28058,39912:28060,39913:28066,39914:28069,39915:28076,39916:28077,39917:28080,39918:28081,39919:28083,39920:28084,39921:28086,39922:28087,39923:28089,39924:28090,39925:28091,39926:28092,39927:28093,39928:28094,39929:28097,39930:28098,39931:28099,39932:28104,39933:28105,39934:28106,40000:28109,40001:28110,40002:28111,40003:28112,40004:28114,40005:28115,40006:28116,40007:28117,40008:28119,40009:28122,40010:28123,40011:28124,40012:28127,40013:28130,40014:28131,40015:28133,40016:28135,40017:28136,40018:28137,40019:28138,40020:28141,40021:28143,40022:28144,40023:28146,40024:28148,40025:28149,40026:28150,40027:28152,40028:28154,40029:28157,40030:28158,40031:28159,40032:28160,40033:28161,40034:28162,40035:28163,40036:28164,40037:28166,40038:28167,40039:28168,40040:28169,40041:28171,40042:28175,40043:28178,40044:28179,40045:28181,40046:28184,40047:28185,40048:28187,40049:28188,40050:28190,40051:28191,40052:28194,40053:28198,40054:28199,40055:28200,40056:28202,40057:28204,40058:28206,40059:28208,40060:28209,40061:28211,40062:28213,40064:28214,40065:28215,40066:28217,40067:28219,40068:28220,40069:28221,40070:28222,40071:28223,40072:28224,40073:28225,40074:28226,40075:28229,40076:28230,40077:28231,40078:28232,40079:28233,40080:28234,40081:28235,40082:28236,40083:28239,40084:28240,40085:28241,40086:28242,40087:28245,40088:28247,40089:28249,40090:28250,40091:28252,40092:28253,40093:28254,40094:28256,40095:28257,40096:28258,40097:28259,40098:28260,40099:28261,40100:28262,40101:28263,40102:28264,40103:28265,40104:28266,40105:28268,40106:28269,40107:28271,40108:28272,40109:28273,40110:28274,40111:28275,40112:28276,40113:28277,40114:28278,40115:28279,40116:28280,40117:28281,40118:28282,40119:28283,40120:28284,40121:28285,40122:28288,40123:28289,40124:28290,40125:28292,40126:28295,40127:28296,40128:28298,40129:28299,40130:28300,40131:28301,40132:28302,40133:28305,40134:28306,40135:28307,40136:28308,40137:28309,40138:28310,40139:28311,40140:28313,40141:28314,40142:28315,40143:28317,40144:28318,40145:28320,40146:28321,40147:28323,40148:28324,40149:28326,40150:28328,40151:28329,40152:28331,40153:28332,40154:28333,40155:28334,40156:28336,40157:28339,40158:28341,40159:28344,40160:28345,40161:28348,40162:28350,40163:28351,40164:28352,40165:28355,40166:28356,40167:28357,40168:28358,40169:28360,40170:28361,40171:28362,40172:28364,40173:28365,40174:28366,40175:28368,40176:28370,40177:28374,40178:28376,40179:28377,40180:28379,40181:28380,40182:28381,40183:28387,40184:28391,40185:28394,40186:28395,40187:28396,40188:28397,40189:28398,40190:28399,40256:28400,40257:28401,40258:28402,40259:28403,40260:28405,40261:28406,40262:28407,40263:28408,40264:28410,40265:28411,40266:28412,40267:28413,40268:28414,40269:28415,40270:28416,40271:28417,40272:28419,40273:28420,40274:28421,40275:28423,40276:28424,40277:28426,40278:28427,40279:28428,40280:28429,40281:28430,40282:28432,40283:28433,40284:28434,40285:28438,40286:28439,40287:28440,40288:28441,40289:28442,40290:28443,40291:28444,40292:28445,40293:28446,40294:28447,40295:28449,40296:28450,40297:28451,40298:28453,40299:28454,40300:28455,40301:28456,40302:28460,40303:28462,40304:28464,40305:28466,40306:28468,40307:28469,40308:28471,40309:28472,40310:28473,40311:28474,40312:28475,40313:28476,40314:28477,40315:28479,40316:28480,40317:28481,40318:28482,40320:28483,40321:28484,40322:28485,40323:28488,40324:28489,40325:28490,40326:28492,40327:28494,40328:28495,40329:28496,40330:28497,40331:28498,40332:28499,40333:28500,40334:28501,40335:28502,40336:28503,40337:28505,40338:28506,40339:28507,40340:28509,40341:28511,40342:28512,40343:28513,40344:28515,40345:28516,40346:28517,40347:28519,40348:28520,40349:28521,40350:28522,40351:28523,40352:28524,40353:28527,40354:28528,40355:28529,40356:28531,40357:28533,40358:28534,40359:28535,40360:28537,40361:28539,40362:28541,40363:28542,40364:28543,40365:28544,40366:28545,40367:28546,40368:28547,40369:28549,40370:28550,40371:28551,40372:28554,40373:28555,40374:28559,40375:28560,40376:28561,40377:28562,40378:28563,40379:28564,40380:28565,40381:28566,40382:28567,40383:28568,40384:28569,40385:28570,40386:28571,40387:28573,40388:28574,40389:28575,40390:28576,40391:28578,40392:28579,40393:28580,40394:28581,40395:28582,40396:28584,40397:28585,40398:28586,40399:28587,40400:28588,40401:28589,40402:28590,40403:28591,40404:28592,40405:28593,40406:28594,40407:28596,40408:28597,40409:28599,40410:28600,40411:28602,40412:28603,40413:28604,40414:28605,40415:28606,40416:28607,40417:28609,40418:28611,40419:28612,40420:28613,40421:28614,40422:28615,40423:28616,40424:28618,40425:28619,40426:28620,40427:28621,40428:28622,40429:28623,40430:28624,40431:28627,40432:28628,40433:28629,40434:28630,40435:28631,40436:28632,40437:28633,40438:28634,40439:28635,40440:28636,40441:28637,40442:28639,40443:28642,40444:28643,40445:28644,40446:28645,40512:28646,40513:28647,40514:28648,40515:28649,40516:28650,40517:28651,40518:28652,40519:28653,40520:28656,40521:28657,40522:28658,40523:28659,40524:28660,40525:28661,40526:28662,40527:28663,40528:28664,40529:28665,40530:28666,40531:28667,40532:28668,40533:28669,40534:28670,40535:28671,40536:28672,40537:28673,40538:28674,40539:28675,40540:28676,40541:28677,40542:28678,40543:28679,40544:28680,40545:28681,40546:28682,40547:28683,40548:28684,40549:28685,40550:28686,40551:28687,40552:28688,40553:28690,40554:28691,40555:28692,40556:28693,40557:28694,40558:28695,40559:28696,40560:28697,40561:28700,40562:28701,40563:28702,40564:28703,40565:28704,40566:28705,40567:28706,40568:28708,40569:28709,40570:28710,40571:28711,40572:28712,40573:28713,40574:28714,40576:28715,40577:28716,40578:28717,40579:28718,40580:28719,40581:28720,40582:28721,40583:28722,40584:28723,40585:28724,40586:28726,40587:28727,40588:28728,40589:28730,40590:28731,40591:28732,40592:28733,40593:28734,40594:28735,40595:28736,40596:28737,40597:28738,40598:28739,40599:28740,40600:28741,40601:28742,40602:28743,40603:28744,40604:28745,40605:28746,40606:28747,40607:28749,40608:28750,40609:28752,40610:28753,40611:28754,40612:28755,40613:28756,40614:28757,40615:28758,40616:28759,40617:28760,40618:28761,40619:28762,40620:28763,40621:28764,40622:28765,40623:28767,40624:28768,40625:28769,40626:28770,40627:28771,40628:28772,40629:28773,40630:28774,40631:28775,40632:28776,40633:28777,40634:28778,40635:28782,40636:28785,40637:28786,40638:28787,40639:28788,40640:28791,40641:28793,40642:28794,40643:28795,40644:28797,40645:28801,40646:28802,40647:28803,40648:28804,40649:28806,40650:28807,40651:28808,40652:28811,40653:28812,40654:28813,40655:28815,40656:28816,40657:28817,40658:28819,40659:28823,40660:28824,40661:28826,40662:28827,40663:28830,40664:28831,40665:28832,40666:28833,40667:28834,40668:28835,40669:28836,40670:28837,40671:28838,40672:28839,40673:28840,40674:28841,40675:28842,40676:28848,40677:28850,40678:28852,40679:28853,40680:28854,40681:28858,40682:28862,40683:28863,40684:28868,40685:28869,40686:28870,40687:28871,40688:28873,40689:28875,40690:28876,40691:28877,40692:28878,40693:28879,40694:28880,40695:28881,40696:28882,40697:28883,40698:28884,40699:28885,40700:28886,40701:28887,40702:28890,40768:28892,40769:28893,40770:28894,40771:28896,40772:28897,40773:28898,40774:28899,40775:28901,40776:28906,40777:28910,40778:28912,40779:28913,40780:28914,40781:28915,40782:28916,40783:28917,40784:28918,40785:28920,40786:28922,40787:28923,40788:28924,40789:28926,40790:28927,40791:28928,40792:28929,40793:28930,40794:28931,40795:28932,40796:28933,40797:28934,40798:28935,40799:28936,40800:28939,40801:28940,40802:28941,40803:28942,40804:28943,40805:28945,40806:28946,40807:28948,40808:28951,40809:28955,40810:28956,40811:28957,40812:28958,40813:28959,40814:28960,40815:28961,40816:28962,40817:28963,40818:28964,40819:28965,40820:28967,40821:28968,40822:28969,40823:28970,40824:28971,40825:28972,40826:28973,40827:28974,40828:28978,40829:28979,40830:28980,40832:28981,40833:28983,40834:28984,40835:28985,40836:28986,40837:28987,40838:28988,40839:28989,40840:28990,40841:28991,40842:28992,40843:28993,40844:28994,40845:28995,40846:28996,40847:28998,40848:28999,40849:29000,40850:29001,40851:29003,40852:29005,40853:29007,40854:29008,40855:29009,40856:29010,40857:29011,40858:29012,40859:29013,40860:29014,40861:29015,40862:29016,40863:29017,40864:29018,40865:29019,40866:29021,40867:29023,40868:29024,40869:29025,40870:29026,40871:29027,40872:29029,40873:29033,40874:29034,40875:29035,40876:29036,40877:29037,40878:29039,40879:29040,40880:29041,40881:29044,40882:29045,40883:29046,40884:29047,40885:29049,40886:29051,40887:29052,40888:29054,40889:29055,40890:29056,40891:29057,40892:29058,40893:29059,40894:29061,40895:29062,40896:29063,40897:29064,40898:29065,40899:29067,40900:29068,40901:29069,40902:29070,40903:29072,40904:29073,40905:29074,40906:29075,40907:29077,40908:29078,40909:29079,40910:29082,40911:29083,40912:29084,40913:29085,40914:29086,40915:29089,40916:29090,40917:29091,40918:29092,40919:29093,40920:29094,40921:29095,40922:29097,40923:29098,40924:29099,40925:29101,40926:29102,40927:29103,40928:29104,40929:29105,40930:29106,40931:29108,40932:29110,40933:29111,40934:29112,40935:29114,40936:29115,40937:29116,40938:29117,40939:29118,40940:29119,40941:29120,40942:29121,40943:29122,40944:29124,40945:29125,40946:29126,40947:29127,40948:29128,40949:29129,40950:29130,40951:29131,40952:29132,40953:29133,40954:29135,40955:29136,40956:29137,40957:29138,40958:29139,41024:29142,41025:29143,41026:29144,41027:29145,41028:29146,41029:29147,41030:29148,41031:29149,41032:29150,41033:29151,41034:29153,41035:29154,41036:29155,41037:29156,41038:29158,41039:29160,41040:29161,41041:29162,41042:29163,41043:29164,41044:29165,41045:29167,41046:29168,41047:29169,41048:29170,41049:29171,41050:29172,41051:29173,41052:29174,41053:29175,41054:29176,41055:29178,41056:29179,41057:29180,41058:29181,41059:29182,41060:29183,41061:29184,41062:29185,41063:29186,41064:29187,41065:29188,41066:29189,41067:29191,41068:29192,41069:29193,41070:29194,41071:29195,41072:29196,41073:29197,41074:29198,41075:29199,41076:29200,41077:29201,41078:29202,41079:29203,41080:29204,41081:29205,41082:29206,41083:29207,41084:29208,41085:29209,41086:29210,41088:29211,41089:29212,41090:29214,41091:29215,41092:29216,41093:29217,41094:29218,41095:29219,41096:29220,41097:29221,41098:29222,41099:29223,41100:29225,41101:29227,41102:29229,41103:29230,41104:29231,41105:29234,41106:29235,41107:29236,41108:29242,41109:29244,41110:29246,41111:29248,41112:29249,41113:29250,41114:29251,41115:29252,41116:29253,41117:29254,41118:29257,41119:29258,41120:29259,41121:29262,41122:29263,41123:29264,41124:29265,41125:29267,41126:29268,41127:29269,41128:29271,41129:29272,41130:29274,41131:29276,41132:29278,41133:29280,41134:29283,41135:29284,41136:29285,41137:29288,41138:29290,41139:29291,41140:29292,41141:29293,41142:29296,41143:29297,41144:29299,41145:29300,41146:29302,41147:29303,41148:29304,41149:29307,41150:29308,41151:29309,41152:29314,41153:29315,41154:29317,41155:29318,41156:29319,41157:29320,41158:29321,41159:29324,41160:29326,41161:29328,41162:29329,41163:29331,41164:29332,41165:29333,41166:29334,41167:29335,41168:29336,41169:29337,41170:29338,41171:29339,41172:29340,41173:29341,41174:29342,41175:29344,41176:29345,41177:29346,41178:29347,41179:29348,41180:29349,41181:29350,41182:29351,41183:29352,41184:29353,41185:29354,41186:29355,41187:29358,41188:29361,41189:29362,41190:29363,41191:29365,41192:29370,41193:29371,41194:29372,41195:29373,41196:29374,41197:29375,41198:29376,41199:29381,41200:29382,41201:29383,41202:29385,41203:29386,41204:29387,41205:29388,41206:29391,41207:29393,41208:29395,41209:29396,41210:29397,41211:29398,41212:29400,41213:29402,41214:29403,41280:58566,41281:58567,41282:58568,41283:58569,41284:58570,41285:58571,41286:58572,41287:58573,41288:58574,41289:58575,41290:58576,41291:58577,41292:58578,41293:58579,41294:58580,41295:58581,41296:58582,41297:58583,41298:58584,41299:58585,41300:58586,41301:58587,41302:58588,41303:58589,41304:58590,41305:58591,41306:58592,41307:58593,41308:58594,41309:58595,41310:58596,41311:58597,41312:58598,41313:58599,41314:58600,41315:58601,41316:58602,41317:58603,41318:58604,41319:58605,41320:58606,41321:58607,41322:58608,41323:58609,41324:58610,41325:58611,41326:58612,41327:58613,41328:58614,41329:58615,41330:58616,41331:58617,41332:58618,41333:58619,41334:58620,41335:58621,41336:58622,41337:58623,41338:58624,41339:58625,41340:58626,41341:58627,41342:58628,41344:58629,41345:58630,41346:58631,41347:58632,41348:58633,41349:58634,41350:58635,41351:58636,41352:58637,41353:58638,41354:58639,41355:58640,41356:58641,41357:58642,41358:58643,41359:58644,41360:58645,41361:58646,41362:58647,41363:58648,41364:58649,41365:58650,41366:58651,41367:58652,41368:58653,41369:58654,41370:58655,41371:58656,41372:58657,41373:58658,41374:58659,41375:58660,41376:58661,41377:12288,41378:12289,41379:12290,41380:183,41381:713,41382:711,41383:168,41384:12291,41385:12293,41386:8212,41387:65374,41388:8214,41389:8230,41390:8216,41391:8217,41392:8220,41393:8221,41394:12308,41395:12309,41396:12296,41397:12297,41398:12298,41399:12299,41400:12300,41401:12301,41402:12302,41403:12303,41404:12310,41405:12311,41406:12304,41407:12305,41408:177,41409:215,41410:247,41411:8758,41412:8743,41413:8744,41414:8721,41415:8719,41416:8746,41417:8745,41418:8712,41419:8759,41420:8730,41421:8869,41422:8741,41423:8736,41424:8978,41425:8857,41426:8747,41427:8750,41428:8801,41429:8780,41430:8776,41431:8765,41432:8733,41433:8800,41434:8814,41435:8815,41436:8804,41437:8805,41438:8734,41439:8757,41440:8756,41441:9794,41442:9792,41443:176,41444:8242,41445:8243,41446:8451,41447:65284,41448:164,41449:65504,41450:65505,41451:8240,41452:167,41453:8470,41454:9734,41455:9733,41456:9675,41457:9679,41458:9678,41459:9671,41460:9670,41461:9633,41462:9632,41463:9651,41464:9650,41465:8251,41466:8594,41467:8592,41468:8593,41469:8595,41470:12307,41536:58662,41537:58663,41538:58664,41539:58665,41540:58666,41541:58667,41542:58668,41543:58669,41544:58670,41545:58671,41546:58672,41547:58673,41548:58674,41549:58675,41550:58676,41551:58677,41552:58678,41553:58679,41554:58680,41555:58681,41556:58682,41557:58683,41558:58684,41559:58685,41560:58686,41561:58687,41562:58688,41563:58689,41564:58690,41565:58691,41566:58692,41567:58693,41568:58694,41569:58695,41570:58696,41571:58697,41572:58698,41573:58699,41574:58700,41575:58701,41576:58702,41577:58703,41578:58704,41579:58705,41580:58706,41581:58707,41582:58708,41583:58709,41584:58710,41585:58711,41586:58712,41587:58713,41588:58714,41589:58715,41590:58716,41591:58717,41592:58718,41593:58719,41594:58720,41595:58721,41596:58722,41597:58723,41598:58724,41600:58725,41601:58726,41602:58727,41603:58728,41604:58729,41605:58730,41606:58731,41607:58732,41608:58733,41609:58734,41610:58735,41611:58736,41612:58737,41613:58738,41614:58739,41615:58740,41616:58741,41617:58742,41618:58743,41619:58744,41620:58745,41621:58746,41622:58747,41623:58748,41624:58749,41625:58750,41626:58751,41627:58752,41628:58753,41629:58754,41630:58755,41631:58756,41632:58757,41633:8560,41634:8561,41635:8562,41636:8563,41637:8564,41638:8565,41639:8566,41640:8567,41641:8568,41642:8569,41643:59238,41644:59239,41645:59240,41646:59241,41647:59242,41648:59243,41649:9352,41650:9353,41651:9354,41652:9355,41653:9356,41654:9357,41655:9358,41656:9359,41657:9360,41658:9361,41659:9362,41660:9363,41661:9364,41662:9365,41663:9366,41664:9367,41665:9368,41666:9369,41667:9370,41668:9371,41669:9332,41670:9333,41671:9334,41672:9335,41673:9336,41674:9337,41675:9338,41676:9339,41677:9340,41678:9341,41679:9342,41680:9343,41681:9344,41682:9345,41683:9346,41684:9347,41685:9348,41686:9349,41687:9350,41688:9351,41689:9312,41690:9313,41691:9314,41692:9315,41693:9316,41694:9317,41695:9318,41696:9319,41697:9320,41698:9321,41699:8364,41700:59245,41701:12832,41702:12833,41703:12834,41704:12835,41705:12836,41706:12837,41707:12838,41708:12839,41709:12840,41710:12841,41711:59246,41712:59247,41713:8544,41714:8545,41715:8546,41716:8547,41717:8548,41718:8549,41719:8550,41720:8551,41721:8552,41722:8553,41723:8554,41724:8555,41725:59248,41726:59249,41792:58758,41793:58759,41794:58760,41795:58761,41796:58762,41797:58763,41798:58764,41799:58765,41800:58766,41801:58767,41802:58768,41803:58769,41804:58770,41805:58771,41806:58772,41807:58773,41808:58774,41809:58775,41810:58776,41811:58777,41812:58778,41813:58779,41814:58780,41815:58781,41816:58782,41817:58783,41818:58784,41819:58785,41820:58786,41821:58787,41822:58788,41823:58789,41824:58790,41825:58791,41826:58792,41827:58793,41828:58794,41829:58795,41830:58796,41831:58797,41832:58798,41833:58799,41834:58800,41835:58801,41836:58802,41837:58803,41838:58804,41839:58805,41840:58806,41841:58807,41842:58808,41843:58809,41844:58810,41845:58811,41846:58812,41847:58813,41848:58814,41849:58815,41850:58816,41851:58817,41852:58818,41853:58819,41854:58820,41856:58821,41857:58822,41858:58823,41859:58824,41860:58825,41861:58826,41862:58827,41863:58828,41864:58829,41865:58830,41866:58831,41867:58832,41868:58833,41869:58834,41870:58835,41871:58836,41872:58837,41873:58838,41874:58839,41875:58840,41876:58841,41877:58842,41878:58843,41879:58844,41880:58845,41881:58846,41882:58847,41883:58848,41884:58849,41885:58850,41886:58851,41887:58852,41888:58853,41889:65281,41890:65282,41891:65283,41892:65509,41893:65285,41894:65286,41895:65287,41896:65288,41897:65289,41898:65290,41899:65291,41900:65292,41901:65293,41902:65294,41903:65295,41904:65296,41905:65297,41906:65298,41907:65299,41908:65300,41909:65301,41910:65302,41911:65303,41912:65304,41913:65305,41914:65306,41915:65307,41916:65308,41917:65309,41918:65310,41919:65311,41920:65312,41921:65313,41922:65314,41923:65315,41924:65316,41925:65317,41926:65318,41927:65319,41928:65320,41929:65321,41930:65322,41931:65323,41932:65324,41933:65325,41934:65326,41935:65327,41936:65328,41937:65329,41938:65330,41939:65331,41940:65332,41941:65333,41942:65334,41943:65335,41944:65336,41945:65337,41946:65338,41947:65339,41948:65340,41949:65341,41950:65342,41951:65343,41952:65344,41953:65345,41954:65346,41955:65347,41956:65348,41957:65349,41958:65350,41959:65351,41960:65352,41961:65353,41962:65354,41963:65355,41964:65356,41965:65357,41966:65358,41967:65359,41968:65360,41969:65361,41970:65362,41971:65363,41972:65364,41973:65365,41974:65366,41975:65367,41976:65368,41977:65369,41978:65370,41979:65371,41980:65372,41981:65373,41982:65507,42048:58854,42049:58855,42050:58856,42051:58857,42052:58858,42053:58859,42054:58860,42055:58861,42056:58862,42057:58863,42058:58864,42059:58865,42060:58866,42061:58867,42062:58868,42063:58869,42064:58870,42065:58871,42066:58872,42067:58873,42068:58874,42069:58875,42070:58876,42071:58877,42072:58878,42073:58879,42074:58880,42075:58881,42076:58882,42077:58883,42078:58884,42079:58885,42080:58886,42081:58887,42082:58888,42083:58889,42084:58890,42085:58891,42086:58892,42087:58893,42088:58894,42089:58895,42090:58896,42091:58897,42092:58898,42093:58899,42094:58900,42095:58901,42096:58902,42097:58903,42098:58904,42099:58905,42100:58906,42101:58907,42102:58908,42103:58909,42104:58910,42105:58911,42106:58912,42107:58913,42108:58914,42109:58915,42110:58916,42112:58917,42113:58918,42114:58919,42115:58920,42116:58921,42117:58922,42118:58923,42119:58924,42120:58925,42121:58926,42122:58927,42123:58928,42124:58929,42125:58930,42126:58931,42127:58932,42128:58933,42129:58934,42130:58935,42131:58936,42132:58937,42133:58938,42134:58939,42135:58940,42136:58941,42137:58942,42138:58943,42139:58944,42140:58945,42141:58946,42142:58947,42143:58948,42144:58949,42145:12353,42146:12354,42147:12355,42148:12356,42149:12357,42150:12358,42151:12359,42152:12360,42153:12361,42154:12362,42155:12363,42156:12364,42157:12365,42158:12366,42159:12367,42160:12368,42161:12369,42162:12370,42163:12371,42164:12372,42165:12373,42166:12374,42167:12375,42168:12376,42169:12377,42170:12378,42171:12379,42172:12380,42173:12381,42174:12382,42175:12383,42176:12384,42177:12385,42178:12386,42179:12387,42180:12388,42181:12389,42182:12390,42183:12391,42184:12392,42185:12393,42186:12394,42187:12395,42188:12396,42189:12397,42190:12398,42191:12399,42192:12400,42193:12401,42194:12402,42195:12403,42196:12404,42197:12405,42198:12406,42199:12407,42200:12408,42201:12409,42202:12410,42203:12411,42204:12412,42205:12413,42206:12414,42207:12415,42208:12416,42209:12417,42210:12418,42211:12419,42212:12420,42213:12421,42214:12422,42215:12423,42216:12424,42217:12425,42218:12426,42219:12427,42220:12428,42221:12429,42222:12430,42223:12431,42224:12432,42225:12433,42226:12434,42227:12435,42228:59250,42229:59251,42230:59252,42231:59253,42232:59254,42233:59255,42234:59256,42235:59257,42236:59258,42237:59259,42238:59260,42304:58950,42305:58951,42306:58952,42307:58953,42308:58954,42309:58955,42310:58956,42311:58957,42312:58958,42313:58959,42314:58960,42315:58961,42316:58962,42317:58963,42318:58964,42319:58965,42320:58966,42321:58967,42322:58968,42323:58969,42324:58970,42325:58971,42326:58972,42327:58973,42328:58974,42329:58975,42330:58976,42331:58977,42332:58978,42333:58979,42334:58980,42335:58981,42336:58982,42337:58983,42338:58984,42339:58985,42340:58986,42341:58987,42342:58988,42343:58989,42344:58990,42345:58991,42346:58992,42347:58993,42348:58994,42349:58995,42350:58996,42351:58997,42352:58998,42353:58999,42354:59000,42355:59001,42356:59002,42357:59003,42358:59004,42359:59005,42360:59006,42361:59007,42362:59008,42363:59009,42364:59010,42365:59011,42366:59012,42368:59013,42369:59014,42370:59015,42371:59016,42372:59017,42373:59018,42374:59019,42375:59020,42376:59021,42377:59022,42378:59023,42379:59024,42380:59025,42381:59026,42382:59027,42383:59028,42384:59029,42385:59030,42386:59031,42387:59032,42388:59033,42389:59034,42390:59035,42391:59036,42392:59037,42393:59038,42394:59039,42395:59040,42396:59041,42397:59042,42398:59043,42399:59044,42400:59045,42401:12449,42402:12450,42403:12451,42404:12452,42405:12453,42406:12454,42407:12455,42408:12456,42409:12457,42410:12458,42411:12459,42412:12460,42413:12461,42414:12462,42415:12463,42416:12464,42417:12465,42418:12466,42419:12467,42420:12468,42421:12469,42422:12470,42423:12471,42424:12472,42425:12473,42426:12474,42427:12475,42428:12476,42429:12477,42430:12478,42431:12479,42432:12480,42433:12481,42434:12482,42435:12483,42436:12484,42437:12485,42438:12486,42439:12487,42440:12488,42441:12489,42442:12490,42443:12491,42444:12492,42445:12493,42446:12494,42447:12495,42448:12496,42449:12497,42450:12498,42451:12499,42452:12500,42453:12501,42454:12502,42455:12503,42456:12504,42457:12505,42458:12506,42459:12507,42460:12508,42461:12509,42462:12510,42463:12511,42464:12512,42465:12513,42466:12514,42467:12515,42468:12516,42469:12517,42470:12518,42471:12519,42472:12520,42473:12521,42474:12522,42475:12523,42476:12524,42477:12525,42478:12526,42479:12527,42480:12528,42481:12529,42482:12530,42483:12531,42484:12532,42485:12533,42486:12534,42487:59261,42488:59262,42489:59263,42490:59264,42491:59265,42492:59266,42493:59267,42494:59268,42560:59046,42561:59047,42562:59048,42563:59049,42564:59050,42565:59051,42566:59052,42567:59053,42568:59054,42569:59055,42570:59056,42571:59057,42572:59058,42573:59059,42574:59060,42575:59061,42576:59062,42577:59063,42578:59064,42579:59065,42580:59066,42581:59067,42582:59068,42583:59069,42584:59070,42585:59071,42586:59072,42587:59073,42588:59074,42589:59075,42590:59076,42591:59077,42592:59078,42593:59079,42594:59080,42595:59081,42596:59082,42597:59083,42598:59084,42599:59085,42600:59086,42601:59087,42602:59088,42603:59089,42604:59090,42605:59091,42606:59092,42607:59093,42608:59094,42609:59095,42610:59096,42611:59097,42612:59098,42613:59099,42614:59100,42615:59101,42616:59102,42617:59103,42618:59104,42619:59105,42620:59106,42621:59107,42622:59108,42624:59109,42625:59110,42626:59111,42627:59112,42628:59113,42629:59114,42630:59115,42631:59116,42632:59117,42633:59118,42634:59119,42635:59120,42636:59121,42637:59122,42638:59123,42639:59124,42640:59125,42641:59126,42642:59127,42643:59128,42644:59129,42645:59130,42646:59131,42647:59132,42648:59133,42649:59134,42650:59135,42651:59136,42652:59137,42653:59138,42654:59139,42655:59140,42656:59141,42657:913,42658:914,42659:915,42660:916,42661:917,42662:918,42663:919,42664:920,42665:921,42666:922,42667:923,42668:924,42669:925,42670:926,42671:927,42672:928,42673:929,42674:931,42675:932,42676:933,42677:934,42678:935,42679:936,42680:937,42681:59269,42682:59270,42683:59271,42684:59272,42685:59273,42686:59274,42687:59275,42688:59276,42689:945,42690:946,42691:947,42692:948,42693:949,42694:950,42695:951,42696:952,42697:953,42698:954,42699:955,42700:956,42701:957,42702:958,42703:959,42704:960,42705:961,42706:963,42707:964,42708:965,42709:966,42710:967,42711:968,42712:969,42713:59277,42714:59278,42715:59279,42716:59280,42717:59281,42718:59282,42719:59283,42720:65077,42721:65078,42722:65081,42723:65082,42724:65087,42725:65088,42726:65085,42727:65086,42728:65089,42729:65090,42730:65091,42731:65092,42732:59284,42733:59285,42734:65083,42735:65084,42736:65079,42737:65080,42738:65073,42739:59286,42740:65075,42741:65076,42742:59287,42743:59288,42744:59289,42745:59290,42746:59291,42747:59292,42748:59293,42749:59294,42750:59295,42816:59142,42817:59143,42818:59144,42819:59145,42820:59146,42821:59147,42822:59148,42823:59149,42824:59150,42825:59151,42826:59152,42827:59153,42828:59154,42829:59155,42830:59156,42831:59157,42832:59158,42833:59159,42834:59160,42835:59161,42836:59162,42837:59163,42838:59164,42839:59165,42840:59166,42841:59167,42842:59168,42843:59169,42844:59170,42845:59171,42846:59172,42847:59173,42848:59174,42849:59175,42850:59176,42851:59177,42852:59178,42853:59179,42854:59180,42855:59181,42856:59182,42857:59183,42858:59184,42859:59185,42860:59186,42861:59187,42862:59188,42863:59189,42864:59190,42865:59191,42866:59192,42867:59193,42868:59194,42869:59195,42870:59196,42871:59197,42872:59198,42873:59199,42874:59200,42875:59201,42876:59202,42877:59203,42878:59204,42880:59205,42881:59206,42882:59207,42883:59208,42884:59209,42885:59210,42886:59211,42887:59212,42888:59213,42889:59214,42890:59215,42891:59216,42892:59217,42893:59218,42894:59219,42895:59220,42896:59221,42897:59222,42898:59223,42899:59224,42900:59225,42901:59226,42902:59227,42903:59228,42904:59229,42905:59230,42906:59231,42907:59232,42908:59233,42909:59234,42910:59235,42911:59236,42912:59237,42913:1040,42914:1041,42915:1042,42916:1043,42917:1044,42918:1045,42919:1025,42920:1046,42921:1047,42922:1048,42923:1049,42924:1050,42925:1051,42926:1052,42927:1053,42928:1054,42929:1055,42930:1056,42931:1057,42932:1058,42933:1059,42934:1060,42935:1061,42936:1062,42937:1063,42938:1064,42939:1065,42940:1066,42941:1067,42942:1068,42943:1069,42944:1070,42945:1071,42946:59296,42947:59297,42948:59298,42949:59299,42950:59300,42951:59301,42952:59302,42953:59303,42954:59304,42955:59305,42956:59306,42957:59307,42958:59308,42959:59309,42960:59310,42961:1072,42962:1073,42963:1074,42964:1075,42965:1076,42966:1077,42967:1105,42968:1078,42969:1079,42970:1080,42971:1081,42972:1082,42973:1083,42974:1084,42975:1085,42976:1086,42977:1087,42978:1088,42979:1089,42980:1090,42981:1091,42982:1092,42983:1093,42984:1094,42985:1095,42986:1096,42987:1097,42988:1098,42989:1099,42990:1100,42991:1101,42992:1102,42993:1103,42994:59311,42995:59312,42996:59313,42997:59314,42998:59315,42999:59316,43000:59317,43001:59318,43002:59319,43003:59320,43004:59321,43005:59322,43006:59323,43072:714,43073:715,43074:729,43075:8211,43076:8213,43077:8229,43078:8245,43079:8453,43080:8457,43081:8598,43082:8599,43083:8600,43084:8601,43085:8725,43086:8735,43087:8739,43088:8786,43089:8806,43090:8807,43091:8895,43092:9552,43093:9553,43094:9554,43095:9555,43096:9556,43097:9557,43098:9558,43099:9559,43100:9560,43101:9561,43102:9562,43103:9563,43104:9564,43105:9565,43106:9566,43107:9567,43108:9568,43109:9569,43110:9570,43111:9571,43112:9572,43113:9573,43114:9574,43115:9575,43116:9576,43117:9577,43118:9578,43119:9579,43120:9580,43121:9581,43122:9582,43123:9583,43124:9584,43125:9585,43126:9586,43127:9587,43128:9601,43129:9602,43130:9603,43131:9604,43132:9605,43133:9606,43134:9607,43136:9608,43137:9609,43138:9610,43139:9611,43140:9612,43141:9613,43142:9614,43143:9615,43144:9619,43145:9620,43146:9621,43147:9660,43148:9661,43149:9698,43150:9699,43151:9700,43152:9701,43153:9737,43154:8853,43155:12306,43156:12317,43157:12318,43158:59324,43159:59325,43160:59326,43161:59327,43162:59328,43163:59329,43164:59330,43165:59331,43166:59332,43167:59333,43168:59334,43169:257,43170:225,43171:462,43172:224,43173:275,43174:233,43175:283,43176:232,43177:299,43178:237,43179:464,43180:236,43181:333,43182:243,43183:466,43184:242,43185:363,43186:250,43187:468,43188:249,43189:470,43190:472,43191:474,43192:476,43193:252,43194:234,43195:593,43196:59335,43197:324,43198:328,43199:505,43200:609,43201:59337,43202:59338,43203:59339,43204:59340,43205:12549,43206:12550,43207:12551,43208:12552,43209:12553,43210:12554,43211:12555,43212:12556,43213:12557,43214:12558,43215:12559,43216:12560,43217:12561,43218:12562,43219:12563,43220:12564,43221:12565,43222:12566,43223:12567,43224:12568,43225:12569,43226:12570,43227:12571,43228:12572,43229:12573,43230:12574,43231:12575,43232:12576,43233:12577,43234:12578,43235:12579,43236:12580,43237:12581,43238:12582,43239:12583,43240:12584,43241:12585,43242:59341,43243:59342,43244:59343,43245:59344,43246:59345,43247:59346,43248:59347,43249:59348,43250:59349,43251:59350,43252:59351,43253:59352,43254:59353,43255:59354,43256:59355,43257:59356,43258:59357,43259:59358,43260:59359,43261:59360,43262:59361,43328:12321,43329:12322,43330:12323,43331:12324,43332:12325,43333:12326,43334:12327,43335:12328,43336:12329,43337:12963,43338:13198,43339:13199,43340:13212,43341:13213,43342:13214,43343:13217,43344:13252,43345:13262,43346:13265,43347:13266,43348:13269,43349:65072,43350:65506,43351:65508,43352:59362,43353:8481,43354:12849,43355:59363,43356:8208,43357:59364,43358:59365,43359:59366,43360:12540,43361:12443,43362:12444,43363:12541,43364:12542,43365:12294,43366:12445,43367:12446,43368:65097,43369:65098,43370:65099,43371:65100,43372:65101,43373:65102,43374:65103,43375:65104,43376:65105,43377:65106,43378:65108,43379:65109,43380:65110,43381:65111,43382:65113,43383:65114,43384:65115,43385:65116,43386:65117,43387:65118,43388:65119,43389:65120,43390:65121,43392:65122,43393:65123,43394:65124,43395:65125,43396:65126,43397:65128,43398:65129,43399:65130,43400:65131,43401:12350,43402:12272,43403:12273,43404:12274,43405:12275,43406:12276,43407:12277,43408:12278,43409:12279,43410:12280,43411:12281,43412:12282,43413:12283,43414:12295,43415:59380,43416:59381,43417:59382,43418:59383,43419:59384,43420:59385,43421:59386,43422:59387,43423:59388,43424:59389,43425:59390,43426:59391,43427:59392,43428:9472,43429:9473,43430:9474,43431:9475,43432:9476,43433:9477,43434:9478,43435:9479,43436:9480,43437:9481,43438:9482,43439:9483,43440:9484,43441:9485,43442:9486,43443:9487,43444:9488,43445:9489,43446:9490,43447:9491,43448:9492,43449:9493,43450:9494,43451:9495,43452:9496,43453:9497,43454:9498,43455:9499,43456:9500,43457:9501,43458:9502,43459:9503,43460:9504,43461:9505,43462:9506,43463:9507,43464:9508,43465:9509,43466:9510,43467:9511,43468:9512,43469:9513,43470:9514,43471:9515,43472:9516,43473:9517,43474:9518,43475:9519,43476:9520,43477:9521,43478:9522,43479:9523,43480:9524,43481:9525,43482:9526,43483:9527,43484:9528,43485:9529,43486:9530,43487:9531,43488:9532,43489:9533,43490:9534,43491:9535,43492:9536,43493:9537,43494:9538,43495:9539,43496:9540,43497:9541,43498:9542,43499:9543,43500:9544,43501:9545,43502:9546,43503:9547,43504:59393,43505:59394,43506:59395,43507:59396,43508:59397,43509:59398,43510:59399,43511:59400,43512:59401,43513:59402,43514:59403,43515:59404,43516:59405,43517:59406,43518:59407,43584:29404,43585:29405,43586:29407,43587:29410,43588:29411,43589:29412,43590:29413,43591:29414,43592:29415,43593:29418,43594:29419,43595:29429,43596:29430,43597:29433,43598:29437,43599:29438,43600:29439,43601:29440,43602:29442,43603:29444,43604:29445,43605:29446,43606:29447,43607:29448,43608:29449,43609:29451,43610:29452,43611:29453,43612:29455,43613:29456,43614:29457,43615:29458,43616:29460,43617:29464,43618:29465,43619:29466,43620:29471,43621:29472,43622:29475,43623:29476,43624:29478,43625:29479,43626:29480,43627:29485,43628:29487,43629:29488,43630:29490,43631:29491,43632:29493,43633:29494,43634:29498,43635:29499,43636:29500,43637:29501,43638:29504,43639:29505,43640:29506,43641:29507,43642:29508,43643:29509,43644:29510,43645:29511,43646:29512,43648:29513,43649:29514,43650:29515,43651:29516,43652:29518,43653:29519,43654:29521,43655:29523,43656:29524,43657:29525,43658:29526,43659:29528,43660:29529,43661:29530,43662:29531,43663:29532,43664:29533,43665:29534,43666:29535,43667:29537,43668:29538,43669:29539,43670:29540,43671:29541,43672:29542,43673:29543,43674:29544,43675:29545,43676:29546,43677:29547,43678:29550,43679:29552,43680:29553,43681:57344,43682:57345,43683:57346,43684:57347,43685:57348,43686:57349,43687:57350,43688:57351,43689:57352,43690:57353,43691:57354,43692:57355,43693:57356,43694:57357,43695:57358,43696:57359,43697:57360,43698:57361,43699:57362,43700:57363,43701:57364,43702:57365,43703:57366,43704:57367,43705:57368,43706:57369,43707:57370,43708:57371,43709:57372,43710:57373,43711:57374,43712:57375,43713:57376,43714:57377,43715:57378,43716:57379,43717:57380,43718:57381,43719:57382,43720:57383,43721:57384,43722:57385,43723:57386,43724:57387,43725:57388,43726:57389,43727:57390,43728:57391,43729:57392,43730:57393,43731:57394,43732:57395,43733:57396,43734:57397,43735:57398,43736:57399,43737:57400,43738:57401,43739:57402,43740:57403,43741:57404,43742:57405,43743:57406,43744:57407,43745:57408,43746:57409,43747:57410,43748:57411,43749:57412,43750:57413,43751:57414,43752:57415,43753:57416,43754:57417,43755:57418,43756:57419,43757:57420,43758:57421,43759:57422,43760:57423,43761:57424,43762:57425,43763:57426,43764:57427,43765:57428,43766:57429,43767:57430,43768:57431,43769:57432,43770:57433,43771:57434,43772:57435,43773:57436,43774:57437,43840:29554,43841:29555,43842:29556,43843:29557,43844:29558,43845:29559,43846:29560,43847:29561,43848:29562,43849:29563,43850:29564,43851:29565,43852:29567,43853:29568,43854:29569,43855:29570,43856:29571,43857:29573,43858:29574,43859:29576,43860:29578,43861:29580,43862:29581,43863:29583,43864:29584,43865:29586,43866:29587,43867:29588,43868:29589,43869:29591,43870:29592,43871:29593,43872:29594,43873:29596,43874:29597,43875:29598,43876:29600,43877:29601,43878:29603,43879:29604,43880:29605,43881:29606,43882:29607,43883:29608,43884:29610,43885:29612,43886:29613,43887:29617,43888:29620,43889:29621,43890:29622,43891:29624,43892:29625,43893:29628,43894:29629,43895:29630,43896:29631,43897:29633,43898:29635,43899:29636,43900:29637,43901:29638,43902:29639,43904:29643,43905:29644,43906:29646,43907:29650,43908:29651,43909:29652,43910:29653,43911:29654,43912:29655,43913:29656,43914:29658,43915:29659,43916:29660,43917:29661,43918:29663,43919:29665,43920:29666,43921:29667,43922:29668,43923:29670,43924:29672,43925:29674,43926:29675,43927:29676,43928:29678,43929:29679,43930:29680,43931:29681,43932:29683,43933:29684,43934:29685,43935:29686,43936:29687,43937:57438,43938:57439,43939:57440,43940:57441,43941:57442,43942:57443,43943:57444,43944:57445,43945:57446,43946:57447,43947:57448,43948:57449,43949:57450,43950:57451,43951:57452,43952:57453,43953:57454,43954:57455,43955:57456,43956:57457,43957:57458,43958:57459,43959:57460,43960:57461,43961:57462,43962:57463,43963:57464,43964:57465,43965:57466,43966:57467,43967:57468,43968:57469,43969:57470,43970:57471,43971:57472,43972:57473,43973:57474,43974:57475,43975:57476,43976:57477,43977:57478,43978:57479,43979:57480,43980:57481,43981:57482,43982:57483,43983:57484,43984:57485,43985:57486,43986:57487,43987:57488,43988:57489,43989:57490,43990:57491,43991:57492,43992:57493,43993:57494,43994:57495,43995:57496,43996:57497,43997:57498,43998:57499,43999:57500,44000:57501,44001:57502,44002:57503,44003:57504,44004:57505,44005:57506,44006:57507,44007:57508,44008:57509,44009:57510,44010:57511,44011:57512,44012:57513,44013:57514,44014:57515,44015:57516,44016:57517,44017:57518,44018:57519,44019:57520,44020:57521,44021:57522,44022:57523,44023:57524,44024:57525,44025:57526,44026:57527,44027:57528,44028:57529,44029:57530,44030:57531,44096:29688,44097:29689,44098:29690,44099:29691,44100:29692,44101:29693,44102:29694,44103:29695,44104:29696,44105:29697,44106:29698,44107:29700,44108:29703,44109:29704,44110:29707,44111:29708,44112:29709,44113:29710,44114:29713,44115:29714,44116:29715,44117:29716,44118:29717,44119:29718,44120:29719,44121:29720,44122:29721,44123:29724,44124:29725,44125:29726,44126:29727,44127:29728,44128:29729,44129:29731,44130:29732,44131:29735,44132:29737,44133:29739,44134:29741,44135:29743,44136:29745,44137:29746,44138:29751,44139:29752,44140:29753,44141:29754,44142:29755,44143:29757,44144:29758,44145:29759,44146:29760,44147:29762,44148:29763,44149:29764,44150:29765,44151:29766,44152:29767,44153:29768,44154:29769,44155:29770,44156:29771,44157:29772,44158:29773,44160:29774,44161:29775,44162:29776,44163:29777,44164:29778,44165:29779,44166:29780,44167:29782,44168:29784,44169:29789,44170:29792,44171:29793,44172:29794,44173:29795,44174:29796,44175:29797,44176:29798,44177:29799,44178:29800,44179:29801,44180:29802,44181:29803,44182:29804,44183:29806,44184:29807,44185:29809,44186:29810,44187:29811,44188:29812,44189:29813,44190:29816,44191:29817,44192:29818,44193:57532,44194:57533,44195:57534,44196:57535,44197:57536,44198:57537,44199:57538,44200:57539,44201:57540,44202:57541,44203:57542,44204:57543,44205:57544,44206:57545,44207:57546,44208:57547,44209:57548,44210:57549,44211:57550,44212:57551,44213:57552,44214:57553,44215:57554,44216:57555,44217:57556,44218:57557,44219:57558,44220:57559,44221:57560,44222:57561,44223:57562,44224:57563,44225:57564,44226:57565,44227:57566,44228:57567,44229:57568,44230:57569,44231:57570,44232:57571,44233:57572,44234:57573,44235:57574,44236:57575,44237:57576,44238:57577,44239:57578,44240:57579,44241:57580,44242:57581,44243:57582,44244:57583,44245:57584,44246:57585,44247:57586,44248:57587,44249:57588,44250:57589,44251:57590,44252:57591,44253:57592,44254:57593,44255:57594,44256:57595,44257:57596,44258:57597,44259:57598,44260:57599,44261:57600,44262:57601,44263:57602,44264:57603,44265:57604,44266:57605,44267:57606,44268:57607,44269:57608,44270:57609,44271:57610,44272:57611,44273:57612,44274:57613,44275:57614,44276:57615,44277:57616,44278:57617,44279:57618,44280:57619,44281:57620,44282:57621,44283:57622,44284:57623,44285:57624,44286:57625,44352:29819,44353:29820,44354:29821,44355:29823,44356:29826,44357:29828,44358:29829,44359:29830,44360:29832,44361:29833,44362:29834,44363:29836,44364:29837,44365:29839,44366:29841,44367:29842,44368:29843,44369:29844,44370:29845,44371:29846,44372:29847,44373:29848,44374:29849,44375:29850,44376:29851,44377:29853,44378:29855,44379:29856,44380:29857,44381:29858,44382:29859,44383:29860,44384:29861,44385:29862,44386:29866,44387:29867,44388:29868,44389:29869,44390:29870,44391:29871,44392:29872,44393:29873,44394:29874,44395:29875,44396:29876,44397:29877,44398:29878,44399:29879,44400:29880,44401:29881,44402:29883,44403:29884,44404:29885,44405:29886,44406:29887,44407:29888,44408:29889,44409:29890,44410:29891,44411:29892,44412:29893,44413:29894,44414:29895,44416:29896,44417:29897,44418:29898,44419:29899,44420:29900,44421:29901,44422:29902,44423:29903,44424:29904,44425:29905,44426:29907,44427:29908,44428:29909,44429:29910,44430:29911,44431:29912,44432:29913,44433:29914,44434:29915,44435:29917,44436:29919,44437:29921,44438:29925,44439:29927,44440:29928,44441:29929,44442:29930,44443:29931,44444:29932,44445:29933,44446:29936,44447:29937,44448:29938,44449:57626,44450:57627,44451:57628,44452:57629,44453:57630,44454:57631,44455:57632,44456:57633,44457:57634,44458:57635,44459:57636,44460:57637,44461:57638,44462:57639,44463:57640,44464:57641,44465:57642,44466:57643,44467:57644,44468:57645,44469:57646,44470:57647,44471:57648,44472:57649,44473:57650,44474:57651,44475:57652,44476:57653,44477:57654,44478:57655,44479:57656,44480:57657,44481:57658,44482:57659,44483:57660,44484:57661,44485:57662,44486:57663,44487:57664,44488:57665,44489:57666,44490:57667,44491:57668,44492:57669,44493:57670,44494:57671,44495:57672,44496:57673,44497:57674,44498:57675,44499:57676,44500:57677,44501:57678,44502:57679,44503:57680,44504:57681,44505:57682,44506:57683,44507:57684,44508:57685,44509:57686,44510:57687,44511:57688,44512:57689,44513:57690,44514:57691,44515:57692,44516:57693,44517:57694,44518:57695,44519:57696,44520:57697,44521:57698,44522:57699,44523:57700,44524:57701,44525:57702,44526:57703,44527:57704,44528:57705,44529:57706,44530:57707,44531:57708,44532:57709,44533:57710,44534:57711,44535:57712,44536:57713,44537:57714,44538:57715,44539:57716,44540:57717,44541:57718,44542:57719,44608:29939,44609:29941,44610:29944,44611:29945,44612:29946,44613:29947,44614:29948,44615:29949,44616:29950,44617:29952,44618:29953,44619:29954,44620:29955,44621:29957,44622:29958,44623:29959,44624:29960,44625:29961,44626:29962,44627:29963,44628:29964,44629:29966,44630:29968,44631:29970,44632:29972,44633:29973,44634:29974,44635:29975,44636:29979,44637:29981,44638:29982,44639:29984,44640:29985,44641:29986,44642:29987,44643:29988,44644:29990,44645:29991,44646:29994,44647:29998,44648:30004,44649:30006,44650:30009,44651:30012,44652:30013,44653:30015,44654:30017,44655:30018,44656:30019,44657:30020,44658:30022,44659:30023,44660:30025,44661:30026,44662:30029,44663:30032,44664:30033,44665:30034,44666:30035,44667:30037,44668:30038,44669:30039,44670:30040,44672:30045,44673:30046,44674:30047,44675:30048,44676:30049,44677:30050,44678:30051,44679:30052,44680:30055,44681:30056,44682:30057,44683:30059,44684:30060,44685:30061,44686:30062,44687:30063,44688:30064,44689:30065,44690:30067,44691:30069,44692:30070,44693:30071,44694:30074,44695:30075,44696:30076,44697:30077,44698:30078,44699:30080,44700:30081,44701:30082,44702:30084,44703:30085,44704:30087,44705:57720,44706:57721,44707:57722,44708:57723,44709:57724,44710:57725,44711:57726,44712:57727,44713:57728,44714:57729,44715:57730,44716:57731,44717:57732,44718:57733,44719:57734,44720:57735,44721:57736,44722:57737,44723:57738,44724:57739,44725:57740,44726:57741,44727:57742,44728:57743,44729:57744,44730:57745,44731:57746,44732:57747,44733:57748,44734:57749,44735:57750,44736:57751,44737:57752,44738:57753,44739:57754,44740:57755,44741:57756,44742:57757,44743:57758,44744:57759,44745:57760,44746:57761,44747:57762,44748:57763,44749:57764,44750:57765,44751:57766,44752:57767,44753:57768,44754:57769,44755:57770,44756:57771,44757:57772,44758:57773,44759:57774,44760:57775,44761:57776,44762:57777,44763:57778,44764:57779,44765:57780,44766:57781,44767:57782,44768:57783,44769:57784,44770:57785,44771:57786,44772:57787,44773:57788,44774:57789,44775:57790,44776:57791,44777:57792,44778:57793,44779:57794,44780:57795,44781:57796,44782:57797,44783:57798,44784:57799,44785:57800,44786:57801,44787:57802,44788:57803,44789:57804,44790:57805,44791:57806,44792:57807,44793:57808,44794:57809,44795:57810,44796:57811,44797:57812,44798:57813,44864:30088,44865:30089,44866:30090,44867:30092,44868:30093,44869:30094,44870:30096,44871:30099,44872:30101,44873:30104,44874:30107,44875:30108,44876:30110,44877:30114,44878:30118,44879:30119,44880:30120,44881:30121,44882:30122,44883:30125,44884:30134,44885:30135,44886:30138,44887:30139,44888:30143,44889:30144,44890:30145,44891:30150,44892:30155,44893:30156,44894:30158,44895:30159,44896:30160,44897:30161,44898:30163,44899:30167,44900:30169,44901:30170,44902:30172,44903:30173,44904:30175,44905:30176,44906:30177,44907:30181,44908:30185,44909:30188,44910:30189,44911:30190,44912:30191,44913:30194,44914:30195,44915:30197,44916:30198,44917:30199,44918:30200,44919:30202,44920:30203,44921:30205,44922:30206,44923:30210,44924:30212,44925:30214,44926:30215,44928:30216,44929:30217,44930:30219,44931:30221,44932:30222,44933:30223,44934:30225,44935:30226,44936:30227,44937:30228,44938:30230,44939:30234,44940:30236,44941:30237,44942:30238,44943:30241,44944:30243,44945:30247,44946:30248,44947:30252,44948:30254,44949:30255,44950:30257,44951:30258,44952:30262,44953:30263,44954:30265,44955:30266,44956:30267,44957:30269,44958:30273,44959:30274,44960:30276,44961:57814,44962:57815,44963:57816,44964:57817,44965:57818,44966:57819,44967:57820,44968:57821,44969:57822,44970:57823,44971:57824,44972:57825,44973:57826,44974:57827,44975:57828,44976:57829,44977:57830,44978:57831,44979:57832,44980:57833,44981:57834,44982:57835,44983:57836,44984:57837,44985:57838,44986:57839,44987:57840,44988:57841,44989:57842,44990:57843,44991:57844,44992:57845,44993:57846,44994:57847,44995:57848,44996:57849,44997:57850,44998:57851,44999:57852,45000:57853,45001:57854,45002:57855,45003:57856,45004:57857,45005:57858,45006:57859,45007:57860,45008:57861,45009:57862,45010:57863,45011:57864,45012:57865,45013:57866,45014:57867,45015:57868,45016:57869,45017:57870,45018:57871,45019:57872,45020:57873,45021:57874,45022:57875,45023:57876,45024:57877,45025:57878,45026:57879,45027:57880,45028:57881,45029:57882,45030:57883,45031:57884,45032:57885,45033:57886,45034:57887,45035:57888,45036:57889,45037:57890,45038:57891,45039:57892,45040:57893,45041:57894,45042:57895,45043:57896,45044:57897,45045:57898,45046:57899,45047:57900,45048:57901,45049:57902,45050:57903,45051:57904,45052:57905,45053:57906,45054:57907,45120:30277,45121:30278,45122:30279,45123:30280,45124:30281,45125:30282,45126:30283,45127:30286,45128:30287,45129:30288,45130:30289,45131:30290,45132:30291,45133:30293,45134:30295,45135:30296,45136:30297,45137:30298,45138:30299,45139:30301,45140:30303,45141:30304,45142:30305,45143:30306,45144:30308,45145:30309,45146:30310,45147:30311,45148:30312,45149:30313,45150:30314,45151:30316,45152:30317,45153:30318,45154:30320,45155:30321,45156:30322,45157:30323,45158:30324,45159:30325,45160:30326,45161:30327,45162:30329,45163:30330,45164:30332,45165:30335,45166:30336,45167:30337,45168:30339,45169:30341,45170:30345,45171:30346,45172:30348,45173:30349,45174:30351,45175:30352,45176:30354,45177:30356,45178:30357,45179:30359,45180:30360,45181:30362,45182:30363,45184:30364,45185:30365,45186:30366,45187:30367,45188:30368,45189:30369,45190:30370,45191:30371,45192:30373,45193:30374,45194:30375,45195:30376,45196:30377,45197:30378,45198:30379,45199:30380,45200:30381,45201:30383,45202:30384,45203:30387,45204:30389,45205:30390,45206:30391,45207:30392,45208:30393,45209:30394,45210:30395,45211:30396,45212:30397,45213:30398,45214:30400,45215:30401,45216:30403,45217:21834,45218:38463,45219:22467,45220:25384,45221:21710,45222:21769,45223:21696,45224:30353,45225:30284,45226:34108,45227:30702,45228:33406,45229:30861,45230:29233,45231:38552,45232:38797,45233:27688,45234:23433,45235:20474,45236:25353,45237:26263,45238:23736,45239:33018,45240:26696,45241:32942,45242:26114,45243:30414,45244:20985,45245:25942,45246:29100,45247:32753,45248:34948,45249:20658,45250:22885,45251:25034,45252:28595,45253:33453,45254:25420,45255:25170,45256:21485,45257:21543,45258:31494,45259:20843,45260:30116,45261:24052,45262:25300,45263:36299,45264:38774,45265:25226,45266:32793,45267:22365,45268:38712,45269:32610,45270:29240,45271:30333,45272:26575,45273:30334,45274:25670,45275:20336,45276:36133,45277:25308,45278:31255,45279:26001,45280:29677,45281:25644,45282:25203,45283:33324,45284:39041,45285:26495,45286:29256,45287:25198,45288:25292,45289:20276,45290:29923,45291:21322,45292:21150,45293:32458,45294:37030,45295:24110,45296:26758,45297:27036,45298:33152,45299:32465,45300:26834,45301:30917,45302:34444,45303:38225,45304:20621,45305:35876,45306:33502,45307:32990,45308:21253,45309:35090,45310:21093,45376:30404,45377:30407,45378:30409,45379:30411,45380:30412,45381:30419,45382:30421,45383:30425,45384:30426,45385:30428,45386:30429,45387:30430,45388:30432,45389:30433,45390:30434,45391:30435,45392:30436,45393:30438,45394:30439,45395:30440,45396:30441,45397:30442,45398:30443,45399:30444,45400:30445,45401:30448,45402:30451,45403:30453,45404:30454,45405:30455,45406:30458,45407:30459,45408:30461,45409:30463,45410:30464,45411:30466,45412:30467,45413:30469,45414:30470,45415:30474,45416:30476,45417:30478,45418:30479,45419:30480,45420:30481,45421:30482,45422:30483,45423:30484,45424:30485,45425:30486,45426:30487,45427:30488,45428:30491,45429:30492,45430:30493,45431:30494,45432:30497,45433:30499,45434:30500,45435:30501,45436:30503,45437:30506,45438:30507,45440:30508,45441:30510,45442:30512,45443:30513,45444:30514,45445:30515,45446:30516,45447:30521,45448:30523,45449:30525,45450:30526,45451:30527,45452:30530,45453:30532,45454:30533,45455:30534,45456:30536,45457:30537,45458:30538,45459:30539,45460:30540,45461:30541,45462:30542,45463:30543,45464:30546,45465:30547,45466:30548,45467:30549,45468:30550,45469:30551,45470:30552,45471:30553,45472:30556,45473:34180,45474:38649,45475:20445,45476:22561,45477:39281,45478:23453,45479:25265,45480:25253,45481:26292,45482:35961,45483:40077,45484:29190,45485:26479,45486:30865,45487:24754,45488:21329,45489:21271,45490:36744,45491:32972,45492:36125,45493:38049,45494:20493,45495:29384,45496:22791,45497:24811,45498:28953,45499:34987,45500:22868,45501:33519,45502:26412,45503:31528,45504:23849,45505:32503,45506:29997,45507:27893,45508:36454,45509:36856,45510:36924,45511:40763,45512:27604,45513:37145,45514:31508,45515:24444,45516:30887,45517:34006,45518:34109,45519:27605,45520:27609,45521:27606,45522:24065,45523:24199,45524:30201,45525:38381,45526:25949,45527:24330,45528:24517,45529:36767,45530:22721,45531:33218,45532:36991,45533:38491,45534:38829,45535:36793,45536:32534,45537:36140,45538:25153,45539:20415,45540:21464,45541:21342,45542:36776,45543:36777,45544:36779,45545:36941,45546:26631,45547:24426,45548:33176,45549:34920,45550:40150,45551:24971,45552:21035,45553:30250,45554:24428,45555:25996,45556:28626,45557:28392,45558:23486,45559:25672,45560:20853,45561:20912,45562:26564,45563:19993,45564:31177,45565:39292,45566:28851,45632:30557,45633:30558,45634:30559,45635:30560,45636:30564,45637:30567,45638:30569,45639:30570,45640:30573,45641:30574,45642:30575,45643:30576,45644:30577,45645:30578,45646:30579,45647:30580,45648:30581,45649:30582,45650:30583,45651:30584,45652:30586,45653:30587,45654:30588,45655:30593,45656:30594,45657:30595,45658:30598,45659:30599,45660:30600,45661:30601,45662:30602,45663:30603,45664:30607,45665:30608,45666:30611,45667:30612,45668:30613,45669:30614,45670:30615,45671:30616,45672:30617,45673:30618,45674:30619,45675:30620,45676:30621,45677:30622,45678:30625,45679:30627,45680:30628,45681:30630,45682:30632,45683:30635,45684:30637,45685:30638,45686:30639,45687:30641,45688:30642,45689:30644,45690:30646,45691:30647,45692:30648,45693:30649,45694:30650,45696:30652,45697:30654,45698:30656,45699:30657,45700:30658,45701:30659,45702:30660,45703:30661,45704:30662,45705:30663,45706:30664,45707:30665,45708:30666,45709:30667,45710:30668,45711:30670,45712:30671,45713:30672,45714:30673,45715:30674,45716:30675,45717:30676,45718:30677,45719:30678,45720:30680,45721:30681,45722:30682,45723:30685,45724:30686,45725:30687,45726:30688,45727:30689,45728:30692,45729:30149,45730:24182,45731:29627,45732:33760,45733:25773,45734:25320,45735:38069,45736:27874,45737:21338,45738:21187,45739:25615,45740:38082,45741:31636,45742:20271,45743:24091,45744:33334,45745:33046,45746:33162,45747:28196,45748:27850,45749:39539,45750:25429,45751:21340,45752:21754,45753:34917,45754:22496,45755:19981,45756:24067,45757:27493,45758:31807,45759:37096,45760:24598,45761:25830,45762:29468,45763:35009,45764:26448,45765:25165,45766:36130,45767:30572,45768:36393,45769:37319,45770:24425,45771:33756,45772:34081,45773:39184,45774:21442,45775:34453,45776:27531,45777:24813,45778:24808,45779:28799,45780:33485,45781:33329,45782:20179,45783:27815,45784:34255,45785:25805,45786:31961,45787:27133,45788:26361,45789:33609,45790:21397,45791:31574,45792:20391,45793:20876,45794:27979,45795:23618,45796:36461,45797:25554,45798:21449,45799:33580,45800:33590,45801:26597,45802:30900,45803:25661,45804:23519,45805:23700,45806:24046,45807:35815,45808:25286,45809:26612,45810:35962,45811:25600,45812:25530,45813:34633,45814:39307,45815:35863,45816:32544,45817:38130,45818:20135,45819:38416,45820:39076,45821:26124,45822:29462,45888:30694,45889:30696,45890:30698,45891:30703,45892:30704,45893:30705,45894:30706,45895:30708,45896:30709,45897:30711,45898:30713,45899:30714,45900:30715,45901:30716,45902:30723,45903:30724,45904:30725,45905:30726,45906:30727,45907:30728,45908:30730,45909:30731,45910:30734,45911:30735,45912:30736,45913:30739,45914:30741,45915:30745,45916:30747,45917:30750,45918:30752,45919:30753,45920:30754,45921:30756,45922:30760,45923:30762,45924:30763,45925:30766,45926:30767,45927:30769,45928:30770,45929:30771,45930:30773,45931:30774,45932:30781,45933:30783,45934:30785,45935:30786,45936:30787,45937:30788,45938:30790,45939:30792,45940:30793,45941:30794,45942:30795,45943:30797,45944:30799,45945:30801,45946:30803,45947:30804,45948:30808,45949:30809,45950:30810,45952:30811,45953:30812,45954:30814,45955:30815,45956:30816,45957:30817,45958:30818,45959:30819,45960:30820,45961:30821,45962:30822,45963:30823,45964:30824,45965:30825,45966:30831,45967:30832,45968:30833,45969:30834,45970:30835,45971:30836,45972:30837,45973:30838,45974:30840,45975:30841,45976:30842,45977:30843,45978:30845,45979:30846,45980:30847,45981:30848,45982:30849,45983:30850,45984:30851,45985:22330,45986:23581,45987:24120,45988:38271,45989:20607,45990:32928,45991:21378,45992:25950,45993:30021,45994:21809,45995:20513,45996:36229,45997:25220,45998:38046,45999:26397,46000:22066,46001:28526,46002:24034,46003:21557,46004:28818,46005:36710,46006:25199,46007:25764,46008:25507,46009:24443,46010:28552,46011:37108,46012:33251,46013:36784,46014:23576,46015:26216,46016:24561,46017:27785,46018:38472,46019:36225,46020:34924,46021:25745,46022:31216,46023:22478,46024:27225,46025:25104,46026:21576,46027:20056,46028:31243,46029:24809,46030:28548,46031:35802,46032:25215,46033:36894,46034:39563,46035:31204,46036:21507,46037:30196,46038:25345,46039:21273,46040:27744,46041:36831,46042:24347,46043:39536,46044:32827,46045:40831,46046:20360,46047:23610,46048:36196,46049:32709,46050:26021,46051:28861,46052:20805,46053:20914,46054:34411,46055:23815,46056:23456,46057:25277,46058:37228,46059:30068,46060:36364,46061:31264,46062:24833,46063:31609,46064:20167,46065:32504,46066:30597,46067:19985,46068:33261,46069:21021,46070:20986,46071:27249,46072:21416,46073:36487,46074:38148,46075:38607,46076:28353,46077:38500,46078:26970,46144:30852,46145:30853,46146:30854,46147:30856,46148:30858,46149:30859,46150:30863,46151:30864,46152:30866,46153:30868,46154:30869,46155:30870,46156:30873,46157:30877,46158:30878,46159:30880,46160:30882,46161:30884,46162:30886,46163:30888,46164:30889,46165:30890,46166:30891,46167:30892,46168:30893,46169:30894,46170:30895,46171:30901,46172:30902,46173:30903,46174:30904,46175:30906,46176:30907,46177:30908,46178:30909,46179:30911,46180:30912,46181:30914,46182:30915,46183:30916,46184:30918,46185:30919,46186:30920,46187:30924,46188:30925,46189:30926,46190:30927,46191:30929,46192:30930,46193:30931,46194:30934,46195:30935,46196:30936,46197:30938,46198:30939,46199:30940,46200:30941,46201:30942,46202:30943,46203:30944,46204:30945,46205:30946,46206:30947,46208:30948,46209:30949,46210:30950,46211:30951,46212:30953,46213:30954,46214:30955,46215:30957,46216:30958,46217:30959,46218:30960,46219:30961,46220:30963,46221:30965,46222:30966,46223:30968,46224:30969,46225:30971,46226:30972,46227:30973,46228:30974,46229:30975,46230:30976,46231:30978,46232:30979,46233:30980,46234:30982,46235:30983,46236:30984,46237:30985,46238:30986,46239:30987,46240:30988,46241:30784,46242:20648,46243:30679,46244:25616,46245:35302,46246:22788,46247:25571,46248:24029,46249:31359,46250:26941,46251:20256,46252:33337,46253:21912,46254:20018,46255:30126,46256:31383,46257:24162,46258:24202,46259:38383,46260:21019,46261:21561,46262:28810,46263:25462,46264:38180,46265:22402,46266:26149,46267:26943,46268:37255,46269:21767,46270:28147,46271:32431,46272:34850,46273:25139,46274:32496,46275:30133,46276:33576,46277:30913,46278:38604,46279:36766,46280:24904,46281:29943,46282:35789,46283:27492,46284:21050,46285:36176,46286:27425,46287:32874,46288:33905,46289:22257,46290:21254,46291:20174,46292:19995,46293:20945,46294:31895,46295:37259,46296:31751,46297:20419,46298:36479,46299:31713,46300:31388,46301:25703,46302:23828,46303:20652,46304:33030,46305:30209,46306:31929,46307:28140,46308:32736,46309:26449,46310:23384,46311:23544,46312:30923,46313:25774,46314:25619,46315:25514,46316:25387,46317:38169,46318:25645,46319:36798,46320:31572,46321:30249,46322:25171,46323:22823,46324:21574,46325:27513,46326:20643,46327:25140,46328:24102,46329:27526,46330:20195,46331:36151,46332:34955,46333:24453,46334:36910,46400:30989,46401:30990,46402:30991,46403:30992,46404:30993,46405:30994,46406:30996,46407:30997,46408:30998,46409:30999,46410:31000,46411:31001,46412:31002,46413:31003,46414:31004,46415:31005,46416:31007,46417:31008,46418:31009,46419:31010,46420:31011,46421:31013,46422:31014,46423:31015,46424:31016,46425:31017,46426:31018,46427:31019,46428:31020,46429:31021,46430:31022,46431:31023,46432:31024,46433:31025,46434:31026,46435:31027,46436:31029,46437:31030,46438:31031,46439:31032,46440:31033,46441:31037,46442:31039,46443:31042,46444:31043,46445:31044,46446:31045,46447:31047,46448:31050,46449:31051,46450:31052,46451:31053,46452:31054,46453:31055,46454:31056,46455:31057,46456:31058,46457:31060,46458:31061,46459:31064,46460:31065,46461:31073,46462:31075,46464:31076,46465:31078,46466:31081,46467:31082,46468:31083,46469:31084,46470:31086,46471:31088,46472:31089,46473:31090,46474:31091,46475:31092,46476:31093,46477:31094,46478:31097,46479:31099,46480:31100,46481:31101,46482:31102,46483:31103,46484:31106,46485:31107,46486:31110,46487:31111,46488:31112,46489:31113,46490:31115,46491:31116,46492:31117,46493:31118,46494:31120,46495:31121,46496:31122,46497:24608,46498:32829,46499:25285,46500:20025,46501:21333,46502:37112,46503:25528,46504:32966,46505:26086,46506:27694,46507:20294,46508:24814,46509:28129,46510:35806,46511:24377,46512:34507,46513:24403,46514:25377,46515:20826,46516:33633,46517:26723,46518:20992,46519:25443,46520:36424,46521:20498,46522:23707,46523:31095,46524:23548,46525:21040,46526:31291,46527:24764,46528:36947,46529:30423,46530:24503,46531:24471,46532:30340,46533:36460,46534:28783,46535:30331,46536:31561,46537:30634,46538:20979,46539:37011,46540:22564,46541:20302,46542:28404,46543:36842,46544:25932,46545:31515,46546:29380,46547:28068,46548:32735,46549:23265,46550:25269,46551:24213,46552:22320,46553:33922,46554:31532,46555:24093,46556:24351,46557:36882,46558:32532,46559:39072,46560:25474,46561:28359,46562:30872,46563:28857,46564:20856,46565:38747,46566:22443,46567:30005,46568:20291,46569:30008,46570:24215,46571:24806,46572:22880,46573:28096,46574:27583,46575:30857,46576:21500,46577:38613,46578:20939,46579:20993,46580:25481,46581:21514,46582:38035,46583:35843,46584:36300,46585:29241,46586:30879,46587:34678,46588:36845,46589:35853,46590:21472,46656:31123,46657:31124,46658:31125,46659:31126,46660:31127,46661:31128,46662:31129,46663:31131,46664:31132,46665:31133,46666:31134,46667:31135,46668:31136,46669:31137,46670:31138,46671:31139,46672:31140,46673:31141,46674:31142,46675:31144,46676:31145,46677:31146,46678:31147,46679:31148,46680:31149,46681:31150,46682:31151,46683:31152,46684:31153,46685:31154,46686:31156,46687:31157,46688:31158,46689:31159,46690:31160,46691:31164,46692:31167,46693:31170,46694:31172,46695:31173,46696:31175,46697:31176,46698:31178,46699:31180,46700:31182,46701:31183,46702:31184,46703:31187,46704:31188,46705:31190,46706:31191,46707:31193,46708:31194,46709:31195,46710:31196,46711:31197,46712:31198,46713:31200,46714:31201,46715:31202,46716:31205,46717:31208,46718:31210,46720:31212,46721:31214,46722:31217,46723:31218,46724:31219,46725:31220,46726:31221,46727:31222,46728:31223,46729:31225,46730:31226,46731:31228,46732:31230,46733:31231,46734:31233,46735:31236,46736:31237,46737:31239,46738:31240,46739:31241,46740:31242,46741:31244,46742:31247,46743:31248,46744:31249,46745:31250,46746:31251,46747:31253,46748:31254,46749:31256,46750:31257,46751:31259,46752:31260,46753:19969,46754:30447,46755:21486,46756:38025,46757:39030,46758:40718,46759:38189,46760:23450,46761:35746,46762:20002,46763:19996,46764:20908,46765:33891,46766:25026,46767:21160,46768:26635,46769:20375,46770:24683,46771:20923,46772:27934,46773:20828,46774:25238,46775:26007,46776:38497,46777:35910,46778:36887,46779:30168,46780:37117,46781:30563,46782:27602,46783:29322,46784:29420,46785:35835,46786:22581,46787:30585,46788:36172,46789:26460,46790:38208,46791:32922,46792:24230,46793:28193,46794:22930,46795:31471,46796:30701,46797:38203,46798:27573,46799:26029,46800:32526,46801:22534,46802:20817,46803:38431,46804:23545,46805:22697,46806:21544,46807:36466,46808:25958,46809:39039,46810:22244,46811:38045,46812:30462,46813:36929,46814:25479,46815:21702,46816:22810,46817:22842,46818:22427,46819:36530,46820:26421,46821:36346,46822:33333,46823:21057,46824:24816,46825:22549,46826:34558,46827:23784,46828:40517,46829:20420,46830:39069,46831:35769,46832:23077,46833:24694,46834:21380,46835:25212,46836:36943,46837:37122,46838:39295,46839:24681,46840:32780,46841:20799,46842:32819,46843:23572,46844:39285,46845:27953,46846:20108,46912:31261,46913:31263,46914:31265,46915:31266,46916:31268,46917:31269,46918:31270,46919:31271,46920:31272,46921:31273,46922:31274,46923:31275,46924:31276,46925:31277,46926:31278,46927:31279,46928:31280,46929:31281,46930:31282,46931:31284,46932:31285,46933:31286,46934:31288,46935:31290,46936:31294,46937:31296,46938:31297,46939:31298,46940:31299,46941:31300,46942:31301,46943:31303,46944:31304,46945:31305,46946:31306,46947:31307,46948:31308,46949:31309,46950:31310,46951:31311,46952:31312,46953:31314,46954:31315,46955:31316,46956:31317,46957:31318,46958:31320,46959:31321,46960:31322,46961:31323,46962:31324,46963:31325,46964:31326,46965:31327,46966:31328,46967:31329,46968:31330,46969:31331,46970:31332,46971:31333,46972:31334,46973:31335,46974:31336,46976:31337,46977:31338,46978:31339,46979:31340,46980:31341,46981:31342,46982:31343,46983:31345,46984:31346,46985:31347,46986:31349,46987:31355,46988:31356,46989:31357,46990:31358,46991:31362,46992:31365,46993:31367,46994:31369,46995:31370,46996:31371,46997:31372,46998:31374,46999:31375,47000:31376,47001:31379,47002:31380,47003:31385,47004:31386,47005:31387,47006:31390,47007:31393,47008:31394,47009:36144,47010:21457,47011:32602,47012:31567,47013:20240,47014:20047,47015:38400,47016:27861,47017:29648,47018:34281,47019:24070,47020:30058,47021:32763,47022:27146,47023:30718,47024:38034,47025:32321,47026:20961,47027:28902,47028:21453,47029:36820,47030:33539,47031:36137,47032:29359,47033:39277,47034:27867,47035:22346,47036:33459,47037:26041,47038:32938,47039:25151,47040:38450,47041:22952,47042:20223,47043:35775,47044:32442,47045:25918,47046:33778,47047:38750,47048:21857,47049:39134,47050:32933,47051:21290,47052:35837,47053:21536,47054:32954,47055:24223,47056:27832,47057:36153,47058:33452,47059:37210,47060:21545,47061:27675,47062:20998,47063:32439,47064:22367,47065:28954,47066:27774,47067:31881,47068:22859,47069:20221,47070:24575,47071:24868,47072:31914,47073:20016,47074:23553,47075:26539,47076:34562,47077:23792,47078:38155,47079:39118,47080:30127,47081:28925,47082:36898,47083:20911,47084:32541,47085:35773,47086:22857,47087:20964,47088:20315,47089:21542,47090:22827,47091:25975,47092:32932,47093:23413,47094:25206,47095:25282,47096:36752,47097:24133,47098:27679,47099:31526,47100:20239,47101:20440,47102:26381,47168:31395,47169:31396,47170:31399,47171:31401,47172:31402,47173:31403,47174:31406,47175:31407,47176:31408,47177:31409,47178:31410,47179:31412,47180:31413,47181:31414,47182:31415,47183:31416,47184:31417,47185:31418,47186:31419,47187:31420,47188:31421,47189:31422,47190:31424,47191:31425,47192:31426,47193:31427,47194:31428,47195:31429,47196:31430,47197:31431,47198:31432,47199:31433,47200:31434,47201:31436,47202:31437,47203:31438,47204:31439,47205:31440,47206:31441,47207:31442,47208:31443,47209:31444,47210:31445,47211:31447,47212:31448,47213:31450,47214:31451,47215:31452,47216:31453,47217:31457,47218:31458,47219:31460,47220:31463,47221:31464,47222:31465,47223:31466,47224:31467,47225:31468,47226:31470,47227:31472,47228:31473,47229:31474,47230:31475,47232:31476,47233:31477,47234:31478,47235:31479,47236:31480,47237:31483,47238:31484,47239:31486,47240:31488,47241:31489,47242:31490,47243:31493,47244:31495,47245:31497,47246:31500,47247:31501,47248:31502,47249:31504,47250:31506,47251:31507,47252:31510,47253:31511,47254:31512,47255:31514,47256:31516,47257:31517,47258:31519,47259:31521,47260:31522,47261:31523,47262:31527,47263:31529,47264:31533,47265:28014,47266:28074,47267:31119,47268:34993,47269:24343,47270:29995,47271:25242,47272:36741,47273:20463,47274:37340,47275:26023,47276:33071,47277:33105,47278:24220,47279:33104,47280:36212,47281:21103,47282:35206,47283:36171,47284:22797,47285:20613,47286:20184,47287:38428,47288:29238,47289:33145,47290:36127,47291:23500,47292:35747,47293:38468,47294:22919,47295:32538,47296:21648,47297:22134,47298:22030,47299:35813,47300:25913,47301:27010,47302:38041,47303:30422,47304:28297,47305:24178,47306:29976,47307:26438,47308:26577,47309:31487,47310:32925,47311:36214,47312:24863,47313:31174,47314:25954,47315:36195,47316:20872,47317:21018,47318:38050,47319:32568,47320:32923,47321:32434,47322:23703,47323:28207,47324:26464,47325:31705,47326:30347,47327:39640,47328:33167,47329:32660,47330:31957,47331:25630,47332:38224,47333:31295,47334:21578,47335:21733,47336:27468,47337:25601,47338:25096,47339:40509,47340:33011,47341:30105,47342:21106,47343:38761,47344:33883,47345:26684,47346:34532,47347:38401,47348:38548,47349:38124,47350:20010,47351:21508,47352:32473,47353:26681,47354:36319,47355:32789,47356:26356,47357:24218,47358:32697,47424:31535,47425:31536,47426:31538,47427:31540,47428:31541,47429:31542,47430:31543,47431:31545,47432:31547,47433:31549,47434:31551,47435:31552,47436:31553,47437:31554,47438:31555,47439:31556,47440:31558,47441:31560,47442:31562,47443:31565,47444:31566,47445:31571,47446:31573,47447:31575,47448:31577,47449:31580,47450:31582,47451:31583,47452:31585,47453:31587,47454:31588,47455:31589,47456:31590,47457:31591,47458:31592,47459:31593,47460:31594,47461:31595,47462:31596,47463:31597,47464:31599,47465:31600,47466:31603,47467:31604,47468:31606,47469:31608,47470:31610,47471:31612,47472:31613,47473:31615,47474:31617,47475:31618,47476:31619,47477:31620,47478:31622,47479:31623,47480:31624,47481:31625,47482:31626,47483:31627,47484:31628,47485:31630,47486:31631,47488:31633,47489:31634,47490:31635,47491:31638,47492:31640,47493:31641,47494:31642,47495:31643,47496:31646,47497:31647,47498:31648,47499:31651,47500:31652,47501:31653,47502:31662,47503:31663,47504:31664,47505:31666,47506:31667,47507:31669,47508:31670,47509:31671,47510:31673,47511:31674,47512:31675,47513:31676,47514:31677,47515:31678,47516:31679,47517:31680,47518:31682,47519:31683,47520:31684,47521:22466,47522:32831,47523:26775,47524:24037,47525:25915,47526:21151,47527:24685,47528:40858,47529:20379,47530:36524,47531:20844,47532:23467,47533:24339,47534:24041,47535:27742,47536:25329,47537:36129,47538:20849,47539:38057,47540:21246,47541:27807,47542:33503,47543:29399,47544:22434,47545:26500,47546:36141,47547:22815,47548:36764,47549:33735,47550:21653,47551:31629,47552:20272,47553:27837,47554:23396,47555:22993,47556:40723,47557:21476,47558:34506,47559:39592,47560:35895,47561:32929,47562:25925,47563:39038,47564:22266,47565:38599,47566:21038,47567:29916,47568:21072,47569:23521,47570:25346,47571:35074,47572:20054,47573:25296,47574:24618,47575:26874,47576:20851,47577:23448,47578:20896,47579:35266,47580:31649,47581:39302,47582:32592,47583:24815,47584:28748,47585:36143,47586:20809,47587:24191,47588:36891,47589:29808,47590:35268,47591:22317,47592:30789,47593:24402,47594:40863,47595:38394,47596:36712,47597:39740,47598:35809,47599:30328,47600:26690,47601:26588,47602:36330,47603:36149,47604:21053,47605:36746,47606:28378,47607:26829,47608:38149,47609:37101,47610:22269,47611:26524,47612:35065,47613:36807,47614:21704,47680:31685,47681:31688,47682:31689,47683:31690,47684:31691,47685:31693,47686:31694,47687:31695,47688:31696,47689:31698,47690:31700,47691:31701,47692:31702,47693:31703,47694:31704,47695:31707,47696:31708,47697:31710,47698:31711,47699:31712,47700:31714,47701:31715,47702:31716,47703:31719,47704:31720,47705:31721,47706:31723,47707:31724,47708:31725,47709:31727,47710:31728,47711:31730,47712:31731,47713:31732,47714:31733,47715:31734,47716:31736,47717:31737,47718:31738,47719:31739,47720:31741,47721:31743,47722:31744,47723:31745,47724:31746,47725:31747,47726:31748,47727:31749,47728:31750,47729:31752,47730:31753,47731:31754,47732:31757,47733:31758,47734:31760,47735:31761,47736:31762,47737:31763,47738:31764,47739:31765,47740:31767,47741:31768,47742:31769,47744:31770,47745:31771,47746:31772,47747:31773,47748:31774,47749:31776,47750:31777,47751:31778,47752:31779,47753:31780,47754:31781,47755:31784,47756:31785,47757:31787,47758:31788,47759:31789,47760:31790,47761:31791,47762:31792,47763:31793,47764:31794,47765:31795,47766:31796,47767:31797,47768:31798,47769:31799,47770:31801,47771:31802,47772:31803,47773:31804,47774:31805,47775:31806,47776:31810,47777:39608,47778:23401,47779:28023,47780:27686,47781:20133,47782:23475,47783:39559,47784:37219,47785:25000,47786:37039,47787:38889,47788:21547,47789:28085,47790:23506,47791:20989,47792:21898,47793:32597,47794:32752,47795:25788,47796:25421,47797:26097,47798:25022,47799:24717,47800:28938,47801:27735,47802:27721,47803:22831,47804:26477,47805:33322,47806:22741,47807:22158,47808:35946,47809:27627,47810:37085,47811:22909,47812:32791,47813:21495,47814:28009,47815:21621,47816:21917,47817:33655,47818:33743,47819:26680,47820:31166,47821:21644,47822:20309,47823:21512,47824:30418,47825:35977,47826:38402,47827:27827,47828:28088,47829:36203,47830:35088,47831:40548,47832:36154,47833:22079,47834:40657,47835:30165,47836:24456,47837:29408,47838:24680,47839:21756,47840:20136,47841:27178,47842:34913,47843:24658,47844:36720,47845:21700,47846:28888,47847:34425,47848:40511,47849:27946,47850:23439,47851:24344,47852:32418,47853:21897,47854:20399,47855:29492,47856:21564,47857:21402,47858:20505,47859:21518,47860:21628,47861:20046,47862:24573,47863:29786,47864:22774,47865:33899,47866:32993,47867:34676,47868:29392,47869:31946,47870:28246,47936:31811,47937:31812,47938:31813,47939:31814,47940:31815,47941:31816,47942:31817,47943:31818,47944:31819,47945:31820,47946:31822,47947:31823,47948:31824,47949:31825,47950:31826,47951:31827,47952:31828,47953:31829,47954:31830,47955:31831,47956:31832,47957:31833,47958:31834,47959:31835,47960:31836,47961:31837,47962:31838,47963:31839,47964:31840,47965:31841,47966:31842,47967:31843,47968:31844,47969:31845,47970:31846,47971:31847,47972:31848,47973:31849,47974:31850,47975:31851,47976:31852,47977:31853,47978:31854,47979:31855,47980:31856,47981:31857,47982:31858,47983:31861,47984:31862,47985:31863,47986:31864,47987:31865,47988:31866,47989:31870,47990:31871,47991:31872,47992:31873,47993:31874,47994:31875,47995:31876,47996:31877,47997:31878,47998:31879,48000:31880,48001:31882,48002:31883,48003:31884,48004:31885,48005:31886,48006:31887,48007:31888,48008:31891,48009:31892,48010:31894,48011:31897,48012:31898,48013:31899,48014:31904,48015:31905,48016:31907,48017:31910,48018:31911,48019:31912,48020:31913,48021:31915,48022:31916,48023:31917,48024:31919,48025:31920,48026:31924,48027:31925,48028:31926,48029:31927,48030:31928,48031:31930,48032:31931,48033:24359,48034:34382,48035:21804,48036:25252,48037:20114,48038:27818,48039:25143,48040:33457,48041:21719,48042:21326,48043:29502,48044:28369,48045:30011,48046:21010,48047:21270,48048:35805,48049:27088,48050:24458,48051:24576,48052:28142,48053:22351,48054:27426,48055:29615,48056:26707,48057:36824,48058:32531,48059:25442,48060:24739,48061:21796,48062:30186,48063:35938,48064:28949,48065:28067,48066:23462,48067:24187,48068:33618,48069:24908,48070:40644,48071:30970,48072:34647,48073:31783,48074:30343,48075:20976,48076:24822,48077:29004,48078:26179,48079:24140,48080:24653,48081:35854,48082:28784,48083:25381,48084:36745,48085:24509,48086:24674,48087:34516,48088:22238,48089:27585,48090:24724,48091:24935,48092:21321,48093:24800,48094:26214,48095:36159,48096:31229,48097:20250,48098:28905,48099:27719,48100:35763,48101:35826,48102:32472,48103:33636,48104:26127,48105:23130,48106:39746,48107:27985,48108:28151,48109:35905,48110:27963,48111:20249,48112:28779,48113:33719,48114:25110,48115:24785,48116:38669,48117:36135,48118:31096,48119:20987,48120:22334,48121:22522,48122:26426,48123:30072,48124:31293,48125:31215,48126:31637,48192:31935,48193:31936,48194:31938,48195:31939,48196:31940,48197:31942,48198:31945,48199:31947,48200:31950,48201:31951,48202:31952,48203:31953,48204:31954,48205:31955,48206:31956,48207:31960,48208:31962,48209:31963,48210:31965,48211:31966,48212:31969,48213:31970,48214:31971,48215:31972,48216:31973,48217:31974,48218:31975,48219:31977,48220:31978,48221:31979,48222:31980,48223:31981,48224:31982,48225:31984,48226:31985,48227:31986,48228:31987,48229:31988,48230:31989,48231:31990,48232:31991,48233:31993,48234:31994,48235:31996,48236:31997,48237:31998,48238:31999,48239:32000,48240:32001,48241:32002,48242:32003,48243:32004,48244:32005,48245:32006,48246:32007,48247:32008,48248:32009,48249:32011,48250:32012,48251:32013,48252:32014,48253:32015,48254:32016,48256:32017,48257:32018,48258:32019,48259:32020,48260:32021,48261:32022,48262:32023,48263:32024,48264:32025,48265:32026,48266:32027,48267:32028,48268:32029,48269:32030,48270:32031,48271:32033,48272:32035,48273:32036,48274:32037,48275:32038,48276:32040,48277:32041,48278:32042,48279:32044,48280:32045,48281:32046,48282:32048,48283:32049,48284:32050,48285:32051,48286:32052,48287:32053,48288:32054,48289:32908,48290:39269,48291:36857,48292:28608,48293:35749,48294:40481,48295:23020,48296:32489,48297:32521,48298:21513,48299:26497,48300:26840,48301:36753,48302:31821,48303:38598,48304:21450,48305:24613,48306:30142,48307:27762,48308:21363,48309:23241,48310:32423,48311:25380,48312:20960,48313:33034,48314:24049,48315:34015,48316:25216,48317:20864,48318:23395,48319:20238,48320:31085,48321:21058,48322:24760,48323:27982,48324:23492,48325:23490,48326:35745,48327:35760,48328:26082,48329:24524,48330:38469,48331:22931,48332:32487,48333:32426,48334:22025,48335:26551,48336:22841,48337:20339,48338:23478,48339:21152,48340:33626,48341:39050,48342:36158,48343:30002,48344:38078,48345:20551,48346:31292,48347:20215,48348:26550,48349:39550,48350:23233,48351:27516,48352:30417,48353:22362,48354:23574,48355:31546,48356:38388,48357:29006,48358:20860,48359:32937,48360:33392,48361:22904,48362:32516,48363:33575,48364:26816,48365:26604,48366:30897,48367:30839,48368:25315,48369:25441,48370:31616,48371:20461,48372:21098,48373:20943,48374:33616,48375:27099,48376:37492,48377:36341,48378:36145,48379:35265,48380:38190,48381:31661,48382:20214,48448:32055,48449:32056,48450:32057,48451:32058,48452:32059,48453:32060,48454:32061,48455:32062,48456:32063,48457:32064,48458:32065,48459:32066,48460:32067,48461:32068,48462:32069,48463:32070,48464:32071,48465:32072,48466:32073,48467:32074,48468:32075,48469:32076,48470:32077,48471:32078,48472:32079,48473:32080,48474:32081,48475:32082,48476:32083,48477:32084,48478:32085,48479:32086,48480:32087,48481:32088,48482:32089,48483:32090,48484:32091,48485:32092,48486:32093,48487:32094,48488:32095,48489:32096,48490:32097,48491:32098,48492:32099,48493:32100,48494:32101,48495:32102,48496:32103,48497:32104,48498:32105,48499:32106,48500:32107,48501:32108,48502:32109,48503:32111,48504:32112,48505:32113,48506:32114,48507:32115,48508:32116,48509:32117,48510:32118,48512:32120,48513:32121,48514:32122,48515:32123,48516:32124,48517:32125,48518:32126,48519:32127,48520:32128,48521:32129,48522:32130,48523:32131,48524:32132,48525:32133,48526:32134,48527:32135,48528:32136,48529:32137,48530:32138,48531:32139,48532:32140,48533:32141,48534:32142,48535:32143,48536:32144,48537:32145,48538:32146,48539:32147,48540:32148,48541:32149,48542:32150,48543:32151,48544:32152,48545:20581,48546:33328,48547:21073,48548:39279,48549:28176,48550:28293,48551:28071,48552:24314,48553:20725,48554:23004,48555:23558,48556:27974,48557:27743,48558:30086,48559:33931,48560:26728,48561:22870,48562:35762,48563:21280,48564:37233,48565:38477,48566:34121,48567:26898,48568:30977,48569:28966,48570:33014,48571:20132,48572:37066,48573:27975,48574:39556,48575:23047,48576:22204,48577:25605,48578:38128,48579:30699,48580:20389,48581:33050,48582:29409,48583:35282,48584:39290,48585:32564,48586:32478,48587:21119,48588:25945,48589:37237,48590:36735,48591:36739,48592:21483,48593:31382,48594:25581,48595:25509,48596:30342,48597:31224,48598:34903,48599:38454,48600:25130,48601:21163,48602:33410,48603:26708,48604:26480,48605:25463,48606:30571,48607:31469,48608:27905,48609:32467,48610:35299,48611:22992,48612:25106,48613:34249,48614:33445,48615:30028,48616:20511,48617:20171,48618:30117,48619:35819,48620:23626,48621:24062,48622:31563,48623:26020,48624:37329,48625:20170,48626:27941,48627:35167,48628:32039,48629:38182,48630:20165,48631:35880,48632:36827,48633:38771,48634:26187,48635:31105,48636:36817,48637:28908,48638:28024,48704:32153,48705:32154,48706:32155,48707:32156,48708:32157,48709:32158,48710:32159,48711:32160,48712:32161,48713:32162,48714:32163,48715:32164,48716:32165,48717:32167,48718:32168,48719:32169,48720:32170,48721:32171,48722:32172,48723:32173,48724:32175,48725:32176,48726:32177,48727:32178,48728:32179,48729:32180,48730:32181,48731:32182,48732:32183,48733:32184,48734:32185,48735:32186,48736:32187,48737:32188,48738:32189,48739:32190,48740:32191,48741:32192,48742:32193,48743:32194,48744:32195,48745:32196,48746:32197,48747:32198,48748:32199,48749:32200,48750:32201,48751:32202,48752:32203,48753:32204,48754:32205,48755:32206,48756:32207,48757:32208,48758:32209,48759:32210,48760:32211,48761:32212,48762:32213,48763:32214,48764:32215,48765:32216,48766:32217,48768:32218,48769:32219,48770:32220,48771:32221,48772:32222,48773:32223,48774:32224,48775:32225,48776:32226,48777:32227,48778:32228,48779:32229,48780:32230,48781:32231,48782:32232,48783:32233,48784:32234,48785:32235,48786:32236,48787:32237,48788:32238,48789:32239,48790:32240,48791:32241,48792:32242,48793:32243,48794:32244,48795:32245,48796:32246,48797:32247,48798:32248,48799:32249,48800:32250,48801:23613,48802:21170,48803:33606,48804:20834,48805:33550,48806:30555,48807:26230,48808:40120,48809:20140,48810:24778,48811:31934,48812:31923,48813:32463,48814:20117,48815:35686,48816:26223,48817:39048,48818:38745,48819:22659,48820:25964,48821:38236,48822:24452,48823:30153,48824:38742,48825:31455,48826:31454,48827:20928,48828:28847,48829:31384,48830:25578,48831:31350,48832:32416,48833:29590,48834:38893,48835:20037,48836:28792,48837:20061,48838:37202,48839:21417,48840:25937,48841:26087,48842:33276,48843:33285,48844:21646,48845:23601,48846:30106,48847:38816,48848:25304,48849:29401,48850:30141,48851:23621,48852:39545,48853:33738,48854:23616,48855:21632,48856:30697,48857:20030,48858:27822,48859:32858,48860:25298,48861:25454,48862:24040,48863:20855,48864:36317,48865:36382,48866:38191,48867:20465,48868:21477,48869:24807,48870:28844,48871:21095,48872:25424,48873:40515,48874:23071,48875:20518,48876:30519,48877:21367,48878:32482,48879:25733,48880:25899,48881:25225,48882:25496,48883:20500,48884:29237,48885:35273,48886:20915,48887:35776,48888:32477,48889:22343,48890:33740,48891:38055,48892:20891,48893:21531,48894:23803,48960:32251,48961:32252,48962:32253,48963:32254,48964:32255,48965:32256,48966:32257,48967:32258,48968:32259,48969:32260,48970:32261,48971:32262,48972:32263,48973:32264,48974:32265,48975:32266,48976:32267,48977:32268,48978:32269,48979:32270,48980:32271,48981:32272,48982:32273,48983:32274,48984:32275,48985:32276,48986:32277,48987:32278,48988:32279,48989:32280,48990:32281,48991:32282,48992:32283,48993:32284,48994:32285,48995:32286,48996:32287,48997:32288,48998:32289,48999:32290,49000:32291,49001:32292,49002:32293,49003:32294,49004:32295,49005:32296,49006:32297,49007:32298,49008:32299,49009:32300,49010:32301,49011:32302,49012:32303,49013:32304,49014:32305,49015:32306,49016:32307,49017:32308,49018:32309,49019:32310,49020:32311,49021:32312,49022:32313,49024:32314,49025:32316,49026:32317,49027:32318,49028:32319,49029:32320,49030:32322,49031:32323,49032:32324,49033:32325,49034:32326,49035:32328,49036:32329,49037:32330,49038:32331,49039:32332,49040:32333,49041:32334,49042:32335,49043:32336,49044:32337,49045:32338,49046:32339,49047:32340,49048:32341,49049:32342,49050:32343,49051:32344,49052:32345,49053:32346,49054:32347,49055:32348,49056:32349,49057:20426,49058:31459,49059:27994,49060:37089,49061:39567,49062:21888,49063:21654,49064:21345,49065:21679,49066:24320,49067:25577,49068:26999,49069:20975,49070:24936,49071:21002,49072:22570,49073:21208,49074:22350,49075:30733,49076:30475,49077:24247,49078:24951,49079:31968,49080:25179,49081:25239,49082:20130,49083:28821,49084:32771,49085:25335,49086:28900,49087:38752,49088:22391,49089:33499,49090:26607,49091:26869,49092:30933,49093:39063,49094:31185,49095:22771,49096:21683,49097:21487,49098:28212,49099:20811,49100:21051,49101:23458,49102:35838,49103:32943,49104:21827,49105:22438,49106:24691,49107:22353,49108:21549,49109:31354,49110:24656,49111:23380,49112:25511,49113:25248,49114:21475,49115:25187,49116:23495,49117:26543,49118:21741,49119:31391,49120:33510,49121:37239,49122:24211,49123:35044,49124:22840,49125:22446,49126:25358,49127:36328,49128:33007,49129:22359,49130:31607,49131:20393,49132:24555,49133:23485,49134:27454,49135:21281,49136:31568,49137:29378,49138:26694,49139:30719,49140:30518,49141:26103,49142:20917,49143:20111,49144:30420,49145:23743,49146:31397,49147:33909,49148:22862,49149:39745,49150:20608,49216:32350,49217:32351,49218:32352,49219:32353,49220:32354,49221:32355,49222:32356,49223:32357,49224:32358,49225:32359,49226:32360,49227:32361,49228:32362,49229:32363,49230:32364,49231:32365,49232:32366,49233:32367,49234:32368,49235:32369,49236:32370,49237:32371,49238:32372,49239:32373,49240:32374,49241:32375,49242:32376,49243:32377,49244:32378,49245:32379,49246:32380,49247:32381,49248:32382,49249:32383,49250:32384,49251:32385,49252:32387,49253:32388,49254:32389,49255:32390,49256:32391,49257:32392,49258:32393,49259:32394,49260:32395,49261:32396,49262:32397,49263:32398,49264:32399,49265:32400,49266:32401,49267:32402,49268:32403,49269:32404,49270:32405,49271:32406,49272:32407,49273:32408,49274:32409,49275:32410,49276:32412,49277:32413,49278:32414,49280:32430,49281:32436,49282:32443,49283:32444,49284:32470,49285:32484,49286:32492,49287:32505,49288:32522,49289:32528,49290:32542,49291:32567,49292:32569,49293:32571,49294:32572,49295:32573,49296:32574,49297:32575,49298:32576,49299:32577,49300:32579,49301:32582,49302:32583,49303:32584,49304:32585,49305:32586,49306:32587,49307:32588,49308:32589,49309:32590,49310:32591,49311:32594,49312:32595,49313:39304,49314:24871,49315:28291,49316:22372,49317:26118,49318:25414,49319:22256,49320:25324,49321:25193,49322:24275,49323:38420,49324:22403,49325:25289,49326:21895,49327:34593,49328:33098,49329:36771,49330:21862,49331:33713,49332:26469,49333:36182,49334:34013,49335:23146,49336:26639,49337:25318,49338:31726,49339:38417,49340:20848,49341:28572,49342:35888,49343:25597,49344:35272,49345:25042,49346:32518,49347:28866,49348:28389,49349:29701,49350:27028,49351:29436,49352:24266,49353:37070,49354:26391,49355:28010,49356:25438,49357:21171,49358:29282,49359:32769,49360:20332,49361:23013,49362:37226,49363:28889,49364:28061,49365:21202,49366:20048,49367:38647,49368:38253,49369:34174,49370:30922,49371:32047,49372:20769,49373:22418,49374:25794,49375:32907,49376:31867,49377:27882,49378:26865,49379:26974,49380:20919,49381:21400,49382:26792,49383:29313,49384:40654,49385:31729,49386:29432,49387:31163,49388:28435,49389:29702,49390:26446,49391:37324,49392:40100,49393:31036,49394:33673,49395:33620,49396:21519,49397:26647,49398:20029,49399:21385,49400:21169,49401:30782,49402:21382,49403:21033,49404:20616,49405:20363,49406:20432,49472:32598,49473:32601,49474:32603,49475:32604,49476:32605,49477:32606,49478:32608,49479:32611,49480:32612,49481:32613,49482:32614,49483:32615,49484:32619,49485:32620,49486:32621,49487:32623,49488:32624,49489:32627,49490:32629,49491:32630,49492:32631,49493:32632,49494:32634,49495:32635,49496:32636,49497:32637,49498:32639,49499:32640,49500:32642,49501:32643,49502:32644,49503:32645,49504:32646,49505:32647,49506:32648,49507:32649,49508:32651,49509:32653,49510:32655,49511:32656,49512:32657,49513:32658,49514:32659,49515:32661,49516:32662,49517:32663,49518:32664,49519:32665,49520:32667,49521:32668,49522:32672,49523:32674,49524:32675,49525:32677,49526:32678,49527:32680,49528:32681,49529:32682,49530:32683,49531:32684,49532:32685,49533:32686,49534:32689,49536:32691,49537:32692,49538:32693,49539:32694,49540:32695,49541:32698,49542:32699,49543:32702,49544:32704,49545:32706,49546:32707,49547:32708,49548:32710,49549:32711,49550:32712,49551:32713,49552:32715,49553:32717,49554:32719,49555:32720,49556:32721,49557:32722,49558:32723,49559:32726,49560:32727,49561:32729,49562:32730,49563:32731,49564:32732,49565:32733,49566:32734,49567:32738,49568:32739,49569:30178,49570:31435,49571:31890,49572:27813,49573:38582,49574:21147,49575:29827,49576:21737,49577:20457,49578:32852,49579:33714,49580:36830,49581:38256,49582:24265,49583:24604,49584:28063,49585:24088,49586:25947,49587:33080,49588:38142,49589:24651,49590:28860,49591:32451,49592:31918,49593:20937,49594:26753,49595:31921,49596:33391,49597:20004,49598:36742,49599:37327,49600:26238,49601:20142,49602:35845,49603:25769,49604:32842,49605:20698,49606:30103,49607:29134,49608:23525,49609:36797,49610:28518,49611:20102,49612:25730,49613:38243,49614:24278,49615:26009,49616:21015,49617:35010,49618:28872,49619:21155,49620:29454,49621:29747,49622:26519,49623:30967,49624:38678,49625:20020,49626:37051,49627:40158,49628:28107,49629:20955,49630:36161,49631:21533,49632:25294,49633:29618,49634:33777,49635:38646,49636:40836,49637:38083,49638:20278,49639:32666,49640:20940,49641:28789,49642:38517,49643:23725,49644:39046,49645:21478,49646:20196,49647:28316,49648:29705,49649:27060,49650:30827,49651:39311,49652:30041,49653:21016,49654:30244,49655:27969,49656:26611,49657:20845,49658:40857,49659:32843,49660:21657,49661:31548,49662:31423,49728:32740,49729:32743,49730:32744,49731:32746,49732:32747,49733:32748,49734:32749,49735:32751,49736:32754,49737:32756,49738:32757,49739:32758,49740:32759,49741:32760,49742:32761,49743:32762,49744:32765,49745:32766,49746:32767,49747:32770,49748:32775,49749:32776,49750:32777,49751:32778,49752:32782,49753:32783,49754:32785,49755:32787,49756:32794,49757:32795,49758:32797,49759:32798,49760:32799,49761:32801,49762:32803,49763:32804,49764:32811,49765:32812,49766:32813,49767:32814,49768:32815,49769:32816,49770:32818,49771:32820,49772:32825,49773:32826,49774:32828,49775:32830,49776:32832,49777:32833,49778:32836,49779:32837,49780:32839,49781:32840,49782:32841,49783:32846,49784:32847,49785:32848,49786:32849,49787:32851,49788:32853,49789:32854,49790:32855,49792:32857,49793:32859,49794:32860,49795:32861,49796:32862,49797:32863,49798:32864,49799:32865,49800:32866,49801:32867,49802:32868,49803:32869,49804:32870,49805:32871,49806:32872,49807:32875,49808:32876,49809:32877,49810:32878,49811:32879,49812:32880,49813:32882,49814:32883,49815:32884,49816:32885,49817:32886,49818:32887,49819:32888,49820:32889,49821:32890,49822:32891,49823:32892,49824:32893,49825:38534,49826:22404,49827:25314,49828:38471,49829:27004,49830:23044,49831:25602,49832:31699,49833:28431,49834:38475,49835:33446,49836:21346,49837:39045,49838:24208,49839:28809,49840:25523,49841:21348,49842:34383,49843:40065,49844:40595,49845:30860,49846:38706,49847:36335,49848:36162,49849:40575,49850:28510,49851:31108,49852:24405,49853:38470,49854:25134,49855:39540,49856:21525,49857:38109,49858:20387,49859:26053,49860:23653,49861:23649,49862:32533,49863:34385,49864:27695,49865:24459,49866:29575,49867:28388,49868:32511,49869:23782,49870:25371,49871:23402,49872:28390,49873:21365,49874:20081,49875:25504,49876:30053,49877:25249,49878:36718,49879:20262,49880:20177,49881:27814,49882:32438,49883:35770,49884:33821,49885:34746,49886:32599,49887:36923,49888:38179,49889:31657,49890:39585,49891:35064,49892:33853,49893:27931,49894:39558,49895:32476,49896:22920,49897:40635,49898:29595,49899:30721,49900:34434,49901:39532,49902:39554,49903:22043,49904:21527,49905:22475,49906:20080,49907:40614,49908:21334,49909:36808,49910:33033,49911:30610,49912:39314,49913:34542,49914:28385,49915:34067,49916:26364,49917:24930,49918:28459,49984:32894,49985:32897,49986:32898,49987:32901,49988:32904,49989:32906,49990:32909,49991:32910,49992:32911,49993:32912,49994:32913,49995:32914,49996:32916,49997:32917,49998:32919,49999:32921,50000:32926,50001:32931,50002:32934,50003:32935,50004:32936,50005:32940,50006:32944,50007:32947,50008:32949,50009:32950,50010:32952,50011:32953,50012:32955,50013:32965,50014:32967,50015:32968,50016:32969,50017:32970,50018:32971,50019:32975,50020:32976,50021:32977,50022:32978,50023:32979,50024:32980,50025:32981,50026:32984,50027:32991,50028:32992,50029:32994,50030:32995,50031:32998,50032:33006,50033:33013,50034:33015,50035:33017,50036:33019,50037:33022,50038:33023,50039:33024,50040:33025,50041:33027,50042:33028,50043:33029,50044:33031,50045:33032,50046:33035,50048:33036,50049:33045,50050:33047,50051:33049,50052:33051,50053:33052,50054:33053,50055:33055,50056:33056,50057:33057,50058:33058,50059:33059,50060:33060,50061:33061,50062:33062,50063:33063,50064:33064,50065:33065,50066:33066,50067:33067,50068:33069,50069:33070,50070:33072,50071:33075,50072:33076,50073:33077,50074:33079,50075:33081,50076:33082,50077:33083,50078:33084,50079:33085,50080:33087,50081:35881,50082:33426,50083:33579,50084:30450,50085:27667,50086:24537,50087:33725,50088:29483,50089:33541,50090:38170,50091:27611,50092:30683,50093:38086,50094:21359,50095:33538,50096:20882,50097:24125,50098:35980,50099:36152,50100:20040,50101:29611,50102:26522,50103:26757,50104:37238,50105:38665,50106:29028,50107:27809,50108:30473,50109:23186,50110:38209,50111:27599,50112:32654,50113:26151,50114:23504,50115:22969,50116:23194,50117:38376,50118:38391,50119:20204,50120:33804,50121:33945,50122:27308,50123:30431,50124:38192,50125:29467,50126:26790,50127:23391,50128:30511,50129:37274,50130:38753,50131:31964,50132:36855,50133:35868,50134:24357,50135:31859,50136:31192,50137:35269,50138:27852,50139:34588,50140:23494,50141:24130,50142:26825,50143:30496,50144:32501,50145:20885,50146:20813,50147:21193,50148:23081,50149:32517,50150:38754,50151:33495,50152:25551,50153:30596,50154:34256,50155:31186,50156:28218,50157:24217,50158:22937,50159:34065,50160:28781,50161:27665,50162:25279,50163:30399,50164:25935,50165:24751,50166:38397,50167:26126,50168:34719,50169:40483,50170:38125,50171:21517,50172:21629,50173:35884,50174:25720,50240:33088,50241:33089,50242:33090,50243:33091,50244:33092,50245:33093,50246:33095,50247:33097,50248:33101,50249:33102,50250:33103,50251:33106,50252:33110,50253:33111,50254:33112,50255:33115,50256:33116,50257:33117,50258:33118,50259:33119,50260:33121,50261:33122,50262:33123,50263:33124,50264:33126,50265:33128,50266:33130,50267:33131,50268:33132,50269:33135,50270:33138,50271:33139,50272:33141,50273:33142,50274:33143,50275:33144,50276:33153,50277:33155,50278:33156,50279:33157,50280:33158,50281:33159,50282:33161,50283:33163,50284:33164,50285:33165,50286:33166,50287:33168,50288:33170,50289:33171,50290:33172,50291:33173,50292:33174,50293:33175,50294:33177,50295:33178,50296:33182,50297:33183,50298:33184,50299:33185,50300:33186,50301:33188,50302:33189,50304:33191,50305:33193,50306:33195,50307:33196,50308:33197,50309:33198,50310:33199,50311:33200,50312:33201,50313:33202,50314:33204,50315:33205,50316:33206,50317:33207,50318:33208,50319:33209,50320:33212,50321:33213,50322:33214,50323:33215,50324:33220,50325:33221,50326:33223,50327:33224,50328:33225,50329:33227,50330:33229,50331:33230,50332:33231,50333:33232,50334:33233,50335:33234,50336:33235,50337:25721,50338:34321,50339:27169,50340:33180,50341:30952,50342:25705,50343:39764,50344:25273,50345:26411,50346:33707,50347:22696,50348:40664,50349:27819,50350:28448,50351:23518,50352:38476,50353:35851,50354:29279,50355:26576,50356:25287,50357:29281,50358:20137,50359:22982,50360:27597,50361:22675,50362:26286,50363:24149,50364:21215,50365:24917,50366:26408,50367:30446,50368:30566,50369:29287,50370:31302,50371:25343,50372:21738,50373:21584,50374:38048,50375:37027,50376:23068,50377:32435,50378:27670,50379:20035,50380:22902,50381:32784,50382:22856,50383:21335,50384:30007,50385:38590,50386:22218,50387:25376,50388:33041,50389:24700,50390:38393,50391:28118,50392:21602,50393:39297,50394:20869,50395:23273,50396:33021,50397:22958,50398:38675,50399:20522,50400:27877,50401:23612,50402:25311,50403:20320,50404:21311,50405:33147,50406:36870,50407:28346,50408:34091,50409:25288,50410:24180,50411:30910,50412:25781,50413:25467,50414:24565,50415:23064,50416:37247,50417:40479,50418:23615,50419:25423,50420:32834,50421:23421,50422:21870,50423:38218,50424:38221,50425:28037,50426:24744,50427:26592,50428:29406,50429:20957,50430:23425,50496:33236,50497:33237,50498:33238,50499:33239,50500:33240,50501:33241,50502:33242,50503:33243,50504:33244,50505:33245,50506:33246,50507:33247,50508:33248,50509:33249,50510:33250,50511:33252,50512:33253,50513:33254,50514:33256,50515:33257,50516:33259,50517:33262,50518:33263,50519:33264,50520:33265,50521:33266,50522:33269,50523:33270,50524:33271,50525:33272,50526:33273,50527:33274,50528:33277,50529:33279,50530:33283,50531:33287,50532:33288,50533:33289,50534:33290,50535:33291,50536:33294,50537:33295,50538:33297,50539:33299,50540:33301,50541:33302,50542:33303,50543:33304,50544:33305,50545:33306,50546:33309,50547:33312,50548:33316,50549:33317,50550:33318,50551:33319,50552:33321,50553:33326,50554:33330,50555:33338,50556:33340,50557:33341,50558:33343,50560:33344,50561:33345,50562:33346,50563:33347,50564:33349,50565:33350,50566:33352,50567:33354,50568:33356,50569:33357,50570:33358,50571:33360,50572:33361,50573:33362,50574:33363,50575:33364,50576:33365,50577:33366,50578:33367,50579:33369,50580:33371,50581:33372,50582:33373,50583:33374,50584:33376,50585:33377,50586:33378,50587:33379,50588:33380,50589:33381,50590:33382,50591:33383,50592:33385,50593:25319,50594:27870,50595:29275,50596:25197,50597:38062,50598:32445,50599:33043,50600:27987,50601:20892,50602:24324,50603:22900,50604:21162,50605:24594,50606:22899,50607:26262,50608:34384,50609:30111,50610:25386,50611:25062,50612:31983,50613:35834,50614:21734,50615:27431,50616:40485,50617:27572,50618:34261,50619:21589,50620:20598,50621:27812,50622:21866,50623:36276,50624:29228,50625:24085,50626:24597,50627:29750,50628:25293,50629:25490,50630:29260,50631:24472,50632:28227,50633:27966,50634:25856,50635:28504,50636:30424,50637:30928,50638:30460,50639:30036,50640:21028,50641:21467,50642:20051,50643:24222,50644:26049,50645:32810,50646:32982,50647:25243,50648:21638,50649:21032,50650:28846,50651:34957,50652:36305,50653:27873,50654:21624,50655:32986,50656:22521,50657:35060,50658:36180,50659:38506,50660:37197,50661:20329,50662:27803,50663:21943,50664:30406,50665:30768,50666:25256,50667:28921,50668:28558,50669:24429,50670:34028,50671:26842,50672:30844,50673:31735,50674:33192,50675:26379,50676:40527,50677:25447,50678:30896,50679:22383,50680:30738,50681:38713,50682:25209,50683:25259,50684:21128,50685:29749,50686:27607,50752:33386,50753:33387,50754:33388,50755:33389,50756:33393,50757:33397,50758:33398,50759:33399,50760:33400,50761:33403,50762:33404,50763:33408,50764:33409,50765:33411,50766:33413,50767:33414,50768:33415,50769:33417,50770:33420,50771:33424,50772:33427,50773:33428,50774:33429,50775:33430,50776:33434,50777:33435,50778:33438,50779:33440,50780:33442,50781:33443,50782:33447,50783:33458,50784:33461,50785:33462,50786:33466,50787:33467,50788:33468,50789:33471,50790:33472,50791:33474,50792:33475,50793:33477,50794:33478,50795:33481,50796:33488,50797:33494,50798:33497,50799:33498,50800:33501,50801:33506,50802:33511,50803:33512,50804:33513,50805:33514,50806:33516,50807:33517,50808:33518,50809:33520,50810:33522,50811:33523,50812:33525,50813:33526,50814:33528,50816:33530,50817:33532,50818:33533,50819:33534,50820:33535,50821:33536,50822:33546,50823:33547,50824:33549,50825:33552,50826:33554,50827:33555,50828:33558,50829:33560,50830:33561,50831:33565,50832:33566,50833:33567,50834:33568,50835:33569,50836:33570,50837:33571,50838:33572,50839:33573,50840:33574,50841:33577,50842:33578,50843:33582,50844:33584,50845:33586,50846:33591,50847:33595,50848:33597,50849:21860,50850:33086,50851:30130,50852:30382,50853:21305,50854:30174,50855:20731,50856:23617,50857:35692,50858:31687,50859:20559,50860:29255,50861:39575,50862:39128,50863:28418,50864:29922,50865:31080,50866:25735,50867:30629,50868:25340,50869:39057,50870:36139,50871:21697,50872:32856,50873:20050,50874:22378,50875:33529,50876:33805,50877:24179,50878:20973,50879:29942,50880:35780,50881:23631,50882:22369,50883:27900,50884:39047,50885:23110,50886:30772,50887:39748,50888:36843,50889:31893,50890:21078,50891:25169,50892:38138,50893:20166,50894:33670,50895:33889,50896:33769,50897:33970,50898:22484,50899:26420,50900:22275,50901:26222,50902:28006,50903:35889,50904:26333,50905:28689,50906:26399,50907:27450,50908:26646,50909:25114,50910:22971,50911:19971,50912:20932,50913:28422,50914:26578,50915:27791,50916:20854,50917:26827,50918:22855,50919:27495,50920:30054,50921:23822,50922:33040,50923:40784,50924:26071,50925:31048,50926:31041,50927:39569,50928:36215,50929:23682,50930:20062,50931:20225,50932:21551,50933:22865,50934:30732,50935:22120,50936:27668,50937:36804,50938:24323,50939:27773,50940:27875,50941:35755,50942:25488,51008:33598,51009:33599,51010:33601,51011:33602,51012:33604,51013:33605,51014:33608,51015:33610,51016:33611,51017:33612,51018:33613,51019:33614,51020:33619,51021:33621,51022:33622,51023:33623,51024:33624,51025:33625,51026:33629,51027:33634,51028:33648,51029:33649,51030:33650,51031:33651,51032:33652,51033:33653,51034:33654,51035:33657,51036:33658,51037:33662,51038:33663,51039:33664,51040:33665,51041:33666,51042:33667,51043:33668,51044:33671,51045:33672,51046:33674,51047:33675,51048:33676,51049:33677,51050:33679,51051:33680,51052:33681,51053:33684,51054:33685,51055:33686,51056:33687,51057:33689,51058:33690,51059:33693,51060:33695,51061:33697,51062:33698,51063:33699,51064:33700,51065:33701,51066:33702,51067:33703,51068:33708,51069:33709,51070:33710,51072:33711,51073:33717,51074:33723,51075:33726,51076:33727,51077:33730,51078:33731,51079:33732,51080:33734,51081:33736,51082:33737,51083:33739,51084:33741,51085:33742,51086:33744,51087:33745,51088:33746,51089:33747,51090:33749,51091:33751,51092:33753,51093:33754,51094:33755,51095:33758,51096:33762,51097:33763,51098:33764,51099:33766,51100:33767,51101:33768,51102:33771,51103:33772,51104:33773,51105:24688,51106:27965,51107:29301,51108:25190,51109:38030,51110:38085,51111:21315,51112:36801,51113:31614,51114:20191,51115:35878,51116:20094,51117:40660,51118:38065,51119:38067,51120:21069,51121:28508,51122:36963,51123:27973,51124:35892,51125:22545,51126:23884,51127:27424,51128:27465,51129:26538,51130:21595,51131:33108,51132:32652,51133:22681,51134:34103,51135:24378,51136:25250,51137:27207,51138:38201,51139:25970,51140:24708,51141:26725,51142:30631,51143:20052,51144:20392,51145:24039,51146:38808,51147:25772,51148:32728,51149:23789,51150:20431,51151:31373,51152:20999,51153:33540,51154:19988,51155:24623,51156:31363,51157:38054,51158:20405,51159:20146,51160:31206,51161:29748,51162:21220,51163:33465,51164:25810,51165:31165,51166:23517,51167:27777,51168:38738,51169:36731,51170:27682,51171:20542,51172:21375,51173:28165,51174:25806,51175:26228,51176:27696,51177:24773,51178:39031,51179:35831,51180:24198,51181:29756,51182:31351,51183:31179,51184:19992,51185:37041,51186:29699,51187:27714,51188:22234,51189:37195,51190:27845,51191:36235,51192:21306,51193:34502,51194:26354,51195:36527,51196:23624,51197:39537,51198:28192,51264:33774,51265:33775,51266:33779,51267:33780,51268:33781,51269:33782,51270:33783,51271:33786,51272:33787,51273:33788,51274:33790,51275:33791,51276:33792,51277:33794,51278:33797,51279:33799,51280:33800,51281:33801,51282:33802,51283:33808,51284:33810,51285:33811,51286:33812,51287:33813,51288:33814,51289:33815,51290:33817,51291:33818,51292:33819,51293:33822,51294:33823,51295:33824,51296:33825,51297:33826,51298:33827,51299:33833,51300:33834,51301:33835,51302:33836,51303:33837,51304:33838,51305:33839,51306:33840,51307:33842,51308:33843,51309:33844,51310:33845,51311:33846,51312:33847,51313:33849,51314:33850,51315:33851,51316:33854,51317:33855,51318:33856,51319:33857,51320:33858,51321:33859,51322:33860,51323:33861,51324:33863,51325:33864,51326:33865,51328:33866,51329:33867,51330:33868,51331:33869,51332:33870,51333:33871,51334:33872,51335:33874,51336:33875,51337:33876,51338:33877,51339:33878,51340:33880,51341:33885,51342:33886,51343:33887,51344:33888,51345:33890,51346:33892,51347:33893,51348:33894,51349:33895,51350:33896,51351:33898,51352:33902,51353:33903,51354:33904,51355:33906,51356:33908,51357:33911,51358:33913,51359:33915,51360:33916,51361:21462,51362:23094,51363:40843,51364:36259,51365:21435,51366:22280,51367:39079,51368:26435,51369:37275,51370:27849,51371:20840,51372:30154,51373:25331,51374:29356,51375:21048,51376:21149,51377:32570,51378:28820,51379:30264,51380:21364,51381:40522,51382:27063,51383:30830,51384:38592,51385:35033,51386:32676,51387:28982,51388:29123,51389:20873,51390:26579,51391:29924,51392:22756,51393:25880,51394:22199,51395:35753,51396:39286,51397:25200,51398:32469,51399:24825,51400:28909,51401:22764,51402:20161,51403:20154,51404:24525,51405:38887,51406:20219,51407:35748,51408:20995,51409:22922,51410:32427,51411:25172,51412:20173,51413:26085,51414:25102,51415:33592,51416:33993,51417:33635,51418:34701,51419:29076,51420:28342,51421:23481,51422:32466,51423:20887,51424:25545,51425:26580,51426:32905,51427:33593,51428:34837,51429:20754,51430:23418,51431:22914,51432:36785,51433:20083,51434:27741,51435:20837,51436:35109,51437:36719,51438:38446,51439:34122,51440:29790,51441:38160,51442:38384,51443:28070,51444:33509,51445:24369,51446:25746,51447:27922,51448:33832,51449:33134,51450:40131,51451:22622,51452:36187,51453:19977,51454:21441,51520:33917,51521:33918,51522:33919,51523:33920,51524:33921,51525:33923,51526:33924,51527:33925,51528:33926,51529:33930,51530:33933,51531:33935,51532:33936,51533:33937,51534:33938,51535:33939,51536:33940,51537:33941,51538:33942,51539:33944,51540:33946,51541:33947,51542:33949,51543:33950,51544:33951,51545:33952,51546:33954,51547:33955,51548:33956,51549:33957,51550:33958,51551:33959,51552:33960,51553:33961,51554:33962,51555:33963,51556:33964,51557:33965,51558:33966,51559:33968,51560:33969,51561:33971,51562:33973,51563:33974,51564:33975,51565:33979,51566:33980,51567:33982,51568:33984,51569:33986,51570:33987,51571:33989,51572:33990,51573:33991,51574:33992,51575:33995,51576:33996,51577:33998,51578:33999,51579:34002,51580:34004,51581:34005,51582:34007,51584:34008,51585:34009,51586:34010,51587:34011,51588:34012,51589:34014,51590:34017,51591:34018,51592:34020,51593:34023,51594:34024,51595:34025,51596:34026,51597:34027,51598:34029,51599:34030,51600:34031,51601:34033,51602:34034,51603:34035,51604:34036,51605:34037,51606:34038,51607:34039,51608:34040,51609:34041,51610:34042,51611:34043,51612:34045,51613:34046,51614:34048,51615:34049,51616:34050,51617:20254,51618:25955,51619:26705,51620:21971,51621:20007,51622:25620,51623:39578,51624:25195,51625:23234,51626:29791,51627:33394,51628:28073,51629:26862,51630:20711,51631:33678,51632:30722,51633:26432,51634:21049,51635:27801,51636:32433,51637:20667,51638:21861,51639:29022,51640:31579,51641:26194,51642:29642,51643:33515,51644:26441,51645:23665,51646:21024,51647:29053,51648:34923,51649:38378,51650:38485,51651:25797,51652:36193,51653:33203,51654:21892,51655:27733,51656:25159,51657:32558,51658:22674,51659:20260,51660:21830,51661:36175,51662:26188,51663:19978,51664:23578,51665:35059,51666:26786,51667:25422,51668:31245,51669:28903,51670:33421,51671:21242,51672:38902,51673:23569,51674:21736,51675:37045,51676:32461,51677:22882,51678:36170,51679:34503,51680:33292,51681:33293,51682:36198,51683:25668,51684:23556,51685:24913,51686:28041,51687:31038,51688:35774,51689:30775,51690:30003,51691:21627,51692:20280,51693:36523,51694:28145,51695:23072,51696:32453,51697:31070,51698:27784,51699:23457,51700:23158,51701:29978,51702:32958,51703:24910,51704:28183,51705:22768,51706:29983,51707:29989,51708:29298,51709:21319,51710:32499,51776:34051,51777:34052,51778:34053,51779:34054,51780:34055,51781:34056,51782:34057,51783:34058,51784:34059,51785:34061,51786:34062,51787:34063,51788:34064,51789:34066,51790:34068,51791:34069,51792:34070,51793:34072,51794:34073,51795:34075,51796:34076,51797:34077,51798:34078,51799:34080,51800:34082,51801:34083,51802:34084,51803:34085,51804:34086,51805:34087,51806:34088,51807:34089,51808:34090,51809:34093,51810:34094,51811:34095,51812:34096,51813:34097,51814:34098,51815:34099,51816:34100,51817:34101,51818:34102,51819:34110,51820:34111,51821:34112,51822:34113,51823:34114,51824:34116,51825:34117,51826:34118,51827:34119,51828:34123,51829:34124,51830:34125,51831:34126,51832:34127,51833:34128,51834:34129,51835:34130,51836:34131,51837:34132,51838:34133,51840:34135,51841:34136,51842:34138,51843:34139,51844:34140,51845:34141,51846:34143,51847:34144,51848:34145,51849:34146,51850:34147,51851:34149,51852:34150,51853:34151,51854:34153,51855:34154,51856:34155,51857:34156,51858:34157,51859:34158,51860:34159,51861:34160,51862:34161,51863:34163,51864:34165,51865:34166,51866:34167,51867:34168,51868:34172,51869:34173,51870:34175,51871:34176,51872:34177,51873:30465,51874:30427,51875:21097,51876:32988,51877:22307,51878:24072,51879:22833,51880:29422,51881:26045,51882:28287,51883:35799,51884:23608,51885:34417,51886:21313,51887:30707,51888:25342,51889:26102,51890:20160,51891:39135,51892:34432,51893:23454,51894:35782,51895:21490,51896:30690,51897:20351,51898:23630,51899:39542,51900:22987,51901:24335,51902:31034,51903:22763,51904:19990,51905:26623,51906:20107,51907:25325,51908:35475,51909:36893,51910:21183,51911:26159,51912:21980,51913:22124,51914:36866,51915:20181,51916:20365,51917:37322,51918:39280,51919:27663,51920:24066,51921:24643,51922:23460,51923:35270,51924:35797,51925:25910,51926:25163,51927:39318,51928:23432,51929:23551,51930:25480,51931:21806,51932:21463,51933:30246,51934:20861,51935:34092,51936:26530,51937:26803,51938:27530,51939:25234,51940:36755,51941:21460,51942:33298,51943:28113,51944:30095,51945:20070,51946:36174,51947:23408,51948:29087,51949:34223,51950:26257,51951:26329,51952:32626,51953:34560,51954:40653,51955:40736,51956:23646,51957:26415,51958:36848,51959:26641,51960:26463,51961:25101,51962:31446,51963:22661,51964:24246,51965:25968,51966:28465,52032:34178,52033:34179,52034:34182,52035:34184,52036:34185,52037:34186,52038:34187,52039:34188,52040:34189,52041:34190,52042:34192,52043:34193,52044:34194,52045:34195,52046:34196,52047:34197,52048:34198,52049:34199,52050:34200,52051:34201,52052:34202,52053:34205,52054:34206,52055:34207,52056:34208,52057:34209,52058:34210,52059:34211,52060:34213,52061:34214,52062:34215,52063:34217,52064:34219,52065:34220,52066:34221,52067:34225,52068:34226,52069:34227,52070:34228,52071:34229,52072:34230,52073:34232,52074:34234,52075:34235,52076:34236,52077:34237,52078:34238,52079:34239,52080:34240,52081:34242,52082:34243,52083:34244,52084:34245,52085:34246,52086:34247,52087:34248,52088:34250,52089:34251,52090:34252,52091:34253,52092:34254,52093:34257,52094:34258,52096:34260,52097:34262,52098:34263,52099:34264,52100:34265,52101:34266,52102:34267,52103:34269,52104:34270,52105:34271,52106:34272,52107:34273,52108:34274,52109:34275,52110:34277,52111:34278,52112:34279,52113:34280,52114:34282,52115:34283,52116:34284,52117:34285,52118:34286,52119:34287,52120:34288,52121:34289,52122:34290,52123:34291,52124:34292,52125:34293,52126:34294,52127:34295,52128:34296,52129:24661,52130:21047,52131:32781,52132:25684,52133:34928,52134:29993,52135:24069,52136:26643,52137:25332,52138:38684,52139:21452,52140:29245,52141:35841,52142:27700,52143:30561,52144:31246,52145:21550,52146:30636,52147:39034,52148:33308,52149:35828,52150:30805,52151:26388,52152:28865,52153:26031,52154:25749,52155:22070,52156:24605,52157:31169,52158:21496,52159:19997,52160:27515,52161:32902,52162:23546,52163:21987,52164:22235,52165:20282,52166:20284,52167:39282,52168:24051,52169:26494,52170:32824,52171:24578,52172:39042,52173:36865,52174:23435,52175:35772,52176:35829,52177:25628,52178:33368,52179:25822,52180:22013,52181:33487,52182:37221,52183:20439,52184:32032,52185:36895,52186:31903,52187:20723,52188:22609,52189:28335,52190:23487,52191:35785,52192:32899,52193:37240,52194:33948,52195:31639,52196:34429,52197:38539,52198:38543,52199:32485,52200:39635,52201:30862,52202:23681,52203:31319,52204:36930,52205:38567,52206:31071,52207:23385,52208:25439,52209:31499,52210:34001,52211:26797,52212:21766,52213:32553,52214:29712,52215:32034,52216:38145,52217:25152,52218:22604,52219:20182,52220:23427,52221:22905,52222:22612,52288:34297,52289:34298,52290:34300,52291:34301,52292:34302,52293:34304,52294:34305,52295:34306,52296:34307,52297:34308,52298:34310,52299:34311,52300:34312,52301:34313,52302:34314,52303:34315,52304:34316,52305:34317,52306:34318,52307:34319,52308:34320,52309:34322,52310:34323,52311:34324,52312:34325,52313:34327,52314:34328,52315:34329,52316:34330,52317:34331,52318:34332,52319:34333,52320:34334,52321:34335,52322:34336,52323:34337,52324:34338,52325:34339,52326:34340,52327:34341,52328:34342,52329:34344,52330:34346,52331:34347,52332:34348,52333:34349,52334:34350,52335:34351,52336:34352,52337:34353,52338:34354,52339:34355,52340:34356,52341:34357,52342:34358,52343:34359,52344:34361,52345:34362,52346:34363,52347:34365,52348:34366,52349:34367,52350:34368,52352:34369,52353:34370,52354:34371,52355:34372,52356:34373,52357:34374,52358:34375,52359:34376,52360:34377,52361:34378,52362:34379,52363:34380,52364:34386,52365:34387,52366:34389,52367:34390,52368:34391,52369:34392,52370:34393,52371:34395,52372:34396,52373:34397,52374:34399,52375:34400,52376:34401,52377:34403,52378:34404,52379:34405,52380:34406,52381:34407,52382:34408,52383:34409,52384:34410,52385:29549,52386:25374,52387:36427,52388:36367,52389:32974,52390:33492,52391:25260,52392:21488,52393:27888,52394:37214,52395:22826,52396:24577,52397:27760,52398:22349,52399:25674,52400:36138,52401:30251,52402:28393,52403:22363,52404:27264,52405:30192,52406:28525,52407:35885,52408:35848,52409:22374,52410:27631,52411:34962,52412:30899,52413:25506,52414:21497,52415:28845,52416:27748,52417:22616,52418:25642,52419:22530,52420:26848,52421:33179,52422:21776,52423:31958,52424:20504,52425:36538,52426:28108,52427:36255,52428:28907,52429:25487,52430:28059,52431:28372,52432:32486,52433:33796,52434:26691,52435:36867,52436:28120,52437:38518,52438:35752,52439:22871,52440:29305,52441:34276,52442:33150,52443:30140,52444:35466,52445:26799,52446:21076,52447:36386,52448:38161,52449:25552,52450:39064,52451:36420,52452:21884,52453:20307,52454:26367,52455:22159,52456:24789,52457:28053,52458:21059,52459:23625,52460:22825,52461:28155,52462:22635,52463:30000,52464:29980,52465:24684,52466:33300,52467:33094,52468:25361,52469:26465,52470:36834,52471:30522,52472:36339,52473:36148,52474:38081,52475:24086,52476:21381,52477:21548,52478:28867,52544:34413,52545:34415,52546:34416,52547:34418,52548:34419,52549:34420,52550:34421,52551:34422,52552:34423,52553:34424,52554:34435,52555:34436,52556:34437,52557:34438,52558:34439,52559:34440,52560:34441,52561:34446,52562:34447,52563:34448,52564:34449,52565:34450,52566:34452,52567:34454,52568:34455,52569:34456,52570:34457,52571:34458,52572:34459,52573:34462,52574:34463,52575:34464,52576:34465,52577:34466,52578:34469,52579:34470,52580:34475,52581:34477,52582:34478,52583:34482,52584:34483,52585:34487,52586:34488,52587:34489,52588:34491,52589:34492,52590:34493,52591:34494,52592:34495,52593:34497,52594:34498,52595:34499,52596:34501,52597:34504,52598:34508,52599:34509,52600:34514,52601:34515,52602:34517,52603:34518,52604:34519,52605:34522,52606:34524,52608:34525,52609:34528,52610:34529,52611:34530,52612:34531,52613:34533,52614:34534,52615:34535,52616:34536,52617:34538,52618:34539,52619:34540,52620:34543,52621:34549,52622:34550,52623:34551,52624:34554,52625:34555,52626:34556,52627:34557,52628:34559,52629:34561,52630:34564,52631:34565,52632:34566,52633:34571,52634:34572,52635:34574,52636:34575,52637:34576,52638:34577,52639:34580,52640:34582,52641:27712,52642:24311,52643:20572,52644:20141,52645:24237,52646:25402,52647:33351,52648:36890,52649:26704,52650:37230,52651:30643,52652:21516,52653:38108,52654:24420,52655:31461,52656:26742,52657:25413,52658:31570,52659:32479,52660:30171,52661:20599,52662:25237,52663:22836,52664:36879,52665:20984,52666:31171,52667:31361,52668:22270,52669:24466,52670:36884,52671:28034,52672:23648,52673:22303,52674:21520,52675:20820,52676:28237,52677:22242,52678:25512,52679:39059,52680:33151,52681:34581,52682:35114,52683:36864,52684:21534,52685:23663,52686:33216,52687:25302,52688:25176,52689:33073,52690:40501,52691:38464,52692:39534,52693:39548,52694:26925,52695:22949,52696:25299,52697:21822,52698:25366,52699:21703,52700:34521,52701:27964,52702:23043,52703:29926,52704:34972,52705:27498,52706:22806,52707:35916,52708:24367,52709:28286,52710:29609,52711:39037,52712:20024,52713:28919,52714:23436,52715:30871,52716:25405,52717:26202,52718:30358,52719:24779,52720:23451,52721:23113,52722:19975,52723:33109,52724:27754,52725:29579,52726:20129,52727:26505,52728:32593,52729:24448,52730:26106,52731:26395,52732:24536,52733:22916,52734:23041,52800:34585,52801:34587,52802:34589,52803:34591,52804:34592,52805:34596,52806:34598,52807:34599,52808:34600,52809:34602,52810:34603,52811:34604,52812:34605,52813:34607,52814:34608,52815:34610,52816:34611,52817:34613,52818:34614,52819:34616,52820:34617,52821:34618,52822:34620,52823:34621,52824:34624,52825:34625,52826:34626,52827:34627,52828:34628,52829:34629,52830:34630,52831:34634,52832:34635,52833:34637,52834:34639,52835:34640,52836:34641,52837:34642,52838:34644,52839:34645,52840:34646,52841:34648,52842:34650,52843:34651,52844:34652,52845:34653,52846:34654,52847:34655,52848:34657,52849:34658,52850:34662,52851:34663,52852:34664,52853:34665,52854:34666,52855:34667,52856:34668,52857:34669,52858:34671,52859:34673,52860:34674,52861:34675,52862:34677,52864:34679,52865:34680,52866:34681,52867:34682,52868:34687,52869:34688,52870:34689,52871:34692,52872:34694,52873:34695,52874:34697,52875:34698,52876:34700,52877:34702,52878:34703,52879:34704,52880:34705,52881:34706,52882:34708,52883:34709,52884:34710,52885:34712,52886:34713,52887:34714,52888:34715,52889:34716,52890:34717,52891:34718,52892:34720,52893:34721,52894:34722,52895:34723,52896:34724,52897:24013,52898:24494,52899:21361,52900:38886,52901:36829,52902:26693,52903:22260,52904:21807,52905:24799,52906:20026,52907:28493,52908:32500,52909:33479,52910:33806,52911:22996,52912:20255,52913:20266,52914:23614,52915:32428,52916:26410,52917:34074,52918:21619,52919:30031,52920:32963,52921:21890,52922:39759,52923:20301,52924:28205,52925:35859,52926:23561,52927:24944,52928:21355,52929:30239,52930:28201,52931:34442,52932:25991,52933:38395,52934:32441,52935:21563,52936:31283,52937:32010,52938:38382,52939:21985,52940:32705,52941:29934,52942:25373,52943:34583,52944:28065,52945:31389,52946:25105,52947:26017,52948:21351,52949:25569,52950:27779,52951:24043,52952:21596,52953:38056,52954:20044,52955:27745,52956:35820,52957:23627,52958:26080,52959:33436,52960:26791,52961:21566,52962:21556,52963:27595,52964:27494,52965:20116,52966:25410,52967:21320,52968:33310,52969:20237,52970:20398,52971:22366,52972:25098,52973:38654,52974:26212,52975:29289,52976:21247,52977:21153,52978:24735,52979:35823,52980:26132,52981:29081,52982:26512,52983:35199,52984:30802,52985:30717,52986:26224,52987:22075,52988:21560,52989:38177,52990:29306,53056:34725,53057:34726,53058:34727,53059:34729,53060:34730,53061:34734,53062:34736,53063:34737,53064:34738,53065:34740,53066:34742,53067:34743,53068:34744,53069:34745,53070:34747,53071:34748,53072:34750,53073:34751,53074:34753,53075:34754,53076:34755,53077:34756,53078:34757,53079:34759,53080:34760,53081:34761,53082:34764,53083:34765,53084:34766,53085:34767,53086:34768,53087:34772,53088:34773,53089:34774,53090:34775,53091:34776,53092:34777,53093:34778,53094:34780,53095:34781,53096:34782,53097:34783,53098:34785,53099:34786,53100:34787,53101:34788,53102:34790,53103:34791,53104:34792,53105:34793,53106:34795,53107:34796,53108:34797,53109:34799,53110:34800,53111:34801,53112:34802,53113:34803,53114:34804,53115:34805,53116:34806,53117:34807,53118:34808,53120:34810,53121:34811,53122:34812,53123:34813,53124:34815,53125:34816,53126:34817,53127:34818,53128:34820,53129:34821,53130:34822,53131:34823,53132:34824,53133:34825,53134:34827,53135:34828,53136:34829,53137:34830,53138:34831,53139:34832,53140:34833,53141:34834,53142:34836,53143:34839,53144:34840,53145:34841,53146:34842,53147:34844,53148:34845,53149:34846,53150:34847,53151:34848,53152:34851,53153:31232,53154:24687,53155:24076,53156:24713,53157:33181,53158:22805,53159:24796,53160:29060,53161:28911,53162:28330,53163:27728,53164:29312,53165:27268,53166:34989,53167:24109,53168:20064,53169:23219,53170:21916,53171:38115,53172:27927,53173:31995,53174:38553,53175:25103,53176:32454,53177:30606,53178:34430,53179:21283,53180:38686,53181:36758,53182:26247,53183:23777,53184:20384,53185:29421,53186:19979,53187:21414,53188:22799,53189:21523,53190:25472,53191:38184,53192:20808,53193:20185,53194:40092,53195:32420,53196:21688,53197:36132,53198:34900,53199:33335,53200:38386,53201:28046,53202:24358,53203:23244,53204:26174,53205:38505,53206:29616,53207:29486,53208:21439,53209:33146,53210:39301,53211:32673,53212:23466,53213:38519,53214:38480,53215:32447,53216:30456,53217:21410,53218:38262,53219:39321,53220:31665,53221:35140,53222:28248,53223:20065,53224:32724,53225:31077,53226:35814,53227:24819,53228:21709,53229:20139,53230:39033,53231:24055,53232:27233,53233:20687,53234:21521,53235:35937,53236:33831,53237:30813,53238:38660,53239:21066,53240:21742,53241:22179,53242:38144,53243:28040,53244:23477,53245:28102,53246:26195,53312:34852,53313:34853,53314:34854,53315:34855,53316:34856,53317:34857,53318:34858,53319:34859,53320:34860,53321:34861,53322:34862,53323:34863,53324:34864,53325:34865,53326:34867,53327:34868,53328:34869,53329:34870,53330:34871,53331:34872,53332:34874,53333:34875,53334:34877,53335:34878,53336:34879,53337:34881,53338:34882,53339:34883,53340:34886,53341:34887,53342:34888,53343:34889,53344:34890,53345:34891,53346:34894,53347:34895,53348:34896,53349:34897,53350:34898,53351:34899,53352:34901,53353:34902,53354:34904,53355:34906,53356:34907,53357:34908,53358:34909,53359:34910,53360:34911,53361:34912,53362:34918,53363:34919,53364:34922,53365:34925,53366:34927,53367:34929,53368:34931,53369:34932,53370:34933,53371:34934,53372:34936,53373:34937,53374:34938,53376:34939,53377:34940,53378:34944,53379:34947,53380:34950,53381:34951,53382:34953,53383:34954,53384:34956,53385:34958,53386:34959,53387:34960,53388:34961,53389:34963,53390:34964,53391:34965,53392:34967,53393:34968,53394:34969,53395:34970,53396:34971,53397:34973,53398:34974,53399:34975,53400:34976,53401:34977,53402:34979,53403:34981,53404:34982,53405:34983,53406:34984,53407:34985,53408:34986,53409:23567,53410:23389,53411:26657,53412:32918,53413:21880,53414:31505,53415:25928,53416:26964,53417:20123,53418:27463,53419:34638,53420:38795,53421:21327,53422:25375,53423:25658,53424:37034,53425:26012,53426:32961,53427:35856,53428:20889,53429:26800,53430:21368,53431:34809,53432:25032,53433:27844,53434:27899,53435:35874,53436:23633,53437:34218,53438:33455,53439:38156,53440:27427,53441:36763,53442:26032,53443:24571,53444:24515,53445:20449,53446:34885,53447:26143,53448:33125,53449:29481,53450:24826,53451:20852,53452:21009,53453:22411,53454:24418,53455:37026,53456:34892,53457:37266,53458:24184,53459:26447,53460:24615,53461:22995,53462:20804,53463:20982,53464:33016,53465:21256,53466:27769,53467:38596,53468:29066,53469:20241,53470:20462,53471:32670,53472:26429,53473:21957,53474:38152,53475:31168,53476:34966,53477:32483,53478:22687,53479:25100,53480:38656,53481:34394,53482:22040,53483:39035,53484:24464,53485:35768,53486:33988,53487:37207,53488:21465,53489:26093,53490:24207,53491:30044,53492:24676,53493:32110,53494:23167,53495:32490,53496:32493,53497:36713,53498:21927,53499:23459,53500:24748,53501:26059,53502:29572,53568:34988,53569:34990,53570:34991,53571:34992,53572:34994,53573:34995,53574:34996,53575:34997,53576:34998,53577:35000,53578:35001,53579:35002,53580:35003,53581:35005,53582:35006,53583:35007,53584:35008,53585:35011,53586:35012,53587:35015,53588:35016,53589:35018,53590:35019,53591:35020,53592:35021,53593:35023,53594:35024,53595:35025,53596:35027,53597:35030,53598:35031,53599:35034,53600:35035,53601:35036,53602:35037,53603:35038,53604:35040,53605:35041,53606:35046,53607:35047,53608:35049,53609:35050,53610:35051,53611:35052,53612:35053,53613:35054,53614:35055,53615:35058,53616:35061,53617:35062,53618:35063,53619:35066,53620:35067,53621:35069,53622:35071,53623:35072,53624:35073,53625:35075,53626:35076,53627:35077,53628:35078,53629:35079,53630:35080,53632:35081,53633:35083,53634:35084,53635:35085,53636:35086,53637:35087,53638:35089,53639:35092,53640:35093,53641:35094,53642:35095,53643:35096,53644:35100,53645:35101,53646:35102,53647:35103,53648:35104,53649:35106,53650:35107,53651:35108,53652:35110,53653:35111,53654:35112,53655:35113,53656:35116,53657:35117,53658:35118,53659:35119,53660:35121,53661:35122,53662:35123,53663:35125,53664:35127,53665:36873,53666:30307,53667:30505,53668:32474,53669:38772,53670:34203,53671:23398,53672:31348,53673:38634,53674:34880,53675:21195,53676:29071,53677:24490,53678:26092,53679:35810,53680:23547,53681:39535,53682:24033,53683:27529,53684:27739,53685:35757,53686:35759,53687:36874,53688:36805,53689:21387,53690:25276,53691:40486,53692:40493,53693:21568,53694:20011,53695:33469,53696:29273,53697:34460,53698:23830,53699:34905,53700:28079,53701:38597,53702:21713,53703:20122,53704:35766,53705:28937,53706:21693,53707:38409,53708:28895,53709:28153,53710:30416,53711:20005,53712:30740,53713:34578,53714:23721,53715:24310,53716:35328,53717:39068,53718:38414,53719:28814,53720:27839,53721:22852,53722:25513,53723:30524,53724:34893,53725:28436,53726:33395,53727:22576,53728:29141,53729:21388,53730:30746,53731:38593,53732:21761,53733:24422,53734:28976,53735:23476,53736:35866,53737:39564,53738:27523,53739:22830,53740:40495,53741:31207,53742:26472,53743:25196,53744:20335,53745:30113,53746:32650,53747:27915,53748:38451,53749:27687,53750:20208,53751:30162,53752:20859,53753:26679,53754:28478,53755:36992,53756:33136,53757:22934,53758:29814,53824:35128,53825:35129,53826:35130,53827:35131,53828:35132,53829:35133,53830:35134,53831:35135,53832:35136,53833:35138,53834:35139,53835:35141,53836:35142,53837:35143,53838:35144,53839:35145,53840:35146,53841:35147,53842:35148,53843:35149,53844:35150,53845:35151,53846:35152,53847:35153,53848:35154,53849:35155,53850:35156,53851:35157,53852:35158,53853:35159,53854:35160,53855:35161,53856:35162,53857:35163,53858:35164,53859:35165,53860:35168,53861:35169,53862:35170,53863:35171,53864:35172,53865:35173,53866:35175,53867:35176,53868:35177,53869:35178,53870:35179,53871:35180,53872:35181,53873:35182,53874:35183,53875:35184,53876:35185,53877:35186,53878:35187,53879:35188,53880:35189,53881:35190,53882:35191,53883:35192,53884:35193,53885:35194,53886:35196,53888:35197,53889:35198,53890:35200,53891:35202,53892:35204,53893:35205,53894:35207,53895:35208,53896:35209,53897:35210,53898:35211,53899:35212,53900:35213,53901:35214,53902:35215,53903:35216,53904:35217,53905:35218,53906:35219,53907:35220,53908:35221,53909:35222,53910:35223,53911:35224,53912:35225,53913:35226,53914:35227,53915:35228,53916:35229,53917:35230,53918:35231,53919:35232,53920:35233,53921:25671,53922:23591,53923:36965,53924:31377,53925:35875,53926:23002,53927:21676,53928:33280,53929:33647,53930:35201,53931:32768,53932:26928,53933:22094,53934:32822,53935:29239,53936:37326,53937:20918,53938:20063,53939:39029,53940:25494,53941:19994,53942:21494,53943:26355,53944:33099,53945:22812,53946:28082,53947:19968,53948:22777,53949:21307,53950:25558,53951:38129,53952:20381,53953:20234,53954:34915,53955:39056,53956:22839,53957:36951,53958:31227,53959:20202,53960:33008,53961:30097,53962:27778,53963:23452,53964:23016,53965:24413,53966:26885,53967:34433,53968:20506,53969:24050,53970:20057,53971:30691,53972:20197,53973:33402,53974:25233,53975:26131,53976:37009,53977:23673,53978:20159,53979:24441,53980:33222,53981:36920,53982:32900,53983:30123,53984:20134,53985:35028,53986:24847,53987:27589,53988:24518,53989:20041,53990:30410,53991:28322,53992:35811,53993:35758,53994:35850,53995:35793,53996:24322,53997:32764,53998:32716,53999:32462,54000:33589,54001:33643,54002:22240,54003:27575,54004:38899,54005:38452,54006:23035,54007:21535,54008:38134,54009:28139,54010:23493,54011:39278,54012:23609,54013:24341,54014:38544,54080:35234,54081:35235,54082:35236,54083:35237,54084:35238,54085:35239,54086:35240,54087:35241,54088:35242,54089:35243,54090:35244,54091:35245,54092:35246,54093:35247,54094:35248,54095:35249,54096:35250,54097:35251,54098:35252,54099:35253,54100:35254,54101:35255,54102:35256,54103:35257,54104:35258,54105:35259,54106:35260,54107:35261,54108:35262,54109:35263,54110:35264,54111:35267,54112:35277,54113:35283,54114:35284,54115:35285,54116:35287,54117:35288,54118:35289,54119:35291,54120:35293,54121:35295,54122:35296,54123:35297,54124:35298,54125:35300,54126:35303,54127:35304,54128:35305,54129:35306,54130:35308,54131:35309,54132:35310,54133:35312,54134:35313,54135:35314,54136:35316,54137:35317,54138:35318,54139:35319,54140:35320,54141:35321,54142:35322,54144:35323,54145:35324,54146:35325,54147:35326,54148:35327,54149:35329,54150:35330,54151:35331,54152:35332,54153:35333,54154:35334,54155:35336,54156:35337,54157:35338,54158:35339,54159:35340,54160:35341,54161:35342,54162:35343,54163:35344,54164:35345,54165:35346,54166:35347,54167:35348,54168:35349,54169:35350,54170:35351,54171:35352,54172:35353,54173:35354,54174:35355,54175:35356,54176:35357,54177:21360,54178:33521,54179:27185,54180:23156,54181:40560,54182:24212,54183:32552,54184:33721,54185:33828,54186:33829,54187:33639,54188:34631,54189:36814,54190:36194,54191:30408,54192:24433,54193:39062,54194:30828,54195:26144,54196:21727,54197:25317,54198:20323,54199:33219,54200:30152,54201:24248,54202:38605,54203:36362,54204:34553,54205:21647,54206:27891,54207:28044,54208:27704,54209:24703,54210:21191,54211:29992,54212:24189,54213:20248,54214:24736,54215:24551,54216:23588,54217:30001,54218:37038,54219:38080,54220:29369,54221:27833,54222:28216,54223:37193,54224:26377,54225:21451,54226:21491,54227:20305,54228:37321,54229:35825,54230:21448,54231:24188,54232:36802,54233:28132,54234:20110,54235:30402,54236:27014,54237:34398,54238:24858,54239:33286,54240:20313,54241:20446,54242:36926,54243:40060,54244:24841,54245:28189,54246:28180,54247:38533,54248:20104,54249:23089,54250:38632,54251:19982,54252:23679,54253:31161,54254:23431,54255:35821,54256:32701,54257:29577,54258:22495,54259:33419,54260:37057,54261:21505,54262:36935,54263:21947,54264:23786,54265:24481,54266:24840,54267:27442,54268:29425,54269:32946,54270:35465,54336:35358,54337:35359,54338:35360,54339:35361,54340:35362,54341:35363,54342:35364,54343:35365,54344:35366,54345:35367,54346:35368,54347:35369,54348:35370,54349:35371,54350:35372,54351:35373,54352:35374,54353:35375,54354:35376,54355:35377,54356:35378,54357:35379,54358:35380,54359:35381,54360:35382,54361:35383,54362:35384,54363:35385,54364:35386,54365:35387,54366:35388,54367:35389,54368:35391,54369:35392,54370:35393,54371:35394,54372:35395,54373:35396,54374:35397,54375:35398,54376:35399,54377:35401,54378:35402,54379:35403,54380:35404,54381:35405,54382:35406,54383:35407,54384:35408,54385:35409,54386:35410,54387:35411,54388:35412,54389:35413,54390:35414,54391:35415,54392:35416,54393:35417,54394:35418,54395:35419,54396:35420,54397:35421,54398:35422,54400:35423,54401:35424,54402:35425,54403:35426,54404:35427,54405:35428,54406:35429,54407:35430,54408:35431,54409:35432,54410:35433,54411:35434,54412:35435,54413:35436,54414:35437,54415:35438,54416:35439,54417:35440,54418:35441,54419:35442,54420:35443,54421:35444,54422:35445,54423:35446,54424:35447,54425:35448,54426:35450,54427:35451,54428:35452,54429:35453,54430:35454,54431:35455,54432:35456,54433:28020,54434:23507,54435:35029,54436:39044,54437:35947,54438:39533,54439:40499,54440:28170,54441:20900,54442:20803,54443:22435,54444:34945,54445:21407,54446:25588,54447:36757,54448:22253,54449:21592,54450:22278,54451:29503,54452:28304,54453:32536,54454:36828,54455:33489,54456:24895,54457:24616,54458:38498,54459:26352,54460:32422,54461:36234,54462:36291,54463:38053,54464:23731,54465:31908,54466:26376,54467:24742,54468:38405,54469:32792,54470:20113,54471:37095,54472:21248,54473:38504,54474:20801,54475:36816,54476:34164,54477:37213,54478:26197,54479:38901,54480:23381,54481:21277,54482:30776,54483:26434,54484:26685,54485:21705,54486:28798,54487:23472,54488:36733,54489:20877,54490:22312,54491:21681,54492:25874,54493:26242,54494:36190,54495:36163,54496:33039,54497:33900,54498:36973,54499:31967,54500:20991,54501:34299,54502:26531,54503:26089,54504:28577,54505:34468,54506:36481,54507:22122,54508:36896,54509:30338,54510:28790,54511:29157,54512:36131,54513:25321,54514:21017,54515:27901,54516:36156,54517:24590,54518:22686,54519:24974,54520:26366,54521:36192,54522:25166,54523:21939,54524:28195,54525:26413,54526:36711,54592:35457,54593:35458,54594:35459,54595:35460,54596:35461,54597:35462,54598:35463,54599:35464,54600:35467,54601:35468,54602:35469,54603:35470,54604:35471,54605:35472,54606:35473,54607:35474,54608:35476,54609:35477,54610:35478,54611:35479,54612:35480,54613:35481,54614:35482,54615:35483,54616:35484,54617:35485,54618:35486,54619:35487,54620:35488,54621:35489,54622:35490,54623:35491,54624:35492,54625:35493,54626:35494,54627:35495,54628:35496,54629:35497,54630:35498,54631:35499,54632:35500,54633:35501,54634:35502,54635:35503,54636:35504,54637:35505,54638:35506,54639:35507,54640:35508,54641:35509,54642:35510,54643:35511,54644:35512,54645:35513,54646:35514,54647:35515,54648:35516,54649:35517,54650:35518,54651:35519,54652:35520,54653:35521,54654:35522,54656:35523,54657:35524,54658:35525,54659:35526,54660:35527,54661:35528,54662:35529,54663:35530,54664:35531,54665:35532,54666:35533,54667:35534,54668:35535,54669:35536,54670:35537,54671:35538,54672:35539,54673:35540,54674:35541,54675:35542,54676:35543,54677:35544,54678:35545,54679:35546,54680:35547,54681:35548,54682:35549,54683:35550,54684:35551,54685:35552,54686:35553,54687:35554,54688:35555,54689:38113,54690:38392,54691:30504,54692:26629,54693:27048,54694:21643,54695:20045,54696:28856,54697:35784,54698:25688,54699:25995,54700:23429,54701:31364,54702:20538,54703:23528,54704:30651,54705:27617,54706:35449,54707:31896,54708:27838,54709:30415,54710:26025,54711:36759,54712:23853,54713:23637,54714:34360,54715:26632,54716:21344,54717:25112,54718:31449,54719:28251,54720:32509,54721:27167,54722:31456,54723:24432,54724:28467,54725:24352,54726:25484,54727:28072,54728:26454,54729:19976,54730:24080,54731:36134,54732:20183,54733:32960,54734:30260,54735:38556,54736:25307,54737:26157,54738:25214,54739:27836,54740:36213,54741:29031,54742:32617,54743:20806,54744:32903,54745:21484,54746:36974,54747:25240,54748:21746,54749:34544,54750:36761,54751:32773,54752:38167,54753:34071,54754:36825,54755:27993,54756:29645,54757:26015,54758:30495,54759:29956,54760:30759,54761:33275,54762:36126,54763:38024,54764:20390,54765:26517,54766:30137,54767:35786,54768:38663,54769:25391,54770:38215,54771:38453,54772:33976,54773:25379,54774:30529,54775:24449,54776:29424,54777:20105,54778:24596,54779:25972,54780:25327,54781:27491,54782:25919,54848:35556,54849:35557,54850:35558,54851:35559,54852:35560,54853:35561,54854:35562,54855:35563,54856:35564,54857:35565,54858:35566,54859:35567,54860:35568,54861:35569,54862:35570,54863:35571,54864:35572,54865:35573,54866:35574,54867:35575,54868:35576,54869:35577,54870:35578,54871:35579,54872:35580,54873:35581,54874:35582,54875:35583,54876:35584,54877:35585,54878:35586,54879:35587,54880:35588,54881:35589,54882:35590,54883:35592,54884:35593,54885:35594,54886:35595,54887:35596,54888:35597,54889:35598,54890:35599,54891:35600,54892:35601,54893:35602,54894:35603,54895:35604,54896:35605,54897:35606,54898:35607,54899:35608,54900:35609,54901:35610,54902:35611,54903:35612,54904:35613,54905:35614,54906:35615,54907:35616,54908:35617,54909:35618,54910:35619,54912:35620,54913:35621,54914:35623,54915:35624,54916:35625,54917:35626,54918:35627,54919:35628,54920:35629,54921:35630,54922:35631,54923:35632,54924:35633,54925:35634,54926:35635,54927:35636,54928:35637,54929:35638,54930:35639,54931:35640,54932:35641,54933:35642,54934:35643,54935:35644,54936:35645,54937:35646,54938:35647,54939:35648,54940:35649,54941:35650,54942:35651,54943:35652,54944:35653,54945:24103,54946:30151,54947:37073,54948:35777,54949:33437,54950:26525,54951:25903,54952:21553,54953:34584,54954:30693,54955:32930,54956:33026,54957:27713,54958:20043,54959:32455,54960:32844,54961:30452,54962:26893,54963:27542,54964:25191,54965:20540,54966:20356,54967:22336,54968:25351,54969:27490,54970:36286,54971:21482,54972:26088,54973:32440,54974:24535,54975:25370,54976:25527,54977:33267,54978:33268,54979:32622,54980:24092,54981:23769,54982:21046,54983:26234,54984:31209,54985:31258,54986:36136,54987:28825,54988:30164,54989:28382,54990:27835,54991:31378,54992:20013,54993:30405,54994:24544,54995:38047,54996:34935,54997:32456,54998:31181,54999:32959,55000:37325,55001:20210,55002:20247,55003:33311,55004:21608,55005:24030,55006:27954,55007:35788,55008:31909,55009:36724,55010:32920,55011:24090,55012:21650,55013:30385,55014:23449,55015:26172,55016:39588,55017:29664,55018:26666,55019:34523,55020:26417,55021:29482,55022:35832,55023:35803,55024:36880,55025:31481,55026:28891,55027:29038,55028:25284,55029:30633,55030:22065,55031:20027,55032:33879,55033:26609,55034:21161,55035:34496,55036:36142,55037:38136,55038:31569,55104:35654,55105:35655,55106:35656,55107:35657,55108:35658,55109:35659,55110:35660,55111:35661,55112:35662,55113:35663,55114:35664,55115:35665,55116:35666,55117:35667,55118:35668,55119:35669,55120:35670,55121:35671,55122:35672,55123:35673,55124:35674,55125:35675,55126:35676,55127:35677,55128:35678,55129:35679,55130:35680,55131:35681,55132:35682,55133:35683,55134:35684,55135:35685,55136:35687,55137:35688,55138:35689,55139:35690,55140:35691,55141:35693,55142:35694,55143:35695,55144:35696,55145:35697,55146:35698,55147:35699,55148:35700,55149:35701,55150:35702,55151:35703,55152:35704,55153:35705,55154:35706,55155:35707,55156:35708,55157:35709,55158:35710,55159:35711,55160:35712,55161:35713,55162:35714,55163:35715,55164:35716,55165:35717,55166:35718,55168:35719,55169:35720,55170:35721,55171:35722,55172:35723,55173:35724,55174:35725,55175:35726,55176:35727,55177:35728,55178:35729,55179:35730,55180:35731,55181:35732,55182:35733,55183:35734,55184:35735,55185:35736,55186:35737,55187:35738,55188:35739,55189:35740,55190:35741,55191:35742,55192:35743,55193:35756,55194:35761,55195:35771,55196:35783,55197:35792,55198:35818,55199:35849,55200:35870,55201:20303,55202:27880,55203:31069,55204:39547,55205:25235,55206:29226,55207:25341,55208:19987,55209:30742,55210:36716,55211:25776,55212:36186,55213:31686,55214:26729,55215:24196,55216:35013,55217:22918,55218:25758,55219:22766,55220:29366,55221:26894,55222:38181,55223:36861,55224:36184,55225:22368,55226:32512,55227:35846,55228:20934,55229:25417,55230:25305,55231:21331,55232:26700,55233:29730,55234:33537,55235:37196,55236:21828,55237:30528,55238:28796,55239:27978,55240:20857,55241:21672,55242:36164,55243:23039,55244:28363,55245:28100,55246:23388,55247:32043,55248:20180,55249:31869,55250:28371,55251:23376,55252:33258,55253:28173,55254:23383,55255:39683,55256:26837,55257:36394,55258:23447,55259:32508,55260:24635,55261:32437,55262:37049,55263:36208,55264:22863,55265:25549,55266:31199,55267:36275,55268:21330,55269:26063,55270:31062,55271:35781,55272:38459,55273:32452,55274:38075,55275:32386,55276:22068,55277:37257,55278:26368,55279:32618,55280:23562,55281:36981,55282:26152,55283:24038,55284:20304,55285:26590,55286:20570,55287:20316,55288:22352,55289:24231,55290:59408,55291:59409,55292:59410,55293:59411,55294:59412,55360:35896,55361:35897,55362:35898,55363:35899,55364:35900,55365:35901,55366:35902,55367:35903,55368:35904,55369:35906,55370:35907,55371:35908,55372:35909,55373:35912,55374:35914,55375:35915,55376:35917,55377:35918,55378:35919,55379:35920,55380:35921,55381:35922,55382:35923,55383:35924,55384:35926,55385:35927,55386:35928,55387:35929,55388:35931,55389:35932,55390:35933,55391:35934,55392:35935,55393:35936,55394:35939,55395:35940,55396:35941,55397:35942,55398:35943,55399:35944,55400:35945,55401:35948,55402:35949,55403:35950,55404:35951,55405:35952,55406:35953,55407:35954,55408:35956,55409:35957,55410:35958,55411:35959,55412:35963,55413:35964,55414:35965,55415:35966,55416:35967,55417:35968,55418:35969,55419:35971,55420:35972,55421:35974,55422:35975,55424:35976,55425:35979,55426:35981,55427:35982,55428:35983,55429:35984,55430:35985,55431:35986,55432:35987,55433:35989,55434:35990,55435:35991,55436:35993,55437:35994,55438:35995,55439:35996,55440:35997,55441:35998,55442:35999,55443:36000,55444:36001,55445:36002,55446:36003,55447:36004,55448:36005,55449:36006,55450:36007,55451:36008,55452:36009,55453:36010,55454:36011,55455:36012,55456:36013,55457:20109,55458:19980,55459:20800,55460:19984,55461:24319,55462:21317,55463:19989,55464:20120,55465:19998,55466:39730,55467:23404,55468:22121,55469:20008,55470:31162,55471:20031,55472:21269,55473:20039,55474:22829,55475:29243,55476:21358,55477:27664,55478:22239,55479:32996,55480:39319,55481:27603,55482:30590,55483:40727,55484:20022,55485:20127,55486:40720,55487:20060,55488:20073,55489:20115,55490:33416,55491:23387,55492:21868,55493:22031,55494:20164,55495:21389,55496:21405,55497:21411,55498:21413,55499:21422,55500:38757,55501:36189,55502:21274,55503:21493,55504:21286,55505:21294,55506:21310,55507:36188,55508:21350,55509:21347,55510:20994,55511:21000,55512:21006,55513:21037,55514:21043,55515:21055,55516:21056,55517:21068,55518:21086,55519:21089,55520:21084,55521:33967,55522:21117,55523:21122,55524:21121,55525:21136,55526:21139,55527:20866,55528:32596,55529:20155,55530:20163,55531:20169,55532:20162,55533:20200,55534:20193,55535:20203,55536:20190,55537:20251,55538:20211,55539:20258,55540:20324,55541:20213,55542:20261,55543:20263,55544:20233,55545:20267,55546:20318,55547:20327,55548:25912,55549:20314,55550:20317,55616:36014,55617:36015,55618:36016,55619:36017,55620:36018,55621:36019,55622:36020,55623:36021,55624:36022,55625:36023,55626:36024,55627:36025,55628:36026,55629:36027,55630:36028,55631:36029,55632:36030,55633:36031,55634:36032,55635:36033,55636:36034,55637:36035,55638:36036,55639:36037,55640:36038,55641:36039,55642:36040,55643:36041,55644:36042,55645:36043,55646:36044,55647:36045,55648:36046,55649:36047,55650:36048,55651:36049,55652:36050,55653:36051,55654:36052,55655:36053,55656:36054,55657:36055,55658:36056,55659:36057,55660:36058,55661:36059,55662:36060,55663:36061,55664:36062,55665:36063,55666:36064,55667:36065,55668:36066,55669:36067,55670:36068,55671:36069,55672:36070,55673:36071,55674:36072,55675:36073,55676:36074,55677:36075,55678:36076,55680:36077,55681:36078,55682:36079,55683:36080,55684:36081,55685:36082,55686:36083,55687:36084,55688:36085,55689:36086,55690:36087,55691:36088,55692:36089,55693:36090,55694:36091,55695:36092,55696:36093,55697:36094,55698:36095,55699:36096,55700:36097,55701:36098,55702:36099,55703:36100,55704:36101,55705:36102,55706:36103,55707:36104,55708:36105,55709:36106,55710:36107,55711:36108,55712:36109,55713:20319,55714:20311,55715:20274,55716:20285,55717:20342,55718:20340,55719:20369,55720:20361,55721:20355,55722:20367,55723:20350,55724:20347,55725:20394,55726:20348,55727:20396,55728:20372,55729:20454,55730:20456,55731:20458,55732:20421,55733:20442,55734:20451,55735:20444,55736:20433,55737:20447,55738:20472,55739:20521,55740:20556,55741:20467,55742:20524,55743:20495,55744:20526,55745:20525,55746:20478,55747:20508,55748:20492,55749:20517,55750:20520,55751:20606,55752:20547,55753:20565,55754:20552,55755:20558,55756:20588,55757:20603,55758:20645,55759:20647,55760:20649,55761:20666,55762:20694,55763:20742,55764:20717,55765:20716,55766:20710,55767:20718,55768:20743,55769:20747,55770:20189,55771:27709,55772:20312,55773:20325,55774:20430,55775:40864,55776:27718,55777:31860,55778:20846,55779:24061,55780:40649,55781:39320,55782:20865,55783:22804,55784:21241,55785:21261,55786:35335,55787:21264,55788:20971,55789:22809,55790:20821,55791:20128,55792:20822,55793:20147,55794:34926,55795:34980,55796:20149,55797:33044,55798:35026,55799:31104,55800:23348,55801:34819,55802:32696,55803:20907,55804:20913,55805:20925,55806:20924,55872:36110,55873:36111,55874:36112,55875:36113,55876:36114,55877:36115,55878:36116,55879:36117,55880:36118,55881:36119,55882:36120,55883:36121,55884:36122,55885:36123,55886:36124,55887:36128,55888:36177,55889:36178,55890:36183,55891:36191,55892:36197,55893:36200,55894:36201,55895:36202,55896:36204,55897:36206,55898:36207,55899:36209,55900:36210,55901:36216,55902:36217,55903:36218,55904:36219,55905:36220,55906:36221,55907:36222,55908:36223,55909:36224,55910:36226,55911:36227,55912:36230,55913:36231,55914:36232,55915:36233,55916:36236,55917:36237,55918:36238,55919:36239,55920:36240,55921:36242,55922:36243,55923:36245,55924:36246,55925:36247,55926:36248,55927:36249,55928:36250,55929:36251,55930:36252,55931:36253,55932:36254,55933:36256,55934:36257,55936:36258,55937:36260,55938:36261,55939:36262,55940:36263,55941:36264,55942:36265,55943:36266,55944:36267,55945:36268,55946:36269,55947:36270,55948:36271,55949:36272,55950:36274,55951:36278,55952:36279,55953:36281,55954:36283,55955:36285,55956:36288,55957:36289,55958:36290,55959:36293,55960:36295,55961:36296,55962:36297,55963:36298,55964:36301,55965:36304,55966:36306,55967:36307,55968:36308,55969:20935,55970:20886,55971:20898,55972:20901,55973:35744,55974:35750,55975:35751,55976:35754,55977:35764,55978:35765,55979:35767,55980:35778,55981:35779,55982:35787,55983:35791,55984:35790,55985:35794,55986:35795,55987:35796,55988:35798,55989:35800,55990:35801,55991:35804,55992:35807,55993:35808,55994:35812,55995:35816,55996:35817,55997:35822,55998:35824,55999:35827,56000:35830,56001:35833,56002:35836,56003:35839,56004:35840,56005:35842,56006:35844,56007:35847,56008:35852,56009:35855,56010:35857,56011:35858,56012:35860,56013:35861,56014:35862,56015:35865,56016:35867,56017:35864,56018:35869,56019:35871,56020:35872,56021:35873,56022:35877,56023:35879,56024:35882,56025:35883,56026:35886,56027:35887,56028:35890,56029:35891,56030:35893,56031:35894,56032:21353,56033:21370,56034:38429,56035:38434,56036:38433,56037:38449,56038:38442,56039:38461,56040:38460,56041:38466,56042:38473,56043:38484,56044:38495,56045:38503,56046:38508,56047:38514,56048:38516,56049:38536,56050:38541,56051:38551,56052:38576,56053:37015,56054:37019,56055:37021,56056:37017,56057:37036,56058:37025,56059:37044,56060:37043,56061:37046,56062:37050,56128:36309,56129:36312,56130:36313,56131:36316,56132:36320,56133:36321,56134:36322,56135:36325,56136:36326,56137:36327,56138:36329,56139:36333,56140:36334,56141:36336,56142:36337,56143:36338,56144:36340,56145:36342,56146:36348,56147:36350,56148:36351,56149:36352,56150:36353,56151:36354,56152:36355,56153:36356,56154:36358,56155:36359,56156:36360,56157:36363,56158:36365,56159:36366,56160:36368,56161:36369,56162:36370,56163:36371,56164:36373,56165:36374,56166:36375,56167:36376,56168:36377,56169:36378,56170:36379,56171:36380,56172:36384,56173:36385,56174:36388,56175:36389,56176:36390,56177:36391,56178:36392,56179:36395,56180:36397,56181:36400,56182:36402,56183:36403,56184:36404,56185:36406,56186:36407,56187:36408,56188:36411,56189:36412,56190:36414,56192:36415,56193:36419,56194:36421,56195:36422,56196:36428,56197:36429,56198:36430,56199:36431,56200:36432,56201:36435,56202:36436,56203:36437,56204:36438,56205:36439,56206:36440,56207:36442,56208:36443,56209:36444,56210:36445,56211:36446,56212:36447,56213:36448,56214:36449,56215:36450,56216:36451,56217:36452,56218:36453,56219:36455,56220:36456,56221:36458,56222:36459,56223:36462,56224:36465,56225:37048,56226:37040,56227:37071,56228:37061,56229:37054,56230:37072,56231:37060,56232:37063,56233:37075,56234:37094,56235:37090,56236:37084,56237:37079,56238:37083,56239:37099,56240:37103,56241:37118,56242:37124,56243:37154,56244:37150,56245:37155,56246:37169,56247:37167,56248:37177,56249:37187,56250:37190,56251:21005,56252:22850,56253:21154,56254:21164,56255:21165,56256:21182,56257:21759,56258:21200,56259:21206,56260:21232,56261:21471,56262:29166,56263:30669,56264:24308,56265:20981,56266:20988,56267:39727,56268:21430,56269:24321,56270:30042,56271:24047,56272:22348,56273:22441,56274:22433,56275:22654,56276:22716,56277:22725,56278:22737,56279:22313,56280:22316,56281:22314,56282:22323,56283:22329,56284:22318,56285:22319,56286:22364,56287:22331,56288:22338,56289:22377,56290:22405,56291:22379,56292:22406,56293:22396,56294:22395,56295:22376,56296:22381,56297:22390,56298:22387,56299:22445,56300:22436,56301:22412,56302:22450,56303:22479,56304:22439,56305:22452,56306:22419,56307:22432,56308:22485,56309:22488,56310:22490,56311:22489,56312:22482,56313:22456,56314:22516,56315:22511,56316:22520,56317:22500,56318:22493,56384:36467,56385:36469,56386:36471,56387:36472,56388:36473,56389:36474,56390:36475,56391:36477,56392:36478,56393:36480,56394:36482,56395:36483,56396:36484,56397:36486,56398:36488,56399:36489,56400:36490,56401:36491,56402:36492,56403:36493,56404:36494,56405:36497,56406:36498,56407:36499,56408:36501,56409:36502,56410:36503,56411:36504,56412:36505,56413:36506,56414:36507,56415:36509,56416:36511,56417:36512,56418:36513,56419:36514,56420:36515,56421:36516,56422:36517,56423:36518,56424:36519,56425:36520,56426:36521,56427:36522,56428:36525,56429:36526,56430:36528,56431:36529,56432:36531,56433:36532,56434:36533,56435:36534,56436:36535,56437:36536,56438:36537,56439:36539,56440:36540,56441:36541,56442:36542,56443:36543,56444:36544,56445:36545,56446:36546,56448:36547,56449:36548,56450:36549,56451:36550,56452:36551,56453:36552,56454:36553,56455:36554,56456:36555,56457:36556,56458:36557,56459:36559,56460:36560,56461:36561,56462:36562,56463:36563,56464:36564,56465:36565,56466:36566,56467:36567,56468:36568,56469:36569,56470:36570,56471:36571,56472:36572,56473:36573,56474:36574,56475:36575,56476:36576,56477:36577,56478:36578,56479:36579,56480:36580,56481:22539,56482:22541,56483:22525,56484:22509,56485:22528,56486:22558,56487:22553,56488:22596,56489:22560,56490:22629,56491:22636,56492:22657,56493:22665,56494:22682,56495:22656,56496:39336,56497:40729,56498:25087,56499:33401,56500:33405,56501:33407,56502:33423,56503:33418,56504:33448,56505:33412,56506:33422,56507:33425,56508:33431,56509:33433,56510:33451,56511:33464,56512:33470,56513:33456,56514:33480,56515:33482,56516:33507,56517:33432,56518:33463,56519:33454,56520:33483,56521:33484,56522:33473,56523:33449,56524:33460,56525:33441,56526:33450,56527:33439,56528:33476,56529:33486,56530:33444,56531:33505,56532:33545,56533:33527,56534:33508,56535:33551,56536:33543,56537:33500,56538:33524,56539:33490,56540:33496,56541:33548,56542:33531,56543:33491,56544:33553,56545:33562,56546:33542,56547:33556,56548:33557,56549:33504,56550:33493,56551:33564,56552:33617,56553:33627,56554:33628,56555:33544,56556:33682,56557:33596,56558:33588,56559:33585,56560:33691,56561:33630,56562:33583,56563:33615,56564:33607,56565:33603,56566:33631,56567:33600,56568:33559,56569:33632,56570:33581,56571:33594,56572:33587,56573:33638,56574:33637,56640:36581,56641:36582,56642:36583,56643:36584,56644:36585,56645:36586,56646:36587,56647:36588,56648:36589,56649:36590,56650:36591,56651:36592,56652:36593,56653:36594,56654:36595,56655:36596,56656:36597,56657:36598,56658:36599,56659:36600,56660:36601,56661:36602,56662:36603,56663:36604,56664:36605,56665:36606,56666:36607,56667:36608,56668:36609,56669:36610,56670:36611,56671:36612,56672:36613,56673:36614,56674:36615,56675:36616,56676:36617,56677:36618,56678:36619,56679:36620,56680:36621,56681:36622,56682:36623,56683:36624,56684:36625,56685:36626,56686:36627,56687:36628,56688:36629,56689:36630,56690:36631,56691:36632,56692:36633,56693:36634,56694:36635,56695:36636,56696:36637,56697:36638,56698:36639,56699:36640,56700:36641,56701:36642,56702:36643,56704:36644,56705:36645,56706:36646,56707:36647,56708:36648,56709:36649,56710:36650,56711:36651,56712:36652,56713:36653,56714:36654,56715:36655,56716:36656,56717:36657,56718:36658,56719:36659,56720:36660,56721:36661,56722:36662,56723:36663,56724:36664,56725:36665,56726:36666,56727:36667,56728:36668,56729:36669,56730:36670,56731:36671,56732:36672,56733:36673,56734:36674,56735:36675,56736:36676,56737:33640,56738:33563,56739:33641,56740:33644,56741:33642,56742:33645,56743:33646,56744:33712,56745:33656,56746:33715,56747:33716,56748:33696,56749:33706,56750:33683,56751:33692,56752:33669,56753:33660,56754:33718,56755:33705,56756:33661,56757:33720,56758:33659,56759:33688,56760:33694,56761:33704,56762:33722,56763:33724,56764:33729,56765:33793,56766:33765,56767:33752,56768:22535,56769:33816,56770:33803,56771:33757,56772:33789,56773:33750,56774:33820,56775:33848,56776:33809,56777:33798,56778:33748,56779:33759,56780:33807,56781:33795,56782:33784,56783:33785,56784:33770,56785:33733,56786:33728,56787:33830,56788:33776,56789:33761,56790:33884,56791:33873,56792:33882,56793:33881,56794:33907,56795:33927,56796:33928,56797:33914,56798:33929,56799:33912,56800:33852,56801:33862,56802:33897,56803:33910,56804:33932,56805:33934,56806:33841,56807:33901,56808:33985,56809:33997,56810:34000,56811:34022,56812:33981,56813:34003,56814:33994,56815:33983,56816:33978,56817:34016,56818:33953,56819:33977,56820:33972,56821:33943,56822:34021,56823:34019,56824:34060,56825:29965,56826:34104,56827:34032,56828:34105,56829:34079,56830:34106,56896:36677,56897:36678,56898:36679,56899:36680,56900:36681,56901:36682,56902:36683,56903:36684,56904:36685,56905:36686,56906:36687,56907:36688,56908:36689,56909:36690,56910:36691,56911:36692,56912:36693,56913:36694,56914:36695,56915:36696,56916:36697,56917:36698,56918:36699,56919:36700,56920:36701,56921:36702,56922:36703,56923:36704,56924:36705,56925:36706,56926:36707,56927:36708,56928:36709,56929:36714,56930:36736,56931:36748,56932:36754,56933:36765,56934:36768,56935:36769,56936:36770,56937:36772,56938:36773,56939:36774,56940:36775,56941:36778,56942:36780,56943:36781,56944:36782,56945:36783,56946:36786,56947:36787,56948:36788,56949:36789,56950:36791,56951:36792,56952:36794,56953:36795,56954:36796,56955:36799,56956:36800,56957:36803,56958:36806,56960:36809,56961:36810,56962:36811,56963:36812,56964:36813,56965:36815,56966:36818,56967:36822,56968:36823,56969:36826,56970:36832,56971:36833,56972:36835,56973:36839,56974:36844,56975:36847,56976:36849,56977:36850,56978:36852,56979:36853,56980:36854,56981:36858,56982:36859,56983:36860,56984:36862,56985:36863,56986:36871,56987:36872,56988:36876,56989:36878,56990:36883,56991:36885,56992:36888,56993:34134,56994:34107,56995:34047,56996:34044,56997:34137,56998:34120,56999:34152,57000:34148,57001:34142,57002:34170,57003:30626,57004:34115,57005:34162,57006:34171,57007:34212,57008:34216,57009:34183,57010:34191,57011:34169,57012:34222,57013:34204,57014:34181,57015:34233,57016:34231,57017:34224,57018:34259,57019:34241,57020:34268,57021:34303,57022:34343,57023:34309,57024:34345,57025:34326,57026:34364,57027:24318,57028:24328,57029:22844,57030:22849,57031:32823,57032:22869,57033:22874,57034:22872,57035:21263,57036:23586,57037:23589,57038:23596,57039:23604,57040:25164,57041:25194,57042:25247,57043:25275,57044:25290,57045:25306,57046:25303,57047:25326,57048:25378,57049:25334,57050:25401,57051:25419,57052:25411,57053:25517,57054:25590,57055:25457,57056:25466,57057:25486,57058:25524,57059:25453,57060:25516,57061:25482,57062:25449,57063:25518,57064:25532,57065:25586,57066:25592,57067:25568,57068:25599,57069:25540,57070:25566,57071:25550,57072:25682,57073:25542,57074:25534,57075:25669,57076:25665,57077:25611,57078:25627,57079:25632,57080:25612,57081:25638,57082:25633,57083:25694,57084:25732,57085:25709,57086:25750,57152:36889,57153:36892,57154:36899,57155:36900,57156:36901,57157:36903,57158:36904,57159:36905,57160:36906,57161:36907,57162:36908,57163:36912,57164:36913,57165:36914,57166:36915,57167:36916,57168:36919,57169:36921,57170:36922,57171:36925,57172:36927,57173:36928,57174:36931,57175:36933,57176:36934,57177:36936,57178:36937,57179:36938,57180:36939,57181:36940,57182:36942,57183:36948,57184:36949,57185:36950,57186:36953,57187:36954,57188:36956,57189:36957,57190:36958,57191:36959,57192:36960,57193:36961,57194:36964,57195:36966,57196:36967,57197:36969,57198:36970,57199:36971,57200:36972,57201:36975,57202:36976,57203:36977,57204:36978,57205:36979,57206:36982,57207:36983,57208:36984,57209:36985,57210:36986,57211:36987,57212:36988,57213:36990,57214:36993,57216:36996,57217:36997,57218:36998,57219:36999,57220:37001,57221:37002,57222:37004,57223:37005,57224:37006,57225:37007,57226:37008,57227:37010,57228:37012,57229:37014,57230:37016,57231:37018,57232:37020,57233:37022,57234:37023,57235:37024,57236:37028,57237:37029,57238:37031,57239:37032,57240:37033,57241:37035,57242:37037,57243:37042,57244:37047,57245:37052,57246:37053,57247:37055,57248:37056,57249:25722,57250:25783,57251:25784,57252:25753,57253:25786,57254:25792,57255:25808,57256:25815,57257:25828,57258:25826,57259:25865,57260:25893,57261:25902,57262:24331,57263:24530,57264:29977,57265:24337,57266:21343,57267:21489,57268:21501,57269:21481,57270:21480,57271:21499,57272:21522,57273:21526,57274:21510,57275:21579,57276:21586,57277:21587,57278:21588,57279:21590,57280:21571,57281:21537,57282:21591,57283:21593,57284:21539,57285:21554,57286:21634,57287:21652,57288:21623,57289:21617,57290:21604,57291:21658,57292:21659,57293:21636,57294:21622,57295:21606,57296:21661,57297:21712,57298:21677,57299:21698,57300:21684,57301:21714,57302:21671,57303:21670,57304:21715,57305:21716,57306:21618,57307:21667,57308:21717,57309:21691,57310:21695,57311:21708,57312:21721,57313:21722,57314:21724,57315:21673,57316:21674,57317:21668,57318:21725,57319:21711,57320:21726,57321:21787,57322:21735,57323:21792,57324:21757,57325:21780,57326:21747,57327:21794,57328:21795,57329:21775,57330:21777,57331:21799,57332:21802,57333:21863,57334:21903,57335:21941,57336:21833,57337:21869,57338:21825,57339:21845,57340:21823,57341:21840,57342:21820,57408:37058,57409:37059,57410:37062,57411:37064,57412:37065,57413:37067,57414:37068,57415:37069,57416:37074,57417:37076,57418:37077,57419:37078,57420:37080,57421:37081,57422:37082,57423:37086,57424:37087,57425:37088,57426:37091,57427:37092,57428:37093,57429:37097,57430:37098,57431:37100,57432:37102,57433:37104,57434:37105,57435:37106,57436:37107,57437:37109,57438:37110,57439:37111,57440:37113,57441:37114,57442:37115,57443:37116,57444:37119,57445:37120,57446:37121,57447:37123,57448:37125,57449:37126,57450:37127,57451:37128,57452:37129,57453:37130,57454:37131,57455:37132,57456:37133,57457:37134,57458:37135,57459:37136,57460:37137,57461:37138,57462:37139,57463:37140,57464:37141,57465:37142,57466:37143,57467:37144,57468:37146,57469:37147,57470:37148,57472:37149,57473:37151,57474:37152,57475:37153,57476:37156,57477:37157,57478:37158,57479:37159,57480:37160,57481:37161,57482:37162,57483:37163,57484:37164,57485:37165,57486:37166,57487:37168,57488:37170,57489:37171,57490:37172,57491:37173,57492:37174,57493:37175,57494:37176,57495:37178,57496:37179,57497:37180,57498:37181,57499:37182,57500:37183,57501:37184,57502:37185,57503:37186,57504:37188,57505:21815,57506:21846,57507:21877,57508:21878,57509:21879,57510:21811,57511:21808,57512:21852,57513:21899,57514:21970,57515:21891,57516:21937,57517:21945,57518:21896,57519:21889,57520:21919,57521:21886,57522:21974,57523:21905,57524:21883,57525:21983,57526:21949,57527:21950,57528:21908,57529:21913,57530:21994,57531:22007,57532:21961,57533:22047,57534:21969,57535:21995,57536:21996,57537:21972,57538:21990,57539:21981,57540:21956,57541:21999,57542:21989,57543:22002,57544:22003,57545:21964,57546:21965,57547:21992,57548:22005,57549:21988,57550:36756,57551:22046,57552:22024,57553:22028,57554:22017,57555:22052,57556:22051,57557:22014,57558:22016,57559:22055,57560:22061,57561:22104,57562:22073,57563:22103,57564:22060,57565:22093,57566:22114,57567:22105,57568:22108,57569:22092,57570:22100,57571:22150,57572:22116,57573:22129,57574:22123,57575:22139,57576:22140,57577:22149,57578:22163,57579:22191,57580:22228,57581:22231,57582:22237,57583:22241,57584:22261,57585:22251,57586:22265,57587:22271,57588:22276,57589:22282,57590:22281,57591:22300,57592:24079,57593:24089,57594:24084,57595:24081,57596:24113,57597:24123,57598:24124,57664:37189,57665:37191,57666:37192,57667:37201,57668:37203,57669:37204,57670:37205,57671:37206,57672:37208,57673:37209,57674:37211,57675:37212,57676:37215,57677:37216,57678:37222,57679:37223,57680:37224,57681:37227,57682:37229,57683:37235,57684:37242,57685:37243,57686:37244,57687:37248,57688:37249,57689:37250,57690:37251,57691:37252,57692:37254,57693:37256,57694:37258,57695:37262,57696:37263,57697:37267,57698:37268,57699:37269,57700:37270,57701:37271,57702:37272,57703:37273,57704:37276,57705:37277,57706:37278,57707:37279,57708:37280,57709:37281,57710:37284,57711:37285,57712:37286,57713:37287,57714:37288,57715:37289,57716:37291,57717:37292,57718:37296,57719:37297,57720:37298,57721:37299,57722:37302,57723:37303,57724:37304,57725:37305,57726:37307,57728:37308,57729:37309,57730:37310,57731:37311,57732:37312,57733:37313,57734:37314,57735:37315,57736:37316,57737:37317,57738:37318,57739:37320,57740:37323,57741:37328,57742:37330,57743:37331,57744:37332,57745:37333,57746:37334,57747:37335,57748:37336,57749:37337,57750:37338,57751:37339,57752:37341,57753:37342,57754:37343,57755:37344,57756:37345,57757:37346,57758:37347,57759:37348,57760:37349,57761:24119,57762:24132,57763:24148,57764:24155,57765:24158,57766:24161,57767:23692,57768:23674,57769:23693,57770:23696,57771:23702,57772:23688,57773:23704,57774:23705,57775:23697,57776:23706,57777:23708,57778:23733,57779:23714,57780:23741,57781:23724,57782:23723,57783:23729,57784:23715,57785:23745,57786:23735,57787:23748,57788:23762,57789:23780,57790:23755,57791:23781,57792:23810,57793:23811,57794:23847,57795:23846,57796:23854,57797:23844,57798:23838,57799:23814,57800:23835,57801:23896,57802:23870,57803:23860,57804:23869,57805:23916,57806:23899,57807:23919,57808:23901,57809:23915,57810:23883,57811:23882,57812:23913,57813:23924,57814:23938,57815:23961,57816:23965,57817:35955,57818:23991,57819:24005,57820:24435,57821:24439,57822:24450,57823:24455,57824:24457,57825:24460,57826:24469,57827:24473,57828:24476,57829:24488,57830:24493,57831:24501,57832:24508,57833:34914,57834:24417,57835:29357,57836:29360,57837:29364,57838:29367,57839:29368,57840:29379,57841:29377,57842:29390,57843:29389,57844:29394,57845:29416,57846:29423,57847:29417,57848:29426,57849:29428,57850:29431,57851:29441,57852:29427,57853:29443,57854:29434,57920:37350,57921:37351,57922:37352,57923:37353,57924:37354,57925:37355,57926:37356,57927:37357,57928:37358,57929:37359,57930:37360,57931:37361,57932:37362,57933:37363,57934:37364,57935:37365,57936:37366,57937:37367,57938:37368,57939:37369,57940:37370,57941:37371,57942:37372,57943:37373,57944:37374,57945:37375,57946:37376,57947:37377,57948:37378,57949:37379,57950:37380,57951:37381,57952:37382,57953:37383,57954:37384,57955:37385,57956:37386,57957:37387,57958:37388,57959:37389,57960:37390,57961:37391,57962:37392,57963:37393,57964:37394,57965:37395,57966:37396,57967:37397,57968:37398,57969:37399,57970:37400,57971:37401,57972:37402,57973:37403,57974:37404,57975:37405,57976:37406,57977:37407,57978:37408,57979:37409,57980:37410,57981:37411,57982:37412,57984:37413,57985:37414,57986:37415,57987:37416,57988:37417,57989:37418,57990:37419,57991:37420,57992:37421,57993:37422,57994:37423,57995:37424,57996:37425,57997:37426,57998:37427,57999:37428,58000:37429,58001:37430,58002:37431,58003:37432,58004:37433,58005:37434,58006:37435,58007:37436,58008:37437,58009:37438,58010:37439,58011:37440,58012:37441,58013:37442,58014:37443,58015:37444,58016:37445,58017:29435,58018:29463,58019:29459,58020:29473,58021:29450,58022:29470,58023:29469,58024:29461,58025:29474,58026:29497,58027:29477,58028:29484,58029:29496,58030:29489,58031:29520,58032:29517,58033:29527,58034:29536,58035:29548,58036:29551,58037:29566,58038:33307,58039:22821,58040:39143,58041:22820,58042:22786,58043:39267,58044:39271,58045:39272,58046:39273,58047:39274,58048:39275,58049:39276,58050:39284,58051:39287,58052:39293,58053:39296,58054:39300,58055:39303,58056:39306,58057:39309,58058:39312,58059:39313,58060:39315,58061:39316,58062:39317,58063:24192,58064:24209,58065:24203,58066:24214,58067:24229,58068:24224,58069:24249,58070:24245,58071:24254,58072:24243,58073:36179,58074:24274,58075:24273,58076:24283,58077:24296,58078:24298,58079:33210,58080:24516,58081:24521,58082:24534,58083:24527,58084:24579,58085:24558,58086:24580,58087:24545,58088:24548,58089:24574,58090:24581,58091:24582,58092:24554,58093:24557,58094:24568,58095:24601,58096:24629,58097:24614,58098:24603,58099:24591,58100:24589,58101:24617,58102:24619,58103:24586,58104:24639,58105:24609,58106:24696,58107:24697,58108:24699,58109:24698,58110:24642,58176:37446,58177:37447,58178:37448,58179:37449,58180:37450,58181:37451,58182:37452,58183:37453,58184:37454,58185:37455,58186:37456,58187:37457,58188:37458,58189:37459,58190:37460,58191:37461,58192:37462,58193:37463,58194:37464,58195:37465,58196:37466,58197:37467,58198:37468,58199:37469,58200:37470,58201:37471,58202:37472,58203:37473,58204:37474,58205:37475,58206:37476,58207:37477,58208:37478,58209:37479,58210:37480,58211:37481,58212:37482,58213:37483,58214:37484,58215:37485,58216:37486,58217:37487,58218:37488,58219:37489,58220:37490,58221:37491,58222:37493,58223:37494,58224:37495,58225:37496,58226:37497,58227:37498,58228:37499,58229:37500,58230:37501,58231:37502,58232:37503,58233:37504,58234:37505,58235:37506,58236:37507,58237:37508,58238:37509,58240:37510,58241:37511,58242:37512,58243:37513,58244:37514,58245:37515,58246:37516,58247:37517,58248:37519,58249:37520,58250:37521,58251:37522,58252:37523,58253:37524,58254:37525,58255:37526,58256:37527,58257:37528,58258:37529,58259:37530,58260:37531,58261:37532,58262:37533,58263:37534,58264:37535,58265:37536,58266:37537,58267:37538,58268:37539,58269:37540,58270:37541,58271:37542,58272:37543,58273:24682,58274:24701,58275:24726,58276:24730,58277:24749,58278:24733,58279:24707,58280:24722,58281:24716,58282:24731,58283:24812,58284:24763,58285:24753,58286:24797,58287:24792,58288:24774,58289:24794,58290:24756,58291:24864,58292:24870,58293:24853,58294:24867,58295:24820,58296:24832,58297:24846,58298:24875,58299:24906,58300:24949,58301:25004,58302:24980,58303:24999,58304:25015,58305:25044,58306:25077,58307:24541,58308:38579,58309:38377,58310:38379,58311:38385,58312:38387,58313:38389,58314:38390,58315:38396,58316:38398,58317:38403,58318:38404,58319:38406,58320:38408,58321:38410,58322:38411,58323:38412,58324:38413,58325:38415,58326:38418,58327:38421,58328:38422,58329:38423,58330:38425,58331:38426,58332:20012,58333:29247,58334:25109,58335:27701,58336:27732,58337:27740,58338:27722,58339:27811,58340:27781,58341:27792,58342:27796,58343:27788,58344:27752,58345:27753,58346:27764,58347:27766,58348:27782,58349:27817,58350:27856,58351:27860,58352:27821,58353:27895,58354:27896,58355:27889,58356:27863,58357:27826,58358:27872,58359:27862,58360:27898,58361:27883,58362:27886,58363:27825,58364:27859,58365:27887,58366:27902,58432:37544,58433:37545,58434:37546,58435:37547,58436:37548,58437:37549,58438:37551,58439:37552,58440:37553,58441:37554,58442:37555,58443:37556,58444:37557,58445:37558,58446:37559,58447:37560,58448:37561,58449:37562,58450:37563,58451:37564,58452:37565,58453:37566,58454:37567,58455:37568,58456:37569,58457:37570,58458:37571,58459:37572,58460:37573,58461:37574,58462:37575,58463:37577,58464:37578,58465:37579,58466:37580,58467:37581,58468:37582,58469:37583,58470:37584,58471:37585,58472:37586,58473:37587,58474:37588,58475:37589,58476:37590,58477:37591,58478:37592,58479:37593,58480:37594,58481:37595,58482:37596,58483:37597,58484:37598,58485:37599,58486:37600,58487:37601,58488:37602,58489:37603,58490:37604,58491:37605,58492:37606,58493:37607,58494:37608,58496:37609,58497:37610,58498:37611,58499:37612,58500:37613,58501:37614,58502:37615,58503:37616,58504:37617,58505:37618,58506:37619,58507:37620,58508:37621,58509:37622,58510:37623,58511:37624,58512:37625,58513:37626,58514:37627,58515:37628,58516:37629,58517:37630,58518:37631,58519:37632,58520:37633,58521:37634,58522:37635,58523:37636,58524:37637,58525:37638,58526:37639,58527:37640,58528:37641,58529:27961,58530:27943,58531:27916,58532:27971,58533:27976,58534:27911,58535:27908,58536:27929,58537:27918,58538:27947,58539:27981,58540:27950,58541:27957,58542:27930,58543:27983,58544:27986,58545:27988,58546:27955,58547:28049,58548:28015,58549:28062,58550:28064,58551:27998,58552:28051,58553:28052,58554:27996,58555:28000,58556:28028,58557:28003,58558:28186,58559:28103,58560:28101,58561:28126,58562:28174,58563:28095,58564:28128,58565:28177,58566:28134,58567:28125,58568:28121,58569:28182,58570:28075,58571:28172,58572:28078,58573:28203,58574:28270,58575:28238,58576:28267,58577:28338,58578:28255,58579:28294,58580:28243,58581:28244,58582:28210,58583:28197,58584:28228,58585:28383,58586:28337,58587:28312,58588:28384,58589:28461,58590:28386,58591:28325,58592:28327,58593:28349,58594:28347,58595:28343,58596:28375,58597:28340,58598:28367,58599:28303,58600:28354,58601:28319,58602:28514,58603:28486,58604:28487,58605:28452,58606:28437,58607:28409,58608:28463,58609:28470,58610:28491,58611:28532,58612:28458,58613:28425,58614:28457,58615:28553,58616:28557,58617:28556,58618:28536,58619:28530,58620:28540,58621:28538,58622:28625,58688:37642,58689:37643,58690:37644,58691:37645,58692:37646,58693:37647,58694:37648,58695:37649,58696:37650,58697:37651,58698:37652,58699:37653,58700:37654,58701:37655,58702:37656,58703:37657,58704:37658,58705:37659,58706:37660,58707:37661,58708:37662,58709:37663,58710:37664,58711:37665,58712:37666,58713:37667,58714:37668,58715:37669,58716:37670,58717:37671,58718:37672,58719:37673,58720:37674,58721:37675,58722:37676,58723:37677,58724:37678,58725:37679,58726:37680,58727:37681,58728:37682,58729:37683,58730:37684,58731:37685,58732:37686,58733:37687,58734:37688,58735:37689,58736:37690,58737:37691,58738:37692,58739:37693,58740:37695,58741:37696,58742:37697,58743:37698,58744:37699,58745:37700,58746:37701,58747:37702,58748:37703,58749:37704,58750:37705,58752:37706,58753:37707,58754:37708,58755:37709,58756:37710,58757:37711,58758:37712,58759:37713,58760:37714,58761:37715,58762:37716,58763:37717,58764:37718,58765:37719,58766:37720,58767:37721,58768:37722,58769:37723,58770:37724,58771:37725,58772:37726,58773:37727,58774:37728,58775:37729,58776:37730,58777:37731,58778:37732,58779:37733,58780:37734,58781:37735,58782:37736,58783:37737,58784:37739,58785:28617,58786:28583,58787:28601,58788:28598,58789:28610,58790:28641,58791:28654,58792:28638,58793:28640,58794:28655,58795:28698,58796:28707,58797:28699,58798:28729,58799:28725,58800:28751,58801:28766,58802:23424,58803:23428,58804:23445,58805:23443,58806:23461,58807:23480,58808:29999,58809:39582,58810:25652,58811:23524,58812:23534,58813:35120,58814:23536,58815:36423,58816:35591,58817:36790,58818:36819,58819:36821,58820:36837,58821:36846,58822:36836,58823:36841,58824:36838,58825:36851,58826:36840,58827:36869,58828:36868,58829:36875,58830:36902,58831:36881,58832:36877,58833:36886,58834:36897,58835:36917,58836:36918,58837:36909,58838:36911,58839:36932,58840:36945,58841:36946,58842:36944,58843:36968,58844:36952,58845:36962,58846:36955,58847:26297,58848:36980,58849:36989,58850:36994,58851:37000,58852:36995,58853:37003,58854:24400,58855:24407,58856:24406,58857:24408,58858:23611,58859:21675,58860:23632,58861:23641,58862:23409,58863:23651,58864:23654,58865:32700,58866:24362,58867:24361,58868:24365,58869:33396,58870:24380,58871:39739,58872:23662,58873:22913,58874:22915,58875:22925,58876:22953,58877:22954,58878:22947,58944:37740,58945:37741,58946:37742,58947:37743,58948:37744,58949:37745,58950:37746,58951:37747,58952:37748,58953:37749,58954:37750,58955:37751,58956:37752,58957:37753,58958:37754,58959:37755,58960:37756,58961:37757,58962:37758,58963:37759,58964:37760,58965:37761,58966:37762,58967:37763,58968:37764,58969:37765,58970:37766,58971:37767,58972:37768,58973:37769,58974:37770,58975:37771,58976:37772,58977:37773,58978:37774,58979:37776,58980:37777,58981:37778,58982:37779,58983:37780,58984:37781,58985:37782,58986:37783,58987:37784,58988:37785,58989:37786,58990:37787,58991:37788,58992:37789,58993:37790,58994:37791,58995:37792,58996:37793,58997:37794,58998:37795,58999:37796,59000:37797,59001:37798,59002:37799,59003:37800,59004:37801,59005:37802,59006:37803,59008:37804,59009:37805,59010:37806,59011:37807,59012:37808,59013:37809,59014:37810,59015:37811,59016:37812,59017:37813,59018:37814,59019:37815,59020:37816,59021:37817,59022:37818,59023:37819,59024:37820,59025:37821,59026:37822,59027:37823,59028:37824,59029:37825,59030:37826,59031:37827,59032:37828,59033:37829,59034:37830,59035:37831,59036:37832,59037:37833,59038:37835,59039:37836,59040:37837,59041:22935,59042:22986,59043:22955,59044:22942,59045:22948,59046:22994,59047:22962,59048:22959,59049:22999,59050:22974,59051:23045,59052:23046,59053:23005,59054:23048,59055:23011,59056:23000,59057:23033,59058:23052,59059:23049,59060:23090,59061:23092,59062:23057,59063:23075,59064:23059,59065:23104,59066:23143,59067:23114,59068:23125,59069:23100,59070:23138,59071:23157,59072:33004,59073:23210,59074:23195,59075:23159,59076:23162,59077:23230,59078:23275,59079:23218,59080:23250,59081:23252,59082:23224,59083:23264,59084:23267,59085:23281,59086:23254,59087:23270,59088:23256,59089:23260,59090:23305,59091:23319,59092:23318,59093:23346,59094:23351,59095:23360,59096:23573,59097:23580,59098:23386,59099:23397,59100:23411,59101:23377,59102:23379,59103:23394,59104:39541,59105:39543,59106:39544,59107:39546,59108:39551,59109:39549,59110:39552,59111:39553,59112:39557,59113:39560,59114:39562,59115:39568,59116:39570,59117:39571,59118:39574,59119:39576,59120:39579,59121:39580,59122:39581,59123:39583,59124:39584,59125:39586,59126:39587,59127:39589,59128:39591,59129:32415,59130:32417,59131:32419,59132:32421,59133:32424,59134:32425,59200:37838,59201:37839,59202:37840,59203:37841,59204:37842,59205:37843,59206:37844,59207:37845,59208:37847,59209:37848,59210:37849,59211:37850,59212:37851,59213:37852,59214:37853,59215:37854,59216:37855,59217:37856,59218:37857,59219:37858,59220:37859,59221:37860,59222:37861,59223:37862,59224:37863,59225:37864,59226:37865,59227:37866,59228:37867,59229:37868,59230:37869,59231:37870,59232:37871,59233:37872,59234:37873,59235:37874,59236:37875,59237:37876,59238:37877,59239:37878,59240:37879,59241:37880,59242:37881,59243:37882,59244:37883,59245:37884,59246:37885,59247:37886,59248:37887,59249:37888,59250:37889,59251:37890,59252:37891,59253:37892,59254:37893,59255:37894,59256:37895,59257:37896,59258:37897,59259:37898,59260:37899,59261:37900,59262:37901,59264:37902,59265:37903,59266:37904,59267:37905,59268:37906,59269:37907,59270:37908,59271:37909,59272:37910,59273:37911,59274:37912,59275:37913,59276:37914,59277:37915,59278:37916,59279:37917,59280:37918,59281:37919,59282:37920,59283:37921,59284:37922,59285:37923,59286:37924,59287:37925,59288:37926,59289:37927,59290:37928,59291:37929,59292:37930,59293:37931,59294:37932,59295:37933,59296:37934,59297:32429,59298:32432,59299:32446,59300:32448,59301:32449,59302:32450,59303:32457,59304:32459,59305:32460,59306:32464,59307:32468,59308:32471,59309:32475,59310:32480,59311:32481,59312:32488,59313:32491,59314:32494,59315:32495,59316:32497,59317:32498,59318:32525,59319:32502,59320:32506,59321:32507,59322:32510,59323:32513,59324:32514,59325:32515,59326:32519,59327:32520,59328:32523,59329:32524,59330:32527,59331:32529,59332:32530,59333:32535,59334:32537,59335:32540,59336:32539,59337:32543,59338:32545,59339:32546,59340:32547,59341:32548,59342:32549,59343:32550,59344:32551,59345:32554,59346:32555,59347:32556,59348:32557,59349:32559,59350:32560,59351:32561,59352:32562,59353:32563,59354:32565,59355:24186,59356:30079,59357:24027,59358:30014,59359:37013,59360:29582,59361:29585,59362:29614,59363:29602,59364:29599,59365:29647,59366:29634,59367:29649,59368:29623,59369:29619,59370:29632,59371:29641,59372:29640,59373:29669,59374:29657,59375:39036,59376:29706,59377:29673,59378:29671,59379:29662,59380:29626,59381:29682,59382:29711,59383:29738,59384:29787,59385:29734,59386:29733,59387:29736,59388:29744,59389:29742,59390:29740,59456:37935,59457:37936,59458:37937,59459:37938,59460:37939,59461:37940,59462:37941,59463:37942,59464:37943,59465:37944,59466:37945,59467:37946,59468:37947,59469:37948,59470:37949,59471:37951,59472:37952,59473:37953,59474:37954,59475:37955,59476:37956,59477:37957,59478:37958,59479:37959,59480:37960,59481:37961,59482:37962,59483:37963,59484:37964,59485:37965,59486:37966,59487:37967,59488:37968,59489:37969,59490:37970,59491:37971,59492:37972,59493:37973,59494:37974,59495:37975,59496:37976,59497:37977,59498:37978,59499:37979,59500:37980,59501:37981,59502:37982,59503:37983,59504:37984,59505:37985,59506:37986,59507:37987,59508:37988,59509:37989,59510:37990,59511:37991,59512:37992,59513:37993,59514:37994,59515:37996,59516:37997,59517:37998,59518:37999,59520:38000,59521:38001,59522:38002,59523:38003,59524:38004,59525:38005,59526:38006,59527:38007,59528:38008,59529:38009,59530:38010,59531:38011,59532:38012,59533:38013,59534:38014,59535:38015,59536:38016,59537:38017,59538:38018,59539:38019,59540:38020,59541:38033,59542:38038,59543:38040,59544:38087,59545:38095,59546:38099,59547:38100,59548:38106,59549:38118,59550:38139,59551:38172,59552:38176,59553:29723,59554:29722,59555:29761,59556:29788,59557:29783,59558:29781,59559:29785,59560:29815,59561:29805,59562:29822,59563:29852,59564:29838,59565:29824,59566:29825,59567:29831,59568:29835,59569:29854,59570:29864,59571:29865,59572:29840,59573:29863,59574:29906,59575:29882,59576:38890,59577:38891,59578:38892,59579:26444,59580:26451,59581:26462,59582:26440,59583:26473,59584:26533,59585:26503,59586:26474,59587:26483,59588:26520,59589:26535,59590:26485,59591:26536,59592:26526,59593:26541,59594:26507,59595:26487,59596:26492,59597:26608,59598:26633,59599:26584,59600:26634,59601:26601,59602:26544,59603:26636,59604:26585,59605:26549,59606:26586,59607:26547,59608:26589,59609:26624,59610:26563,59611:26552,59612:26594,59613:26638,59614:26561,59615:26621,59616:26674,59617:26675,59618:26720,59619:26721,59620:26702,59621:26722,59622:26692,59623:26724,59624:26755,59625:26653,59626:26709,59627:26726,59628:26689,59629:26727,59630:26688,59631:26686,59632:26698,59633:26697,59634:26665,59635:26805,59636:26767,59637:26740,59638:26743,59639:26771,59640:26731,59641:26818,59642:26990,59643:26876,59644:26911,59645:26912,59646:26873,59712:38183,59713:38195,59714:38205,59715:38211,59716:38216,59717:38219,59718:38229,59719:38234,59720:38240,59721:38254,59722:38260,59723:38261,59724:38263,59725:38264,59726:38265,59727:38266,59728:38267,59729:38268,59730:38269,59731:38270,59732:38272,59733:38273,59734:38274,59735:38275,59736:38276,59737:38277,59738:38278,59739:38279,59740:38280,59741:38281,59742:38282,59743:38283,59744:38284,59745:38285,59746:38286,59747:38287,59748:38288,59749:38289,59750:38290,59751:38291,59752:38292,59753:38293,59754:38294,59755:38295,59756:38296,59757:38297,59758:38298,59759:38299,59760:38300,59761:38301,59762:38302,59763:38303,59764:38304,59765:38305,59766:38306,59767:38307,59768:38308,59769:38309,59770:38310,59771:38311,59772:38312,59773:38313,59774:38314,59776:38315,59777:38316,59778:38317,59779:38318,59780:38319,59781:38320,59782:38321,59783:38322,59784:38323,59785:38324,59786:38325,59787:38326,59788:38327,59789:38328,59790:38329,59791:38330,59792:38331,59793:38332,59794:38333,59795:38334,59796:38335,59797:38336,59798:38337,59799:38338,59800:38339,59801:38340,59802:38341,59803:38342,59804:38343,59805:38344,59806:38345,59807:38346,59808:38347,59809:26916,59810:26864,59811:26891,59812:26881,59813:26967,59814:26851,59815:26896,59816:26993,59817:26937,59818:26976,59819:26946,59820:26973,59821:27012,59822:26987,59823:27008,59824:27032,59825:27000,59826:26932,59827:27084,59828:27015,59829:27016,59830:27086,59831:27017,59832:26982,59833:26979,59834:27001,59835:27035,59836:27047,59837:27067,59838:27051,59839:27053,59840:27092,59841:27057,59842:27073,59843:27082,59844:27103,59845:27029,59846:27104,59847:27021,59848:27135,59849:27183,59850:27117,59851:27159,59852:27160,59853:27237,59854:27122,59855:27204,59856:27198,59857:27296,59858:27216,59859:27227,59860:27189,59861:27278,59862:27257,59863:27197,59864:27176,59865:27224,59866:27260,59867:27281,59868:27280,59869:27305,59870:27287,59871:27307,59872:29495,59873:29522,59874:27521,59875:27522,59876:27527,59877:27524,59878:27538,59879:27539,59880:27533,59881:27546,59882:27547,59883:27553,59884:27562,59885:36715,59886:36717,59887:36721,59888:36722,59889:36723,59890:36725,59891:36726,59892:36728,59893:36727,59894:36729,59895:36730,59896:36732,59897:36734,59898:36737,59899:36738,59900:36740,59901:36743,59902:36747,59968:38348,59969:38349,59970:38350,59971:38351,59972:38352,59973:38353,59974:38354,59975:38355,59976:38356,59977:38357,59978:38358,59979:38359,59980:38360,59981:38361,59982:38362,59983:38363,59984:38364,59985:38365,59986:38366,59987:38367,59988:38368,59989:38369,59990:38370,59991:38371,59992:38372,59993:38373,59994:38374,59995:38375,59996:38380,59997:38399,59998:38407,59999:38419,60000:38424,60001:38427,60002:38430,60003:38432,60004:38435,60005:38436,60006:38437,60007:38438,60008:38439,60009:38440,60010:38441,60011:38443,60012:38444,60013:38445,60014:38447,60015:38448,60016:38455,60017:38456,60018:38457,60019:38458,60020:38462,60021:38465,60022:38467,60023:38474,60024:38478,60025:38479,60026:38481,60027:38482,60028:38483,60029:38486,60030:38487,60032:38488,60033:38489,60034:38490,60035:38492,60036:38493,60037:38494,60038:38496,60039:38499,60040:38501,60041:38502,60042:38507,60043:38509,60044:38510,60045:38511,60046:38512,60047:38513,60048:38515,60049:38520,60050:38521,60051:38522,60052:38523,60053:38524,60054:38525,60055:38526,60056:38527,60057:38528,60058:38529,60059:38530,60060:38531,60061:38532,60062:38535,60063:38537,60064:38538,60065:36749,60066:36750,60067:36751,60068:36760,60069:36762,60070:36558,60071:25099,60072:25111,60073:25115,60074:25119,60075:25122,60076:25121,60077:25125,60078:25124,60079:25132,60080:33255,60081:29935,60082:29940,60083:29951,60084:29967,60085:29969,60086:29971,60087:25908,60088:26094,60089:26095,60090:26096,60091:26122,60092:26137,60093:26482,60094:26115,60095:26133,60096:26112,60097:28805,60098:26359,60099:26141,60100:26164,60101:26161,60102:26166,60103:26165,60104:32774,60105:26207,60106:26196,60107:26177,60108:26191,60109:26198,60110:26209,60111:26199,60112:26231,60113:26244,60114:26252,60115:26279,60116:26269,60117:26302,60118:26331,60119:26332,60120:26342,60121:26345,60122:36146,60123:36147,60124:36150,60125:36155,60126:36157,60127:36160,60128:36165,60129:36166,60130:36168,60131:36169,60132:36167,60133:36173,60134:36181,60135:36185,60136:35271,60137:35274,60138:35275,60139:35276,60140:35278,60141:35279,60142:35280,60143:35281,60144:29294,60145:29343,60146:29277,60147:29286,60148:29295,60149:29310,60150:29311,60151:29316,60152:29323,60153:29325,60154:29327,60155:29330,60156:25352,60157:25394,60158:25520,60224:38540,60225:38542,60226:38545,60227:38546,60228:38547,60229:38549,60230:38550,60231:38554,60232:38555,60233:38557,60234:38558,60235:38559,60236:38560,60237:38561,60238:38562,60239:38563,60240:38564,60241:38565,60242:38566,60243:38568,60244:38569,60245:38570,60246:38571,60247:38572,60248:38573,60249:38574,60250:38575,60251:38577,60252:38578,60253:38580,60254:38581,60255:38583,60256:38584,60257:38586,60258:38587,60259:38591,60260:38594,60261:38595,60262:38600,60263:38602,60264:38603,60265:38608,60266:38609,60267:38611,60268:38612,60269:38614,60270:38615,60271:38616,60272:38617,60273:38618,60274:38619,60275:38620,60276:38621,60277:38622,60278:38623,60279:38625,60280:38626,60281:38627,60282:38628,60283:38629,60284:38630,60285:38631,60286:38635,60288:38636,60289:38637,60290:38638,60291:38640,60292:38641,60293:38642,60294:38644,60295:38645,60296:38648,60297:38650,60298:38651,60299:38652,60300:38653,60301:38655,60302:38658,60303:38659,60304:38661,60305:38666,60306:38667,60307:38668,60308:38672,60309:38673,60310:38674,60311:38676,60312:38677,60313:38679,60314:38680,60315:38681,60316:38682,60317:38683,60318:38685,60319:38687,60320:38688,60321:25663,60322:25816,60323:32772,60324:27626,60325:27635,60326:27645,60327:27637,60328:27641,60329:27653,60330:27655,60331:27654,60332:27661,60333:27669,60334:27672,60335:27673,60336:27674,60337:27681,60338:27689,60339:27684,60340:27690,60341:27698,60342:25909,60343:25941,60344:25963,60345:29261,60346:29266,60347:29270,60348:29232,60349:34402,60350:21014,60351:32927,60352:32924,60353:32915,60354:32956,60355:26378,60356:32957,60357:32945,60358:32939,60359:32941,60360:32948,60361:32951,60362:32999,60363:33000,60364:33001,60365:33002,60366:32987,60367:32962,60368:32964,60369:32985,60370:32973,60371:32983,60372:26384,60373:32989,60374:33003,60375:33009,60376:33012,60377:33005,60378:33037,60379:33038,60380:33010,60381:33020,60382:26389,60383:33042,60384:35930,60385:33078,60386:33054,60387:33068,60388:33048,60389:33074,60390:33096,60391:33100,60392:33107,60393:33140,60394:33113,60395:33114,60396:33137,60397:33120,60398:33129,60399:33148,60400:33149,60401:33133,60402:33127,60403:22605,60404:23221,60405:33160,60406:33154,60407:33169,60408:28373,60409:33187,60410:33194,60411:33228,60412:26406,60413:33226,60414:33211,60480:38689,60481:38690,60482:38691,60483:38692,60484:38693,60485:38694,60486:38695,60487:38696,60488:38697,60489:38699,60490:38700,60491:38702,60492:38703,60493:38705,60494:38707,60495:38708,60496:38709,60497:38710,60498:38711,60499:38714,60500:38715,60501:38716,60502:38717,60503:38719,60504:38720,60505:38721,60506:38722,60507:38723,60508:38724,60509:38725,60510:38726,60511:38727,60512:38728,60513:38729,60514:38730,60515:38731,60516:38732,60517:38733,60518:38734,60519:38735,60520:38736,60521:38737,60522:38740,60523:38741,60524:38743,60525:38744,60526:38746,60527:38748,60528:38749,60529:38751,60530:38755,60531:38756,60532:38758,60533:38759,60534:38760,60535:38762,60536:38763,60537:38764,60538:38765,60539:38766,60540:38767,60541:38768,60542:38769,60544:38770,60545:38773,60546:38775,60547:38776,60548:38777,60549:38778,60550:38779,60551:38781,60552:38782,60553:38783,60554:38784,60555:38785,60556:38786,60557:38787,60558:38788,60559:38790,60560:38791,60561:38792,60562:38793,60563:38794,60564:38796,60565:38798,60566:38799,60567:38800,60568:38803,60569:38805,60570:38806,60571:38807,60572:38809,60573:38810,60574:38811,60575:38812,60576:38813,60577:33217,60578:33190,60579:27428,60580:27447,60581:27449,60582:27459,60583:27462,60584:27481,60585:39121,60586:39122,60587:39123,60588:39125,60589:39129,60590:39130,60591:27571,60592:24384,60593:27586,60594:35315,60595:26000,60596:40785,60597:26003,60598:26044,60599:26054,60600:26052,60601:26051,60602:26060,60603:26062,60604:26066,60605:26070,60606:28800,60607:28828,60608:28822,60609:28829,60610:28859,60611:28864,60612:28855,60613:28843,60614:28849,60615:28904,60616:28874,60617:28944,60618:28947,60619:28950,60620:28975,60621:28977,60622:29043,60623:29020,60624:29032,60625:28997,60626:29042,60627:29002,60628:29048,60629:29050,60630:29080,60631:29107,60632:29109,60633:29096,60634:29088,60635:29152,60636:29140,60637:29159,60638:29177,60639:29213,60640:29224,60641:28780,60642:28952,60643:29030,60644:29113,60645:25150,60646:25149,60647:25155,60648:25160,60649:25161,60650:31035,60651:31040,60652:31046,60653:31049,60654:31067,60655:31068,60656:31059,60657:31066,60658:31074,60659:31063,60660:31072,60661:31087,60662:31079,60663:31098,60664:31109,60665:31114,60666:31130,60667:31143,60668:31155,60669:24529,60670:24528,60736:38814,60737:38815,60738:38817,60739:38818,60740:38820,60741:38821,60742:38822,60743:38823,60744:38824,60745:38825,60746:38826,60747:38828,60748:38830,60749:38832,60750:38833,60751:38835,60752:38837,60753:38838,60754:38839,60755:38840,60756:38841,60757:38842,60758:38843,60759:38844,60760:38845,60761:38846,60762:38847,60763:38848,60764:38849,60765:38850,60766:38851,60767:38852,60768:38853,60769:38854,60770:38855,60771:38856,60772:38857,60773:38858,60774:38859,60775:38860,60776:38861,60777:38862,60778:38863,60779:38864,60780:38865,60781:38866,60782:38867,60783:38868,60784:38869,60785:38870,60786:38871,60787:38872,60788:38873,60789:38874,60790:38875,60791:38876,60792:38877,60793:38878,60794:38879,60795:38880,60796:38881,60797:38882,60798:38883,60800:38884,60801:38885,60802:38888,60803:38894,60804:38895,60805:38896,60806:38897,60807:38898,60808:38900,60809:38903,60810:38904,60811:38905,60812:38906,60813:38907,60814:38908,60815:38909,60816:38910,60817:38911,60818:38912,60819:38913,60820:38914,60821:38915,60822:38916,60823:38917,60824:38918,60825:38919,60826:38920,60827:38921,60828:38922,60829:38923,60830:38924,60831:38925,60832:38926,60833:24636,60834:24669,60835:24666,60836:24679,60837:24641,60838:24665,60839:24675,60840:24747,60841:24838,60842:24845,60843:24925,60844:25001,60845:24989,60846:25035,60847:25041,60848:25094,60849:32896,60850:32895,60851:27795,60852:27894,60853:28156,60854:30710,60855:30712,60856:30720,60857:30729,60858:30743,60859:30744,60860:30737,60861:26027,60862:30765,60863:30748,60864:30749,60865:30777,60866:30778,60867:30779,60868:30751,60869:30780,60870:30757,60871:30764,60872:30755,60873:30761,60874:30798,60875:30829,60876:30806,60877:30807,60878:30758,60879:30800,60880:30791,60881:30796,60882:30826,60883:30875,60884:30867,60885:30874,60886:30855,60887:30876,60888:30881,60889:30883,60890:30898,60891:30905,60892:30885,60893:30932,60894:30937,60895:30921,60896:30956,60897:30962,60898:30981,60899:30964,60900:30995,60901:31012,60902:31006,60903:31028,60904:40859,60905:40697,60906:40699,60907:40700,60908:30449,60909:30468,60910:30477,60911:30457,60912:30471,60913:30472,60914:30490,60915:30498,60916:30489,60917:30509,60918:30502,60919:30517,60920:30520,60921:30544,60922:30545,60923:30535,60924:30531,60925:30554,60926:30568,60992:38927,60993:38928,60994:38929,60995:38930,60996:38931,60997:38932,60998:38933,60999:38934,61000:38935,61001:38936,61002:38937,61003:38938,61004:38939,61005:38940,61006:38941,61007:38942,61008:38943,61009:38944,61010:38945,61011:38946,61012:38947,61013:38948,61014:38949,61015:38950,61016:38951,61017:38952,61018:38953,61019:38954,61020:38955,61021:38956,61022:38957,61023:38958,61024:38959,61025:38960,61026:38961,61027:38962,61028:38963,61029:38964,61030:38965,61031:38966,61032:38967,61033:38968,61034:38969,61035:38970,61036:38971,61037:38972,61038:38973,61039:38974,61040:38975,61041:38976,61042:38977,61043:38978,61044:38979,61045:38980,61046:38981,61047:38982,61048:38983,61049:38984,61050:38985,61051:38986,61052:38987,61053:38988,61054:38989,61056:38990,61057:38991,61058:38992,61059:38993,61060:38994,61061:38995,61062:38996,61063:38997,61064:38998,61065:38999,61066:39000,61067:39001,61068:39002,61069:39003,61070:39004,61071:39005,61072:39006,61073:39007,61074:39008,61075:39009,61076:39010,61077:39011,61078:39012,61079:39013,61080:39014,61081:39015,61082:39016,61083:39017,61084:39018,61085:39019,61086:39020,61087:39021,61088:39022,61089:30562,61090:30565,61091:30591,61092:30605,61093:30589,61094:30592,61095:30604,61096:30609,61097:30623,61098:30624,61099:30640,61100:30645,61101:30653,61102:30010,61103:30016,61104:30030,61105:30027,61106:30024,61107:30043,61108:30066,61109:30073,61110:30083,61111:32600,61112:32609,61113:32607,61114:35400,61115:32616,61116:32628,61117:32625,61118:32633,61119:32641,61120:32638,61121:30413,61122:30437,61123:34866,61124:38021,61125:38022,61126:38023,61127:38027,61128:38026,61129:38028,61130:38029,61131:38031,61132:38032,61133:38036,61134:38039,61135:38037,61136:38042,61137:38043,61138:38044,61139:38051,61140:38052,61141:38059,61142:38058,61143:38061,61144:38060,61145:38063,61146:38064,61147:38066,61148:38068,61149:38070,61150:38071,61151:38072,61152:38073,61153:38074,61154:38076,61155:38077,61156:38079,61157:38084,61158:38088,61159:38089,61160:38090,61161:38091,61162:38092,61163:38093,61164:38094,61165:38096,61166:38097,61167:38098,61168:38101,61169:38102,61170:38103,61171:38105,61172:38104,61173:38107,61174:38110,61175:38111,61176:38112,61177:38114,61178:38116,61179:38117,61180:38119,61181:38120,61182:38122,61248:39023,61249:39024,61250:39025,61251:39026,61252:39027,61253:39028,61254:39051,61255:39054,61256:39058,61257:39061,61258:39065,61259:39075,61260:39080,61261:39081,61262:39082,61263:39083,61264:39084,61265:39085,61266:39086,61267:39087,61268:39088,61269:39089,61270:39090,61271:39091,61272:39092,61273:39093,61274:39094,61275:39095,61276:39096,61277:39097,61278:39098,61279:39099,61280:39100,61281:39101,61282:39102,61283:39103,61284:39104,61285:39105,61286:39106,61287:39107,61288:39108,61289:39109,61290:39110,61291:39111,61292:39112,61293:39113,61294:39114,61295:39115,61296:39116,61297:39117,61298:39119,61299:39120,61300:39124,61301:39126,61302:39127,61303:39131,61304:39132,61305:39133,61306:39136,61307:39137,61308:39138,61309:39139,61310:39140,61312:39141,61313:39142,61314:39145,61315:39146,61316:39147,61317:39148,61318:39149,61319:39150,61320:39151,61321:39152,61322:39153,61323:39154,61324:39155,61325:39156,61326:39157,61327:39158,61328:39159,61329:39160,61330:39161,61331:39162,61332:39163,61333:39164,61334:39165,61335:39166,61336:39167,61337:39168,61338:39169,61339:39170,61340:39171,61341:39172,61342:39173,61343:39174,61344:39175,61345:38121,61346:38123,61347:38126,61348:38127,61349:38131,61350:38132,61351:38133,61352:38135,61353:38137,61354:38140,61355:38141,61356:38143,61357:38147,61358:38146,61359:38150,61360:38151,61361:38153,61362:38154,61363:38157,61364:38158,61365:38159,61366:38162,61367:38163,61368:38164,61369:38165,61370:38166,61371:38168,61372:38171,61373:38173,61374:38174,61375:38175,61376:38178,61377:38186,61378:38187,61379:38185,61380:38188,61381:38193,61382:38194,61383:38196,61384:38198,61385:38199,61386:38200,61387:38204,61388:38206,61389:38207,61390:38210,61391:38197,61392:38212,61393:38213,61394:38214,61395:38217,61396:38220,61397:38222,61398:38223,61399:38226,61400:38227,61401:38228,61402:38230,61403:38231,61404:38232,61405:38233,61406:38235,61407:38238,61408:38239,61409:38237,61410:38241,61411:38242,61412:38244,61413:38245,61414:38246,61415:38247,61416:38248,61417:38249,61418:38250,61419:38251,61420:38252,61421:38255,61422:38257,61423:38258,61424:38259,61425:38202,61426:30695,61427:30700,61428:38601,61429:31189,61430:31213,61431:31203,61432:31211,61433:31238,61434:23879,61435:31235,61436:31234,61437:31262,61438:31252,61504:39176,61505:39177,61506:39178,61507:39179,61508:39180,61509:39182,61510:39183,61511:39185,61512:39186,61513:39187,61514:39188,61515:39189,61516:39190,61517:39191,61518:39192,61519:39193,61520:39194,61521:39195,61522:39196,61523:39197,61524:39198,61525:39199,61526:39200,61527:39201,61528:39202,61529:39203,61530:39204,61531:39205,61532:39206,61533:39207,61534:39208,61535:39209,61536:39210,61537:39211,61538:39212,61539:39213,61540:39215,61541:39216,61542:39217,61543:39218,61544:39219,61545:39220,61546:39221,61547:39222,61548:39223,61549:39224,61550:39225,61551:39226,61552:39227,61553:39228,61554:39229,61555:39230,61556:39231,61557:39232,61558:39233,61559:39234,61560:39235,61561:39236,61562:39237,61563:39238,61564:39239,61565:39240,61566:39241,61568:39242,61569:39243,61570:39244,61571:39245,61572:39246,61573:39247,61574:39248,61575:39249,61576:39250,61577:39251,61578:39254,61579:39255,61580:39256,61581:39257,61582:39258,61583:39259,61584:39260,61585:39261,61586:39262,61587:39263,61588:39264,61589:39265,61590:39266,61591:39268,61592:39270,61593:39283,61594:39288,61595:39289,61596:39291,61597:39294,61598:39298,61599:39299,61600:39305,61601:31289,61602:31287,61603:31313,61604:40655,61605:39333,61606:31344,61607:30344,61608:30350,61609:30355,61610:30361,61611:30372,61612:29918,61613:29920,61614:29996,61615:40480,61616:40482,61617:40488,61618:40489,61619:40490,61620:40491,61621:40492,61622:40498,61623:40497,61624:40502,61625:40504,61626:40503,61627:40505,61628:40506,61629:40510,61630:40513,61631:40514,61632:40516,61633:40518,61634:40519,61635:40520,61636:40521,61637:40523,61638:40524,61639:40526,61640:40529,61641:40533,61642:40535,61643:40538,61644:40539,61645:40540,61646:40542,61647:40547,61648:40550,61649:40551,61650:40552,61651:40553,61652:40554,61653:40555,61654:40556,61655:40561,61656:40557,61657:40563,61658:30098,61659:30100,61660:30102,61661:30112,61662:30109,61663:30124,61664:30115,61665:30131,61666:30132,61667:30136,61668:30148,61669:30129,61670:30128,61671:30147,61672:30146,61673:30166,61674:30157,61675:30179,61676:30184,61677:30182,61678:30180,61679:30187,61680:30183,61681:30211,61682:30193,61683:30204,61684:30207,61685:30224,61686:30208,61687:30213,61688:30220,61689:30231,61690:30218,61691:30245,61692:30232,61693:30229,61694:30233,61760:39308,61761:39310,61762:39322,61763:39323,61764:39324,61765:39325,61766:39326,61767:39327,61768:39328,61769:39329,61770:39330,61771:39331,61772:39332,61773:39334,61774:39335,61775:39337,61776:39338,61777:39339,61778:39340,61779:39341,61780:39342,61781:39343,61782:39344,61783:39345,61784:39346,61785:39347,61786:39348,61787:39349,61788:39350,61789:39351,61790:39352,61791:39353,61792:39354,61793:39355,61794:39356,61795:39357,61796:39358,61797:39359,61798:39360,61799:39361,61800:39362,61801:39363,61802:39364,61803:39365,61804:39366,61805:39367,61806:39368,61807:39369,61808:39370,61809:39371,61810:39372,61811:39373,61812:39374,61813:39375,61814:39376,61815:39377,61816:39378,61817:39379,61818:39380,61819:39381,61820:39382,61821:39383,61822:39384,61824:39385,61825:39386,61826:39387,61827:39388,61828:39389,61829:39390,61830:39391,61831:39392,61832:39393,61833:39394,61834:39395,61835:39396,61836:39397,61837:39398,61838:39399,61839:39400,61840:39401,61841:39402,61842:39403,61843:39404,61844:39405,61845:39406,61846:39407,61847:39408,61848:39409,61849:39410,61850:39411,61851:39412,61852:39413,61853:39414,61854:39415,61855:39416,61856:39417,61857:30235,61858:30268,61859:30242,61860:30240,61861:30272,61862:30253,61863:30256,61864:30271,61865:30261,61866:30275,61867:30270,61868:30259,61869:30285,61870:30302,61871:30292,61872:30300,61873:30294,61874:30315,61875:30319,61876:32714,61877:31462,61878:31352,61879:31353,61880:31360,61881:31366,61882:31368,61883:31381,61884:31398,61885:31392,61886:31404,61887:31400,61888:31405,61889:31411,61890:34916,61891:34921,61892:34930,61893:34941,61894:34943,61895:34946,61896:34978,61897:35014,61898:34999,61899:35004,61900:35017,61901:35042,61902:35022,61903:35043,61904:35045,61905:35057,61906:35098,61907:35068,61908:35048,61909:35070,61910:35056,61911:35105,61912:35097,61913:35091,61914:35099,61915:35082,61916:35124,61917:35115,61918:35126,61919:35137,61920:35174,61921:35195,61922:30091,61923:32997,61924:30386,61925:30388,61926:30684,61927:32786,61928:32788,61929:32790,61930:32796,61931:32800,61932:32802,61933:32805,61934:32806,61935:32807,61936:32809,61937:32808,61938:32817,61939:32779,61940:32821,61941:32835,61942:32838,61943:32845,61944:32850,61945:32873,61946:32881,61947:35203,61948:39032,61949:39040,61950:39043,62016:39418,62017:39419,62018:39420,62019:39421,62020:39422,62021:39423,62022:39424,62023:39425,62024:39426,62025:39427,62026:39428,62027:39429,62028:39430,62029:39431,62030:39432,62031:39433,62032:39434,62033:39435,62034:39436,62035:39437,62036:39438,62037:39439,62038:39440,62039:39441,62040:39442,62041:39443,62042:39444,62043:39445,62044:39446,62045:39447,62046:39448,62047:39449,62048:39450,62049:39451,62050:39452,62051:39453,62052:39454,62053:39455,62054:39456,62055:39457,62056:39458,62057:39459,62058:39460,62059:39461,62060:39462,62061:39463,62062:39464,62063:39465,62064:39466,62065:39467,62066:39468,62067:39469,62068:39470,62069:39471,62070:39472,62071:39473,62072:39474,62073:39475,62074:39476,62075:39477,62076:39478,62077:39479,62078:39480,62080:39481,62081:39482,62082:39483,62083:39484,62084:39485,62085:39486,62086:39487,62087:39488,62088:39489,62089:39490,62090:39491,62091:39492,62092:39493,62093:39494,62094:39495,62095:39496,62096:39497,62097:39498,62098:39499,62099:39500,62100:39501,62101:39502,62102:39503,62103:39504,62104:39505,62105:39506,62106:39507,62107:39508,62108:39509,62109:39510,62110:39511,62111:39512,62112:39513,62113:39049,62114:39052,62115:39053,62116:39055,62117:39060,62118:39066,62119:39067,62120:39070,62121:39071,62122:39073,62123:39074,62124:39077,62125:39078,62126:34381,62127:34388,62128:34412,62129:34414,62130:34431,62131:34426,62132:34428,62133:34427,62134:34472,62135:34445,62136:34443,62137:34476,62138:34461,62139:34471,62140:34467,62141:34474,62142:34451,62143:34473,62144:34486,62145:34500,62146:34485,62147:34510,62148:34480,62149:34490,62150:34481,62151:34479,62152:34505,62153:34511,62154:34484,62155:34537,62156:34545,62157:34546,62158:34541,62159:34547,62160:34512,62161:34579,62162:34526,62163:34548,62164:34527,62165:34520,62166:34513,62167:34563,62168:34567,62169:34552,62170:34568,62171:34570,62172:34573,62173:34569,62174:34595,62175:34619,62176:34590,62177:34597,62178:34606,62179:34586,62180:34622,62181:34632,62182:34612,62183:34609,62184:34601,62185:34615,62186:34623,62187:34690,62188:34594,62189:34685,62190:34686,62191:34683,62192:34656,62193:34672,62194:34636,62195:34670,62196:34699,62197:34643,62198:34659,62199:34684,62200:34660,62201:34649,62202:34661,62203:34707,62204:34735,62205:34728,62206:34770,62272:39514,62273:39515,62274:39516,62275:39517,62276:39518,62277:39519,62278:39520,62279:39521,62280:39522,62281:39523,62282:39524,62283:39525,62284:39526,62285:39527,62286:39528,62287:39529,62288:39530,62289:39531,62290:39538,62291:39555,62292:39561,62293:39565,62294:39566,62295:39572,62296:39573,62297:39577,62298:39590,62299:39593,62300:39594,62301:39595,62302:39596,62303:39597,62304:39598,62305:39599,62306:39602,62307:39603,62308:39604,62309:39605,62310:39609,62311:39611,62312:39613,62313:39614,62314:39615,62315:39619,62316:39620,62317:39622,62318:39623,62319:39624,62320:39625,62321:39626,62322:39629,62323:39630,62324:39631,62325:39632,62326:39634,62327:39636,62328:39637,62329:39638,62330:39639,62331:39641,62332:39642,62333:39643,62334:39644,62336:39645,62337:39646,62338:39648,62339:39650,62340:39651,62341:39652,62342:39653,62343:39655,62344:39656,62345:39657,62346:39658,62347:39660,62348:39662,62349:39664,62350:39665,62351:39666,62352:39667,62353:39668,62354:39669,62355:39670,62356:39671,62357:39672,62358:39674,62359:39676,62360:39677,62361:39678,62362:39679,62363:39680,62364:39681,62365:39682,62366:39684,62367:39685,62368:39686,62369:34758,62370:34696,62371:34693,62372:34733,62373:34711,62374:34691,62375:34731,62376:34789,62377:34732,62378:34741,62379:34739,62380:34763,62381:34771,62382:34749,62383:34769,62384:34752,62385:34762,62386:34779,62387:34794,62388:34784,62389:34798,62390:34838,62391:34835,62392:34814,62393:34826,62394:34843,62395:34849,62396:34873,62397:34876,62398:32566,62399:32578,62400:32580,62401:32581,62402:33296,62403:31482,62404:31485,62405:31496,62406:31491,62407:31492,62408:31509,62409:31498,62410:31531,62411:31503,62412:31559,62413:31544,62414:31530,62415:31513,62416:31534,62417:31537,62418:31520,62419:31525,62420:31524,62421:31539,62422:31550,62423:31518,62424:31576,62425:31578,62426:31557,62427:31605,62428:31564,62429:31581,62430:31584,62431:31598,62432:31611,62433:31586,62434:31602,62435:31601,62436:31632,62437:31654,62438:31655,62439:31672,62440:31660,62441:31645,62442:31656,62443:31621,62444:31658,62445:31644,62446:31650,62447:31659,62448:31668,62449:31697,62450:31681,62451:31692,62452:31709,62453:31706,62454:31717,62455:31718,62456:31722,62457:31756,62458:31742,62459:31740,62460:31759,62461:31766,62462:31755,62528:39687,62529:39689,62530:39690,62531:39691,62532:39692,62533:39693,62534:39694,62535:39696,62536:39697,62537:39698,62538:39700,62539:39701,62540:39702,62541:39703,62542:39704,62543:39705,62544:39706,62545:39707,62546:39708,62547:39709,62548:39710,62549:39712,62550:39713,62551:39714,62552:39716,62553:39717,62554:39718,62555:39719,62556:39720,62557:39721,62558:39722,62559:39723,62560:39724,62561:39725,62562:39726,62563:39728,62564:39729,62565:39731,62566:39732,62567:39733,62568:39734,62569:39735,62570:39736,62571:39737,62572:39738,62573:39741,62574:39742,62575:39743,62576:39744,62577:39750,62578:39754,62579:39755,62580:39756,62581:39758,62582:39760,62583:39762,62584:39763,62585:39765,62586:39766,62587:39767,62588:39768,62589:39769,62590:39770,62592:39771,62593:39772,62594:39773,62595:39774,62596:39775,62597:39776,62598:39777,62599:39778,62600:39779,62601:39780,62602:39781,62603:39782,62604:39783,62605:39784,62606:39785,62607:39786,62608:39787,62609:39788,62610:39789,62611:39790,62612:39791,62613:39792,62614:39793,62615:39794,62616:39795,62617:39796,62618:39797,62619:39798,62620:39799,62621:39800,62622:39801,62623:39802,62624:39803,62625:31775,62626:31786,62627:31782,62628:31800,62629:31809,62630:31808,62631:33278,62632:33281,62633:33282,62634:33284,62635:33260,62636:34884,62637:33313,62638:33314,62639:33315,62640:33325,62641:33327,62642:33320,62643:33323,62644:33336,62645:33339,62646:33331,62647:33332,62648:33342,62649:33348,62650:33353,62651:33355,62652:33359,62653:33370,62654:33375,62655:33384,62656:34942,62657:34949,62658:34952,62659:35032,62660:35039,62661:35166,62662:32669,62663:32671,62664:32679,62665:32687,62666:32688,62667:32690,62668:31868,62669:25929,62670:31889,62671:31901,62672:31900,62673:31902,62674:31906,62675:31922,62676:31932,62677:31933,62678:31937,62679:31943,62680:31948,62681:31949,62682:31944,62683:31941,62684:31959,62685:31976,62686:33390,62687:26280,62688:32703,62689:32718,62690:32725,62691:32741,62692:32737,62693:32742,62694:32745,62695:32750,62696:32755,62697:31992,62698:32119,62699:32166,62700:32174,62701:32327,62702:32411,62703:40632,62704:40628,62705:36211,62706:36228,62707:36244,62708:36241,62709:36273,62710:36199,62711:36205,62712:35911,62713:35913,62714:37194,62715:37200,62716:37198,62717:37199,62718:37220,62784:39804,62785:39805,62786:39806,62787:39807,62788:39808,62789:39809,62790:39810,62791:39811,62792:39812,62793:39813,62794:39814,62795:39815,62796:39816,62797:39817,62798:39818,62799:39819,62800:39820,62801:39821,62802:39822,62803:39823,62804:39824,62805:39825,62806:39826,62807:39827,62808:39828,62809:39829,62810:39830,62811:39831,62812:39832,62813:39833,62814:39834,62815:39835,62816:39836,62817:39837,62818:39838,62819:39839,62820:39840,62821:39841,62822:39842,62823:39843,62824:39844,62825:39845,62826:39846,62827:39847,62828:39848,62829:39849,62830:39850,62831:39851,62832:39852,62833:39853,62834:39854,62835:39855,62836:39856,62837:39857,62838:39858,62839:39859,62840:39860,62841:39861,62842:39862,62843:39863,62844:39864,62845:39865,62846:39866,62848:39867,62849:39868,62850:39869,62851:39870,62852:39871,62853:39872,62854:39873,62855:39874,62856:39875,62857:39876,62858:39877,62859:39878,62860:39879,62861:39880,62862:39881,62863:39882,62864:39883,62865:39884,62866:39885,62867:39886,62868:39887,62869:39888,62870:39889,62871:39890,62872:39891,62873:39892,62874:39893,62875:39894,62876:39895,62877:39896,62878:39897,62879:39898,62880:39899,62881:37218,62882:37217,62883:37232,62884:37225,62885:37231,62886:37245,62887:37246,62888:37234,62889:37236,62890:37241,62891:37260,62892:37253,62893:37264,62894:37261,62895:37265,62896:37282,62897:37283,62898:37290,62899:37293,62900:37294,62901:37295,62902:37301,62903:37300,62904:37306,62905:35925,62906:40574,62907:36280,62908:36331,62909:36357,62910:36441,62911:36457,62912:36277,62913:36287,62914:36284,62915:36282,62916:36292,62917:36310,62918:36311,62919:36314,62920:36318,62921:36302,62922:36303,62923:36315,62924:36294,62925:36332,62926:36343,62927:36344,62928:36323,62929:36345,62930:36347,62931:36324,62932:36361,62933:36349,62934:36372,62935:36381,62936:36383,62937:36396,62938:36398,62939:36387,62940:36399,62941:36410,62942:36416,62943:36409,62944:36405,62945:36413,62946:36401,62947:36425,62948:36417,62949:36418,62950:36433,62951:36434,62952:36426,62953:36464,62954:36470,62955:36476,62956:36463,62957:36468,62958:36485,62959:36495,62960:36500,62961:36496,62962:36508,62963:36510,62964:35960,62965:35970,62966:35978,62967:35973,62968:35992,62969:35988,62970:26011,62971:35286,62972:35294,62973:35290,62974:35292,63040:39900,63041:39901,63042:39902,63043:39903,63044:39904,63045:39905,63046:39906,63047:39907,63048:39908,63049:39909,63050:39910,63051:39911,63052:39912,63053:39913,63054:39914,63055:39915,63056:39916,63057:39917,63058:39918,63059:39919,63060:39920,63061:39921,63062:39922,63063:39923,63064:39924,63065:39925,63066:39926,63067:39927,63068:39928,63069:39929,63070:39930,63071:39931,63072:39932,63073:39933,63074:39934,63075:39935,63076:39936,63077:39937,63078:39938,63079:39939,63080:39940,63081:39941,63082:39942,63083:39943,63084:39944,63085:39945,63086:39946,63087:39947,63088:39948,63089:39949,63090:39950,63091:39951,63092:39952,63093:39953,63094:39954,63095:39955,63096:39956,63097:39957,63098:39958,63099:39959,63100:39960,63101:39961,63102:39962,63104:39963,63105:39964,63106:39965,63107:39966,63108:39967,63109:39968,63110:39969,63111:39970,63112:39971,63113:39972,63114:39973,63115:39974,63116:39975,63117:39976,63118:39977,63119:39978,63120:39979,63121:39980,63122:39981,63123:39982,63124:39983,63125:39984,63126:39985,63127:39986,63128:39987,63129:39988,63130:39989,63131:39990,63132:39991,63133:39992,63134:39993,63135:39994,63136:39995,63137:35301,63138:35307,63139:35311,63140:35390,63141:35622,63142:38739,63143:38633,63144:38643,63145:38639,63146:38662,63147:38657,63148:38664,63149:38671,63150:38670,63151:38698,63152:38701,63153:38704,63154:38718,63155:40832,63156:40835,63157:40837,63158:40838,63159:40839,63160:40840,63161:40841,63162:40842,63163:40844,63164:40702,63165:40715,63166:40717,63167:38585,63168:38588,63169:38589,63170:38606,63171:38610,63172:30655,63173:38624,63174:37518,63175:37550,63176:37576,63177:37694,63178:37738,63179:37834,63180:37775,63181:37950,63182:37995,63183:40063,63184:40066,63185:40069,63186:40070,63187:40071,63188:40072,63189:31267,63190:40075,63191:40078,63192:40080,63193:40081,63194:40082,63195:40084,63196:40085,63197:40090,63198:40091,63199:40094,63200:40095,63201:40096,63202:40097,63203:40098,63204:40099,63205:40101,63206:40102,63207:40103,63208:40104,63209:40105,63210:40107,63211:40109,63212:40110,63213:40112,63214:40113,63215:40114,63216:40115,63217:40116,63218:40117,63219:40118,63220:40119,63221:40122,63222:40123,63223:40124,63224:40125,63225:40132,63226:40133,63227:40134,63228:40135,63229:40138,63230:40139,63296:39996,63297:39997,63298:39998,63299:39999,63300:40000,63301:40001,63302:40002,63303:40003,63304:40004,63305:40005,63306:40006,63307:40007,63308:40008,63309:40009,63310:40010,63311:40011,63312:40012,63313:40013,63314:40014,63315:40015,63316:40016,63317:40017,63318:40018,63319:40019,63320:40020,63321:40021,63322:40022,63323:40023,63324:40024,63325:40025,63326:40026,63327:40027,63328:40028,63329:40029,63330:40030,63331:40031,63332:40032,63333:40033,63334:40034,63335:40035,63336:40036,63337:40037,63338:40038,63339:40039,63340:40040,63341:40041,63342:40042,63343:40043,63344:40044,63345:40045,63346:40046,63347:40047,63348:40048,63349:40049,63350:40050,63351:40051,63352:40052,63353:40053,63354:40054,63355:40055,63356:40056,63357:40057,63358:40058,63360:40059,63361:40061,63362:40062,63363:40064,63364:40067,63365:40068,63366:40073,63367:40074,63368:40076,63369:40079,63370:40083,63371:40086,63372:40087,63373:40088,63374:40089,63375:40093,63376:40106,63377:40108,63378:40111,63379:40121,63380:40126,63381:40127,63382:40128,63383:40129,63384:40130,63385:40136,63386:40137,63387:40145,63388:40146,63389:40154,63390:40155,63391:40160,63392:40161,63393:40140,63394:40141,63395:40142,63396:40143,63397:40144,63398:40147,63399:40148,63400:40149,63401:40151,63402:40152,63403:40153,63404:40156,63405:40157,63406:40159,63407:40162,63408:38780,63409:38789,63410:38801,63411:38802,63412:38804,63413:38831,63414:38827,63415:38819,63416:38834,63417:38836,63418:39601,63419:39600,63420:39607,63421:40536,63422:39606,63423:39610,63424:39612,63425:39617,63426:39616,63427:39621,63428:39618,63429:39627,63430:39628,63431:39633,63432:39749,63433:39747,63434:39751,63435:39753,63436:39752,63437:39757,63438:39761,63439:39144,63440:39181,63441:39214,63442:39253,63443:39252,63444:39647,63445:39649,63446:39654,63447:39663,63448:39659,63449:39675,63450:39661,63451:39673,63452:39688,63453:39695,63454:39699,63455:39711,63456:39715,63457:40637,63458:40638,63459:32315,63460:40578,63461:40583,63462:40584,63463:40587,63464:40594,63465:37846,63466:40605,63467:40607,63468:40667,63469:40668,63470:40669,63471:40672,63472:40671,63473:40674,63474:40681,63475:40679,63476:40677,63477:40682,63478:40687,63479:40738,63480:40748,63481:40751,63482:40761,63483:40759,63484:40765,63485:40766,63486:40772,63552:40163,63553:40164,63554:40165,63555:40166,63556:40167,63557:40168,63558:40169,63559:40170,63560:40171,63561:40172,63562:40173,63563:40174,63564:40175,63565:40176,63566:40177,63567:40178,63568:40179,63569:40180,63570:40181,63571:40182,63572:40183,63573:40184,63574:40185,63575:40186,63576:40187,63577:40188,63578:40189,63579:40190,63580:40191,63581:40192,63582:40193,63583:40194,63584:40195,63585:40196,63586:40197,63587:40198,63588:40199,63589:40200,63590:40201,63591:40202,63592:40203,63593:40204,63594:40205,63595:40206,63596:40207,63597:40208,63598:40209,63599:40210,63600:40211,63601:40212,63602:40213,63603:40214,63604:40215,63605:40216,63606:40217,63607:40218,63608:40219,63609:40220,63610:40221,63611:40222,63612:40223,63613:40224,63614:40225,63616:40226,63617:40227,63618:40228,63619:40229,63620:40230,63621:40231,63622:40232,63623:40233,63624:40234,63625:40235,63626:40236,63627:40237,63628:40238,63629:40239,63630:40240,63631:40241,63632:40242,63633:40243,63634:40244,63635:40245,63636:40246,63637:40247,63638:40248,63639:40249,63640:40250,63641:40251,63642:40252,63643:40253,63644:40254,63645:40255,63646:40256,63647:40257,63648:40258,63649:57908,63650:57909,63651:57910,63652:57911,63653:57912,63654:57913,63655:57914,63656:57915,63657:57916,63658:57917,63659:57918,63660:57919,63661:57920,63662:57921,63663:57922,63664:57923,63665:57924,63666:57925,63667:57926,63668:57927,63669:57928,63670:57929,63671:57930,63672:57931,63673:57932,63674:57933,63675:57934,63676:57935,63677:57936,63678:57937,63679:57938,63680:57939,63681:57940,63682:57941,63683:57942,63684:57943,63685:57944,63686:57945,63687:57946,63688:57947,63689:57948,63690:57949,63691:57950,63692:57951,63693:57952,63694:57953,63695:57954,63696:57955,63697:57956,63698:57957,63699:57958,63700:57959,63701:57960,63702:57961,63703:57962,63704:57963,63705:57964,63706:57965,63707:57966,63708:57967,63709:57968,63710:57969,63711:57970,63712:57971,63713:57972,63714:57973,63715:57974,63716:57975,63717:57976,63718:57977,63719:57978,63720:57979,63721:57980,63722:57981,63723:57982,63724:57983,63725:57984,63726:57985,63727:57986,63728:57987,63729:57988,63730:57989,63731:57990,63732:57991,63733:57992,63734:57993,63735:57994,63736:57995,63737:57996,63738:57997,63739:57998,63740:57999,63741:58000,63742:58001,63808:40259,63809:40260,63810:40261,63811:40262,63812:40263,63813:40264,63814:40265,63815:40266,63816:40267,63817:40268,63818:40269,63819:40270,63820:40271,63821:40272,63822:40273,63823:40274,63824:40275,63825:40276,63826:40277,63827:40278,63828:40279,63829:40280,63830:40281,63831:40282,63832:40283,63833:40284,63834:40285,63835:40286,63836:40287,63837:40288,63838:40289,63839:40290,63840:40291,63841:40292,63842:40293,63843:40294,63844:40295,63845:40296,63846:40297,63847:40298,63848:40299,63849:40300,63850:40301,63851:40302,63852:40303,63853:40304,63854:40305,63855:40306,63856:40307,63857:40308,63858:40309,63859:40310,63860:40311,63861:40312,63862:40313,63863:40314,63864:40315,63865:40316,63866:40317,63867:40318,63868:40319,63869:40320,63870:40321,63872:40322,63873:40323,63874:40324,63875:40325,63876:40326,63877:40327,63878:40328,63879:40329,63880:40330,63881:40331,63882:40332,63883:40333,63884:40334,63885:40335,63886:40336,63887:40337,63888:40338,63889:40339,63890:40340,63891:40341,63892:40342,63893:40343,63894:40344,63895:40345,63896:40346,63897:40347,63898:40348,63899:40349,63900:40350,63901:40351,63902:40352,63903:40353,63904:40354,63905:58002,63906:58003,63907:58004,63908:58005,63909:58006,63910:58007,63911:58008,63912:58009,63913:58010,63914:58011,63915:58012,63916:58013,63917:58014,63918:58015,63919:58016,63920:58017,63921:58018,63922:58019,63923:58020,63924:58021,63925:58022,63926:58023,63927:58024,63928:58025,63929:58026,63930:58027,63931:58028,63932:58029,63933:58030,63934:58031,63935:58032,63936:58033,63937:58034,63938:58035,63939:58036,63940:58037,63941:58038,63942:58039,63943:58040,63944:58041,63945:58042,63946:58043,63947:58044,63948:58045,63949:58046,63950:58047,63951:58048,63952:58049,63953:58050,63954:58051,63955:58052,63956:58053,63957:58054,63958:58055,63959:58056,63960:58057,63961:58058,63962:58059,63963:58060,63964:58061,63965:58062,63966:58063,63967:58064,63968:58065,63969:58066,63970:58067,63971:58068,63972:58069,63973:58070,63974:58071,63975:58072,63976:58073,63977:58074,63978:58075,63979:58076,63980:58077,63981:58078,63982:58079,63983:58080,63984:58081,63985:58082,63986:58083,63987:58084,63988:58085,63989:58086,63990:58087,63991:58088,63992:58089,63993:58090,63994:58091,63995:58092,63996:58093,63997:58094,63998:58095,64064:40355,64065:40356,64066:40357,64067:40358,64068:40359,64069:40360,64070:40361,64071:40362,64072:40363,64073:40364,64074:40365,64075:40366,64076:40367,64077:40368,64078:40369,64079:40370,64080:40371,64081:40372,64082:40373,64083:40374,64084:40375,64085:40376,64086:40377,64087:40378,64088:40379,64089:40380,64090:40381,64091:40382,64092:40383,64093:40384,64094:40385,64095:40386,64096:40387,64097:40388,64098:40389,64099:40390,64100:40391,64101:40392,64102:40393,64103:40394,64104:40395,64105:40396,64106:40397,64107:40398,64108:40399,64109:40400,64110:40401,64111:40402,64112:40403,64113:40404,64114:40405,64115:40406,64116:40407,64117:40408,64118:40409,64119:40410,64120:40411,64121:40412,64122:40413,64123:40414,64124:40415,64125:40416,64126:40417,64128:40418,64129:40419,64130:40420,64131:40421,64132:40422,64133:40423,64134:40424,64135:40425,64136:40426,64137:40427,64138:40428,64139:40429,64140:40430,64141:40431,64142:40432,64143:40433,64144:40434,64145:40435,64146:40436,64147:40437,64148:40438,64149:40439,64150:40440,64151:40441,64152:40442,64153:40443,64154:40444,64155:40445,64156:40446,64157:40447,64158:40448,64159:40449,64160:40450,64161:58096,64162:58097,64163:58098,64164:58099,64165:58100,64166:58101,64167:58102,64168:58103,64169:58104,64170:58105,64171:58106,64172:58107,64173:58108,64174:58109,64175:58110,64176:58111,64177:58112,64178:58113,64179:58114,64180:58115,64181:58116,64182:58117,64183:58118,64184:58119,64185:58120,64186:58121,64187:58122,64188:58123,64189:58124,64190:58125,64191:58126,64192:58127,64193:58128,64194:58129,64195:58130,64196:58131,64197:58132,64198:58133,64199:58134,64200:58135,64201:58136,64202:58137,64203:58138,64204:58139,64205:58140,64206:58141,64207:58142,64208:58143,64209:58144,64210:58145,64211:58146,64212:58147,64213:58148,64214:58149,64215:58150,64216:58151,64217:58152,64218:58153,64219:58154,64220:58155,64221:58156,64222:58157,64223:58158,64224:58159,64225:58160,64226:58161,64227:58162,64228:58163,64229:58164,64230:58165,64231:58166,64232:58167,64233:58168,64234:58169,64235:58170,64236:58171,64237:58172,64238:58173,64239:58174,64240:58175,64241:58176,64242:58177,64243:58178,64244:58179,64245:58180,64246:58181,64247:58182,64248:58183,64249:58184,64250:58185,64251:58186,64252:58187,64253:58188,64254:58189,64320:40451,64321:40452,64322:40453,64323:40454,64324:40455,64325:40456,64326:40457,64327:40458,64328:40459,64329:40460,64330:40461,64331:40462,64332:40463,64333:40464,64334:40465,64335:40466,64336:40467,64337:40468,64338:40469,64339:40470,64340:40471,64341:40472,64342:40473,64343:40474,64344:40475,64345:40476,64346:40477,64347:40478,64348:40484,64349:40487,64350:40494,64351:40496,64352:40500,64353:40507,64354:40508,64355:40512,64356:40525,64357:40528,64358:40530,64359:40531,64360:40532,64361:40534,64362:40537,64363:40541,64364:40543,64365:40544,64366:40545,64367:40546,64368:40549,64369:40558,64370:40559,64371:40562,64372:40564,64373:40565,64374:40566,64375:40567,64376:40568,64377:40569,64378:40570,64379:40571,64380:40572,64381:40573,64382:40576,64384:40577,64385:40579,64386:40580,64387:40581,64388:40582,64389:40585,64390:40586,64391:40588,64392:40589,64393:40590,64394:40591,64395:40592,64396:40593,64397:40596,64398:40597,64399:40598,64400:40599,64401:40600,64402:40601,64403:40602,64404:40603,64405:40604,64406:40606,64407:40608,64408:40609,64409:40610,64410:40611,64411:40612,64412:40613,64413:40615,64414:40616,64415:40617,64416:40618,64417:58190,64418:58191,64419:58192,64420:58193,64421:58194,64422:58195,64423:58196,64424:58197,64425:58198,64426:58199,64427:58200,64428:58201,64429:58202,64430:58203,64431:58204,64432:58205,64433:58206,64434:58207,64435:58208,64436:58209,64437:58210,64438:58211,64439:58212,64440:58213,64441:58214,64442:58215,64443:58216,64444:58217,64445:58218,64446:58219,64447:58220,64448:58221,64449:58222,64450:58223,64451:58224,64452:58225,64453:58226,64454:58227,64455:58228,64456:58229,64457:58230,64458:58231,64459:58232,64460:58233,64461:58234,64462:58235,64463:58236,64464:58237,64465:58238,64466:58239,64467:58240,64468:58241,64469:58242,64470:58243,64471:58244,64472:58245,64473:58246,64474:58247,64475:58248,64476:58249,64477:58250,64478:58251,64479:58252,64480:58253,64481:58254,64482:58255,64483:58256,64484:58257,64485:58258,64486:58259,64487:58260,64488:58261,64489:58262,64490:58263,64491:58264,64492:58265,64493:58266,64494:58267,64495:58268,64496:58269,64497:58270,64498:58271,64499:58272,64500:58273,64501:58274,64502:58275,64503:58276,64504:58277,64505:58278,64506:58279,64507:58280,64508:58281,64509:58282,64510:58283,64576:40619,64577:40620,64578:40621,64579:40622,64580:40623,64581:40624,64582:40625,64583:40626,64584:40627,64585:40629,64586:40630,64587:40631,64588:40633,64589:40634,64590:40636,64591:40639,64592:40640,64593:40641,64594:40642,64595:40643,64596:40645,64597:40646,64598:40647,64599:40648,64600:40650,64601:40651,64602:40652,64603:40656,64604:40658,64605:40659,64606:40661,64607:40662,64608:40663,64609:40665,64610:40666,64611:40670,64612:40673,64613:40675,64614:40676,64615:40678,64616:40680,64617:40683,64618:40684,64619:40685,64620:40686,64621:40688,64622:40689,64623:40690,64624:40691,64625:40692,64626:40693,64627:40694,64628:40695,64629:40696,64630:40698,64631:40701,64632:40703,64633:40704,64634:40705,64635:40706,64636:40707,64637:40708,64638:40709,64640:40710,64641:40711,64642:40712,64643:40713,64644:40714,64645:40716,64646:40719,64647:40721,64648:40722,64649:40724,64650:40725,64651:40726,64652:40728,64653:40730,64654:40731,64655:40732,64656:40733,64657:40734,64658:40735,64659:40737,64660:40739,64661:40740,64662:40741,64663:40742,64664:40743,64665:40744,64666:40745,64667:40746,64668:40747,64669:40749,64670:40750,64671:40752,64672:40753,64673:58284,64674:58285,64675:58286,64676:58287,64677:58288,64678:58289,64679:58290,64680:58291,64681:58292,64682:58293,64683:58294,64684:58295,64685:58296,64686:58297,64687:58298,64688:58299,64689:58300,64690:58301,64691:58302,64692:58303,64693:58304,64694:58305,64695:58306,64696:58307,64697:58308,64698:58309,64699:58310,64700:58311,64701:58312,64702:58313,64703:58314,64704:58315,64705:58316,64706:58317,64707:58318,64708:58319,64709:58320,64710:58321,64711:58322,64712:58323,64713:58324,64714:58325,64715:58326,64716:58327,64717:58328,64718:58329,64719:58330,64720:58331,64721:58332,64722:58333,64723:58334,64724:58335,64725:58336,64726:58337,64727:58338,64728:58339,64729:58340,64730:58341,64731:58342,64732:58343,64733:58344,64734:58345,64735:58346,64736:58347,64737:58348,64738:58349,64739:58350,64740:58351,64741:58352,64742:58353,64743:58354,64744:58355,64745:58356,64746:58357,64747:58358,64748:58359,64749:58360,64750:58361,64751:58362,64752:58363,64753:58364,64754:58365,64755:58366,64756:58367,64757:58368,64758:58369,64759:58370,64760:58371,64761:58372,64762:58373,64763:58374,64764:58375,64765:58376,64766:58377,64832:40754,64833:40755,64834:40756,64835:40757,64836:40758,64837:40760,64838:40762,64839:40764,64840:40767,64841:40768,64842:40769,64843:40770,64844:40771,64845:40773,64846:40774,64847:40775,64848:40776,64849:40777,64850:40778,64851:40779,64852:40780,64853:40781,64854:40782,64855:40783,64856:40786,64857:40787,64858:40788,64859:40789,64860:40790,64861:40791,64862:40792,64863:40793,64864:40794,64865:40795,64866:40796,64867:40797,64868:40798,64869:40799,64870:40800,64871:40801,64872:40802,64873:40803,64874:40804,64875:40805,64876:40806,64877:40807,64878:40808,64879:40809,64880:40810,64881:40811,64882:40812,64883:40813,64884:40814,64885:40815,64886:40816,64887:40817,64888:40818,64889:40819,64890:40820,64891:40821,64892:40822,64893:40823,64894:40824,64896:40825,64897:40826,64898:40827,64899:40828,64900:40829,64901:40830,64902:40833,64903:40834,64904:40845,64905:40846,64906:40847,64907:40848,64908:40849,64909:40850,64910:40851,64911:40852,64912:40853,64913:40854,64914:40855,64915:40856,64916:40860,64917:40861,64918:40862,64919:40865,64920:40866,64921:40867,64922:40868,64923:40869,64924:63788,64925:63865,64926:63893,64927:63975,64928:63985,64929:58378,64930:58379,64931:58380,64932:58381,64933:58382,64934:58383,64935:58384,64936:58385,64937:58386,64938:58387,64939:58388,64940:58389,64941:58390,64942:58391,64943:58392,64944:58393,64945:58394,64946:58395,64947:58396,64948:58397,64949:58398,64950:58399,64951:58400,64952:58401,64953:58402,64954:58403,64955:58404,64956:58405,64957:58406,64958:58407,64959:58408,64960:58409,64961:58410,64962:58411,64963:58412,64964:58413,64965:58414,64966:58415,64967:58416,64968:58417,64969:58418,64970:58419,64971:58420,64972:58421,64973:58422,64974:58423,64975:58424,64976:58425,64977:58426,64978:58427,64979:58428,64980:58429,64981:58430,64982:58431,64983:58432,64984:58433,64985:58434,64986:58435,64987:58436,64988:58437,64989:58438,64990:58439,64991:58440,64992:58441,64993:58442,64994:58443,64995:58444,64996:58445,64997:58446,64998:58447,64999:58448,65000:58449,65001:58450,65002:58451,65003:58452,65004:58453,65005:58454,65006:58455,65007:58456,65008:58457,65009:58458,65010:58459,65011:58460,65012:58461,65013:58462,65014:58463,65015:58464,65016:58465,65017:58466,65018:58467,65019:58468,65020:58469,65021:58470,65022:58471,65088:64012,65089:64013,65090:64014,65091:64015,65092:64017,65093:64019,65094:64020,65095:64024,65096:64031,65097:64032,65098:64033,65099:64035,65100:64036,65101:64039,65102:64040,65103:64041,65104:11905,65105:59414,65106:59415,65107:59416,65108:11908,65109:13427,65110:13383,65111:11912,65112:11915,65113:59422,65114:13726,65115:13850,65116:13838,65117:11916,65118:11927,65119:14702,65120:14616,65121:59430,65122:14799,65123:14815,65124:14963,65125:14800,65126:59435,65127:59436,65128:15182,65129:15470,65130:15584,65131:11943,65132:59441,65133:59442,65134:11946,65135:16470,65136:16735,65137:11950,65138:17207,65139:11955,65140:11958,65141:11959,65142:59451,65143:17329,65144:17324,65145:11963,65146:17373,65147:17622,65148:18017,65149:17996,65150:59459,65152:18211,65153:18217,65154:18300,65155:18317,65156:11978,65157:18759,65158:18810,65159:18813,65160:18818,65161:18819,65162:18821,65163:18822,65164:18847,65165:18843,65166:18871,65167:18870,65168:59476,65169:59477,65170:19619,65171:19615,65172:19616,65173:19617,65174:19575,65175:19618,65176:19731,65177:19732,65178:19733,65179:19734,65180:19735,65181:19736,65182:19737,65183:19886,65184:59492,65185:58472,65186:58473,65187:58474,65188:58475,65189:58476,65190:58477,65191:58478,65192:58479,65193:58480,65194:58481,65195:58482,65196:58483,65197:58484,65198:58485,65199:58486,65200:58487,65201:58488,65202:58489,65203:58490,65204:58491,65205:58492,65206:58493,65207:58494,65208:58495,65209:58496,65210:58497,65211:58498,65212:58499,65213:58500,65214:58501,65215:58502,65216:58503,65217:58504,65218:58505,65219:58506,65220:58507,65221:58508,65222:58509,65223:58510,65224:58511,65225:58512,65226:58513,65227:58514,65228:58515,65229:58516,65230:58517,65231:58518,65232:58519,65233:58520,65234:58521,65235:58522,65236:58523,65237:58524,65238:58525,65239:58526,65240:58527,65241:58528,65242:58529,65243:58530,65244:58531,65245:58532,65246:58533,65247:58534,65248:58535,65249:58536,65250:58537,65251:58538,65252:58539,65253:58540,65254:58541,65255:58542,65256:58543,65257:58544,65258:58545,65259:58546,65260:58547,65261:58548,65262:58549,65263:58550,65264:58551,65265:58552,65266:58553,65267:58554,65268:58555,65269:58556,65270:58557,65271:58558,65272:58559,65273:58560,65274:58561,65275:58562,65276:58563,65277:58564,65278:58565}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/generation/generate-big5-table.js
-@@ -0,0 +1,25 @@
-+var http = require('http');
-+var fs = require('fs');
-+// BIG5
-+var cp950_b2u = {host:'moztw.org',path:'/docs/big5/table/cp950-b2u.txt'},
-+    cp950_u2b = {host:'moztw.org',path:'/docs/big5/table/cp950-u2b.txt'},
-+    cp950_moz18_b2u = {host:'moztw.org',path:'/docs/big5/table/moz18-b2u.txt'};
-+
-+http.get(cp950_moz18_b2u, function(res) {
-+  var data = '';
-+  res.on('data', function(chunk) {
-+    data += chunk;
-+  });
-+  res.on('end', function() {
-+    var table = {};
-+    data = data.split('\n').slice(1);
-+    data.forEach(function(line, idx) {
-+      var pair = line.split(' ');
-+      var key = parseInt(pair[0]);
-+      var val = parseInt(pair[1]);
-+      table[key] = val;
-+    });
-+    fs.createWriteSync('encodings/table/big5.js',
-+    	'module.exports = ' + JSON.stringify(table) + ';');
-+  });
-+});
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/generation/generate-singlebyte.js
-@@ -0,0 +1,142 @@
-+var fs  = require("fs");
-+var Iconv  = require("iconv").Iconv;
-+
-+
-+var encodingFamilies = [
-+    {
-+        // Windows code pages
-+        encodings: [1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258],
-+        convert: function(cp) {
-+            return {
-+                name: "windows-"+cp,
-+                aliases: ["win"+cp, "cp"+cp, ""+cp],
-+            }
-+        }
-+    },
-+    {
-+        // ISO-8859 code pages
-+        encodings: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16],
-+        convert: function(i) {
-+            return {
-+                name: "iso-8859-"+i,
-+                aliases: ["cp"+(28590+i), (28590+i)],
-+            }
-+        }
-+    },
-+    {
-+        // IBM/DOS code pages
-+        encodings: [437, 737, 775, 850, 852, 855, 857, 858, 860, 861, 862, 863, 864, 865, 866, 869],
-+        convert: function(cp) {
-+            return {
-+                name: "CP"+cp,
-+                aliases: ["ibm"+cp, ""+cp],
-+            }
-+        }
-+    },
-+    {
-+        // Macintosh code pages
-+        encodings: ["macCroatian", "macCyrillic", "macGreek", 
-+                    "macIceland", "macRoman", "macRomania", 
-+                    "macThai", "macTurkish", "macUkraine"],
-+    },
-+    {
-+        // KOI8 code pages
-+        encodings: ["KOI8-R", "KOI8-U"],
-+    },
-+];
-+
-+
-+var encodings = {
-+    // Aliases.
-+    "ascii8bit": "ascii",
-+    "usascii": "ascii",
-+
-+    "latin1": "iso88591",
-+    "latin2": "iso88592",
-+    "latin3": "iso88593",
-+    "latin4": "iso88594",
-+    "latin6": "iso885910",
-+    "latin7": "iso885913",
-+    "latin8": "iso885914",
-+    "latin9": "iso885915",
-+    "latin10": "iso885916",
-+
-+    "cp819": "iso88951",
-+    "arabic": "iso88596",
-+    "arabic8": "iso88596",
-+    "greek" : "iso88597",
-+    "greek8" : "iso88597",
-+    "hebrew": "iso88598",
-+    "hebrew8": "iso88598",
-+    "turkish": "iso88599",
-+    "turkish8": "iso88599",
-+    "thai": "iso885911",
-+    "thai8": "iso885911",
-+    "tis620": "iso885911",
-+    "windows874": "iso885911",
-+    "win874": "iso885911",
-+    "cp874": "iso885911",
-+    "874": "iso885911",
-+    "celtic": "iso885914",
-+    "celtic8": "iso885914",
-+
-+    "cp20866": "koi8r",
-+    "20866": "koi8r",
-+    "ibm878": "koi8r",
-+    "cp21866": "koi8u",
-+    "21866": "koi8u",
-+    "ibm1168": "koi8u",
-+    
-+};
-+
-+// Add all encodings from encodingFamilies.
-+encodingFamilies.forEach(function(family){
-+    family.encodings.forEach(function(encoding){
-+        if (family.convert)
-+            encoding = family.convert(encoding);
-+
-+        var encodingIconvName = encoding.name ? encoding.name : encoding; 
-+        var encodingName = encodingIconvName.replace(/[-_]/g, "").toLowerCase();
-+
-+        encodings[encodingName] = {
-+            type: "singlebyte",
-+            chars: generateCharsString(encodingIconvName)
-+        };
-+
-+        if (encoding.aliases)
-+            encoding.aliases.forEach(function(alias){
-+                encodings[alias] = encodingName;
-+            });
-+    });
-+});
-+
-+// Write encodings.
-+fs.writeFileSync("encodings/singlebyte.js", 
-+    "module.exports = " + JSON.stringify(encodings, undefined, "  ") + ";");
-+
-+
-+function generateCharsString(encoding) {
-+    console.log("Generate encoding for " + encoding);
-+    var iconvToUtf8 = new Iconv(encoding, "UTF-8");
-+    var chars = "";
-+
-+    for (var b = 0x80; b < 0x100; b++) {
-+
-+        try {
-+            var convertedChar = iconvToUtf8.convert(new Buffer([b])).toString();
-+            
-+            if (convertedChar.length != 1)
-+                throw new Error("Single-byte encoding error: Must return single char.");
-+        } catch (exception) {
-+            if (exception.code === "EILSEQ") {
-+                convertedChar = "\ufffd";
-+            } else {
-+                throw exception;
-+            }
-+        }
-+
-+        chars += convertedChar;
-+    }
-+
-+    return chars;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/index.js
-@@ -0,0 +1,231 @@
-+var RE_SPACEDASH = /[- ]/g;
-+// Module exports
-+var iconv = module.exports = {
-+    toEncoding: function(str, encoding) {
-+        return iconv.getCodec(encoding).toEncoding(str);
-+    },
-+    fromEncoding: function(buf, encoding) {
-+        return iconv.getCodec(encoding).fromEncoding(buf);
-+    },
-+    encodingExists: function(enc) {
-+        loadEncodings();
-+        enc = enc.replace(RE_SPACEDASH, "").toLowerCase();
-+        return (iconv.encodings[enc] !== undefined);
-+    },
-+    
-+    defaultCharUnicode: '�',
-+    defaultCharSingleByte: '?',
-+
-+    encodingsLoaded: false,
-+    
-+    // Get correct codec for given encoding.
-+    getCodec: function(encoding) {
-+        loadEncodings();
-+        var enc = encoding || "utf8";
-+        var codecOptions = undefined;
-+        while (1) {
-+            if (getType(enc) === "String")
-+                enc = enc.replace(RE_SPACEDASH, "").toLowerCase();
-+            var codec = iconv.encodings[enc];
-+            var type = getType(codec);
-+            if (type === "String") {
-+                // Link to other encoding.
-+                codecOptions = {originalEncoding: enc};
-+                enc = codec;
-+            }
-+            else if (type === "Object" && codec.type != undefined) {
-+                // Options for other encoding.
-+                codecOptions = codec;
-+                enc = codec.type;
-+            } 
-+            else if (type === "Function")
-+                // Codec itself.
-+                return codec(codecOptions);
-+            else
-+                throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')");
-+        }
-+    },
-+    
-+    // Define basic encodings
-+    encodings: {
-+        internal: function(options) {
-+            return {
-+                toEncoding: toInternalEncoding,
-+                fromEncoding: fromInternalEncoding,
-+                options: options
-+            };
-+        },
-+        utf8: "internal",
-+        ucs2: "internal",
-+        binary: "internal",
-+        ascii: "internal",
-+        base64: "internal",
-+        
-+        // Codepage single-byte encodings.
-+        singlebyte: function(options) {
-+            // Prepare chars if needed
-+            if (!options.charsBuf) {
-+                if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256))
-+                    throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)");
-+                
-+                if (options.chars.length === 128)
-+                    options.chars = asciiString + options.chars;
-+
-+                options.charsBuf = new Buffer(options.chars, 'ucs2');
-+            }
-+            
-+            if (!options.revCharsBuf) {
-+                options.revCharsBuf = new Buffer(65536);
-+                var defChar = iconv.defaultCharSingleByte.charCodeAt(0);
-+                for (var i = 0; i < options.revCharsBuf.length; i++)
-+                    options.revCharsBuf[i] = defChar;
-+                for (var i = 0; i < options.chars.length; i++)
-+                    options.revCharsBuf[options.chars.charCodeAt(i)] = i;
-+            }
-+
-+            return {
-+                toEncoding: toSingleByteEncoding,
-+                fromEncoding: fromSingleByteEncoding,
-+                options: options,
-+            };
-+        },
-+
-+        // Codepage double-byte encodings.
-+        table: function(options) {
-+            if (!options.table) {
-+                throw new Error("Encoding '" + options.type + "' has incorect 'table' option");
-+            }
-+            if (!options.revCharsTable) {
-+                var revCharsTable = options.revCharsTable = {};
-+                for (var i = 0; i <= 0xFFFF; i++) {
-+                    revCharsTable[i] = 0;
-+                }
-+
-+                var table = options.table;
-+                for (var key in table) {
-+                    revCharsTable[table[key]] = +key;
-+                }
-+            }
-+            
-+            return {
-+                toEncoding: toTableEncoding,
-+                fromEncoding: fromTableEncoding,
-+                options: options,
-+            };
-+        }
-+    }
-+};
-+
-+function toInternalEncoding(str) {
-+    return new Buffer(ensureString(str), this.options.originalEncoding);
-+}
-+
-+function fromInternalEncoding(buf) {
-+    return ensureBuffer(buf).toString(this.options.originalEncoding);
-+}
-+
-+function toTableEncoding(str) {
-+    str = ensureString(str);
-+    var strLen = str.length;
-+    var revCharsTable = this.options.revCharsTable;
-+    var newBuf = new Buffer(strLen*2), gbkcode, unicode,
-+        defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)];
-+
-+    for (var i = 0, j = 0; i < strLen; i++) {
-+        unicode = str.charCodeAt(i);
-+        if (unicode >> 7) {
-+            gbkcode = revCharsTable[unicode] || defaultChar;
-+            newBuf[j++] = gbkcode >> 8; //high byte;
-+            newBuf[j++] = gbkcode & 0xFF; //low byte
-+        } else {//ascii
-+            newBuf[j++] = unicode;
-+        }
-+    }
-+    return newBuf.slice(0, j);
-+}
-+
-+function fromTableEncoding(buf) {
-+    buf = ensureBuffer(buf);
-+    var bufLen = buf.length;
-+    var table = this.options.table;
-+    var newBuf = new Buffer(bufLen*2), unicode, gbkcode,
-+        defaultChar = iconv.defaultCharUnicode.charCodeAt(0);
-+
-+    for (var i = 0, j = 0; i < bufLen; i++, j+=2) {
-+        gbkcode = buf[i];
-+        if (gbkcode & 0x80) {
-+            gbkcode = (gbkcode << 8) + buf[++i];
-+            unicode = table[gbkcode] || defaultChar;
-+        } else {
-+            unicode = gbkcode;
-+        }
-+        newBuf[j] = unicode & 0xFF; //low byte
-+        newBuf[j+1] = unicode >> 8; //high byte
-+    }
-+    return newBuf.slice(0, j).toString('ucs2');
-+}
-+
-+function toSingleByteEncoding(str) {
-+    str = ensureString(str);
-+    
-+    var buf = new Buffer(str.length);
-+    var revCharsBuf = this.options.revCharsBuf;
-+    for (var i = 0; i < str.length; i++)
-+        buf[i] = revCharsBuf[str.charCodeAt(i)];
-+    
-+    return buf;
-+}
-+
-+function fromSingleByteEncoding(buf) {
-+    buf = ensureBuffer(buf);
-+    
-+    // Strings are immutable in JS -> we use ucs2 buffer to speed up computations.
-+    var charsBuf = this.options.charsBuf;
-+    var newBuf = new Buffer(buf.length*2);
-+    var idx1 = 0, idx2 = 0;
-+    for (var i = 0, _len = buf.length; i < _len; i++) {
-+        idx1 = buf[i]*2; idx2 = i*2;
-+        newBuf[idx2] = charsBuf[idx1];
-+        newBuf[idx2+1] = charsBuf[idx1+1];
-+    }
-+    return newBuf.toString('ucs2');
-+}
-+
-+// Add aliases to convert functions
-+iconv.encode = iconv.toEncoding;
-+iconv.decode = iconv.fromEncoding;
-+
-+// Load other encodings manually from files in /encodings dir.
-+function loadEncodings() {
-+    if (!iconv.encodingsLoaded) {
-+        [ require('./encodings/singlebyte'),
-+          require('./encodings/gbk'),
-+          require('./encodings/big5')
-+        ].forEach(function(encodings) {
-+            for (var key in encodings)
-+                iconv.encodings[key] = encodings[key]
-+        });
-+        iconv.encodingsLoaded = true;
-+    }
-+}
-+
-+
-+
-+// Utilities
-+var asciiString = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+
-+              ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f';
-+
-+var ensureBuffer = function(buf) {
-+    buf = buf || new Buffer(0);
-+    return (buf instanceof Buffer) ? buf : new Buffer(""+buf, "binary");
-+}
-+
-+var ensureString = function(str) {
-+    str = str || "";
-+    return (str instanceof Buffer) ? str.toString('utf8') : (""+str);
-+}
-+
-+var getType = function(obj) {
-+    return Object.prototype.toString.call(obj).slice(8, -1);
-+}
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/package.json
-@@ -0,0 +1,80 @@
-+{
-+  "name": "iconv-lite",
-+  "description": "Convert character encodings in pure javascript.",
-+  "version": "0.2.11",
-+  "license": "MIT",
-+  "keywords": [
-+    "iconv",
-+    "convert",
-+    "charset"
-+  ],
-+  "author": {
-+    "name": "Alexander Shtuchkin",
-+    "email": "ashtuchkin at gmail.com"
-+  },
-+  "contributors": [
-+    {
-+      "name": "Jinwu Zhan",
-+      "url": "https://github.com/jenkinv"
-+    },
-+    {
-+      "name": "Adamansky Anton",
-+      "url": "https://github.com/adamansky"
-+    },
-+    {
-+      "name": "George Stagas",
-+      "url": "https://github.com/stagas"
-+    },
-+    {
-+      "name": "Mike D Pilsbury",
-+      "url": "https://github.com/pekim"
-+    },
-+    {
-+      "name": "Niggler",
-+      "url": "https://github.com/Niggler"
-+    },
-+    {
-+      "name": "wychi",
-+      "url": "https://github.com/wychi"
-+    },
-+    {
-+      "name": "David Kuo",
-+      "url": "https://github.com/david50407"
-+    },
-+    {
-+      "name": "ChangZhuo Chen",
-+      "url": "https://github.com/czchen"
-+    },
-+    {
-+      "name": "Lee Treveil",
-+      "url": "https://github.com/leetreveil"
-+    },
-+    {
-+      "name": "Brian White",
-+      "url": "https://github.com/mscdex"
-+    }
-+  ],
-+  "main": "index.js",
-+  "homepage": "https://github.com/ashtuchkin/iconv-lite",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/ashtuchkin/iconv-lite.git"
-+  },
-+  "engines": {
-+    "node": ">=0.4.0"
-+  },
-+  "scripts": {
-+    "test": "vows --spec"
-+  },
-+  "devDependencies": {
-+    "vows": "",
-+    "iconv": ">=1.1"
-+  },
-+  "readme": "iconv-lite - pure javascript character encoding conversion\n======================================================================\n\n[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite)\n\n## Features\n\n*   Pure javascript. Doesn't need native code compilation.\n*   Easy API.\n*   Works on Windows and in sandboxed environments like [Cloud9](http://c9.io).\n*   Encoding is much faster than node-iconv (see below for performance comparison).\n\n## Usage\n\n    var iconv = require('iconv-lite');\n    \n    // Convert from an encoded buffer to string.\n    str = iconv.decode(buf, 'win1251');\n    \n    // Convert from string to an encoded buffer.\n    buf = iconv.encode(\"Sample input string\", 'win1251');\n\n    // Check if encoding is supported\n    iconv.encodingExists(\"us-ascii\")\n\n\n## Supported encodings\n\n*   All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64'\n*   All widespread single byte encodings: Windows 125x family, ISO-8859 family, \n    IBM/DOS codepages, Macintosh family, KOI8 family. \n    Aliases like 'latin1', 'us-ascii' also supported.\n*   Multibyte encodings: 'gbk', 'gb2313', 'Big5', 'cp950'.\n\nOthers are easy to add, see the source. Please, participate.\nMost encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors!\n\nNot supported yet: EUC family, Shift_JIS.\n\n\n## Encoding/decoding speed\n\nComparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). \nNote: your results may vary, so please always check on your hardware.\n\n    operation             iconv at 1.2.4   iconv-lite at 0.2.4 \n    ----------------------------------------------------------\n    encode('win1251')     ~115 Mb/s     ~230 Mb/s\n    decode('win1251')     ~95 Mb/s      ~130 Mb/s\n\n\n## Notes\n\nWhen decoding, a 'binary'-encoded string can be used as a source buffer.  \nUntranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome.\n\n## Testing\n\n    git clone git at github.com:ashtuchkin/iconv-lite.git\n    cd iconv-lite\n    npm install\n    npm test\n    \n    # To view performance:\n    node test/performance.js\n\n## TODO\n\n*   Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')).\n*   Add more encodings.\n*   Add transliteration (best fit char).\n*   Add tests and correct support of variable-byte encodings (currently work is delegated to node).\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/ashtuchkin/iconv-lite/issues"
-+  },
-+  "_id": "iconv-lite at 0.2.11",
-+  "_from": "iconv-lite@~0.2.11"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/big5-test.js
-@@ -0,0 +1,36 @@
-+var vows    = require('vows'),
-+    fs      = require('fs'),
-+    assert  = require('assert'),
-+    iconv   = require(__dirname + '/../');
-+
-+var testString = "中文abc", //unicode contains Big5-code and ascii
-+    testStringBig5Buffer = new Buffer([0xa4,0xa4,0xa4,0xe5,0x61,0x62,0x63]),
-+    testString2 = '測試',
-+    testStringBig5Buffer2 = new Buffer([0xb4, 0xfa, 0xb8, 0xd5]);
-+
-+vows.describe("Big5 tests").addBatch({
-+    "Big5 correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testString, "big5").toString('binary'), testStringBig5Buffer.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "big5"), testString);
-+        assert.strictEqual(iconv.toEncoding(testString2, 'big5').toString('binary'), testStringBig5Buffer2.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer2, 'big5'), testString2);
-+    },
-+    "cp950 correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testString, "cp950").toString('binary'), testStringBig5Buffer.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "cp950"), testString);
-+    },
-+    "Big5 file read decoded,compare with iconv result": function() {
-+        var contentBuffer = fs.readFileSync(__dirname+"/big5File.txt");
-+        var str = iconv.fromEncoding(contentBuffer, "big5");
-+        var iconvc = new (require('iconv').Iconv)('big5','utf8');
-+        assert.strictEqual(iconvc.convert(contentBuffer).toString(), str);
-+    },
-+    "Big5 correctly decodes and encodes characters · and ×": function() {
-+        // https://github.com/ashtuchkin/iconv-lite/issues/13
-+        // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT
-+        var chars = "·×";
-+        var big5Chars = new Buffer([0xA1, 0x50, 0xA1, 0xD1]);
-+        assert.strictEqual(iconv.toEncoding(chars, "big5").toString('binary'), big5Chars.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(big5Chars, "big5"), chars)
-+    },
-+}).export(module)
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/big5File.txt
-@@ -0,0 +1,13 @@
-+<HTML>
-+<HEAD>    
-+	<TITLE> meta ¼ÐÅÒªº¨Ï¥Î¡G¤¤¤åºô­¶ </TITLE>
-+	<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
-+</HEAD>
-+<BODY>
-+
-+³o¬O¤@­ÓÁcÅ餤¤åºô­¶¡I<br>
-+(This page uses big5 character set.)<br>
-+charset=big5
-+
-+</BODY>
-+</HTML>
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/cyrillic-test.js
-@@ -0,0 +1,86 @@
-+var vows = require('vows'),
-+    assert = require('assert'),
-+    iconv = require(__dirname+'/../');
-+
-+var baseStrings = {
-+    empty: "",
-+    hi: "Привет!",
-+    ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+
-+           ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f',
-+    rus: "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя",
-+    additional1: "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬\xAD®Ї°±Ііґµ¶·ё№є»јЅѕї",
-+    additional2: "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©",
-+    additional3: " ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏ№ёђѓєѕіїјљњћќ§ўџ",
-+    untranslatable: "£Åçþÿ¿",
-+};
-+
-+var encodings = [{
-+    name: "Win-1251",
-+    variations: ['win1251', 'Windows-1251', 'windows1251', 'CP1251', 1251],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\xcf\xf0\xe8\xe2\xe5\xf2!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        rus: new Buffer('\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'),
-+        additional1: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf','binary'),
-+    }
-+}, {
-+    name: "Koi8-R",
-+    variations: ['koi8r', 'KOI8-R', 'cp20866', 20866],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\xf0\xd2\xc9\xd7\xc5\xd4!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        rus: new Buffer('\xe1\xe2\xf7\xe7\xe4\xe5\xf6\xfa\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf2\xf3\xf4\xf5\xe6\xe8\xe3\xfe\xfb\xfd\xff\xf9\xf8\xfc\xe0\xf1\xc1\xc2\xd7\xc7\xc4\xc5\xd6\xda\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd2\xd3\xd4\xd5\xc6\xc8\xc3\xde\xdb\xdd\xdf\xd9\xd8\xdc\xc0\xd1', 'binary'),
-+        additional2: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf', 'binary'),
-+    }
-+}, {
-+    name: "ISO 8859-5",
-+    variations: ['iso88595', 'ISO-8859-5', 'ISO 8859-5', 'cp28595', 28595],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\xbf\xe0\xd8\xd2\xd5\xe2!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        rus: new Buffer('\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef', 'binary'),
-+        additional3: new Buffer('\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'),
-+    }
-+}];
-+
-+var testsBatch = {};
-+encodings.forEach(function(encoding) {
-+    var enc = encoding.variations[0];
-+    var key = "hi";
-+    var tests = {
-+        "Convert to empty buffer": function() {
-+            assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary'));
-+        },
-+        "Convert from empty buffer": function() {
-+            assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), "");
-+        },
-+        "Convert from buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), 
-+                    baseStrings[key]);
-+        },
-+        "Convert to buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), 
-+                    encoding.encodedStrings[key].toString('binary'));
-+        },
-+        "Try different variations of encoding": function() {
-+            encoding.variations.forEach(function(enc) {
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]);
-+                assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary'));
-+            });
-+        },
-+        "Untranslatable chars are converted to defaultCharSingleByte": function() {
-+            var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join('');
-+            assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters.
-+        }
-+    };
-+    
-+    testsBatch[encoding.name+":"] = tests;
-+});
-+
-+vows.describe("Test Cyrillic encodings").addBatch(testsBatch).export(module);
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/gbk-test.js
-@@ -0,0 +1,38 @@
-+var vows    = require('vows'),
-+    fs      = require('fs'),
-+    assert  = require('assert'),
-+    iconv   = require(__dirname+'/../');
-+
-+var testString = "中国abc",//unicode contains GBK-code and ascii
-+    testStringGBKBuffer = new Buffer([0xd6,0xd0,0xb9,0xfa,0x61,0x62,0x63]);
-+
-+vows.describe("GBK tests").addBatch({
-+    "Vows is working": function() {},
-+    "Return values are of correct types": function() {
-+        assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer);        
-+        var s = iconv.fromEncoding(new Buffer(testString), "utf8");
-+        assert.strictEqual(Object.prototype.toString.call(s), "[object String]");
-+    },
-+    "GBK correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testString, "GBK").toString('binary'), testStringGBKBuffer.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GBK"), testString);
-+    },
-+    "GB2312 correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testString, "GB2312").toString('binary'), testStringGBKBuffer.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GB2312"), testString);
-+    },
-+    "GBK file read decoded,compare with iconv result": function() {
-+        var contentBuffer = fs.readFileSync(__dirname+"/gbkFile.txt");
-+        var str = iconv.fromEncoding(contentBuffer, "GBK");
-+        var iconvc = new (require('iconv').Iconv)('GBK','utf8');
-+        assert.strictEqual(iconvc.convert(contentBuffer).toString(), str);
-+    },
-+    "GBK correctly decodes and encodes characters · and ×": function() {
-+        // https://github.com/ashtuchkin/iconv-lite/issues/13
-+        // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT
-+        var chars = "·×";
-+        var gbkChars = new Buffer([0xA1, 0xA4, 0xA1, 0xC1]);
-+        assert.strictEqual(iconv.toEncoding(chars, "GBK").toString('binary'), gbkChars.toString('binary'));
-+        assert.strictEqual(iconv.fromEncoding(gbkChars, "GBK"), chars)
-+    },
-+}).export(module)
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/gbkFile.txt
-@@ -0,0 +1,14 @@
-+<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html;charset=gb2312"><title>°Ù¶Èһϣ¬Äã¾ÍÖªµÀ      </title><style>html{overflow-y:auto}body{font:12px arial;text-align:center;background:#fff}body,p,form,ul,li{margin:0;padding:0;list-style:none}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{padding:7px 10px 3px 0;text-align:right}#m{width:680px;margin:0 auto}#nv{font-size:16px;margin:0 0 4px;text-align:left;text-indent:117px}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:90px;text-align:left}#kw{width:404px;height:22px;padding:4px 7px;padding:6px 7px 2px\9;font:16px arial;background:url(http://www.baidu.com/img/i-1.0.0.png) no-repeat -304px 0;_background-attachment:fixed;border:1px solid #cdcdcd;border-color:#9a9a9a #cdcdcd #cdcdcd #9a9a9a;vertical-align:top}.btn{width:95px;height:32px;padding:0;padding-top:2px\9;border:0;background:#ddd url(http://www.baidu.com/img/i-1.0.0.png) no-repeat;cursor:pointer}.btn_h{background-position:-100px 0}#kw,.btn_wr{margin:0 5px 0 0}.btn_wr{width:97px;height:34px;display:inline-block;background:url(http://www.baidu.com/img/i-1.0.0.png) no-repeat -202px 0;_top:1px;*position:relative}#lk{margin:33px 0}#lk span{font:14px "ËÎÌå"}#lm{height:60px}#lh{margin:16px 0 5px;word-spacing:3px}.tools{position:absolute;top:-4px;*top:10px;right:-13px;}#mHolder{width:62px;position:relative;z-index:296;display:none}#mCon{height:18px;line-height:18px;position:absolute;cursor:pointer;padding:0 18px 0 0;background:url(http://www.baidu.com/img/bg-1.0.0.gif) no-repeat right -134px;background-position:right -136px\9}#mCon span{color:#00c;cursor:default;display:block}#mCon .hw{text-decoration:underline;cursor:pointer}#mMenu{width:56px;border:1px solid #9a99ff;list-style:none;position:absolute;right:7px;top:28px;display:none;background:#fff}#mMenu a{width:100%;height:100%;display:block;line-height:22px;text-indent:6px;text-decoration:none}#mMenu a:hover{background:#d9e1f6}#mMenu .ln{height:1px;background:#ccf;overflow:hidden;margin:2px;font-size:1px;line-height:1px}#cp,#cp a{color:#77c}#seth{display:none;behavior:url(#default#homepage)}#setf{display:none}</style>
-+</head>
-+
-+<body><div id="u"><a href="http://www.baidu.com/gaoji/preferences.html" name="tj_setting">ËÑË÷ÉèÖÃ</a> | <a href="http://passport.baidu.com/?login&tpl=mn" name="tj_login">µÇ¼</a></div>
-+<div id="m"><p id="lg"><img src="http://www.baidu.com/img/baidu_sylogo1.gif" width="270" height="129" usemap="#mp"><map name="mp"><area shape="rect" coords="40,25,230,95" href="http://hi.baidu.com/baidu/" target="_blank" title="µã´Ë½øÈë °Ù¶ÈµÄ¿Õ¼ä" ></map></p><p id="nv"><a href="http://news.baidu.com">РÎÅ</a>¡¡<b>Íø Ò³</b>¡¡<a href="http://tieba.baidu.com">Ìù °É</a>¡¡<a href="http://zhidao.baidu.com">Öª µÀ</a>¡¡<a href="http://mp3.baidu.com">MP3</a>¡¡<a href="http://image.baidu.com">ͼ Æ¬</a>¡¡<a href="http://video.baidu.com">ÊӠƵ</a>¡¡<a href="http://map.baidu.com">µØ Í¼</a></p><div id="fm"><form name="f" action="/s"><input type="text" name="wd" id="kw" maxlength="100"><input type="hidden" name="rsv_bp" value="0"><input type="hidden" name="rsv_spt" value="3"><span class="btn_wr"><input type="submit" value="°Ù¶ÈÒ»ÏÂ" id="su" class="btn" onmousedown="this.className='btn btn_h'" onmouseout="this.className='btn'"></span></form><span class="tools"><span id="mHolder"><div id="mCon"><span>ÊäÈë·¨</span></div></span></span><ul id="mMenu"><li><a href="#" name="ime_hw">ÊÖд</a></li><li><a href="#" name="ime_py">Æ´Òô</a></li><li class="ln"></li><li><a href="#" name="ime_cl">¹Ø±Õ</a></li></ul></div>
-+<p id="lk"><a href="http://hi.baidu.com">¿Õ¼ä</a>¡¡<a href="http://baike.baidu.com">°Ù¿Æ</a>¡¡<a href="http://www.hao123.com">hao123</a><span> | <a href="/more/">¸ü¶à>></a></span></p><p id="lm"></p><p><a id="seth" onClick="this.setHomePage('http://www.baidu.com')" href="http://utility.baidu.com/traf/click.php?id=215&url=http://www.baidu.com" onmousedown="return ns_c({'fm':'behs','tab':'homepage','pos':0})">°Ñ°Ù¶ÈÉèΪÖ÷Ò³</a><a id="setf" onClick="fa(this)" href="javascript:void(0)" onmousedown="return ns_c({'fm':'behs','tab':'favorites','pos':0})">°Ñ°Ù¶È¼ÓÈëÊղؼÐ</a></p>
-+<p id="lh"><a href="http://e.baidu.com/?refer=888">¼ÓÈë°Ù¶ÈÍƹã</a> | <a href="http://top.baidu.com">ËÑË÷·çÔÆ°ñ</a> | <a href="http://home.baidu.com">¹ØÓÚ°Ù¶È</a> | <a href="http://ir.baidu.com">About Baidu</a></p><p id="cp">©2011 Baidu <a href="/duty/">ʹÓðٶÈÇ°±Ø¶Á</a> <a href="http://www.miibeian.gov.cn" target="_blank">¾©ICPÖ¤030173ºÅ</a> <img src="http://gimg.baidu.com/img/gs.gif"></p></div></body>
-+
-+<script>var w=window,d=document,n=navigator,k=d.f.wd,a=d.getElementById("nv").getElementsByTagName("a"),isIE=n.userAgent.indexOf("MSIE")!=-1&&!window.opera;for(var i=0;i<a.length;i++){a[i].onclick=function(){if(k.value.length>0){var C=this,A=C.href,B=encodeURIComponent(k.value);if(A.indexOf("q=")!=-1){C.href=A.replace(/q=[^&\x24]*/,"q="+B)}else{this.href+="?q="+B}}}}(function(){if(/q=([^&]+)/.test(location.search)){k.value=decodeURIComponent(RegExp["\x241"])}})();if(n.cookieEnabled&&!/sug?=0/.test(d.cookie)){d.write("<script src=http://www.baidu.com/js/bdsug.js?v=1.0.3.0><\/script>")}function addEV(C,B,A){if(w.attachEvent){C.attachEvent("on"+B,A)}else{if(w.addEventListener){C.addEventListener(B,A,false)}}}function G(A){return d.getElementById(A)}function ns_c(E){var F=encodeURIComponent(window.document.location.href),D="",A="",B="",C=window["BD_PS_C"+(new Date()).getTime()]=new Image();for(v in E){A=E[v];D+=v+"="+A+"&"}B="&mu="+F;C.src="http://nsclick.baidu.com/v.gif?pid=201&pj=www&"+D+"path="+F+"&t="+new Date().getTime();return true}if(/\bbdime=[12]/.test(d.cookie)){document.write("<script src=http://www.baidu.com/cache/ime/js/openime-1.0.0.js><\/script>")}(function(){var B=G("user"),A=G("userMenu");if(B&&A){addEV(B,"click",function(C){A.style.display=A.style.display=="block"?"none":"block";window.event?C.cancelBubble=true:C.stopPropagation()});addEV(document,"click",function(){A.style.display="none"})}})();(function(){var E=G("u").getElementsByTagName("a"),C=G("nv").getElementsByTagName("a"),I=G("lk").getElementsByTagName("a"),B="";var A=["news","tieba","zhidao","mp3","img","video","map"];var H=["hi","baike","hao123","more"];if(G("un")&&G("un").innerHTML!=""){B=G("un").innerHTML}function D(J){addEV(J,"mousedown",function(L){var L=L||window.event;var K=L.target||L.srcElement;ns_c({fm:"behs",tab:K.name||"tj_user",un:encodeURIComponent(B)})})}for(var F=0;F<E.length;F++){D(E[F])}for(var F=0;F<C.length;F++){C[F].name="tj_"+A[F];D(C[F])}for(var F=0;F<I.length;F++){I[F].name="tj_"+H[F];D(I[F])}})();addEV(w,"load",function(){k.focus()});w.onunload=function(){};</script>
-+
-+
-+<script type="text/javascript" src="http://www.baidu.com/cache/hps/js/hps-1.2.js"></script>
-+
-+</html><!--b762345d979562e8-->
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/greek-test.js
-@@ -0,0 +1,79 @@
-+var vows = require('vows'),
-+    assert = require('assert'),
-+    iconv = require(__dirname+'/../');
-+
-+var baseStrings = {
-+    empty: "",
-+    hi: "Γειά!",
-+    ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+
-+           ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f',
-+    greek: "αβγδεζηθικλμνξοπρστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίόύώΆΈΉΊΌΎΏϊϋΪΫ",
-+    untranslatable: "Åçþÿ¿"
-+};
-+
-+var encodings = [{
-+    name: "windows1253",
-+    variations: ['windows-1253', 'win-1253', 'win1253', 'cp1253', 'cp-1253', 1253],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xa2\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'),
-+    }
-+}, {
-+    name: "iso88597",
-+    variations: ['iso-8859-7', 'greek', 'greek8', 'cp28597', 'cp-28597', 28597],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xb6\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'),
-+    }
-+}, {
-+    name: "cp737",
-+    variations: ['cp-737', 737],
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        hi: new Buffer('\x82\x9c\xa0\xe1!', 'binary'),
-+        ascii: new Buffer(baseStrings.ascii, 'binary'),
-+        greek: new Buffer('\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xab\xac\xad\xae\xaf\xe0\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\xe1\xe2\xe3\xe5\xe6\xe7\xe9\xea\xeb\xec\xed\xee\xef\xf0\xe4\xe8\xf4\xf5', 'binary'),
-+    }
-+}];
-+
-+var testsBatch = {};
-+encodings.forEach(function(encoding) {
-+    var enc = encoding.variations[0];
-+    var key = "hi";
-+    var tests = {
-+        "Convert to empty buffer": function() {
-+            assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary'));
-+        },
-+        "Convert from empty buffer": function() {
-+            assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), "");
-+        },
-+        "Convert from buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), 
-+                    baseStrings[key]);
-+        },
-+        "Convert to buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), 
-+                    encoding.encodedStrings[key].toString('binary'));
-+        },
-+        "Try different variations of encoding": function() {
-+            encoding.variations.forEach(function(enc) {
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]);
-+                assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary'));
-+            });
-+        },
-+        "Untranslatable chars are converted to defaultCharSingleByte": function() {
-+            var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join('');
-+            assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters.
-+        }
-+    };
-+    
-+    testsBatch[encoding.name+":"] = tests;
-+});
-+
-+vows.describe("Test Greek encodings").addBatch(testsBatch).export(module);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/main-test.js
-@@ -0,0 +1,55 @@
-+var vows = require('vows'),
-+    assert = require('assert'),
-+    iconv = require(__dirname+'/../');
-+
-+var testString = "Hello123!";
-+var testStringLatin1 = "Hello123!£Å÷×çþÿ¿®";
-+var testStringBase64 = "SGVsbG8xMjMh";
-+
-+vows.describe("Generic UTF8-UCS2 tests").addBatch({
-+    "Vows is working": function() {},
-+    "Return values are of correct types": function() {
-+        assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer);
-+        
-+        var s = iconv.fromEncoding(new Buffer(testString), "utf8");
-+        assert.strictEqual(Object.prototype.toString.call(s), "[object String]");
-+    },
-+    "Internal encodings all correctly encoded/decoded": function() {
-+        ['utf8', "UTF-8", "UCS2", "binary", ""].forEach(function(enc) {
-+            assert.strictEqual(iconv.toEncoding(testStringLatin1, enc).toString(enc), testStringLatin1);
-+            assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, enc), enc), testStringLatin1);
-+        });
-+    },
-+    "Base64 correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testStringBase64, "base64").toString("binary"), testString);
-+        assert.strictEqual(iconv.fromEncoding(new Buffer(testString, "binary"), "base64"), testStringBase64);
-+    },
-+    "Latin1 correctly encoded/decoded": function() {    
-+        assert.strictEqual(iconv.toEncoding(testStringLatin1, "latin1").toString("binary"), testStringLatin1);
-+        assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, "binary"), "latin1"), testStringLatin1);
-+    },
-+    "Convert from string, not buffer (binary encoding used)": function() {
-+        assert.strictEqual(iconv.fromEncoding(testStringLatin1, "binary"), testStringLatin1);
-+    },
-+    "Convert to string, not buffer (utf8 used)": function() {
-+        var res = iconv.toEncoding(new Buffer(testStringLatin1, "utf8"));
-+        assert.ok(res instanceof Buffer);
-+        assert.strictEqual(res.toString("utf8"), testStringLatin1);
-+    },
-+    "Throws on unknown encodings": function() {
-+        assert.throws(function() { iconv.toEncoding("a", "xxx"); });
-+        assert.throws(function() { iconv.fromEncoding("a", "xxx"); });
-+    },
-+    "Convert non-strings and non-buffers": function() {
-+        assert.strictEqual(iconv.toEncoding({}, "utf8").toString(), "[object Object]");
-+        assert.strictEqual(iconv.toEncoding(10, "utf8").toString(), "10");
-+        assert.strictEqual(iconv.toEncoding(undefined, "utf8").toString(), "");
-+        assert.strictEqual(iconv.fromEncoding({}, "utf8"), "[object Object]");
-+        assert.strictEqual(iconv.fromEncoding(10, "utf8"), "10");
-+        assert.strictEqual(iconv.fromEncoding(undefined, "utf8"), "");
-+    },
-+    "Aliases encode and decode work the same as toEncoding and fromEncoding": function() {
-+        assert.strictEqual(iconv.toEncoding(testString, "latin1").toString("binary"), iconv.encode(testString, "latin1").toString("binary"));
-+        assert.strictEqual(iconv.fromEncoding(testStringLatin1, "latin1"), iconv.decode(testStringLatin1, "latin1"));
-+    },
-+}).export(module)
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/performance.js
-@@ -0,0 +1,67 @@
-+
-+var iconv = require('iconv');
-+var iconv_lite = require("../index");
-+
-+var encoding = process.argv[2] || "windows-1251";
-+var convertTimes = 10000;
-+
-+var encodingStrings = {
-+    'windows-1251': 'This is a test string 32 chars..',
-+    'gbk':          '这是中文字符测试。。!@¥%12',
-+    'utf8': '这是中文字符测试。。!@¥%12This is a test string 48 chars..',
-+};
-+// Test encoding.
-+var str = encodingStrings[encoding];
-+if (!str) {
-+    throw new Error('Don\'t support ' + encoding + ' performance test.');
-+}
-+for (var i = 0; i < 13; i++) {
-+    str = str + str;
-+}
-+
-+console.log('\n' + encoding + ' charset performance test:');
-+console.log("\nEncoding "+str.length+" chars "+convertTimes+" times:");
-+
-+var start = Date.now();
-+var converter = new iconv.Iconv("utf8", encoding);
-+for (var i = 0; i < convertTimes; i++) {
-+    var b = converter.convert(str);
-+}
-+var duration = Date.now() - start;
-+var mbs = convertTimes*b.length/duration/1024;
-+
-+console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s.");
-+
-+var start = Date.now();
-+for (var i = 0; i < convertTimes; i++) {
-+    var b = iconv_lite.encode(str, encoding);
-+}
-+var duration = Date.now() - start;
-+var mbs = convertTimes*b.length/duration/1024;
-+
-+console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s.");
-+
-+
-+// Test decoding.
-+var buf = iconv_lite.encode(str, encoding);
-+console.log("\nDecoding "+buf.length+" bytes "+convertTimes+" times:");
-+
-+var start = Date.now();
-+var converter = new iconv.Iconv(encoding, "utf8");
-+for (var i = 0; i < convertTimes; i++) {
-+    var s = converter.convert(buf).toString();
-+}
-+var duration = Date.now() - start;
-+var mbs = convertTimes*buf.length/duration/1024;
-+
-+console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s.");
-+
-+var start = Date.now();
-+for (var i = 0; i < convertTimes; i++) {
-+    var s = iconv_lite.decode(buf, encoding);
-+}
-+var duration = Date.now() - start;
-+var mbs = convertTimes*buf.length/duration/1024;
-+
-+console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s.");
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/iconv-lite/test/turkish-test.js
-@@ -0,0 +1,90 @@
-+var vows = require('vows'),
-+    assert = require('assert'),
-+    iconv = require(__dirname+'/../');
-+
-+var ascii = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+
-+           ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f';
-+
-+var encodings = [{
-+    name: "windows1254",
-+    variations: ['windows-1254', 'win-1254', 'win1254', 'cp1254', 'cp-1254', 1254],
-+    strings: {
-+        empty: "",
-+        ascii: ascii,
-+        turkish: "€‚ƒ„…†‡ˆ‰Š‹Œ‘’“”•–—˜™š›œŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ",
-+        untranslatable: "\x81\x8d\x8e\x8f\x90\x9d\x9e"
-+    },
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        ascii: new Buffer(ascii, 'binary'),
-+        turkish: new Buffer(
-+            '\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c' +
-+            '\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9f' +
-+            '\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf' +
-+            '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' +
-+            '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' +
-+            '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' +
-+            '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' +
-+            '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff',
-+            'binary'),
-+    }
-+}, {
-+    name: "iso88599",
-+    variations: ['iso-8859-9', 'turkish', 'turkish8', 'cp28599', 'cp-28599', 28599],
-+    strings: {
-+        empty: "",
-+        ascii: ascii,
-+        turkish: "\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ",
-+        untranslatable: ''
-+    },
-+    encodedStrings: {
-+        empty: new Buffer(''),
-+        ascii: new Buffer(ascii, 'binary'),
-+        turkish: new Buffer(
-+            '\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf' +
-+            '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' +
-+            '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' +
-+            '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' +
-+            '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' +
-+            '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff',
-+             'binary')
-+    }
-+}];
-+
-+var testsBatch = {};
-+encodings.forEach(function(encoding) {
-+    var enc = encoding.variations[0];
-+    var key = "turkish";
-+    var tests = {
-+        "Convert to empty buffer": function() {
-+            assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary'));
-+        },
-+        "Convert from empty buffer": function() {
-+            assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), "");
-+        },
-+        "Convert from buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc),
-+                    encoding.strings[key]);
-+        },
-+        "Convert to buffer": function() {
-+            for (var key in encoding.encodedStrings)
-+                assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'),
-+                    encoding.encodedStrings[key].toString('binary'));
-+        },
-+        "Try different variations of encoding": function() {
-+            encoding.variations.forEach(function(enc) {
-+                assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), encoding.strings[key]);
-+                assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary'));
-+            });
-+        },
-+        "Untranslatable chars are converted to defaultCharSingleByte": function() {
-+            var expected = encoding.strings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join('');
-+            assert.strictEqual(iconv.toEncoding(encoding.strings.untranslatable, enc).toString('binary'), expected); // Only '?' characters.
-+        }
-+    };
-+
-+    testsBatch[encoding.name+":"] = tests;
-+});
-+
-+vows.describe("Test Turkish encodings").addBatch(testsBatch).export(module);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/.npmignore
-@@ -0,0 +1,15 @@
-+lib-cov
-+*.seed
-+*.log
-+*.csv
-+*.dat
-+*.out
-+*.pid
-+*.gz
-+
-+pids
-+logs
-+results
-+
-+node_modules
-+npm-debug.log
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/.travis.yml
-@@ -0,0 +1,5 @@
-+language: node_js
-+node_js:
-+  - "0.10"
-+  - "0.8"
-+  - "0.6"
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/LICENSE.txt
-@@ -0,0 +1,22 @@
-+Copyright (c) 2013 Garen Torikian
-+
-+MIT License
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/README.md
-@@ -0,0 +1,107 @@
-+isBinaryFile
-+============
-+
-+Detects if a file is binary in Node.js. Similar to [Perl's `-B` switch](http://stackoverflow.com/questions/899206/how-does-perl-know-a-file-is-binary),
-+in that:
-+
-+* it reads the first few thousand bytes of a file
-+* checks for a `null` byte; if it's found, it's binary
-+* flags non-ASCII characters. After a certain number of "weird" characters, the
-+file is flagged as binary
-+
-+All the logic is also pretty much ported from
-+[ag](https://github.com/ggreer/the_silver_searcher).
-+
-+Note: if the file doesn't exist or it is empty, this function returns `false`.
-+
-+## Installation
-+
-+```
-+npm install isbinaryfile
-+```
-+
-+## Usage
-+
-+If you pass in one argument, this module assumes it's just the file path, and
-+performs the appropriate file read and stat functionality internally, as sync
-+options:
-+
-+``` javascript
-+var isBinaryFileSync = require("isbinaryfile");
-+
-+if (isBinaryFileSync(process.argv[2]))
-+  console.log("It is!")
-+else
-+  console.log("No.")
-+```
-+
-+Ta da.
-+
-+However, if you've already read and `stat()`-ed a file (for some other reason),
-+you can pass in both the file's raw data and the stat's `size` info to save
-+time:
-+
-+```javascript
-+fs.readFile(process.argv[2], function(err, data) {
-+  fs.lstat(process.argv[2], function(err, stat) {
-+    if (isBinaryFileSync(data, stat.size))
-+      console.log("It is!")
-+    else
-+      console.log("No.")
-+  });
-+});
-+```
-+
-+### Async
-+
-+Previous to version 2.0.0, this program always ran in sync mode. Now, there's
-+an async option. Simply pass a function as your second parameter, and isBinaryFile
-+will figure the rest out:
-+
-+``` javascript
-+var isBinaryFileSync = require("isbinaryfile");
-+
-+isBinaryFileSync(process.argv[2], function(err, result) {
-+  if (err) return console.error(err);
-+
-+  if (result)
-+    console.log("It is!")
-+  else
-+    console.log("No.")
-+}
-+```
-+
-+## Testing
-+
-+Install mocha on your machine:
-+
-+```
-+npm install mocha -g
-+```
-+
-+Then run `npm test`.
-+
-+# MIT License
-+
-+Copyright (c) 2013 Garen J. Torikian
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/index.js
-@@ -0,0 +1,87 @@
-+var fs = require('fs');
-+var path = require("path");
-+var max_bytes = 512;
-+
-+module.exports = function(bytes, size) {
-+  // Read the file with no encoding for raw buffer access.
-+  if (size === undefined) {
-+    var file = bytes, existsSync = fs.existsSync || path.existsSync;
-+    if (!existsSync(file))
-+       return false;
-+    var descriptor = fs.openSync(file, 'r');
-+    try {
-+      bytes = new Buffer(max_bytes);
-+      size = fs.readSync(descriptor, bytes, 0, bytes.length, 0);
-+    } finally {
-+      fs.closeSync(descriptor);
-+    }
-+  }
-+  else if (typeof size === "function") {
-+    var file = bytes, callback = size;
-+    var exists = fs.exists || path.exists;
-+    exists(file, function (exists) {
-+      if (!exists) return callback(null, false);
-+
-+      fs.open(file, 'r', function(err, descriptor){
-+          if (err) return callback(err);
-+          var bytes = new Buffer(max_bytes);
-+          // Read the file with no encoding for raw buffer access.
-+          fs.read(descriptor, bytes, 0, bytes.length, 0, function(err, size, bytes){
-+            fs.close(descriptor, function(err2){
-+                if (err || err2)
-+                    return callback(err || err2);
-+                return callback(null, isBinaryCheck(bytes, size));
-+            });
-+          });
-+      });
-+    });
-+  }
-+
-+  return isBinaryCheck(bytes, size);
-+}
-+
-+function isBinaryCheck(bytes, size) {
-+  if (size === 0)
-+    return false;
-+
-+  var suspicious_bytes = 0;
-+  var total_bytes = Math.min(size, max_bytes);
-+
-+  if (size >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
-+    // UTF-8 BOM. This isn't binary.
-+    return false;
-+  }
-+
-+  for (var i = 0; i < total_bytes; i++) {
-+    if (bytes[i] === 0) { // NULL byte--it's binary!
-+      return true;
-+    }
-+    else if ((bytes[i] < 7 || bytes[i] > 14) && (bytes[i] < 32 || bytes[i] > 127)) {
-+      // UTF-8 detection
-+      if (bytes[i] > 191 && bytes[i] < 224 && i + 1 < total_bytes) {
-+          i++;
-+          if (bytes[i] < 192) {
-+              continue;
-+          }
-+      }
-+      else if (bytes[i] > 223 && bytes[i] < 239 && i + 2 < total_bytes) {
-+          i++;
-+          if (bytes[i] < 192 && bytes[i + 1] < 192) {
-+              i++;
-+              continue;
-+          }
-+      }
-+      suspicious_bytes++;
-+      // Read at least 32 bytes before making a decision
-+      if (i > 32 && (suspicious_bytes * 100) / total_bytes > 10) {
-+          return true;
-+      }
-+    }
-+  }
-+
-+  if ((suspicious_bytes * 100) / total_bytes > 10) {
-+    return true;
-+  }
-+
-+  return false;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "isbinaryfile",
-+  "version": "2.0.1",
-+  "description": "Detects if a file is binary in Node.js. Similar to Perl's -B.",
-+  "main": "./lib/panino.js",
-+  "engines": {
-+    "node": ">=0.6.0"
-+  },
-+  "maintainers": [
-+    {
-+      "name": "Garen J. Torikian",
-+      "email": "gjtorikian at gmail.com"
-+    }
-+  ],
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/gjtorikian/isBinaryFile"
-+  },
-+  "devDependencies": {
-+    "mocha": ""
-+  },
-+  "scripts": {
-+    "test": "mocha tests/test.js"
-+  },
-+  "readme": "isBinaryFile\n============\n\nDetects if a file is binary in Node.js. Similar to [Perl's `-B` switch](http://stackoverflow.com/questions/899206/how-does-perl-know-a-file-is-binary),\nin that:\n\n* it reads the first few thousand bytes of a file\n* checks for a `null` byte; if it's found, it's binary\n* flags non-ASCII characters. After a certain number of \"weird\" characters, the\nfile is flagged as binary\n\nAll the logic is also pretty much ported from\n[ag](https://github.com/ggreer/the_silver_searcher).\n\nNote: if the file doesn't exist or it is empty, this function returns `false`.\n\n## Installation\n\n```\nnpm install isbinaryfile\n```\n\n## Usage\n\nIf you pass in one argument, this module assumes it's just the file path, and\nperforms the appropriate file read and stat functionality internally, as sync\noptions:\n\n``` javascript\nvar isBinaryFileSync = require(\"isbinaryfile\");\n\nif (isBinaryFileSync(process.argv[2]))\n  console.log(\"It is!\")\nelse\n  console.log(\"No.\")\n```\n\nTa da.\n\nHowever, if you've already read and `stat()`-ed a file (for some other reason),\nyou can pass in both the file's raw data and the stat's `size` info to save\ntime:\n\n```javascript\nfs.readFile(process.argv[2], function(err, data) {\n  fs.lstat(process.argv[2], function(err, stat) {\n    if (isBinaryFileSync(data, stat.size))\n      console.log(\"It is!\")\n    else\n      console.log(\"No.\")\n  });\n});\n```\n\n### Async\n\nPrevious to version 2.0.0, this program always ran in sync mode. Now, there's\nan async option. Simply pass a function as your second parameter, and isBinaryFile\nwill figure the rest out:\n\n``` javascript\nvar isBinaryFileSync = require(\"isbinaryfile\");\n\nisBinaryFileSync(process.argv[2], function(err, result) {\n  if (err) return console.error(err);\n\n  if (result)\n    console.log(\"It is!\")\n  else\n    console.log(\"No.\")\n}\n```\n\n## Testing\n\nInstall mocha on your machine:\n\n```\nnpm install mocha -g\n```\n\nThen run `npm test`.\n\n# MIT License\n\nCopyright (c) 2013 Garen J. Torikian\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/gjtorikian/isBinaryFile/issues"
-+  },
-+  "_id": "isbinaryfile at 2.0.1",
-+  "_from": "isbinaryfile@~2.0.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/tests/fixtures/02_perl_script
-@@ -0,0 +1,2 @@
-+#!/usr/bin/perl
-+ print "Hello World.\n";
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/tests/fixtures/03_russian_file.rst
-@@ -0,0 +1,49 @@
-+Общие сведения о программном комплексе
-+**************************************
-+test
-+
-+Назначение программного комплекса
-+=================================
-+
-+Функции программного комплекса
-+==============================
-+
-+Требования к минимальному составу аппаратных средств
-+====================================================
-+.. Сведения о средствах, обеспечивающих выполнение программы.
-+
-+Требования к минимальному составу программных средств
-+=====================================================
-+.. Сведения о средствах, обеспечивающих выполнение программы.
-+
-+Требования к персоналу (системному программисту)
-+================================================
-+
-+Структура программного комплекса
-+********************************
-+.. Сведения о структуре программы, ее составных частях, о связях между
-+.. составными частями и о связях с другими программами.
-+
-+Настройка программного комплекса
-+********************************
-+
-+Настройка на состав технических средств
-+=======================================
-+.. Описание действий по настройке программного комплекса на условия конкретного применения.
-+
-+Настройка на состав программных средств
-+=======================================
-+.. Описание действий по настройке программного комплекса на условия конкретного
-+.. применения.
-+
-+Проверка программного комплекса
-+*******************************
-+.. Описание способов проверки, позволяющих дать общее заключение о
-+.. работоспособности программного комплекса (контрольные примеры, методы прогона,
-+.. результаты).
-+
-+Сообщения системному программисту
-+*********************************
-+.. Тексты сообщений, выдаваемых в ходе выполнения настройки, проверки
-+.. программы, а также в ходе выполнения программы, описание их содержания и
-+.. действий, которые необходимо предпринять по этим сообщениям.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/isbinaryfile/tests/test.js
-@@ -0,0 +1,68 @@
-+"mocha";
-+
-+var assert = require("assert");
-+var fs = require("fs");
-+var isBinaryFile = require("../index");
-+
-+describe('isBinaryFile', function() {
-+  it('should fail on a binary program', function() {
-+    assert(isBinaryFile("tests/fixtures/01_grep"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/01_grep");
-+    var stat = fs.lstatSync("tests/fixtures/01_grep");
-+    assert(isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail on an extensionless script', function() {
-+    assert(!isBinaryFile("tests/fixtures/02_perl_script"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/02_perl_script");
-+    var stat = fs.lstatSync("tests/fixtures/02_perl_script");
-+    assert(!isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail on a russian text', function() {
-+    assert(!isBinaryFile("tests/fixtures/03_russian_file.rst"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/03_russian_file.rst");
-+    var stat = fs.lstatSync("tests/fixtures/03_russian_file.rst");
-+    assert(!isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail on a PDF', function() {
-+    assert(isBinaryFile("tests/fixtures/04_HelloWorld.pdf"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/04_HelloWorld.pdf");
-+    var stat = fs.lstatSync("tests/fixtures/04_HelloWorld.pdf");
-+    assert(isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail on a zero-byte file', function() {
-+    assert(!isBinaryFile("tests/fixtures/05_null_file.gif"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/05_null_file.gif");
-+    var stat = fs.lstatSync("tests/fixtures/05_null_file.gif");
-+    assert(!isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail on a gif', function() {
-+    assert(isBinaryFile("tests/fixtures/06_trunks.gif"));
-+
-+    var bytes = fs.readFileSync("tests/fixtures/06_trunks.gif");
-+    var stat = fs.lstatSync("tests/fixtures/06_trunks.gif");
-+    assert(isBinaryFile(bytes, stat.size));
-+  });
-+
-+  it('should not fail with async', function(done) {
-+    assert.doesNotThrow(function() {
-+      isBinaryFile("tests/fixtures/06_trunks.gif", function(err, result) {
-+        assert(!err);
-+        assert(result);
-+        done();
-+      }, function(err) {
-+        if (err) throw err;
-+        done();
-+      });
-+    });
-+  });
-+});
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/.npmignore
-@@ -0,0 +1 @@
-+node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-+All rights reserved.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/README.md
-@@ -0,0 +1,218 @@
-+# minimatch
-+
-+A minimal matching utility.
-+
-+[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
-+
-+
-+This is the matching library used internally by npm.
-+
-+Eventually, it will replace the C binding in node-glob.
-+
-+It works by converting glob expressions into JavaScript `RegExp`
-+objects.
-+
-+## Usage
-+
-+```javascript
-+var minimatch = require("minimatch")
-+
-+minimatch("bar.foo", "*.foo") // true!
-+minimatch("bar.foo", "*.bar") // false!
-+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
-+```
-+
-+## Features
-+
-+Supports these glob features:
-+
-+* Brace Expansion
-+* Extended glob matching
-+* "Globstar" `**` matching
-+
-+See:
-+
-+* `man sh`
-+* `man bash`
-+* `man 3 fnmatch`
-+* `man 5 gitignore`
-+
-+## Minimatch Class
-+
-+Create a minimatch object by instanting the `minimatch.Minimatch` class.
-+
-+```javascript
-+var Minimatch = require("minimatch").Minimatch
-+var mm = new Minimatch(pattern, options)
-+```
-+
-+### Properties
-+
-+* `pattern` The original pattern the minimatch object represents.
-+* `options` The options supplied to the constructor.
-+* `set` A 2-dimensional array of regexp or string expressions.
-+  Each row in the
-+  array corresponds to a brace-expanded pattern.  Each item in the row
-+  corresponds to a single path-part.  For example, the pattern
-+  `{a,b/c}/d` would expand to a set of patterns like:
-+
-+        [ [ a, d ]
-+        , [ b, c, d ] ]
-+
-+    If a portion of the pattern doesn't have any "magic" in it
-+    (that is, it's something like `"foo"` rather than `fo*o?`), then it
-+    will be left as a string rather than converted to a regular
-+    expression.
-+
-+* `regexp` Created by the `makeRe` method.  A single regular expression
-+  expressing the entire pattern.  This is useful in cases where you wish
-+  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
-+* `negate` True if the pattern is negated.
-+* `comment` True if the pattern is a comment.
-+* `empty` True if the pattern is `""`.
-+
-+### Methods
-+
-+* `makeRe` Generate the `regexp` member if necessary, and return it.
-+  Will return `false` if the pattern is invalid.
-+* `match(fname)` Return true if the filename matches the pattern, or
-+  false otherwise.
-+* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
-+  filename, and match it against a single row in the `regExpSet`.  This
-+  method is mainly for internal use, but is exposed so that it can be
-+  used by a glob-walker that needs to avoid excessive filesystem calls.
-+
-+All other methods are internal, and will be called as necessary.
-+
-+## Functions
-+
-+The top-level exported function has a `cache` property, which is an LRU
-+cache set to store 100 items.  So, calling these methods repeatedly
-+with the same pattern and options will use the same Minimatch object,
-+saving the cost of parsing it multiple times.
-+
-+### minimatch(path, pattern, options)
-+
-+Main export.  Tests a path against the pattern using the options.
-+
-+```javascript
-+var isJS = minimatch(file, "*.js", { matchBase: true })
-+```
-+
-+### minimatch.filter(pattern, options)
-+
-+Returns a function that tests its
-+supplied argument, suitable for use with `Array.filter`.  Example:
-+
-+```javascript
-+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
-+```
-+
-+### minimatch.match(list, pattern, options)
-+
-+Match against the list of
-+files, in the style of fnmatch or glob.  If nothing is matched, and
-+options.nonull is set, then return a list containing the pattern itself.
-+
-+```javascript
-+var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
-+```
-+
-+### minimatch.makeRe(pattern, options)
-+
-+Make a regular expression object from the pattern.
-+
-+## Options
-+
-+All options are `false` by default.
-+
-+### debug
-+
-+Dump a ton of stuff to stderr.
-+
-+### nobrace
-+
-+Do not expand `{a,b}` and `{1..3}` brace sets.
-+
-+### noglobstar
-+
-+Disable `**` matching against multiple folder names.
-+
-+### dot
-+
-+Allow patterns to match filenames starting with a period, even if
-+the pattern does not explicitly have a period in that spot.
-+
-+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
-+is set.
-+
-+### noext
-+
-+Disable "extglob" style patterns like `+(a|b)`.
-+
-+### nocase
-+
-+Perform a case-insensitive match.
-+
-+### nonull
-+
-+When a match is not found by `minimatch.match`, return a list containing
-+the pattern itself.  When set, an empty list is returned if there are
-+no matches.
-+
-+### matchBase
-+
-+If set, then patterns without slashes will be matched
-+against the basename of the path if it contains slashes.  For example,
-+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-+
-+### nocomment
-+
-+Suppress the behavior of treating `#` at the start of a pattern as a
-+comment.
-+
-+### nonegate
-+
-+Suppress the behavior of treating a leading `!` character as negation.
-+
-+### flipNegate
-+
-+Returns from negate expressions the same as if they were not negated.
-+(Ie, true on a hit, false on a miss.)
-+
-+
-+## Comparisons to other fnmatch/glob implementations
-+
-+While strict compliance with the existing standards is a worthwhile
-+goal, some discrepancies exist between minimatch and other
-+implementations, and are intentional.
-+
-+If the pattern starts with a `!` character, then it is negated.  Set the
-+`nonegate` flag to suppress this behavior, and treat leading `!`
-+characters normally.  This is perhaps relevant if you wish to start the
-+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
-+characters at the start of a pattern will negate the pattern multiple
-+times.
-+
-+If a pattern starts with `#`, then it is treated as a comment, and
-+will not match anything.  Use `\#` to match a literal `#` at the
-+start of a line, or set the `nocomment` flag to suppress this behavior.
-+
-+The double-star character `**` is supported by default, unless the
-+`noglobstar` flag is set.  This is supported in the manner of bsdglob
-+and bash 4.1, where `**` only has special significance if it is the only
-+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
-+`a/**b` will not.
-+
-+If an escaped pattern has no matches, and the `nonull` flag is set,
-+then minimatch.match returns the pattern as-provided, rather than
-+interpreting the character escapes.  For example,
-+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
-+that it does not resolve escaped pattern characters.
-+
-+If brace expansion is not disabled, then it is performed before any
-+other interpretation of the glob pattern.  Thus, a pattern like
-+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-+checked for validity.  Since those two are valid, matching proceeds.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/minimatch.js
-@@ -0,0 +1,1055 @@
-+;(function (require, exports, module, platform) {
-+
-+if (module) module.exports = minimatch
-+else exports.minimatch = minimatch
-+
-+if (!require) {
-+  require = function (id) {
-+    switch (id) {
-+      case "sigmund": return function sigmund (obj) {
-+        return JSON.stringify(obj)
-+      }
-+      case "path": return { basename: function (f) {
-+        f = f.split(/[\/\\]/)
-+        var e = f.pop()
-+        if (!e) e = f.pop()
-+        return e
-+      }}
-+      case "lru-cache": return function LRUCache () {
-+        // not quite an LRU, but still space-limited.
-+        var cache = {}
-+        var cnt = 0
-+        this.set = function (k, v) {
-+          cnt ++
-+          if (cnt >= 100) cache = {}
-+          cache[k] = v
-+        }
-+        this.get = function (k) { return cache[k] }
-+      }
-+    }
-+  }
-+}
-+
-+minimatch.Minimatch = Minimatch
-+
-+var LRU = require("lru-cache")
-+  , cache = minimatch.cache = new LRU({max: 100})
-+  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
-+  , sigmund = require("sigmund")
-+
-+var path = require("path")
-+  // any single thing other than /
-+  // don't need to escape / when using new RegExp()
-+  , qmark = "[^/]"
-+
-+  // * => any number of characters
-+  , star = qmark + "*?"
-+
-+  // ** when dots are allowed.  Anything goes, except .. and .
-+  // not (^ or / followed by one or two dots followed by $ or /),
-+  // followed by anything, any number of times.
-+  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
-+
-+  // not a ^ or / followed by a dot,
-+  // followed by anything, any number of times.
-+  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
-+
-+  // characters that need to be escaped in RegExp.
-+  , reSpecials = charSet("().*{}+?[]^$\\!")
-+
-+// "abc" -> { a:true, b:true, c:true }
-+function charSet (s) {
-+  return s.split("").reduce(function (set, c) {
-+    set[c] = true
-+    return set
-+  }, {})
-+}
-+
-+// normalizes slashes.
-+var slashSplit = /\/+/
-+
-+minimatch.filter = filter
-+function filter (pattern, options) {
-+  options = options || {}
-+  return function (p, i, list) {
-+    return minimatch(p, pattern, options)
-+  }
-+}
-+
-+function ext (a, b) {
-+  a = a || {}
-+  b = b || {}
-+  var t = {}
-+  Object.keys(b).forEach(function (k) {
-+    t[k] = b[k]
-+  })
-+  Object.keys(a).forEach(function (k) {
-+    t[k] = a[k]
-+  })
-+  return t
-+}
-+
-+minimatch.defaults = function (def) {
-+  if (!def || !Object.keys(def).length) return minimatch
-+
-+  var orig = minimatch
-+
-+  var m = function minimatch (p, pattern, options) {
-+    return orig.minimatch(p, pattern, ext(def, options))
-+  }
-+
-+  m.Minimatch = function Minimatch (pattern, options) {
-+    return new orig.Minimatch(pattern, ext(def, options))
-+  }
-+
-+  return m
-+}
-+
-+Minimatch.defaults = function (def) {
-+  if (!def || !Object.keys(def).length) return Minimatch
-+  return minimatch.defaults(def).Minimatch
-+}
-+
-+
-+function minimatch (p, pattern, options) {
-+  if (typeof pattern !== "string") {
-+    throw new TypeError("glob pattern string required")
-+  }
-+
-+  if (!options) options = {}
-+
-+  // shortcut: comments match nothing.
-+  if (!options.nocomment && pattern.charAt(0) === "#") {
-+    return false
-+  }
-+
-+  // "" only matches ""
-+  if (pattern.trim() === "") return p === ""
-+
-+  return new Minimatch(pattern, options).match(p)
-+}
-+
-+function Minimatch (pattern, options) {
-+  if (!(this instanceof Minimatch)) {
-+    return new Minimatch(pattern, options, cache)
-+  }
-+
-+  if (typeof pattern !== "string") {
-+    throw new TypeError("glob pattern string required")
-+  }
-+
-+  if (!options) options = {}
-+  pattern = pattern.trim()
-+
-+  // windows: need to use /, not \
-+  // On other platforms, \ is a valid (albeit bad) filename char.
-+  if (platform === "win32") {
-+    pattern = pattern.split("\\").join("/")
-+  }
-+
-+  // lru storage.
-+  // these things aren't particularly big, but walking down the string
-+  // and turning it into a regexp can get pretty costly.
-+  var cacheKey = pattern + "\n" + sigmund(options)
-+  var cached = minimatch.cache.get(cacheKey)
-+  if (cached) return cached
-+  minimatch.cache.set(cacheKey, this)
-+
-+  this.options = options
-+  this.set = []
-+  this.pattern = pattern
-+  this.regexp = null
-+  this.negate = false
-+  this.comment = false
-+  this.empty = false
-+
-+  // make the set of regexps etc.
-+  this.make()
-+}
-+
-+Minimatch.prototype.debug = function() {}
-+
-+Minimatch.prototype.make = make
-+function make () {
-+  // don't do it more than once.
-+  if (this._made) return
-+
-+  var pattern = this.pattern
-+  var options = this.options
-+
-+  // empty patterns and comments match nothing.
-+  if (!options.nocomment && pattern.charAt(0) === "#") {
-+    this.comment = true
-+    return
-+  }
-+  if (!pattern) {
-+    this.empty = true
-+    return
-+  }
-+
-+  // step 1: figure out negation, etc.
-+  this.parseNegate()
-+
-+  // step 2: expand braces
-+  var set = this.globSet = this.braceExpand()
-+
-+  if (options.debug) this.debug = console.error
-+
-+  this.debug(this.pattern, set)
-+
-+  // step 3: now we have a set, so turn each one into a series of path-portion
-+  // matching patterns.
-+  // These will be regexps, except in the case of "**", which is
-+  // set to the GLOBSTAR object for globstar behavior,
-+  // and will not contain any / characters
-+  set = this.globParts = set.map(function (s) {
-+    return s.split(slashSplit)
-+  })
-+
-+  this.debug(this.pattern, set)
-+
-+  // glob --> regexps
-+  set = set.map(function (s, si, set) {
-+    return s.map(this.parse, this)
-+  }, this)
-+
-+  this.debug(this.pattern, set)
-+
-+  // filter out everything that didn't compile properly.
-+  set = set.filter(function (s) {
-+    return -1 === s.indexOf(false)
-+  })
-+
-+  this.debug(this.pattern, set)
-+
-+  this.set = set
-+}
-+
-+Minimatch.prototype.parseNegate = parseNegate
-+function parseNegate () {
-+  var pattern = this.pattern
-+    , negate = false
-+    , options = this.options
-+    , negateOffset = 0
-+
-+  if (options.nonegate) return
-+
-+  for ( var i = 0, l = pattern.length
-+      ; i < l && pattern.charAt(i) === "!"
-+      ; i ++) {
-+    negate = !negate
-+    negateOffset ++
-+  }
-+
-+  if (negateOffset) this.pattern = pattern.substr(negateOffset)
-+  this.negate = negate
-+}
-+
-+// Brace expansion:
-+// a{b,c}d -> abd acd
-+// a{b,}c -> abc ac
-+// a{0..3}d -> a0d a1d a2d a3d
-+// a{b,c{d,e}f}g -> abg acdfg acefg
-+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-+//
-+// Invalid sets are not expanded.
-+// a{2..}b -> a{2..}b
-+// a{b}c -> a{b}c
-+minimatch.braceExpand = function (pattern, options) {
-+  return new Minimatch(pattern, options).braceExpand()
-+}
-+
-+Minimatch.prototype.braceExpand = braceExpand
-+function braceExpand (pattern, options) {
-+  options = options || this.options
-+  pattern = typeof pattern === "undefined"
-+    ? this.pattern : pattern
-+
-+  if (typeof pattern === "undefined") {
-+    throw new Error("undefined pattern")
-+  }
-+
-+  if (options.nobrace ||
-+      !pattern.match(/\{.*\}/)) {
-+    // shortcut. no need to expand.
-+    return [pattern]
-+  }
-+
-+  var escaping = false
-+
-+  // examples and comments refer to this crazy pattern:
-+  // a{b,c{d,e},{f,g}h}x{y,z}
-+  // expected:
-+  // abxy
-+  // abxz
-+  // acdxy
-+  // acdxz
-+  // acexy
-+  // acexz
-+  // afhxy
-+  // afhxz
-+  // aghxy
-+  // aghxz
-+
-+  // everything before the first \{ is just a prefix.
-+  // So, we pluck that off, and work with the rest,
-+  // and then prepend it to everything we find.
-+  if (pattern.charAt(0) !== "{") {
-+    this.debug(pattern)
-+    var prefix = null
-+    for (var i = 0, l = pattern.length; i < l; i ++) {
-+      var c = pattern.charAt(i)
-+      this.debug(i, c)
-+      if (c === "\\") {
-+        escaping = !escaping
-+      } else if (c === "{" && !escaping) {
-+        prefix = pattern.substr(0, i)
-+        break
-+      }
-+    }
-+
-+    // actually no sets, all { were escaped.
-+    if (prefix === null) {
-+      this.debug("no sets")
-+      return [pattern]
-+    }
-+
-+   var tail = braceExpand.call(this, pattern.substr(i), options)
-+    return tail.map(function (t) {
-+      return prefix + t
-+    })
-+  }
-+
-+  // now we have something like:
-+  // {b,c{d,e},{f,g}h}x{y,z}
-+  // walk through the set, expanding each part, until
-+  // the set ends.  then, we'll expand the suffix.
-+  // If the set only has a single member, then'll put the {} back
-+
-+  // first, handle numeric sets, since they're easier
-+  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
-+  if (numset) {
-+    this.debug("numset", numset[1], numset[2])
-+    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
-+      , start = +numset[1]
-+      , end = +numset[2]
-+      , inc = start > end ? -1 : 1
-+      , set = []
-+    for (var i = start; i != (end + inc); i += inc) {
-+      // append all the suffixes
-+      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
-+        set.push(i + suf[ii])
-+      }
-+    }
-+    return set
-+  }
-+
-+  // ok, walk through the set
-+  // We hope, somewhat optimistically, that there
-+  // will be a } at the end.
-+  // If the closing brace isn't found, then the pattern is
-+  // interpreted as braceExpand("\\" + pattern) so that
-+  // the leading \{ will be interpreted literally.
-+  var i = 1 // skip the \{
-+    , depth = 1
-+    , set = []
-+    , member = ""
-+    , sawEnd = false
-+    , escaping = false
-+
-+  function addMember () {
-+    set.push(member)
-+    member = ""
-+  }
-+
-+  this.debug("Entering for")
-+  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
-+    var c = pattern.charAt(i)
-+    this.debug("", i, c)
-+
-+    if (escaping) {
-+      escaping = false
-+      member += "\\" + c
-+    } else {
-+      switch (c) {
-+        case "\\":
-+          escaping = true
-+          continue
-+
-+        case "{":
-+          depth ++
-+          member += "{"
-+          continue
-+
-+        case "}":
-+          depth --
-+          // if this closes the actual set, then we're done
-+          if (depth === 0) {
-+            addMember()
-+            // pluck off the close-brace
-+            i ++
-+            break FOR
-+          } else {
-+            member += c
-+            continue
-+          }
-+
-+        case ",":
-+          if (depth === 1) {
-+            addMember()
-+          } else {
-+            member += c
-+          }
-+          continue
-+
-+        default:
-+          member += c
-+          continue
-+      } // switch
-+    } // else
-+  } // for
-+
-+  // now we've either finished the set, and the suffix is
-+  // pattern.substr(i), or we have *not* closed the set,
-+  // and need to escape the leading brace
-+  if (depth !== 0) {
-+    this.debug("didn't close", pattern)
-+    return braceExpand.call(this, "\\" + pattern, options)
-+  }
-+
-+  // x{y,z} -> ["xy", "xz"]
-+  this.debug("set", set)
-+  this.debug("suffix", pattern.substr(i))
-+  var suf = braceExpand.call(this, pattern.substr(i), options)
-+  // ["b", "c{d,e}","{f,g}h"] ->
-+  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
-+  var addBraces = set.length === 1
-+  this.debug("set pre-expanded", set)
-+  set = set.map(function (p) {
-+    return braceExpand.call(this, p, options)
-+  }, this)
-+  this.debug("set expanded", set)
-+
-+
-+  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
-+  //   ["b", "cd", "ce", "fh", "gh"]
-+  set = set.reduce(function (l, r) {
-+    return l.concat(r)
-+  })
-+
-+  if (addBraces) {
-+    set = set.map(function (s) {
-+      return "{" + s + "}"
-+    })
-+  }
-+
-+  // now attach the suffixes.
-+  var ret = []
-+  for (var i = 0, l = set.length; i < l; i ++) {
-+    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
-+      ret.push(set[i] + suf[ii])
-+    }
-+  }
-+  return ret
-+}
-+
-+// parse a component of the expanded set.
-+// At this point, no pattern may contain "/" in it
-+// so we're going to return a 2d array, where each entry is the full
-+// pattern, split on '/', and then turned into a regular expression.
-+// A regexp is made at the end which joins each array with an
-+// escaped /, and another full one which joins each regexp with |.
-+//
-+// Following the lead of Bash 4.1, note that "**" only has special meaning
-+// when it is the *only* thing in a path portion.  Otherwise, any series
-+// of * is equivalent to a single *.  Globstar behavior is enabled by
-+// default, and can be disabled by setting options.noglobstar.
-+Minimatch.prototype.parse = parse
-+var SUBPARSE = {}
-+function parse (pattern, isSub) {
-+  var options = this.options
-+
-+  // shortcuts
-+  if (!options.noglobstar && pattern === "**") return GLOBSTAR
-+  if (pattern === "") return ""
-+
-+  var re = ""
-+    , hasMagic = !!options.nocase
-+    , escaping = false
-+    // ? => one single character
-+    , patternListStack = []
-+    , plType
-+    , stateChar
-+    , inClass = false
-+    , reClassStart = -1
-+    , classStart = -1
-+    // . and .. never match anything that doesn't start with .,
-+    // even when options.dot is set.
-+    , patternStart = pattern.charAt(0) === "." ? "" // anything
-+      // not (start or / followed by . or .. followed by / or end)
-+      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
-+      : "(?!\\.)"
-+    , self = this
-+
-+  function clearStateChar () {
-+    if (stateChar) {
-+      // we had some state-tracking character
-+      // that wasn't consumed by this pass.
-+      switch (stateChar) {
-+        case "*":
-+          re += star
-+          hasMagic = true
-+          break
-+        case "?":
-+          re += qmark
-+          hasMagic = true
-+          break
-+        default:
-+          re += "\\"+stateChar
-+          break
-+      }
-+      self.debug('clearStateChar %j %j', stateChar, re)
-+      stateChar = false
-+    }
-+  }
-+
-+  for ( var i = 0, len = pattern.length, c
-+      ; (i < len) && (c = pattern.charAt(i))
-+      ; i ++ ) {
-+
-+    this.debug("%s\t%s %s %j", pattern, i, re, c)
-+
-+    // skip over any that are escaped.
-+    if (escaping && reSpecials[c]) {
-+      re += "\\" + c
-+      escaping = false
-+      continue
-+    }
-+
-+    SWITCH: switch (c) {
-+      case "/":
-+        // completely not allowed, even escaped.
-+        // Should already be path-split by now.
-+        return false
-+
-+      case "\\":
-+        clearStateChar()
-+        escaping = true
-+        continue
-+
-+      // the various stateChar values
-+      // for the "extglob" stuff.
-+      case "?":
-+      case "*":
-+      case "+":
-+      case "@":
-+      case "!":
-+        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
-+
-+        // all of those are literals inside a class, except that
-+        // the glob [!a] means [^a] in regexp
-+        if (inClass) {
-+          this.debug('  in class')
-+          if (c === "!" && i === classStart + 1) c = "^"
-+          re += c
-+          continue
-+        }
-+
-+        // if we already have a stateChar, then it means
-+        // that there was something like ** or +? in there.
-+        // Handle the stateChar, then proceed with this one.
-+        self.debug('call clearStateChar %j', stateChar)
-+        clearStateChar()
-+        stateChar = c
-+        // if extglob is disabled, then +(asdf|foo) isn't a thing.
-+        // just clear the statechar *now*, rather than even diving into
-+        // the patternList stuff.
-+        if (options.noext) clearStateChar()
-+        continue
-+
-+      case "(":
-+        if (inClass) {
-+          re += "("
-+          continue
-+        }
-+
-+        if (!stateChar) {
-+          re += "\\("
-+          continue
-+        }
-+
-+        plType = stateChar
-+        patternListStack.push({ type: plType
-+                              , start: i - 1
-+                              , reStart: re.length })
-+        // negation is (?:(?!js)[^/]*)
-+        re += stateChar === "!" ? "(?:(?!" : "(?:"
-+        this.debug('plType %j %j', stateChar, re)
-+        stateChar = false
-+        continue
-+
-+      case ")":
-+        if (inClass || !patternListStack.length) {
-+          re += "\\)"
-+          continue
-+        }
-+
-+        clearStateChar()
-+        hasMagic = true
-+        re += ")"
-+        plType = patternListStack.pop().type
-+        // negation is (?:(?!js)[^/]*)
-+        // The others are (?:<pattern>)<type>
-+        switch (plType) {
-+          case "!":
-+            re += "[^/]*?)"
-+            break
-+          case "?":
-+          case "+":
-+          case "*": re += plType
-+          case "@": break // the default anyway
-+        }
-+        continue
-+
-+      case "|":
-+        if (inClass || !patternListStack.length || escaping) {
-+          re += "\\|"
-+          escaping = false
-+          continue
-+        }
-+
-+        clearStateChar()
-+        re += "|"
-+        continue
-+
-+      // these are mostly the same in regexp and glob
-+      case "[":
-+        // swallow any state-tracking char before the [
-+        clearStateChar()
-+
-+        if (inClass) {
-+          re += "\\" + c
-+          continue
-+        }
-+
-+        inClass = true
-+        classStart = i
-+        reClassStart = re.length
-+        re += c
-+        continue
-+
-+      case "]":
-+        //  a right bracket shall lose its special
-+        //  meaning and represent itself in
-+        //  a bracket expression if it occurs
-+        //  first in the list.  -- POSIX.2 2.8.3.2
-+        if (i === classStart + 1 || !inClass) {
-+          re += "\\" + c
-+          escaping = false
-+          continue
-+        }
-+
-+        // finish up the class.
-+        hasMagic = true
-+        inClass = false
-+        re += c
-+        continue
-+
-+      default:
-+        // swallow any state char that wasn't consumed
-+        clearStateChar()
-+
-+        if (escaping) {
-+          // no need
-+          escaping = false
-+        } else if (reSpecials[c]
-+                   && !(c === "^" && inClass)) {
-+          re += "\\"
-+        }
-+
-+        re += c
-+
-+    } // switch
-+  } // for
-+
-+
-+  // handle the case where we left a class open.
-+  // "[abc" is valid, equivalent to "\[abc"
-+  if (inClass) {
-+    // split where the last [ was, and escape it
-+    // this is a huge pita.  We now have to re-walk
-+    // the contents of the would-be class to re-translate
-+    // any characters that were passed through as-is
-+    var cs = pattern.substr(classStart + 1)
-+      , sp = this.parse(cs, SUBPARSE)
-+    re = re.substr(0, reClassStart) + "\\[" + sp[0]
-+    hasMagic = hasMagic || sp[1]
-+  }
-+
-+  // handle the case where we had a +( thing at the *end*
-+  // of the pattern.
-+  // each pattern list stack adds 3 chars, and we need to go through
-+  // and escape any | chars that were passed through as-is for the regexp.
-+  // Go through and escape them, taking care not to double-escape any
-+  // | chars that were already escaped.
-+  var pl
-+  while (pl = patternListStack.pop()) {
-+    var tail = re.slice(pl.reStart + 3)
-+    // maybe some even number of \, then maybe 1 \, followed by a |
-+    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
-+      if (!$2) {
-+        // the | isn't already escaped, so escape it.
-+        $2 = "\\"
-+      }
-+
-+      // need to escape all those slashes *again*, without escaping the
-+      // one that we need for escaping the | character.  As it works out,
-+      // escaping an even number of slashes can be done by simply repeating
-+      // it exactly after itself.  That's why this trick works.
-+      //
-+      // I am sorry that you have to see this.
-+      return $1 + $1 + $2 + "|"
-+    })
-+
-+    this.debug("tail=%j\n   %s", tail, tail)
-+    var t = pl.type === "*" ? star
-+          : pl.type === "?" ? qmark
-+          : "\\" + pl.type
-+
-+    hasMagic = true
-+    re = re.slice(0, pl.reStart)
-+       + t + "\\("
-+       + tail
-+  }
-+
-+  // handle trailing things that only matter at the very end.
-+  clearStateChar()
-+  if (escaping) {
-+    // trailing \\
-+    re += "\\\\"
-+  }
-+
-+  // only need to apply the nodot start if the re starts with
-+  // something that could conceivably capture a dot
-+  var addPatternStart = false
-+  switch (re.charAt(0)) {
-+    case ".":
-+    case "[":
-+    case "(": addPatternStart = true
-+  }
-+
-+  // if the re is not "" at this point, then we need to make sure
-+  // it doesn't match against an empty path part.
-+  // Otherwise a/* will match a/, which it should not.
-+  if (re !== "" && hasMagic) re = "(?=.)" + re
-+
-+  if (addPatternStart) re = patternStart + re
-+
-+  // parsing just a piece of a larger pattern.
-+  if (isSub === SUBPARSE) {
-+    return [ re, hasMagic ]
-+  }
-+
-+  // skip the regexp for non-magical patterns
-+  // unescape anything in it, though, so that it'll be
-+  // an exact match against a file etc.
-+  if (!hasMagic) {
-+    return globUnescape(pattern)
-+  }
-+
-+  var flags = options.nocase ? "i" : ""
-+    , regExp = new RegExp("^" + re + "$", flags)
-+
-+  regExp._glob = pattern
-+  regExp._src = re
-+
-+  return regExp
-+}
-+
-+minimatch.makeRe = function (pattern, options) {
-+  return new Minimatch(pattern, options || {}).makeRe()
-+}
-+
-+Minimatch.prototype.makeRe = makeRe
-+function makeRe () {
-+  if (this.regexp || this.regexp === false) return this.regexp
-+
-+  // at this point, this.set is a 2d array of partial
-+  // pattern strings, or "**".
-+  //
-+  // It's better to use .match().  This function shouldn't
-+  // be used, really, but it's pretty convenient sometimes,
-+  // when you just want to work with a regex.
-+  var set = this.set
-+
-+  if (!set.length) return this.regexp = false
-+  var options = this.options
-+
-+  var twoStar = options.noglobstar ? star
-+      : options.dot ? twoStarDot
-+      : twoStarNoDot
-+    , flags = options.nocase ? "i" : ""
-+
-+  var re = set.map(function (pattern) {
-+    return pattern.map(function (p) {
-+      return (p === GLOBSTAR) ? twoStar
-+           : (typeof p === "string") ? regExpEscape(p)
-+           : p._src
-+    }).join("\\\/")
-+  }).join("|")
-+
-+  // must match entire pattern
-+  // ending in a * or ** will make it less strict.
-+  re = "^(?:" + re + ")$"
-+
-+  // can match anything, as long as it's not this.
-+  if (this.negate) re = "^(?!" + re + ").*$"
-+
-+  try {
-+    return this.regexp = new RegExp(re, flags)
-+  } catch (ex) {
-+    return this.regexp = false
-+  }
-+}
-+
-+minimatch.match = function (list, pattern, options) {
-+  var mm = new Minimatch(pattern, options)
-+  list = list.filter(function (f) {
-+    return mm.match(f)
-+  })
-+  if (options.nonull && !list.length) {
-+    list.push(pattern)
-+  }
-+  return list
-+}
-+
-+Minimatch.prototype.match = match
-+function match (f, partial) {
-+  this.debug("match", f, this.pattern)
-+  // short-circuit in the case of busted things.
-+  // comments, etc.
-+  if (this.comment) return false
-+  if (this.empty) return f === ""
-+
-+  if (f === "/" && partial) return true
-+
-+  var options = this.options
-+
-+  // windows: need to use /, not \
-+  // On other platforms, \ is a valid (albeit bad) filename char.
-+  if (platform === "win32") {
-+    f = f.split("\\").join("/")
-+  }
-+
-+  // treat the test path as a set of pathparts.
-+  f = f.split(slashSplit)
-+  this.debug(this.pattern, "split", f)
-+
-+  // just ONE of the pattern sets in this.set needs to match
-+  // in order for it to be valid.  If negating, then just one
-+  // match means that we have failed.
-+  // Either way, return on the first hit.
-+
-+  var set = this.set
-+  this.debug(this.pattern, "set", set)
-+
-+  var splitFile = path.basename(f.join("/")).split("/")
-+
-+  for (var i = 0, l = set.length; i < l; i ++) {
-+    var pattern = set[i], file = f
-+    if (options.matchBase && pattern.length === 1) {
-+      file = splitFile
-+    }
-+    var hit = this.matchOne(file, pattern, partial)
-+    if (hit) {
-+      if (options.flipNegate) return true
-+      return !this.negate
-+    }
-+  }
-+
-+  // didn't get any hits.  this is success if it's a negative
-+  // pattern, failure otherwise.
-+  if (options.flipNegate) return false
-+  return this.negate
-+}
-+
-+// set partial to true to test if, for example,
-+// "/a/b" matches the start of "/*/b/*/d"
-+// Partial means, if you run out of file before you run
-+// out of pattern, then that's fine, as long as all
-+// the parts match.
-+Minimatch.prototype.matchOne = function (file, pattern, partial) {
-+  var options = this.options
-+
-+  this.debug("matchOne",
-+              { "this": this
-+              , file: file
-+              , pattern: pattern })
-+
-+  this.debug("matchOne", file.length, pattern.length)
-+
-+  for ( var fi = 0
-+          , pi = 0
-+          , fl = file.length
-+          , pl = pattern.length
-+      ; (fi < fl) && (pi < pl)
-+      ; fi ++, pi ++ ) {
-+
-+    this.debug("matchOne loop")
-+    var p = pattern[pi]
-+      , f = file[fi]
-+
-+    this.debug(pattern, p, f)
-+
-+    // should be impossible.
-+    // some invalid regexp stuff in the set.
-+    if (p === false) return false
-+
-+    if (p === GLOBSTAR) {
-+      this.debug('GLOBSTAR', [pattern, p, f])
-+
-+      // "**"
-+      // a/**/b/**/c would match the following:
-+      // a/b/x/y/z/c
-+      // a/x/y/z/b/c
-+      // a/b/x/b/x/c
-+      // a/b/c
-+      // To do this, take the rest of the pattern after
-+      // the **, and see if it would match the file remainder.
-+      // If so, return success.
-+      // If not, the ** "swallows" a segment, and try again.
-+      // This is recursively awful.
-+      //
-+      // a/**/b/**/c matching a/b/x/y/z/c
-+      // - a matches a
-+      // - doublestar
-+      //   - matchOne(b/x/y/z/c, b/**/c)
-+      //     - b matches b
-+      //     - doublestar
-+      //       - matchOne(x/y/z/c, c) -> no
-+      //       - matchOne(y/z/c, c) -> no
-+      //       - matchOne(z/c, c) -> no
-+      //       - matchOne(c, c) yes, hit
-+      var fr = fi
-+        , pr = pi + 1
-+      if (pr === pl) {
-+        this.debug('** at the end')
-+        // a ** at the end will just swallow the rest.
-+        // We have found a match.
-+        // however, it will not swallow /.x, unless
-+        // options.dot is set.
-+        // . and .. are *never* matched by **, for explosively
-+        // exponential reasons.
-+        for ( ; fi < fl; fi ++) {
-+          if (file[fi] === "." || file[fi] === ".." ||
-+              (!options.dot && file[fi].charAt(0) === ".")) return false
-+        }
-+        return true
-+      }
-+
-+      // ok, let's see if we can swallow whatever we can.
-+      WHILE: while (fr < fl) {
-+        var swallowee = file[fr]
-+
-+        this.debug('\nglobstar while',
-+                    file, fr, pattern, pr, swallowee)
-+
-+        // XXX remove this slice.  Just pass the start index.
-+        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-+          this.debug('globstar found match!', fr, fl, swallowee)
-+          // found a match.
-+          return true
-+        } else {
-+          // can't swallow "." or ".." ever.
-+          // can only swallow ".foo" when explicitly asked.
-+          if (swallowee === "." || swallowee === ".." ||
-+              (!options.dot && swallowee.charAt(0) === ".")) {
-+            this.debug("dot detected!", file, fr, pattern, pr)
-+            break WHILE
-+          }
-+
-+          // ** swallows a segment, and continue.
-+          this.debug('globstar swallow a segment, and continue')
-+          fr ++
-+        }
-+      }
-+      // no match was found.
-+      // However, in partial mode, we can't say this is necessarily over.
-+      // If there's more *pattern* left, then 
-+      if (partial) {
-+        // ran out of file
-+        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
-+        if (fr === fl) return true
-+      }
-+      return false
-+    }
-+
-+    // something other than **
-+    // non-magic patterns just have to match exactly
-+    // patterns with magic have been turned into regexps.
-+    var hit
-+    if (typeof p === "string") {
-+      if (options.nocase) {
-+        hit = f.toLowerCase() === p.toLowerCase()
-+      } else {
-+        hit = f === p
-+      }
-+      this.debug("string match", p, f, hit)
-+    } else {
-+      hit = f.match(p)
-+      this.debug("pattern match", p, f, hit)
-+    }
-+
-+    if (!hit) return false
-+  }
-+
-+  // Note: ending in / means that we'll get a final ""
-+  // at the end of the pattern.  This can only match a
-+  // corresponding "" at the end of the file.
-+  // If the file ends in /, then it can only match a
-+  // a pattern that ends in /, unless the pattern just
-+  // doesn't have any more for it. But, a/b/ should *not*
-+  // match "a/b/*", even though "" matches against the
-+  // [^/]*? pattern, except in partial mode, where it might
-+  // simply not be reached yet.
-+  // However, a/b/ should still satisfy a/*
-+
-+  // now either we fell off the end of the pattern, or we're done.
-+  if (fi === fl && pi === pl) {
-+    // ran out of pattern and filename at the same time.
-+    // an exact hit!
-+    return true
-+  } else if (fi === fl) {
-+    // ran out of file, but still had pattern left.
-+    // this is ok if we're doing the match as part of
-+    // a glob fs traversal.
-+    return partial
-+  } else if (pi === pl) {
-+    // ran out of pattern, still have file left.
-+    // this is only acceptable if we're on the very last
-+    // empty segment of a file with a trailing slash.
-+    // a/* should match a/b/
-+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
-+    return emptyFileEnd
-+  }
-+
-+  // should be unreachable.
-+  throw new Error("wtf?")
-+}
-+
-+
-+// replace stuff like \* with *
-+function globUnescape (s) {
-+  return s.replace(/\\(.)/g, "$1")
-+}
-+
-+
-+function regExpEscape (s) {
-+  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-+}
-+
-+})( typeof require === "function" ? require : null,
-+    this,
-+    typeof module === "object" ? module : null,
-+    typeof process === "object" ? process.platform : "win32"
-+  )
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/.npmignore
-@@ -0,0 +1 @@
-+/node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
-@@ -0,0 +1,14 @@
-+# Authors, sorted by whether or not they are me
-+Isaac Z. Schlueter <i at izs.me>
-+Brian Cottingham <spiffytech at gmail.com>
-+Carlos Brito Lage <carlos at carloslage.net>
-+Jesse Dailey <jesse.dailey at gmail.com>
-+Kevin O'Hara <kevinohara80 at gmail.com>
-+Marco Rogers <marco.rogers at gmail.com>
-+Mark Cavage <mcavage at gmail.com>
-+Marko Mikulicic <marko.mikulicic at isti.cnr.it>
-+Nathan Rajlich <nathan at tootallnate.net>
-+Satheesh Natesan <snateshan at myspace-inc.com>
-+Trent Mick <trentm at gmail.com>
-+ashleybrener <ashley at starlogik.com>
-+n4kz <n4kz at n4kz.com>
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-+All rights reserved.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/README.md
-@@ -0,0 +1,97 @@
-+# lru cache
-+
-+A cache object that deletes the least-recently-used items.
-+
-+## Usage:
-+
-+```javascript
-+var LRU = require("lru-cache")
-+  , options = { max: 500
-+              , length: function (n) { return n * 2 }
-+              , dispose: function (key, n) { n.close() }
-+              , maxAge: 1000 * 60 * 60 }
-+  , cache = LRU(options)
-+  , otherCache = LRU(50) // sets just the max size
-+
-+cache.set("key", "value")
-+cache.get("key") // "value"
-+
-+cache.reset()    // empty the cache
-+```
-+
-+If you put more stuff in it, then items will fall out.
-+
-+If you try to put an oversized thing in it, then it'll fall out right
-+away.
-+
-+## Options
-+
-+* `max` The maximum size of the cache, checked by applying the length
-+  function to all values in the cache.  Not setting this is kind of
-+  silly, since that's the whole purpose of this lib, but it defaults
-+  to `Infinity`.
-+* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out
-+  as they age, but if you try to get an item that is too old, it'll
-+  drop it and return undefined instead of giving it to you.
-+* `length` Function that is used to calculate the length of stored
-+  items.  If you're storing strings or buffers, then you probably want
-+  to do something like `function(n){return n.length}`.  The default is
-+  `function(n){return 1}`, which is fine if you want to store `n`
-+  like-sized things.
-+* `dispose` Function that is called on items when they are dropped
-+  from the cache.  This can be handy if you want to close file
-+  descriptors or do other cleanup tasks when items are no longer
-+  accessible.  Called with `key, value`.  It's called *before*
-+  actually removing the item from the internal cache, so if you want
-+  to immediately put it back in, you'll have to do that in a
-+  `nextTick` or `setTimeout` callback or it won't do anything.
-+* `stale` By default, if you set a `maxAge`, it'll only actually pull
-+  stale items out of the cache when you `get(key)`.  (That is, it's
-+  not pre-emptively doing a `setTimeout` or anything.)  If you set
-+  `stale:true`, it'll return the stale value before deleting it.  If
-+  you don't set this, then it'll return `undefined` when you try to
-+  get a stale entry, as if it had already been deleted.
-+
-+## API
-+
-+* `set(key, value)`
-+* `get(key) => value`
-+
-+    Both of these will update the "recently used"-ness of the key.
-+    They do what you think.
-+
-+* `peek(key)`
-+
-+    Returns the key value (or `undefined` if not found) without
-+    updating the "recently used"-ness of the key.
-+
-+    (If you find yourself using this a lot, you *might* be using the
-+    wrong sort of data structure, but there are some use cases where
-+    it's handy.)
-+
-+* `del(key)`
-+
-+    Deletes a key out of the cache.
-+
-+* `reset()`
-+
-+    Clear the cache entirely, throwing away all values.
-+
-+* `has(key)`
-+
-+    Check if a key is in the cache, without updating the recent-ness
-+    or deleting it for being stale.
-+
-+* `forEach(function(value,key,cache), [thisp])`
-+
-+    Just like `Array.prototype.forEach`.  Iterates over all the keys
-+    in the cache, in order of recent-ness.  (Ie, more recently used
-+    items are iterated over first.)
-+
-+* `keys()`
-+
-+    Return an array of the keys in the cache.
-+
-+* `values()`
-+
-+    Return an array of the values in the cache.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
-@@ -0,0 +1,252 @@
-+;(function () { // closure for web browsers
-+
-+if (typeof module === 'object' && module.exports) {
-+  module.exports = LRUCache
-+} else {
-+  // just set the global for non-node platforms.
-+  this.LRUCache = LRUCache
-+}
-+
-+function hOP (obj, key) {
-+  return Object.prototype.hasOwnProperty.call(obj, key)
-+}
-+
-+function naiveLength () { return 1 }
-+
-+function LRUCache (options) {
-+  if (!(this instanceof LRUCache))
-+    return new LRUCache(options)
-+
-+  if (typeof options === 'number')
-+    options = { max: options }
-+
-+  if (!options)
-+    options = {}
-+
-+  this._max = options.max
-+  // Kind of weird to have a default max of Infinity, but oh well.
-+  if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
-+    this._max = Infinity
-+
-+  this._lengthCalculator = options.length || naiveLength
-+  if (typeof this._lengthCalculator !== "function")
-+    this._lengthCalculator = naiveLength
-+
-+  this._allowStale = options.stale || false
-+  this._maxAge = options.maxAge || null
-+  this._dispose = options.dispose
-+  this.reset()
-+}
-+
-+// resize the cache when the max changes.
-+Object.defineProperty(LRUCache.prototype, "max",
-+  { set : function (mL) {
-+      if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
-+      this._max = mL
-+      if (this._length > this._max) trim(this)
-+    }
-+  , get : function () { return this._max }
-+  , enumerable : true
-+  })
-+
-+// resize the cache when the lengthCalculator changes.
-+Object.defineProperty(LRUCache.prototype, "lengthCalculator",
-+  { set : function (lC) {
-+      if (typeof lC !== "function") {
-+        this._lengthCalculator = naiveLength
-+        this._length = this._itemCount
-+        for (var key in this._cache) {
-+          this._cache[key].length = 1
-+        }
-+      } else {
-+        this._lengthCalculator = lC
-+        this._length = 0
-+        for (var key in this._cache) {
-+          this._cache[key].length = this._lengthCalculator(this._cache[key].value)
-+          this._length += this._cache[key].length
-+        }
-+      }
-+
-+      if (this._length > this._max) trim(this)
-+    }
-+  , get : function () { return this._lengthCalculator }
-+  , enumerable : true
-+  })
-+
-+Object.defineProperty(LRUCache.prototype, "length",
-+  { get : function () { return this._length }
-+  , enumerable : true
-+  })
-+
-+
-+Object.defineProperty(LRUCache.prototype, "itemCount",
-+  { get : function () { return this._itemCount }
-+  , enumerable : true
-+  })
-+
-+LRUCache.prototype.forEach = function (fn, thisp) {
-+  thisp = thisp || this
-+  var i = 0;
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    i++
-+    var hit = this._lruList[k]
-+    if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
-+      del(this, hit)
-+      if (!this._allowStale) hit = undefined
-+    }
-+    if (hit) {
-+      fn.call(thisp, hit.value, hit.key, this)
-+    }
-+  }
-+}
-+
-+LRUCache.prototype.keys = function () {
-+  var keys = new Array(this._itemCount)
-+  var i = 0
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    var hit = this._lruList[k]
-+    keys[i++] = hit.key
-+  }
-+  return keys
-+}
-+
-+LRUCache.prototype.values = function () {
-+  var values = new Array(this._itemCount)
-+  var i = 0
-+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
-+    var hit = this._lruList[k]
-+    values[i++] = hit.value
-+  }
-+  return values
-+}
-+
-+LRUCache.prototype.reset = function () {
-+  if (this._dispose && this._cache) {
-+    for (var k in this._cache) {
-+      this._dispose(k, this._cache[k].value)
-+    }
-+  }
-+
-+  this._cache = Object.create(null) // hash of items by key
-+  this._lruList = Object.create(null) // list of items in order of use recency
-+  this._mru = 0 // most recently used
-+  this._lru = 0 // least recently used
-+  this._length = 0 // number of items in the list
-+  this._itemCount = 0
-+}
-+
-+// Provided for debugging/dev purposes only. No promises whatsoever that
-+// this API stays stable.
-+LRUCache.prototype.dump = function () {
-+  return this._cache
-+}
-+
-+LRUCache.prototype.dumpLru = function () {
-+  return this._lruList
-+}
-+
-+LRUCache.prototype.set = function (key, value) {
-+  if (hOP(this._cache, key)) {
-+    // dispose of the old one before overwriting
-+    if (this._dispose) this._dispose(key, this._cache[key].value)
-+    if (this._maxAge) this._cache[key].now = Date.now()
-+    this._cache[key].value = value
-+    this.get(key)
-+    return true
-+  }
-+
-+  var len = this._lengthCalculator(value)
-+  var age = this._maxAge ? Date.now() : 0
-+  var hit = new Entry(key, value, this._mru++, len, age)
-+
-+  // oversized objects fall out of cache automatically.
-+  if (hit.length > this._max) {
-+    if (this._dispose) this._dispose(key, value)
-+    return false
-+  }
-+
-+  this._length += hit.length
-+  this._lruList[hit.lu] = this._cache[key] = hit
-+  this._itemCount ++
-+
-+  if (this._length > this._max) trim(this)
-+  return true
-+}
-+
-+LRUCache.prototype.has = function (key) {
-+  if (!hOP(this._cache, key)) return false
-+  var hit = this._cache[key]
-+  if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
-+    return false
-+  }
-+  return true
-+}
-+
-+LRUCache.prototype.get = function (key) {
-+  return get(this, key, true)
-+}
-+
-+LRUCache.prototype.peek = function (key) {
-+  return get(this, key, false)
-+}
-+
-+LRUCache.prototype.pop = function () {
-+  var hit = this._lruList[this._lru]
-+  del(this, hit)
-+  return hit || null
-+}
-+
-+LRUCache.prototype.del = function (key) {
-+  del(this, this._cache[key])
-+}
-+
-+function get (self, key, doUse) {
-+  var hit = self._cache[key]
-+  if (hit) {
-+    if (self._maxAge && (Date.now() - hit.now > self._maxAge)) {
-+      del(self, hit)
-+      if (!self._allowStale) hit = undefined
-+    } else {
-+      if (doUse) use(self, hit)
-+    }
-+    if (hit) hit = hit.value
-+  }
-+  return hit
-+}
-+
-+function use (self, hit) {
-+  shiftLU(self, hit)
-+  hit.lu = self._mru ++
-+  self._lruList[hit.lu] = hit
-+}
-+
-+function trim (self) {
-+  while (self._lru < self._mru && self._length > self._max)
-+    del(self, self._lruList[self._lru])
-+}
-+
-+function shiftLU (self, hit) {
-+  delete self._lruList[ hit.lu ]
-+  while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
-+}
-+
-+function del (self, hit) {
-+  if (hit) {
-+    if (self._dispose) self._dispose(hit.key, hit.value)
-+    self._length -= hit.length
-+    self._itemCount --
-+    delete self._cache[ hit.key ]
-+    shiftLU(self, hit)
-+  }
-+}
-+
-+// classy, since V8 prefers predictable objects.
-+function Entry (key, value, lu, length, now) {
-+  this.key = key
-+  this.value = value
-+  this.lu = lu
-+  this.length = length
-+  this.now = now
-+}
-+
-+})()
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "lru-cache",
-+  "description": "A cache object that deletes the least-recently-used items.",
-+  "version": "2.5.0",
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me"
-+  },
-+  "scripts": {
-+    "test": "tap test --gc"
-+  },
-+  "main": "lib/lru-cache.js",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/node-lru-cache.git"
-+  },
-+  "devDependencies": {
-+    "tap": "",
-+    "weak": ""
-+  },
-+  "license": {
-+    "type": "MIT",
-+    "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE"
-+  },
-+  "readme": "# lru cache\n\nA cache object that deletes the least-recently-used items.\n\n## Usage:\n\n```javascript\nvar LRU = require(\"lru-cache\")\n  , options = { max: 500\n              , length: function (n) { return n * 2 }\n              , dispose: function (key, n) { n.close() }\n              , maxAge: 1000 * 60 * 60 }\n  , cache = LRU(options)\n  , otherCache = LRU(50) // sets just the max size\n\ncache.set(\"key\", \"value\")\ncache.get(\"key\") // \"value\"\n\ncache.reset()    // empty the cache\n```\n\nIf you put more stuff in it, then items will fall out.\n\nIf you try to put an oversized thing in it, then it'll fall out right\naway.\n\n## Options\n\n* `max` The maximum size of the cache, checked by applying the length\n  function to all values in the cache.  Not setting this is kind of\n  silly, since that's the whole purpose of this lib, but it defaults\n  to `Infinity`.\n* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out\n  as they age, but if you try to get an item that is too old, it'll\n  drop it and return undefined instead of giving it to you.\n* `length` Function that is used to calculate the length of stored\n  items.  If you're storing strings or buffers, then you probably want\n  to do something like `function(n){return n.length}`.  The default is\n  `function(n){return 1}`, which is fine if you want to store `n`\n  like-sized things.\n* `dispose` Function that is called on items when they are dropped\n  from the cache.  This can be handy if you want to close file\n  descriptors or do other cleanup tasks when items are no longer\n  accessible.  Called with `key, value`.  It's called *before*\n  actually removing the item from the internal cache, so if you want\n  to immediately put it back in, you'll have to do that in a\n  `nextTick` or `setTimeout` callback or it won't do anything.\n* `stale` By default, if you set a `maxAge`, it'll only actually pull\n  stale items out of the cache when you `get(key)`.  (That is, it's\n  not pre-emptively doing a `setTimeout` or anything.)  If you set\n  `stale:true`, it'll return the stale value before deleting it.  If\n  you don't set this, then it'll return `undefined` when you try to\n  get a stale entry, as if it had already been deleted.\n\n## API\n\n* `set(key, value)`\n* `get(key) => value`\n\n    Both of these will update the \"recently used\"-ness of the key.\n    They do what you think.\n\n* `peek(key)`\n\n    Returns the key value (or `undefined` if not found) without\n    updating the \"recently used\"-ness of the key.\n\n    (If you find yourself using this a lot, you *might* be using the\n    wrong sort of data structure, but there are some use cases where\n    it's handy.)\n\n* `del(key)`\n\n    Deletes a key out of the cache.\n\n* `reset()`\n\n    Clear the cache entirely, throwing away all values.\n\n* `has(key)`\n\n    Check if a key is in the cache, without updating the recent-ness\n    or deleting it for being stale.\n\n* `forEach(function(value,key,cache), [thisp])`\n\n    Just like `Array.prototype.forEach`.  Iterates over all the keys\n    in the cache, in order of recent-ness.  (Ie, more recently used\n    items are iterated over first.)\n\n* `keys()`\n\n    Return an array of the keys in the cache.\n\n* `values()`\n\n    Return an array of the values in the cache.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/node-lru-cache/issues"
-+  },
-+  "_id": "lru-cache at 2.5.0",
-+  "_from": "lru-cache at 2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/test/basic.js
-@@ -0,0 +1,369 @@
-+var test = require("tap").test
-+  , LRU = require("../")
-+
-+test("basic", function (t) {
-+  var cache = new LRU({max: 10})
-+  cache.set("key", "value")
-+  t.equal(cache.get("key"), "value")
-+  t.equal(cache.get("nada"), undefined)
-+  t.equal(cache.length, 1)
-+  t.equal(cache.max, 10)
-+  t.end()
-+})
-+
-+test("least recently set", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), "B")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("lru recently gotten", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.get("a")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), undefined)
-+  t.equal(cache.get("a"), "A")
-+  t.end()
-+})
-+
-+test("del", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.del("a")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("max", function (t) {
-+  var cache = new LRU(3)
-+
-+  // test changing the max, verify that the LRU items get dropped.
-+  cache.max = 100
-+  for (var i = 0; i < 100; i ++) cache.set(i, i)
-+  t.equal(cache.length, 100)
-+  for (var i = 0; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  cache.max = 3
-+  t.equal(cache.length, 3)
-+  for (var i = 0; i < 97; i ++) {
-+    t.equal(cache.get(i), undefined)
-+  }
-+  for (var i = 98; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+
-+  // now remove the max restriction, and try again.
-+  cache.max = "hello"
-+  for (var i = 0; i < 100; i ++) cache.set(i, i)
-+  t.equal(cache.length, 100)
-+  for (var i = 0; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  // should trigger an immediate resize
-+  cache.max = 3
-+  t.equal(cache.length, 3)
-+  for (var i = 0; i < 97; i ++) {
-+    t.equal(cache.get(i), undefined)
-+  }
-+  for (var i = 98; i < 100; i ++) {
-+    t.equal(cache.get(i), i)
-+  }
-+  t.end()
-+})
-+
-+test("reset", function (t) {
-+  var cache = new LRU(10)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.reset()
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 10)
-+  t.equal(cache.get("a"), undefined)
-+  t.equal(cache.get("b"), undefined)
-+  t.end()
-+})
-+
-+
-+// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made
-+// about the format/layout of the response.
-+test("dump", function (t) {
-+  var cache = new LRU(10)
-+  var d = cache.dump();
-+  t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
-+  cache.set("a", "A")
-+  var d = cache.dump()  // { a: { key: "a", value: "A", lu: 0 } }
-+  t.ok(d.a)
-+  t.equal(d.a.key, "a")
-+  t.equal(d.a.value, "A")
-+  t.equal(d.a.lu, 0)
-+
-+  cache.set("b", "B")
-+  cache.get("b")
-+  d = cache.dump()
-+  t.ok(d.b)
-+  t.equal(d.b.key, "b")
-+  t.equal(d.b.value, "B")
-+  t.equal(d.b.lu, 2)
-+
-+  t.end()
-+})
-+
-+
-+test("basic with weighed length", function (t) {
-+  var cache = new LRU({
-+    max: 100,
-+    length: function (item) { return item.size }
-+  })
-+  cache.set("key", {val: "value", size: 50})
-+  t.equal(cache.get("key").val, "value")
-+  t.equal(cache.get("nada"), undefined)
-+  t.equal(cache.lengthCalculator(cache.get("key")), 50)
-+  t.equal(cache.length, 50)
-+  t.equal(cache.max, 100)
-+  t.end()
-+})
-+
-+
-+test("weighed length item too large", function (t) {
-+  var cache = new LRU({
-+    max: 10,
-+    length: function (item) { return item.size }
-+  })
-+  t.equal(cache.max, 10)
-+
-+  // should fall out immediately
-+  cache.set("key", {val: "value", size: 50})
-+
-+  t.equal(cache.length, 0)
-+  t.equal(cache.get("key"), undefined)
-+  t.end()
-+})
-+
-+test("least recently set with weighed length", function (t) {
-+  var cache = new LRU({
-+    max:8,
-+    length: function (item) { return item.length }
-+  })
-+  cache.set("a", "A")
-+  cache.set("b", "BB")
-+  cache.set("c", "CCC")
-+  cache.set("d", "DDDD")
-+  t.equal(cache.get("d"), "DDDD")
-+  t.equal(cache.get("c"), "CCC")
-+  t.equal(cache.get("b"), undefined)
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("lru recently gotten with weighed length", function (t) {
-+  var cache = new LRU({
-+    max: 8,
-+    length: function (item) { return item.length }
-+  })
-+  cache.set("a", "A")
-+  cache.set("b", "BB")
-+  cache.set("c", "CCC")
-+  cache.get("a")
-+  cache.get("b")
-+  cache.set("d", "DDDD")
-+  t.equal(cache.get("c"), undefined)
-+  t.equal(cache.get("d"), "DDDD")
-+  t.equal(cache.get("b"), "BB")
-+  t.equal(cache.get("a"), "A")
-+  t.end()
-+})
-+
-+test("set returns proper booleans", function(t) {
-+  var cache = new LRU({
-+    max: 5,
-+    length: function (item) { return item.length }
-+  })
-+
-+  t.equal(cache.set("a", "A"), true)
-+
-+  // should return false for max exceeded
-+  t.equal(cache.set("b", "donuts"), false)
-+
-+  t.equal(cache.set("b", "B"), true)
-+  t.equal(cache.set("c", "CCCC"), true)
-+  t.end()
-+})
-+
-+test("drop the old items", function(t) {
-+  var cache = new LRU({
-+    max: 5,
-+    maxAge: 50
-+  })
-+
-+  cache.set("a", "A")
-+
-+  setTimeout(function () {
-+    cache.set("b", "b")
-+    t.equal(cache.get("a"), "A")
-+  }, 25)
-+
-+  setTimeout(function () {
-+    cache.set("c", "C")
-+    // timed out
-+    t.notOk(cache.get("a"))
-+  }, 60)
-+
-+  setTimeout(function () {
-+    t.notOk(cache.get("b"))
-+    t.equal(cache.get("c"), "C")
-+  }, 90)
-+
-+  setTimeout(function () {
-+    t.notOk(cache.get("c"))
-+    t.end()
-+  }, 155)
-+})
-+
-+test("disposal function", function(t) {
-+  var disposed = false
-+  var cache = new LRU({
-+    max: 1,
-+    dispose: function (k, n) {
-+      disposed = n
-+    }
-+  })
-+
-+  cache.set(1, 1)
-+  cache.set(2, 2)
-+  t.equal(disposed, 1)
-+  cache.set(3, 3)
-+  t.equal(disposed, 2)
-+  cache.reset()
-+  t.equal(disposed, 3)
-+  t.end()
-+})
-+
-+test("disposal function on too big of item", function(t) {
-+  var disposed = false
-+  var cache = new LRU({
-+    max: 1,
-+    length: function (k) {
-+      return k.length
-+    },
-+    dispose: function (k, n) {
-+      disposed = n
-+    }
-+  })
-+  var obj = [ 1, 2 ]
-+
-+  t.equal(disposed, false)
-+  cache.set("obj", obj)
-+  t.equal(disposed, obj)
-+  t.end()
-+})
-+
-+test("has()", function(t) {
-+  var cache = new LRU({
-+    max: 1,
-+    maxAge: 10
-+  })
-+
-+  cache.set('foo', 'bar')
-+  t.equal(cache.has('foo'), true)
-+  cache.set('blu', 'baz')
-+  t.equal(cache.has('foo'), false)
-+  t.equal(cache.has('blu'), true)
-+  setTimeout(function() {
-+    t.equal(cache.has('blu'), false)
-+    t.end()
-+  }, 15)
-+})
-+
-+test("stale", function(t) {
-+  var cache = new LRU({
-+    maxAge: 10,
-+    stale: true
-+  })
-+
-+  cache.set('foo', 'bar')
-+  t.equal(cache.get('foo'), 'bar')
-+  t.equal(cache.has('foo'), true)
-+  setTimeout(function() {
-+    t.equal(cache.has('foo'), false)
-+    t.equal(cache.get('foo'), 'bar')
-+    t.equal(cache.get('foo'), undefined)
-+    t.end()
-+  }, 15)
-+})
-+
-+test("lru update via set", function(t) {
-+  var cache = LRU({ max: 2 });
-+
-+  cache.set('foo', 1);
-+  cache.set('bar', 2);
-+  cache.del('bar');
-+  cache.set('baz', 3);
-+  cache.set('qux', 4);
-+
-+  t.equal(cache.get('foo'), undefined)
-+  t.equal(cache.get('bar'), undefined)
-+  t.equal(cache.get('baz'), 3)
-+  t.equal(cache.get('qux'), 4)
-+  t.end()
-+})
-+
-+test("least recently set w/ peek", function (t) {
-+  var cache = new LRU(2)
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  t.equal(cache.peek("a"), "A")
-+  cache.set("c", "C")
-+  t.equal(cache.get("c"), "C")
-+  t.equal(cache.get("b"), "B")
-+  t.equal(cache.get("a"), undefined)
-+  t.end()
-+})
-+
-+test("pop the least used item", function (t) {
-+  var cache = new LRU(3)
-+  , last
-+
-+  cache.set("a", "A")
-+  cache.set("b", "B")
-+  cache.set("c", "C")
-+
-+  t.equal(cache.length, 3)
-+  t.equal(cache.max, 3)
-+
-+  // Ensure we pop a, c, b
-+  cache.get("b", "B")
-+
-+  last = cache.pop()
-+  t.equal(last.key, "a")
-+  t.equal(last.value, "A")
-+  t.equal(cache.length, 2)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last.key, "c")
-+  t.equal(last.value, "C")
-+  t.equal(cache.length, 1)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last.key, "b")
-+  t.equal(last.value, "B")
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 3)
-+
-+  last = cache.pop()
-+  t.equal(last, null)
-+  t.equal(cache.length, 0)
-+  t.equal(cache.max, 3)
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
-@@ -0,0 +1,52 @@
-+var test = require('tap').test
-+var LRU = require('../')
-+
-+test('forEach', function (t) {
-+  var l = new LRU(5)
-+  for (var i = 0; i < 10; i ++) {
-+    l.set(i.toString(), i.toString(2))
-+  }
-+
-+  var i = 9
-+  l.forEach(function (val, key, cache) {
-+    t.equal(cache, l)
-+    t.equal(key, i.toString())
-+    t.equal(val, i.toString(2))
-+    i -= 1
-+  })
-+
-+  // get in order of most recently used
-+  l.get(6)
-+  l.get(8)
-+
-+  var order = [ 8, 6, 9, 7, 5 ]
-+  var i = 0
-+
-+  l.forEach(function (val, key, cache) {
-+    var j = order[i ++]
-+    t.equal(cache, l)
-+    t.equal(key, j.toString())
-+    t.equal(val, j.toString(2))
-+  })
-+
-+  t.end()
-+})
-+
-+test('keys() and values()', function (t) {
-+  var l = new LRU(5)
-+  for (var i = 0; i < 10; i ++) {
-+    l.set(i.toString(), i.toString(2))
-+  }
-+
-+  t.similar(l.keys(), ['9', '8', '7', '6', '5'])
-+  t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
-+
-+  // get in order of most recently used
-+  l.get(6)
-+  l.get(8)
-+
-+  t.similar(l.keys(), ['8', '6', '9', '7', '5'])
-+  t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
-+
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
-@@ -0,0 +1,50 @@
-+#!/usr/bin/env node --expose_gc
-+
-+var weak = require('weak');
-+var test = require('tap').test
-+var LRU = require('../')
-+var l = new LRU({ max: 10 })
-+var refs = 0
-+function X() {
-+  refs ++
-+  weak(this, deref)
-+}
-+
-+function deref() {
-+  refs --
-+}
-+
-+test('no leaks', function (t) {
-+  // fill up the cache
-+  for (var i = 0; i < 100; i++) {
-+    l.set(i, new X);
-+    // throw some gets in there, too.
-+    if (i % 2 === 0)
-+      l.get(i / 2)
-+  }
-+
-+  gc()
-+
-+  var start = process.memoryUsage()
-+
-+  // capture the memory
-+  var startRefs = refs
-+
-+  // do it again, but more
-+  for (var i = 0; i < 10000; i++) {
-+    l.set(i, new X);
-+    // throw some gets in there, too.
-+    if (i % 2 === 0)
-+      l.get(i / 2)
-+  }
-+
-+  gc()
-+
-+  var end = process.memoryUsage()
-+  t.equal(refs, startRefs, 'no leaky refs')
-+
-+  console.error('start: %j\n' +
-+                'end:   %j', start, end);
-+  t.pass();
-+  t.end();
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/LICENSE
-@@ -0,0 +1,27 @@
-+Copyright (c) Isaac Z. Schlueter ("Author")
-+All rights reserved.
-+
-+The BSD License
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+1. Redistributions of source code must retain the above copyright
-+   notice, this list of conditions and the following disclaimer.
-+
-+2. Redistributions in binary form must reproduce the above copyright
-+   notice, this list of conditions and the following disclaimer in the
-+   documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/README.md
-@@ -0,0 +1,53 @@
-+# sigmund
-+
-+Quick and dirty signatures for Objects.
-+
-+This is like a much faster `deepEquals` comparison, which returns a
-+string key suitable for caches and the like.
-+
-+## Usage
-+
-+```javascript
-+function doSomething (someObj) {
-+  var key = sigmund(someObj, maxDepth) // max depth defaults to 10
-+  var cached = cache.get(key)
-+  if (cached) return cached)
-+
-+  var result = expensiveCalculation(someObj)
-+  cache.set(key, result)
-+  return result
-+}
-+```
-+
-+The resulting key will be as unique and reproducible as calling
-+`JSON.stringify` or `util.inspect` on the object, but is much faster.
-+In order to achieve this speed, some differences are glossed over.
-+For example, the object `{0:'foo'}` will be treated identically to the
-+array `['foo']`.
-+
-+Also, just as there is no way to summon the soul from the scribblings
-+of a cocain-addled psychoanalyst, there is no way to revive the object
-+from the signature string that sigmund gives you.  In fact, it's
-+barely even readable.
-+
-+As with `sys.inspect` and `JSON.stringify`, larger objects will
-+produce larger signature strings.
-+
-+Because sigmund is a bit less strict than the more thorough
-+alternatives, the strings will be shorter, and also there is a
-+slightly higher chance for collisions.  For example, these objects
-+have the same signature:
-+
-+    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-+    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-+
-+Like a good Freudian, sigmund is most effective when you already have
-+some understanding of what you're looking for.  It can help you help
-+yourself, but you must be willing to do some work as well.
-+
-+Cycles are handled, and cyclical objects are silently omitted (though
-+the key is included in the signature output.)
-+
-+The second argument is the maximum depth, which defaults to 10,
-+because that is the maximum object traversal depth covered by most
-+insurance carriers.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/bench.js
-@@ -0,0 +1,283 @@
-+// different ways to id objects
-+// use a req/res pair, since it's crazy deep and cyclical
-+
-+// sparseFE10 and sigmund are usually pretty close, which is to be expected,
-+// since they are essentially the same algorithm, except that sigmund handles
-+// regular expression objects properly.
-+
-+
-+var http = require('http')
-+var util = require('util')
-+var sigmund = require('./sigmund.js')
-+var sreq, sres, creq, cres, test
-+
-+http.createServer(function (q, s) {
-+  sreq = q
-+  sres = s
-+  sres.end('ok')
-+  this.close(function () { setTimeout(function () {
-+    start()
-+  }, 200) })
-+}).listen(1337, function () {
-+  creq = http.get({ port: 1337 })
-+  creq.on('response', function (s) { cres = s })
-+})
-+
-+function start () {
-+  test = [sreq, sres, creq, cres]
-+  // test = sreq
-+  // sreq.sres = sres
-+  // sreq.creq = creq
-+  // sreq.cres = cres
-+
-+  for (var i in exports.compare) {
-+    console.log(i)
-+    var hash = exports.compare[i]()
-+    console.log(hash)
-+    console.log(hash.length)
-+    console.log('')
-+  }
-+
-+  require('bench').runMain()
-+}
-+
-+function customWs (obj, md, d) {
-+  d = d || 0
-+  var to = typeof obj
-+  if (to === 'undefined' || to === 'function' || to === null) return ''
-+  if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
-+
-+  if (Array.isArray(obj)) {
-+    return obj.map(function (i, _, __) {
-+      return customWs(i, md, d + 1)
-+    }).reduce(function (a, b) { return a + b }, '')
-+  }
-+
-+  var keys = Object.keys(obj)
-+  return keys.map(function (k, _, __) {
-+    return k + ':' + customWs(obj[k], md, d + 1)
-+  }).reduce(function (a, b) { return a + b }, '')
-+}
-+
-+function custom (obj, md, d) {
-+  d = d || 0
-+  var to = typeof obj
-+  if (to === 'undefined' || to === 'function' || to === null) return ''
-+  if (d > md || !obj || to !== 'object') return '' + obj
-+
-+  if (Array.isArray(obj)) {
-+    return obj.map(function (i, _, __) {
-+      return custom(i, md, d + 1)
-+    }).reduce(function (a, b) { return a + b }, '')
-+  }
-+
-+  var keys = Object.keys(obj)
-+  return keys.map(function (k, _, __) {
-+    return k + ':' + custom(obj[k], md, d + 1)
-+  }).reduce(function (a, b) { return a + b }, '')
-+}
-+
-+function sparseFE2 (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    Object.keys(v).forEach(function (k, _, __) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') return
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') return
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+    })
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function sparseFE (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    Object.keys(v).forEach(function (k, _, __) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') return
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') return
-+      soFar += k
-+      ch(v[k], depth + 1)
-+    })
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function sparse (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k
-+      ch(v[k], depth + 1)
-+    }
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+function noCommas (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+    }
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+
-+function flatten (obj, maxDepth) {
-+  var seen = []
-+  var soFar = ''
-+  function ch (v, depth) {
-+    if (depth > maxDepth) return
-+    if (typeof v === 'function' || typeof v === 'undefined') return
-+    if (typeof v !== 'object' || !v) {
-+      soFar += v
-+      return
-+    }
-+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
-+    seen.push(v)
-+    soFar += '{'
-+    for (var k in v) {
-+      // pseudo-private values.  skip those.
-+      if (k.charAt(0) === '_') continue
-+      var to = typeof v[k]
-+      if (to === 'function' || to === 'undefined') continue
-+      soFar += k + ':'
-+      ch(v[k], depth + 1)
-+      soFar += ','
-+    }
-+    soFar += '}'
-+  }
-+  ch(obj, 0)
-+  return soFar
-+}
-+
-+exports.compare =
-+{
-+  // 'custom 2': function () {
-+  //   return custom(test, 2, 0)
-+  // },
-+  // 'customWs 2': function () {
-+  //   return customWs(test, 2, 0)
-+  // },
-+  'JSON.stringify (guarded)': function () {
-+    var seen = []
-+    return JSON.stringify(test, function (k, v) {
-+      if (typeof v !== 'object' || !v) return v
-+      if (seen.indexOf(v) !== -1) return undefined
-+      seen.push(v)
-+      return v
-+    })
-+  },
-+
-+  'flatten 10': function () {
-+    return flatten(test, 10)
-+  },
-+
-+  // 'flattenFE 10': function () {
-+  //   return flattenFE(test, 10)
-+  // },
-+
-+  'noCommas 10': function () {
-+    return noCommas(test, 10)
-+  },
-+
-+  'sparse 10': function () {
-+    return sparse(test, 10)
-+  },
-+
-+  'sparseFE 10': function () {
-+    return sparseFE(test, 10)
-+  },
-+
-+  'sparseFE2 10': function () {
-+    return sparseFE2(test, 10)
-+  },
-+
-+  sigmund: function() {
-+    return sigmund(test, 10)
-+  },
-+
-+
-+  // 'util.inspect 1': function () {
-+  //   return util.inspect(test, false, 1, false)
-+  // },
-+  // 'util.inspect undefined': function () {
-+  //   util.inspect(test)
-+  // },
-+  // 'util.inspect 2': function () {
-+  //   util.inspect(test, false, 2, false)
-+  // },
-+  // 'util.inspect 3': function () {
-+  //   util.inspect(test, false, 3, false)
-+  // },
-+  // 'util.inspect 4': function () {
-+  //   util.inspect(test, false, 4, false)
-+  // },
-+  // 'util.inspect Infinity': function () {
-+  //   util.inspect(test, false, Infinity, false)
-+  // }
-+}
-+
-+/** results
-+**/
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/package.json
-@@ -0,0 +1,41 @@
-+{
-+  "name": "sigmund",
-+  "version": "1.0.0",
-+  "description": "Quick and dirty signatures for Objects.",
-+  "main": "sigmund.js",
-+  "directories": {
-+    "test": "test"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "~0.3.0"
-+  },
-+  "scripts": {
-+    "test": "tap test/*.js",
-+    "bench": "node bench.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/sigmund"
-+  },
-+  "keywords": [
-+    "object",
-+    "signature",
-+    "key",
-+    "data",
-+    "psychoanalysis"
-+  ],
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": "BSD",
-+  "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n  var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n  var cached = cache.get(key)\n  if (cached) return cached)\n\n  var result = expensiveCalculation(someObj)\n  cache.set(key, result)\n  return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you.  In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions.  For example, these objects\nhave the same signature:\n\n    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for.  It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/sigmund/issues"
-+  },
-+  "_id": "sigmund at 1.0.0",
-+  "_from": "sigmund@~1.0.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/sigmund.js
-@@ -0,0 +1,39 @@
-+module.exports = sigmund
-+function sigmund (subject, maxSessions) {
-+    maxSessions = maxSessions || 10;
-+    var notes = [];
-+    var analysis = '';
-+    var RE = RegExp;
-+
-+    function psychoAnalyze (subject, session) {
-+        if (session > maxSessions) return;
-+
-+        if (typeof subject === 'function' ||
-+            typeof subject === 'undefined') {
-+            return;
-+        }
-+
-+        if (typeof subject !== 'object' || !subject ||
-+            (subject instanceof RE)) {
-+            analysis += subject;
-+            return;
-+        }
-+
-+        if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
-+
-+        notes.push(subject);
-+        analysis += '{';
-+        Object.keys(subject).forEach(function (issue, _, __) {
-+            // pseudo-private values.  skip those.
-+            if (issue.charAt(0) === '_') return;
-+            var to = typeof subject[issue];
-+            if (to === 'function' || to === 'undefined') return;
-+            analysis += issue;
-+            psychoAnalyze(subject[issue], session + 1);
-+        });
-+    }
-+    psychoAnalyze(subject, 0);
-+    return analysis;
-+}
-+
-+// vim: set softtabstop=4 shiftwidth=4:
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/node_modules/sigmund/test/basic.js
-@@ -0,0 +1,24 @@
-+var test = require('tap').test
-+var sigmund = require('../sigmund.js')
-+
-+
-+// occasionally there are duplicates
-+// that's an acceptable edge-case.  JSON.stringify and util.inspect
-+// have some collision potential as well, though less, and collision
-+// detection is expensive.
-+var hash = '{abc/def/g{0h1i2{jkl'
-+var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-+var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-+
-+var obj3 = JSON.parse(JSON.stringify(obj1))
-+obj3.c = /def/
-+obj3.g[2].cycle = obj3
-+var cycleHash = '{abc/def/g{0h1i2{jklcycle'
-+
-+test('basic', function (t) {
-+    t.equal(sigmund(obj1), hash)
-+    t.equal(sigmund(obj2), hash)
-+    t.equal(sigmund(obj3), cycleHash)
-+    t.end()
-+})
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/package.json
-@@ -0,0 +1,39 @@
-+{
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me"
-+  },
-+  "name": "minimatch",
-+  "description": "a glob matcher in javascript",
-+  "version": "0.2.14",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/minimatch.git"
-+  },
-+  "main": "minimatch.js",
-+  "scripts": {
-+    "test": "tap test/*.js"
-+  },
-+  "engines": {
-+    "node": "*"
-+  },
-+  "dependencies": {
-+    "lru-cache": "2",
-+    "sigmund": "~1.0.0"
-+  },
-+  "devDependencies": {
-+    "tap": ""
-+  },
-+  "license": {
-+    "type": "MIT",
-+    "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
-+  },
-+  "readme": "# minimatch\n\nA minimal matching utility.\n\n[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)\n\n\nThis is the matching library used internally by npm.\n\nEventually, it will replace the C binding in node-glob.\n\nIt works by converting glob expressions into JavaScript `RegExp`\nobjects.\n\n## Usage\n\n```javascript\nvar minimatch = require(\"minimatch\")\n\nminimatch(\"bar.foo\", \"*.foo\") // true!\nminimatch(\"bar.foo\", \"*.bar\") // false!\nminimatch(\"bar.foo\", \"*.+(bar|foo)\", { debug: true }) // true, and noisy!\n```\n\n## Features\n\nSupports these glob features:\n\n* Brace Expansion\n* Extended glob matching\n* \"Globstar\" `**` matching\n\nSee:\n\n* `man sh`\n* `man bash`\n* `man 3 fnmatch`\n* `man 5 gitignore`\n\n## Minimatch Class\n\nCreate a minimatch object by instanting the `minimatch.Minimatch` class.\n\n```javascript\nvar Minimatch = require(\"minimatch\").Minimatch\nvar mm = new Minimatch(pattern, options)\n```\n\n### Properties\n\n* `pattern` The original pattern the minimatch object represents.\n* `options` The options supplied to the constructor.\n* `set` A 2-dimensional array of regexp or string expressions.\n  Each row in the\n  array corresponds to a brace-expanded pattern.  Each item in the row\n  corresponds to a single path-part.  For example, the pattern\n  `{a,b/c}/d` would expand to a set of patterns like:\n\n        [ [ a, d ]\n        , [ b, c, d ] ]\n\n    If a portion of the pattern doesn't have any \"magic\" in it\n    (that is, it's something like `\"foo\"` rather than `fo*o?`), then it\n    will be left as a string rather than converted to a regular\n    expression.\n\n* `regexp` Created by the `makeRe` method.  A single regular expression\n  expressing the entire pattern.  This is useful in cases where you wish\n  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.\n* `negate` True if the pattern is negated.\n* `comment` True if the pattern is a comment.\n* `empty` True if the pattern is `\"\"`.\n\n### Methods\n\n* `makeRe` Generate the `regexp` member if necessary, and return it.\n  Will return `false` if the pattern is invalid.\n* `match(fname)` Return true if the filename matches the pattern, or\n  false otherwise.\n* `matchOne(fileArray, patternArray, partial)` Take a `/`-split\n  filename, and match it against a single row in the `regExpSet`.  This\n  method is mainly for internal use, but is exposed so that it can be\n  used by a glob-walker that needs to avoid excessive filesystem calls.\n\nAll other methods are internal, and will be called as necessary.\n\n## Functions\n\nThe top-level exported function has a `cache` property, which is an LRU\ncache set to store 100 items.  So, calling these methods repeatedly\nwith the same pattern and options will use the same Minimatch object,\nsaving the cost of parsing it multiple times.\n\n### minimatch(path, pattern, options)\n\nMain export.  Tests a path against the pattern using the options.\n\n```javascript\nvar isJS = minimatch(file, \"*.js\", { matchBase: true })\n```\n\n### minimatch.filter(pattern, options)\n\nReturns a function that tests its\nsupplied argument, suitable for use with `Array.filter`.  Example:\n\n```javascript\nvar javascripts = fileList.filter(minimatch.filter(\"*.js\", {matchBase: true}))\n```\n\n### minimatch.match(list, pattern, options)\n\nMatch against the list of\nfiles, in the style of fnmatch or glob.  If nothing is matched, and\noptions.nonull is set, then return a list containing the pattern itself.\n\n```javascript\nvar javascripts = minimatch.match(fileList, \"*.js\", {matchBase: true}))\n```\n\n### minimatch.makeRe(pattern, options)\n\nMake a regular expression object from the pattern.\n\n## Options\n\nAll options are `false` by default.\n\n### debug\n\nDump a ton of stuff to stderr.\n\n### nobrace\n\nDo not expand `{a,b}` and `{1..3}` brace sets.\n\n### noglobstar\n\nDisable `**` matching against multiple folder names.\n\n### dot\n\nAllow patterns to match filenames starting with a period, even if\nthe pattern does not explicitly have a period in that spot.\n\nNote that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`\nis set.\n\n### noext\n\nDisable \"extglob\" style patterns like `+(a|b)`.\n\n### nocase\n\nPerform a case-insensitive match.\n\n### nonull\n\nWhen a match is not found by `minimatch.match`, return a list containing\nthe pattern itself.  When set, an empty list is returned if there are\nno matches.\n\n### matchBase\n\nIf set, then patterns without slashes will be matched\nagainst the basename of the path if it contains slashes.  For example,\n`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.\n\n### nocomment\n\nSuppress the behavior of treating `#` at the start of a pattern as a\ncomment.\n\n### nonegate\n\nSuppress the behavior of treating a leading `!` character as negation.\n\n### flipNegate\n\nReturns from negate expressions the same as if they were not negated.\n(Ie, true on a hit, false on a miss.)\n\n\n## Comparisons to other fnmatch/glob implementations\n\nWhile strict compliance with the existing standards is a worthwhile\ngoal, some discrepancies exist between minimatch and other\nimplementations, and are intentional.\n\nIf the pattern starts with a `!` character, then it is negated.  Set the\n`nonegate` flag to suppress this behavior, and treat leading `!`\ncharacters normally.  This is perhaps relevant if you wish to start the\npattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`\ncharacters at the start of a pattern will negate the pattern multiple\ntimes.\n\nIf a pattern starts with `#`, then it is treated as a comment, and\nwill not match anything.  Use `\\#` to match a literal `#` at the\nstart of a line, or set the `nocomment` flag to suppress this behavior.\n\nThe double-star character `**` is supported by default, unless the\n`noglobstar` flag is set.  This is supported in the manner of bsdglob\nand bash 4.1, where `**` only has special significance if it is the only\nthing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but\n`a/**b` will not.\n\nIf an escaped pattern has no matches, and the `nonull` flag is set,\nthen minimatch.match returns the pattern as-provided, rather than\ninterpreting the character escapes.  For example,\n`minimatch.match([], \"\\\\*a\\\\?\")` will return `\"\\\\*a\\\\?\"` rather than\n`\"*a?\"`.  This is akin to setting the `nullglob` option in bash, except\nthat it does not resolve escaped pattern characters.\n\nIf brace expansion is not disabled, then it is performed before any\nother interpretation of the glob pattern.  Thus, a pattern like\n`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded\n**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are\nchecked for validity.  Since those two are valid, matching proceeds.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/minimatch/issues"
-+  },
-+  "_id": "minimatch at 0.2.14",
-+  "_from": "minimatch@~0.2.12"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/test/basic.js
-@@ -0,0 +1,399 @@
-+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-+//
-+// TODO: Some of these tests do very bad things with backslashes, and will
-+// most likely fail badly on windows.  They should probably be skipped.
-+
-+var tap = require("tap")
-+  , globalBefore = Object.keys(global)
-+  , mm = require("../")
-+  , files = [ "a", "b", "c", "d", "abc"
-+            , "abd", "abe", "bb", "bcd"
-+            , "ca", "cb", "dd", "de"
-+            , "bdir/", "bdir/cfile"]
-+  , next = files.concat([ "a-b", "aXb"
-+                        , ".x", ".y" ])
-+
-+
-+var patterns =
-+  [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
-+  , ["a*", ["a", "abc", "abd", "abe"]]
-+  , ["X*", ["X*"], {nonull: true}]
-+
-+  // allow null glob expansion
-+  , ["X*", []]
-+
-+  // isaacs: Slightly different than bash/sh/ksh
-+  // \\* is not un-escaped to literal "*" in a failed match,
-+  // but it does make it get treated as a literal star
-+  , ["\\*", ["\\*"], {nonull: true}]
-+  , ["\\**", ["\\**"], {nonull: true}]
-+  , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-+
-+  , ["b*/", ["bdir/"]]
-+  , ["c*", ["c", "ca", "cb"]]
-+  , ["**", files]
-+
-+  , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
-+  , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-+
-+  , "legendary larry crashes bashes"
-+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
-+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-+
-+  , "character classes"
-+  , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
-+  , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
-+     "bdir/", "ca", "cb", "dd", "de"]]
-+  , ["a*[^c]", ["abd", "abe"]]
-+  , function () { files.push("a-b", "aXb") }
-+  , ["a[X-]b", ["a-b", "aXb"]]
-+  , function () { files.push(".x", ".y") }
-+  , ["[^a-c]*", ["d", "dd", "de"]]
-+  , function () { files.push("a*b/", "a*b/ooo") }
-+  , ["a\\*b/*", ["a*b/ooo"]]
-+  , ["a\\*?/*", ["a*b/ooo"]]
-+  , ["*\\\\!*", [], {null: true}, ["echo !7"]]
-+  , ["*\\!*", ["echo !7"], null, ["echo !7"]]
-+  , ["*.\\*", ["r.*"], null, ["r.*"]]
-+  , ["a[b]c", ["abc"]]
-+  , ["a[\\b]c", ["abc"]]
-+  , ["a?c", ["abc"]]
-+  , ["a\\*c", [], {null: true}, ["abc"]]
-+  , ["", [""], { null: true }, [""]]
-+
-+  , "http://www.opensource.apple.com/source/bash/bash-23/" +
-+    "bash/tests/glob-test"
-+  , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
-+  , ["*/man*/bash.*", ["man/man1/bash.1"]]
-+  , ["man/man1/bash.1", ["man/man1/bash.1"]]
-+  , ["a***c", ["abc"], null, ["abc"]]
-+  , ["a*****?c", ["abc"], null, ["abc"]]
-+  , ["?*****??", ["abc"], null, ["abc"]]
-+  , ["*****??", ["abc"], null, ["abc"]]
-+  , ["?*****?c", ["abc"], null, ["abc"]]
-+  , ["?***?****c", ["abc"], null, ["abc"]]
-+  , ["?***?****?", ["abc"], null, ["abc"]]
-+  , ["?***?****", ["abc"], null, ["abc"]]
-+  , ["*******c", ["abc"], null, ["abc"]]
-+  , ["*******?", ["abc"], null, ["abc"]]
-+  , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+  , ["[-abc]", ["-"], null, ["-"]]
-+  , ["[abc-]", ["-"], null, ["-"]]
-+  , ["\\", ["\\"], null, ["\\"]]
-+  , ["[\\\\]", ["\\"], null, ["\\"]]
-+  , ["[[]", ["["], null, ["["]]
-+  , ["[", ["["], null, ["["]]
-+  , ["[*", ["[abc"], null, ["[abc"]]
-+  , "a right bracket shall lose its special meaning and\n" +
-+    "represent itself in a bracket expression if it occurs\n" +
-+    "first in the list.  -- POSIX.2 2.8.3.2"
-+  , ["[]]", ["]"], null, ["]"]]
-+  , ["[]-]", ["]"], null, ["]"]]
-+  , ["[a-\z]", ["p"], null, ["p"]]
-+  , ["??**********?****?", [], { null: true }, ["abc"]]
-+  , ["??**********?****c", [], { null: true }, ["abc"]]
-+  , ["?************c****?****", [], { null: true }, ["abc"]]
-+  , ["*c*?**", [], { null: true }, ["abc"]]
-+  , ["a*****c*?**", [], { null: true }, ["abc"]]
-+  , ["a********???*******", [], { null: true }, ["abc"]]
-+  , ["[]", [], { null: true }, ["a"]]
-+  , ["[abc", [], { null: true }, ["["]]
-+
-+  , "nocase tests"
-+  , ["XYZ", ["xYz"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+  , ["ab*", ["ABC"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+  , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
-+    , ["xYz", "ABC", "IjK"]]
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  , "onestar/twostar"
-+  , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
-+  , ["{/?,*}", ["/a", "bb"], {null: true}
-+    , ["/a", "/b/b", "/a/b/c", "bb"]]
-+
-+  , "dots should not match unless requested"
-+  , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-+
-+  // .. and . can only match patterns starting with .,
-+  // even when options.dot is set.
-+  , function () {
-+      files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
-+    }
-+  , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
-+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
-+  , ["a/*/b", ["a/c/b"], {dot:false}]
-+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-+
-+
-+  // this also tests that changing the options needs
-+  // to change the cache key, even if the pattern is
-+  // the same!
-+  , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
-+    , [ ".a/.d", "a/.d", "a/b"]]
-+
-+  , "paren sets cannot contain slashes"
-+  , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-+
-+  // brace sets trump all else.
-+  //
-+  // invalid glob pattern.  fails on bash4 and bsdglob.
-+  // however, in this implementation, it's easier just
-+  // to do the intuitive thing, and let brace-expansion
-+  // actually come before parsing any extglob patterns,
-+  // like the documentation seems to say.
-+  //
-+  // XXX: if anyone complains about this, either fix it
-+  // or tell them to grow up and stop complaining.
-+  //
-+  // bash/bsdglob says this:
-+  // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
-+  // but we do this instead:
-+  , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-+
-+  // test partial parsing in the presence of comment/negation chars
-+  , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
-+  , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-+
-+  // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
-+  , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
-+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
-+    , {}
-+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-+
-+
-+  // crazy nested {,,} and *(||) tests.
-+  , function () {
-+      files = [ "a", "b", "c", "d"
-+              , "ab", "ac", "ad"
-+              , "bc", "cb"
-+              , "bc,d", "c,db", "c,d"
-+              , "d)", "(b|c", "*(b|c"
-+              , "b|c", "b|cc", "cb|c"
-+              , "x(a|b|c)", "x(a|c)"
-+              , "(a|b|c)", "(a|c)"]
-+    }
-+  , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
-+  , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
-+  // a
-+  // *(b|c)
-+  // *(b|d)
-+  , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
-+  , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-+
-+
-+  // test various flag settings.
-+  , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
-+    , { noext: true } ]
-+  , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
-+    , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
-+  , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-+
-+
-+  // begin channelling Boole and deMorgan...
-+  , "negation tests"
-+  , function () {
-+      files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
-+    }
-+
-+  // anything that is NOT a* matches.
-+  , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-+
-+  // anything that IS !a* matches.
-+  , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-+
-+  // anything that IS a* matches
-+  , ["!!a*", ["a!b"]]
-+
-+  // anything that is NOT !a* matches
-+  , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-+
-+  // negation nestled within a pattern
-+  , function () {
-+      files = [ "foo.js"
-+              , "foo.bar"
-+              // can't match this one without negative lookbehind.
-+              , "foo.js.js"
-+              , "blar.js"
-+              , "foo."
-+              , "boo.js.boo" ]
-+    }
-+  , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-+
-+  // https://github.com/isaacs/minimatch/issues/5
-+  , function () {
-+      files = [ 'a/b/.x/c'
-+              , 'a/b/.x/c/d'
-+              , 'a/b/.x/c/d/e'
-+              , 'a/b/.x'
-+              , 'a/b/.x/'
-+              , 'a/.x/b'
-+              , '.x'
-+              , '.x/'
-+              , '.x/a'
-+              , '.x/a/b'
-+              , 'a/.x/b/.x/c'
-+              , '.x/.x' ]
-+  }
-+  , ["**/.x/**", [ '.x/'
-+                 , '.x/a'
-+                 , '.x/a/b'
-+                 , 'a/.x/b'
-+                 , 'a/b/.x/'
-+                 , 'a/b/.x/c'
-+                 , 'a/b/.x/c/d'
-+                 , 'a/b/.x/c/d/e' ] ]
-+
-+  ]
-+
-+var regexps =
-+  [ '/^(?:(?=.)a[^/]*?)$/',
-+    '/^(?:(?=.)X[^/]*?)$/',
-+    '/^(?:(?=.)X[^/]*?)$/',
-+    '/^(?:\\*)$/',
-+    '/^(?:(?=.)\\*[^/]*?)$/',
-+    '/^(?:\\*\\*)$/',
-+    '/^(?:(?=.)b[^/]*?\\/)$/',
-+    '/^(?:(?=.)c[^/]*?)$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
-+    '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
-+    '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
-+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
-+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
-+    '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
-+    '/^(?:(?=.)a[^/]*?[^c])$/',
-+    '/^(?:(?=.)a[X-]b)$/',
-+    '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
-+    '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
-+    '/^(?:(?=.)a[b]c)$/',
-+    '/^(?:(?=.)a[b]c)$/',
-+    '/^(?:(?=.)a[^/]c)$/',
-+    '/^(?:a\\*c)$/',
-+    'false',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
-+    '/^(?:man\\/man1\\/bash\\.1)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[-abc])$/',
-+    '/^(?:(?!\\.)(?=.)[abc-])$/',
-+    '/^(?:\\\\)$/',
-+    '/^(?:(?!\\.)(?=.)[\\\\])$/',
-+    '/^(?:(?!\\.)(?=.)[\\[])$/',
-+    '/^(?:\\[)$/',
-+    '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[\\]])$/',
-+    '/^(?:(?!\\.)(?=.)[\\]-])$/',
-+    '/^(?:(?!\\.)(?=.)[a-z])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
-+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
-+    '/^(?:\\[\\])$/',
-+    '/^(?:\\[abc)$/',
-+    '/^(?:(?=.)XYZ)$/i',
-+    '/^(?:(?=.)ab[^/]*?)$/i',
-+    '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
-+    '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
-+    '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
-+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
-+    '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
-+    '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
-+    '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
-+    '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
-+    '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
-+    '/^(?:(?=.)a[^/]b)$/',
-+    '/^(?:(?=.)#[^/]*?)$/',
-+    '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
-+    '/^(?:(?=.)\\!a[^/]*?)$/',
-+    '/^(?:(?=.)a[^/]*?)$/',
-+    '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
-+    '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
-+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
-+var re = 0;
-+
-+tap.test("basic tests", function (t) {
-+  var start = Date.now()
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  patterns.forEach(function (c) {
-+    if (typeof c === "function") return c()
-+    if (typeof c === "string") return t.comment(c)
-+
-+    var pattern = c[0]
-+      , expect = c[1].sort(alpha)
-+      , options = c[2] || {}
-+      , f = c[3] || files
-+      , tapOpts = c[4] || {}
-+
-+    // options.debug = true
-+    var m = new mm.Minimatch(pattern, options)
-+    var r = m.makeRe()
-+    var expectRe = regexps[re++]
-+    tapOpts.re = String(r) || JSON.stringify(r)
-+    tapOpts.files = JSON.stringify(f)
-+    tapOpts.pattern = pattern
-+    tapOpts.set = m.set
-+    tapOpts.negated = m.negate
-+
-+    var actual = mm.match(f, pattern, options)
-+    actual.sort(alpha)
-+
-+    t.equivalent( actual, expect
-+                , JSON.stringify(pattern) + " " + JSON.stringify(expect)
-+                , tapOpts )
-+
-+    t.equal(tapOpts.re, expectRe, tapOpts)
-+  })
-+
-+  t.comment("time=" + (Date.now() - start) + "ms")
-+  t.end()
-+})
-+
-+tap.test("global leak test", function (t) {
-+  var globalAfter = Object.keys(global)
-+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
-+  t.end()
-+})
-+
-+function alpha (a, b) {
-+  return a > b ? 1 : -1
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/test/brace-expand.js
-@@ -0,0 +1,33 @@
-+var tap = require("tap")
-+  , minimatch = require("../")
-+
-+tap.test("brace expansion", function (t) {
-+  // [ pattern, [expanded] ]
-+  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
-+      , [ "abxy"
-+        , "abxz"
-+        , "acdxy"
-+        , "acdxz"
-+        , "acexy"
-+        , "acexz"
-+        , "afhxy"
-+        , "afhxz"
-+        , "aghxy"
-+        , "aghxz" ] ]
-+    , [ "a{1..5}b"
-+      , [ "a1b"
-+        , "a2b"
-+        , "a3b"
-+        , "a4b"
-+        , "a5b" ] ]
-+    , [ "a{b}c", ["a{b}c"] ]
-+  ].forEach(function (tc) {
-+    var p = tc[0]
-+      , expect = tc[1]
-+    t.equivalent(minimatch.braceExpand(p), expect, p)
-+  })
-+  console.error("ending")
-+  t.end()
-+})
-+
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/test/caching.js
-@@ -0,0 +1,14 @@
-+var Minimatch = require("../minimatch.js").Minimatch
-+var tap = require("tap")
-+tap.test("cache test", function (t) {
-+  var mm1 = new Minimatch("a?b")
-+  var mm2 = new Minimatch("a?b")
-+  t.equal(mm1, mm2, "should get the same object")
-+  // the lru should drop it after 100 entries
-+  for (var i = 0; i < 100; i ++) {
-+    new Minimatch("a"+i)
-+  }
-+  mm2 = new Minimatch("a?b")
-+  t.notEqual(mm1, mm2, "cache should have dropped")
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/test/defaults.js
-@@ -0,0 +1,274 @@
-+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-+//
-+// TODO: Some of these tests do very bad things with backslashes, and will
-+// most likely fail badly on windows.  They should probably be skipped.
-+
-+var tap = require("tap")
-+  , globalBefore = Object.keys(global)
-+  , mm = require("../")
-+  , files = [ "a", "b", "c", "d", "abc"
-+            , "abd", "abe", "bb", "bcd"
-+            , "ca", "cb", "dd", "de"
-+            , "bdir/", "bdir/cfile"]
-+  , next = files.concat([ "a-b", "aXb"
-+                        , ".x", ".y" ])
-+
-+tap.test("basic tests", function (t) {
-+  var start = Date.now()
-+
-+  // [ pattern, [matches], MM opts, files, TAP opts]
-+  ; [ "http://www.bashcookbook.com/bashinfo" +
-+      "/source/bash-1.14.7/tests/glob-test"
-+    , ["a*", ["a", "abc", "abd", "abe"]]
-+    , ["X*", ["X*"], {nonull: true}]
-+
-+    // allow null glob expansion
-+    , ["X*", []]
-+
-+    // isaacs: Slightly different than bash/sh/ksh
-+    // \\* is not un-escaped to literal "*" in a failed match,
-+    // but it does make it get treated as a literal star
-+    , ["\\*", ["\\*"], {nonull: true}]
-+    , ["\\**", ["\\**"], {nonull: true}]
-+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-+
-+    , ["b*/", ["bdir/"]]
-+    , ["c*", ["c", "ca", "cb"]]
-+    , ["**", files]
-+
-+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
-+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-+
-+    , "legendary larry crashes bashes"
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
-+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
-+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
-+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-+
-+    , "character classes"
-+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
-+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
-+       "bdir/", "ca", "cb", "dd", "de"]]
-+    , ["a*[^c]", ["abd", "abe"]]
-+    , function () { files.push("a-b", "aXb") }
-+    , ["a[X-]b", ["a-b", "aXb"]]
-+    , function () { files.push(".x", ".y") }
-+    , ["[^a-c]*", ["d", "dd", "de"]]
-+    , function () { files.push("a*b/", "a*b/ooo") }
-+    , ["a\\*b/*", ["a*b/ooo"]]
-+    , ["a\\*?/*", ["a*b/ooo"]]
-+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
-+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
-+    , ["*.\\*", ["r.*"], null, ["r.*"]]
-+    , ["a[b]c", ["abc"]]
-+    , ["a[\\b]c", ["abc"]]
-+    , ["a?c", ["abc"]]
-+    , ["a\\*c", [], {null: true}, ["abc"]]
-+    , ["", [""], { null: true }, [""]]
-+
-+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
-+      "bash/tests/glob-test"
-+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
-+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
-+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
-+    , ["a***c", ["abc"], null, ["abc"]]
-+    , ["a*****?c", ["abc"], null, ["abc"]]
-+    , ["?*****??", ["abc"], null, ["abc"]]
-+    , ["*****??", ["abc"], null, ["abc"]]
-+    , ["?*****?c", ["abc"], null, ["abc"]]
-+    , ["?***?****c", ["abc"], null, ["abc"]]
-+    , ["?***?****?", ["abc"], null, ["abc"]]
-+    , ["?***?****", ["abc"], null, ["abc"]]
-+    , ["*******c", ["abc"], null, ["abc"]]
-+    , ["*******?", ["abc"], null, ["abc"]]
-+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
-+    , ["[-abc]", ["-"], null, ["-"]]
-+    , ["[abc-]", ["-"], null, ["-"]]
-+    , ["\\", ["\\"], null, ["\\"]]
-+    , ["[\\\\]", ["\\"], null, ["\\"]]
-+    , ["[[]", ["["], null, ["["]]
-+    , ["[", ["["], null, ["["]]
-+    , ["[*", ["[abc"], null, ["[abc"]]
-+    , "a right bracket shall lose its special meaning and\n" +
-+      "represent itself in a bracket expression if it occurs\n" +
-+      "first in the list.  -- POSIX.2 2.8.3.2"
-+    , ["[]]", ["]"], null, ["]"]]
-+    , ["[]-]", ["]"], null, ["]"]]
-+    , ["[a-\z]", ["p"], null, ["p"]]
-+    , ["??**********?****?", [], { null: true }, ["abc"]]
-+    , ["??**********?****c", [], { null: true }, ["abc"]]
-+    , ["?************c****?****", [], { null: true }, ["abc"]]
-+    , ["*c*?**", [], { null: true }, ["abc"]]
-+    , ["a*****c*?**", [], { null: true }, ["abc"]]
-+    , ["a********???*******", [], { null: true }, ["abc"]]
-+    , ["[]", [], { null: true }, ["a"]]
-+    , ["[abc", [], { null: true }, ["["]]
-+
-+    , "nocase tests"
-+    , ["XYZ", ["xYz"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+    , ["ab*", ["ABC"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
-+      , ["xYz", "ABC", "IjK"]]
-+
-+    // [ pattern, [matches], MM opts, files, TAP opts]
-+    , "onestar/twostar"
-+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
-+    , ["{/?,*}", ["/a", "bb"], {null: true}
-+      , ["/a", "/b/b", "/a/b/c", "bb"]]
-+
-+    , "dots should not match unless requested"
-+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-+
-+    // .. and . can only match patterns starting with .,
-+    // even when options.dot is set.
-+    , function () {
-+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
-+      }
-+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
-+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
-+    , ["a/*/b", ["a/c/b"], {dot:false}]
-+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-+
-+
-+    // this also tests that changing the options needs
-+    // to change the cache key, even if the pattern is
-+    // the same!
-+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
-+      , [ ".a/.d", "a/.d", "a/b"]]
-+
-+    , "paren sets cannot contain slashes"
-+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-+
-+    // brace sets trump all else.
-+    //
-+    // invalid glob pattern.  fails on bash4 and bsdglob.
-+    // however, in this implementation, it's easier just
-+    // to do the intuitive thing, and let brace-expansion
-+    // actually come before parsing any extglob patterns,
-+    // like the documentation seems to say.
-+    //
-+    // XXX: if anyone complains about this, either fix it
-+    // or tell them to grow up and stop complaining.
-+    //
-+    // bash/bsdglob says this:
-+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
-+    // but we do this instead:
-+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-+
-+    // test partial parsing in the presence of comment/negation chars
-+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
-+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-+
-+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
-+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
-+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
-+      , {}
-+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-+
-+
-+    // crazy nested {,,} and *(||) tests.
-+    , function () {
-+        files = [ "a", "b", "c", "d"
-+                , "ab", "ac", "ad"
-+                , "bc", "cb"
-+                , "bc,d", "c,db", "c,d"
-+                , "d)", "(b|c", "*(b|c"
-+                , "b|c", "b|cc", "cb|c"
-+                , "x(a|b|c)", "x(a|c)"
-+                , "(a|b|c)", "(a|c)"]
-+      }
-+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
-+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
-+    // a
-+    // *(b|c)
-+    // *(b|d)
-+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
-+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-+
-+
-+    // test various flag settings.
-+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
-+      , { noext: true } ]
-+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
-+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
-+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-+
-+
-+    // begin channelling Boole and deMorgan...
-+    , "negation tests"
-+    , function () {
-+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
-+      }
-+
-+    // anything that is NOT a* matches.
-+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-+
-+    // anything that IS !a* matches.
-+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-+
-+    // anything that IS a* matches
-+    , ["!!a*", ["a!b"]]
-+
-+    // anything that is NOT !a* matches
-+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-+
-+    // negation nestled within a pattern
-+    , function () {
-+        files = [ "foo.js"
-+                , "foo.bar"
-+                // can't match this one without negative lookbehind.
-+                , "foo.js.js"
-+                , "blar.js"
-+                , "foo."
-+                , "boo.js.boo" ]
-+      }
-+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-+
-+    ].forEach(function (c) {
-+      if (typeof c === "function") return c()
-+      if (typeof c === "string") return t.comment(c)
-+
-+      var pattern = c[0]
-+        , expect = c[1].sort(alpha)
-+        , options = c[2] || {}
-+        , f = c[3] || files
-+        , tapOpts = c[4] || {}
-+
-+      // options.debug = true
-+      var Class = mm.defaults(options).Minimatch
-+      var m = new Class(pattern, {})
-+      var r = m.makeRe()
-+      tapOpts.re = String(r) || JSON.stringify(r)
-+      tapOpts.files = JSON.stringify(f)
-+      tapOpts.pattern = pattern
-+      tapOpts.set = m.set
-+      tapOpts.negated = m.negate
-+
-+      var actual = mm.match(f, pattern, options)
-+      actual.sort(alpha)
-+
-+      t.equivalent( actual, expect
-+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
-+                  , tapOpts )
-+    })
-+
-+  t.comment("time=" + (Date.now() - start) + "ms")
-+  t.end()
-+})
-+
-+tap.test("global leak test", function (t) {
-+  var globalAfter = Object.keys(global)
-+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
-+  t.end()
-+})
-+
-+function alpha (a, b) {
-+  return a > b ? 1 : -1
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/minimatch/test/extglob-ending-with-state-char.js
-@@ -0,0 +1,8 @@
-+var test = require('tap').test
-+var minimatch = require('../')
-+
-+test('extglob ending with statechar', function(t) {
-+  t.notOk(minimatch('ax', 'a?(b*)'))
-+  t.ok(minimatch('ax', '?(a*|b)'))
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/AUTHORS
-@@ -0,0 +1,6 @@
-+# Authors sorted by whether or not they're me.
-+Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me)
-+Wayne Larsen <wayne at larsen.st> (http://github.com/wvl)
-+ritch <skawful at gmail.com>
-+Marcel Laverdet
-+Yosef Dinerstein <yosefd at microsoft.com>
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-+All rights reserved.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/README.md
-@@ -0,0 +1,30 @@
-+`rm -rf` for node.
-+
-+Install with `npm install rimraf`, or just drop rimraf.js somewhere.
-+
-+## API
-+
-+`rimraf(f, callback)`
-+
-+The callback will be called with an error if there is one.  Certain
-+errors are handled for you:
-+
-+* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
-+  `opts.maxBusyTries` times before giving up.
-+* `ENOENT` - If the file doesn't exist, rimraf will return
-+  successfully, since your desired outcome is already the case.
-+
-+## rimraf.sync
-+
-+It can remove stuff synchronously, too.  But that's not so good.  Use
-+the async API.  It's better.
-+
-+## CLI
-+
-+If installed with `npm install rimraf -g` it can be used as a global
-+command `rimraf <path>` which is useful for cross platform support.
-+
-+## mkdirp
-+
-+If you need to create a directory recursively, check out
-+[mkdirp](https://github.com/substack/node-mkdirp).
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/bin.js
-@@ -0,0 +1,33 @@
-+#!/usr/bin/env node
-+
-+var rimraf = require('./')
-+
-+var help = false
-+var dashdash = false
-+var args = process.argv.slice(2).filter(function(arg) {
-+  if (dashdash)
-+    return !!arg
-+  else if (arg === '--')
-+    dashdash = true
-+  else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))
-+    help = true
-+  else
-+    return !!arg
-+});
-+
-+if (help || args.length === 0) {
-+  // If they didn't ask for help, then this is not a "success"
-+  var log = help ? console.log : console.error
-+  log('Usage: rimraf <path>')
-+  log('')
-+  log('  Deletes all files and folders at "path" recursively.')
-+  log('')
-+  log('Options:')
-+  log('')
-+  log('  -h, --help    Display this usage info')
-+  process.exit(help ? 0 : 1)
-+} else {
-+  args.forEach(function(arg) {
-+    rimraf.sync(arg)
-+  })
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/package.json
-@@ -0,0 +1,55 @@
-+{
-+  "name": "rimraf",
-+  "version": "2.2.8",
-+  "main": "rimraf.js",
-+  "description": "A deep deletion module for node (like `rm -rf`)",
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": {
-+    "type": "MIT",
-+    "url": "https://github.com/isaacs/rimraf/raw/master/LICENSE"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/rimraf.git"
-+  },
-+  "scripts": {
-+    "test": "cd test && bash run.sh"
-+  },
-+  "bin": {
-+    "rimraf": "./bin.js"
-+  },
-+  "contributors": [
-+    {
-+      "name": "Isaac Z. Schlueter",
-+      "email": "i at izs.me",
-+      "url": "http://blog.izs.me"
-+    },
-+    {
-+      "name": "Wayne Larsen",
-+      "email": "wayne at larsen.st",
-+      "url": "http://github.com/wvl"
-+    },
-+    {
-+      "name": "ritch",
-+      "email": "skawful at gmail.com"
-+    },
-+    {
-+      "name": "Marcel Laverdet"
-+    },
-+    {
-+      "name": "Yosef Dinerstein",
-+      "email": "yosefd at microsoft.com"
-+    }
-+  ],
-+  "readme": "`rm -rf` for node.\n\nInstall with `npm install rimraf`, or just drop rimraf.js somewhere.\n\n## API\n\n`rimraf(f, callback)`\n\nThe callback will be called with an error if there is one.  Certain\nerrors are handled for you:\n\n* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of\n  `opts.maxBusyTries` times before giving up.\n* `ENOENT` - If the file doesn't exist, rimraf will return\n  successfully, since your desired outcome is already the case.\n\n## rimraf.sync\n\nIt can remove stuff synchronously, too.  But that's not so good.  Use\nthe async API.  It's better.\n\n## CLI\n\nIf installed with `npm install rimraf -g` it can be used as a global\ncommand `rimraf <path>` which is useful for cross platform support.\n\n## mkdirp\n\nIf you need to create a directory recursively, check out\n[mkdirp](https://github.com/substack/node-mkdirp).\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/rimraf/issues"
-+  },
-+  "_id": "rimraf at 2.2.8",
-+  "_from": "rimraf@~2.2.2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/rimraf.js
-@@ -0,0 +1,248 @@
-+module.exports = rimraf
-+rimraf.sync = rimrafSync
-+
-+var assert = require("assert")
-+var path = require("path")
-+var fs = require("fs")
-+
-+// for EMFILE handling
-+var timeout = 0
-+exports.EMFILE_MAX = 1000
-+exports.BUSYTRIES_MAX = 3
-+
-+var isWindows = (process.platform === "win32")
-+
-+function defaults (options) {
-+  var methods = [
-+    'unlink',
-+    'chmod',
-+    'stat',
-+    'rmdir',
-+    'readdir'
-+  ]
-+  methods.forEach(function(m) {
-+    options[m] = options[m] || fs[m]
-+    m = m + 'Sync'
-+    options[m] = options[m] || fs[m]
-+  })
-+}
-+
-+function rimraf (p, options, cb) {
-+  if (typeof options === 'function') {
-+    cb = options
-+    options = {}
-+  }
-+  assert(p)
-+  assert(options)
-+  assert(typeof cb === 'function')
-+
-+  defaults(options)
-+
-+  if (!cb) throw new Error("No callback passed to rimraf()")
-+
-+  var busyTries = 0
-+  rimraf_(p, options, function CB (er) {
-+    if (er) {
-+      if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY") &&
-+          busyTries < exports.BUSYTRIES_MAX) {
-+        busyTries ++
-+        var time = busyTries * 100
-+        // try again, with the same exact callback as this one.
-+        return setTimeout(function () {
-+          rimraf_(p, options, CB)
-+        }, time)
-+      }
-+
-+      // this one won't happen if graceful-fs is used.
-+      if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
-+        return setTimeout(function () {
-+          rimraf_(p, options, CB)
-+        }, timeout ++)
-+      }
-+
-+      // already gone
-+      if (er.code === "ENOENT") er = null
-+    }
-+
-+    timeout = 0
-+    cb(er)
-+  })
-+}
-+
-+// Two possible strategies.
-+// 1. Assume it's a file.  unlink it, then do the dir stuff on EPERM or EISDIR
-+// 2. Assume it's a directory.  readdir, then do the file stuff on ENOTDIR
-+//
-+// Both result in an extra syscall when you guess wrong.  However, there
-+// are likely far more normal files in the world than directories.  This
-+// is based on the assumption that a the average number of files per
-+// directory is >= 1.
-+//
-+// If anyone ever complains about this, then I guess the strategy could
-+// be made configurable somehow.  But until then, YAGNI.
-+function rimraf_ (p, options, cb) {
-+  assert(p)
-+  assert(options)
-+  assert(typeof cb === 'function')
-+
-+  options.unlink(p, function (er) {
-+    if (er) {
-+      if (er.code === "ENOENT")
-+        return cb(null)
-+      if (er.code === "EPERM")
-+        return (isWindows)
-+          ? fixWinEPERM(p, options, er, cb)
-+          : rmdir(p, options, er, cb)
-+      if (er.code === "EISDIR")
-+        return rmdir(p, options, er, cb)
-+    }
-+    return cb(er)
-+  })
-+}
-+
-+function fixWinEPERM (p, options, er, cb) {
-+  assert(p)
-+  assert(options)
-+  assert(typeof cb === 'function')
-+  if (er)
-+    assert(er instanceof Error)
-+
-+  options.chmod(p, 666, function (er2) {
-+    if (er2)
-+      cb(er2.code === "ENOENT" ? null : er)
-+    else
-+      options.stat(p, function(er3, stats) {
-+        if (er3)
-+          cb(er3.code === "ENOENT" ? null : er)
-+        else if (stats.isDirectory())
-+          rmdir(p, options, er, cb)
-+        else
-+          options.unlink(p, cb)
-+      })
-+  })
-+}
-+
-+function fixWinEPERMSync (p, options, er) {
-+  assert(p)
-+  assert(options)
-+  if (er)
-+    assert(er instanceof Error)
-+
-+  try {
-+    options.chmodSync(p, 666)
-+  } catch (er2) {
-+    if (er2.code === "ENOENT")
-+      return
-+    else
-+      throw er
-+  }
-+
-+  try {
-+    var stats = options.statSync(p)
-+  } catch (er3) {
-+    if (er3.code === "ENOENT")
-+      return
-+    else
-+      throw er
-+  }
-+
-+  if (stats.isDirectory())
-+    rmdirSync(p, options, er)
-+  else
-+    options.unlinkSync(p)
-+}
-+
-+function rmdir (p, options, originalEr, cb) {
-+  assert(p)
-+  assert(options)
-+  if (originalEr)
-+    assert(originalEr instanceof Error)
-+  assert(typeof cb === 'function')
-+
-+  // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
-+  // if we guessed wrong, and it's not a directory, then
-+  // raise the original error.
-+  options.rmdir(p, function (er) {
-+    if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
-+      rmkids(p, options, cb)
-+    else if (er && er.code === "ENOTDIR")
-+      cb(originalEr)
-+    else
-+      cb(er)
-+  })
-+}
-+
-+function rmkids(p, options, cb) {
-+  assert(p)
-+  assert(options)
-+  assert(typeof cb === 'function')
-+
-+  options.readdir(p, function (er, files) {
-+    if (er)
-+      return cb(er)
-+    var n = files.length
-+    if (n === 0)
-+      return options.rmdir(p, cb)
-+    var errState
-+    files.forEach(function (f) {
-+      rimraf(path.join(p, f), options, function (er) {
-+        if (errState)
-+          return
-+        if (er)
-+          return cb(errState = er)
-+        if (--n === 0)
-+          options.rmdir(p, cb)
-+      })
-+    })
-+  })
-+}
-+
-+// this looks simpler, and is strictly *faster*, but will
-+// tie up the JavaScript thread and fail on excessively
-+// deep directory trees.
-+function rimrafSync (p, options) {
-+  options = options || {}
-+  defaults(options)
-+
-+  assert(p)
-+  assert(options)
-+
-+  try {
-+    options.unlinkSync(p)
-+  } catch (er) {
-+    if (er.code === "ENOENT")
-+      return
-+    if (er.code === "EPERM")
-+      return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
-+    if (er.code !== "EISDIR")
-+      throw er
-+    rmdirSync(p, options, er)
-+  }
-+}
-+
-+function rmdirSync (p, options, originalEr) {
-+  assert(p)
-+  assert(options)
-+  if (originalEr)
-+    assert(originalEr instanceof Error)
-+
-+  try {
-+    options.rmdirSync(p)
-+  } catch (er) {
-+    if (er.code === "ENOENT")
-+      return
-+    if (er.code === "ENOTDIR")
-+      throw originalEr
-+    if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
-+      rmkidsSync(p, options)
-+  }
-+}
-+
-+function rmkidsSync (p, options) {
-+  assert(p)
-+  assert(options)
-+  options.readdirSync(p).forEach(function (f) {
-+    rimrafSync(path.join(p, f), options)
-+  })
-+  options.rmdirSync(p, options)
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/test/run.sh
-@@ -0,0 +1,16 @@
-+#!/bin/bash
-+set -e
-+code=0
-+for i in test-*.js; do
-+  echo -n $i ...
-+  bash setup.sh
-+  node $i
-+  if [ -d target ]; then
-+    echo "fail"
-+    code=1
-+  else
-+    echo "pass"
-+  fi
-+done
-+rm -rf target
-+exit $code
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/test/setup.sh
-@@ -0,0 +1,47 @@
-+#!/bin/bash
-+
-+set -e
-+
-+files=10
-+folders=2
-+depth=4
-+target="$PWD/target"
-+
-+rm -rf target
-+
-+fill () {
-+  local depth=$1
-+  local files=$2
-+  local folders=$3
-+  local target=$4
-+
-+  if ! [ -d $target ]; then
-+    mkdir -p $target
-+  fi
-+
-+  local f
-+
-+  f=$files
-+  while [ $f -gt 0 ]; do
-+    touch "$target/f-$depth-$f"
-+    let f--
-+  done
-+
-+  let depth--
-+
-+  if [ $depth -le 0 ]; then
-+    return 0
-+  fi
-+
-+  f=$folders
-+  while [ $f -gt 0 ]; do
-+    mkdir "$target/folder-$depth-$f"
-+    fill $depth $files $folders "$target/d-$depth-$f"
-+    let f--
-+  done
-+}
-+
-+fill $depth $files $folders $target
-+
-+# sanity assert
-+[ -d $target ]
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/test/test-async.js
-@@ -0,0 +1,5 @@
-+var rimraf = require("../rimraf")
-+  , path = require("path")
-+rimraf(path.join(__dirname, "target"), function (er) {
-+  if (er) throw er
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/node_modules/rimraf/test/test-sync.js
-@@ -0,0 +1,3 @@
-+var rimraf = require("../rimraf")
-+  , path = require("path")
-+rimraf.sync(path.join(__dirname, "target"))
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/package.json
-@@ -0,0 +1,53 @@
-+{
-+  "name": "file-utils",
-+  "version": "0.2.0",
-+  "description": "Sync file utility for Node.js command line tools",
-+  "main": "index.js",
-+  "directories": {
-+    "test": "tests"
-+  },
-+  "scripts": {
-+    "test": "grunt test"
-+  },
-+  "license": "MIT",
-+  "dependencies": {
-+    "lodash": "~2.4.1",
-+    "iconv-lite": "~0.2.11",
-+    "rimraf": "~2.2.2",
-+    "glob": "~3.2.6",
-+    "minimatch": "~0.2.12",
-+    "findup-sync": "~0.1.2",
-+    "isbinaryfile": "~2.0.0"
-+  },
-+  "devDependencies": {
-+    "temporary": "~0.0.4",
-+    "grunt-contrib-jshint": "~0.8.0",
-+    "grunt-contrib-nodeunit": "~0.2.0",
-+    "grunt-contrib-watch": "~0.5.3",
-+    "grunt-release": "~0.6.0"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/SBoudrias/file-utils.git"
-+  },
-+  "keywords": [
-+    "file",
-+    "utils",
-+    "scaffold",
-+    "tool",
-+    "cli"
-+  ],
-+  "author": {
-+    "name": "Simon Boudrias"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/SBoudrias/file-utils/issues"
-+  },
-+  "engines": {
-+    "node": ">=0.10.0"
-+  },
-+  "readme": "file-utils [![](https://travis-ci.org/SBoudrias/file-utils.png)](https://travis-ci.org/SBoudrias/file-utils)\r\n==========\r\n\r\nThis is a Grunt.file forks to allow the creation of scoped file utilities and the ability to add write filters.\r\n\r\nSame as Grunt.file, this is a set of _synchronous_ utility. As so, it should **never** be used on a Node.js server. This is meant for users/command line utilities.\r\n\r\n\r\nFile API\r\n=========\r\n\r\nUpcoming. Meanwhile, check [Grunt.file documentation](http://gruntjs.com/api/grunt.file) as the same methods are available.\r\n\r\n#### Setting options - `file.option( name, [ value ])`\r\n\r\n```\r\n// Set option\r\nfile.option('write', false);\r\n\r\n// Get option\r\nfile.option('write');\r\n```\r\n\r\n**Available Options**\r\n- `write` (Boolean): If write is set to `false`, then no file will be written or deleted. Useful for test run without side effets.\r\n- `logger` (Logger object): Used internally to log information to the console. **API still work in progress**\r\n- `encoding` (String): Defaults `utf8`. Set the default encoding used for reading/writing. Note most methods allow you to overwridde it for a single run.\r\n- `force` (Boolean): `force: true` Force the deletion of folders and file outside the utility scope (or CWD if no scope).\r\n\r\n\r\nENV scope and filters\r\n=========\r\n\r\n### Creating an Env - file#createEnv([ options ]);\r\n\r\n```javascript\r\nvar file = require('file-utils');\r\n\r\nvar env = file.createEnv({\r\n  base: 'my/scoped/path',\r\n  dest: 'destination/path' // optionnal\r\n});\r\n\r\n// Alternatively, they can be functions returning a path:\r\n\r\nvar env = file.createEnv({\r\n  base: function() {\r\n    return 'my/scoped/path';\r\n  },\r\n  dest: function() { // optionnal\r\n    return 'destination/path';\r\n  }\r\n});\r\n```\r\n\r\nThe `base` directory will prefix any paths passed to `mkdir`, `recurse`, `read`, `readJSON`, `write`, `delete`, `exists`, `isLink`, `isDir` and `isFile` methods.\r\n\r\nThe `dest` directory will prefix the `destination` path provided in the `copy` method. Note that this option is optionnal and will default to the current working directory.\r\n\r\nIf [options (`logger`, `write`, etc)](#setting-options---fileoption-name--value-) are not passed, each `Env` instance inherit those of its parent.\r\n\r\nWrite Filters\r\n---------\r\n\r\nWrite filters are applied on `env.write` and `env.copy`.\r\n\r\nThey're used to modifiy the content or the filepath of a file.\r\n\r\n#### Add a write filter - `env.registerWriteFilter( name, filter )`\r\n\r\n**options**\r\n- `name` (String): The name under which registering the filter\r\n- `filter` (Function): The filter function\r\n\r\nThe filter function take a file object as parameter. This file object is a hash containing a `path` and a `contents` property. You can modify these two property as you like and returning the modified object.\r\n\r\n```javascript\r\nenv.registerWriteFilter( 'coffee', function( file ) {\r\n  if (!path.extname(file) !== '.js') return file;\r\n\r\n  file.path = file.path.replace(/(\\.js)$/, '.coffee');\r\n  file.content = convertJsToCoffee( file.contents );\r\n\r\n  return file;\r\n});\r\n```\r\n\r\n#### Remove a write filter - `env.removeWriteFilter( name )`\r\n\r\n```javascript\r\nenv.removeWriteFilter('coffee');\r\n```\r\n\r\n#### Async filter\r\n\r\nThe filter can also be asynchronous. This is done by calling `this.async()` and passing the return value to the callback provided.\r\n\r\n```javascript\r\nenv.registerWriteFilter( 'coffee', function( file ) {\r\n  var done = this.async();\r\n\r\n  // some process\r\n  setTimeout(function() {\r\n    done({ path: '/newfile', contents: 'filtered content' });\r\n  }, 1000);\r\n});\r\n```\r\n\r\n**Caution:** Using an asynchronous filter will change the way write and copy method are called to. This will make both of those method to run asynchronously too.\r\n\r\nValidation Filters\r\n----------\r\n\r\nValidation filters are applied on `env.write` and `env.copy`.\r\n\r\nThey're used to allow or disallow the write action.\r\n\r\n#### Add a validation filter - `env.registerValidationFilter( name, filter )`\r\n\r\n**options**\r\n- `name` (String): The name under which registering the filter\r\n- `filter` (Function): The filter function\r\n\r\nThe filter function take a file object as parameter. This file object is a hash containing a `path` (String) and a `contents` (String if text file, Buffer otherwise) property.\r\n\r\nReturn `true` to allow the file to be written. Return `false` or an error message `String` to disallow the write action.\r\n\r\n```javascript\r\nenv.registerValidationFilter( 'checkConflicts', function( toOutput ) {\r\n  if ( file.exists(toOutput.path) ) {\r\n    return 'file is already present';\r\n  }\r\n  return true;\r\n});\r\n```\r\n\r\nJust like the write filters, [this filter can be asynchronous](#async-filter).\r\n\r\n#### Remove a validation filter - `env.removeValidationFilter( name )`\r\n\r\n```javascript\r\nenv.removeValidationFilter('checkConflicts');\r\n```\r\n\r\n\r\nTodos\r\n=========\r\n\r\n- Real Logging system\r\n",
-+  "readmeFilename": "README.md",
-+  "_id": "file-utils at 0.2.0",
-+  "_from": "file-utils@~0.2.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/env.js
-@@ -0,0 +1,286 @@
-+'use strict';
-+
-+var path = require('path');
-+var fs = require('fs');
-+var file = require('..');
-+var _ = require('lodash');
-+var helpers = require('./helpers/helpers');
-+var defLogger = require('../lib/logger');
-+
-+var Tempdir = require('temporary/lib/dir');
-+var tmpdir = new Tempdir();
-+
-+exports['Env()'] = {
-+  'setUp': function(done) {
-+    this.fixtures = file.createEnv({ base: path.join(__dirname, 'fixtures') });
-+    this.env = file.createEnv({ base: path.join(tmpdir.path, '/env/scope') });
-+    done();
-+  },
-+  'inherits from global file config': function(test) {
-+    test.expect(3);
-+    var logger = { bar: 'foo' };
-+    file.option('logger', logger);
-+    file.option('write', false);
-+    var env = file.createEnv();
-+    test.deepEqual(env.option('logger'), logger, 'logger should be inherited');
-+    test.deepEqual(env.log, file.log, 'logger should be inherited');
-+    test.equal(env.option('write'), false, 'write state should be inherited');
-+    file.option('write', true);
-+    file.option('logger', defLogger);
-+    test.done();
-+  },
-+  'read': function(test) {
-+    test.expect(1);
-+    helpers.assertTextEqual(this.fixtures.read('utf8.txt'), 'Ação é isso aí\n', test, 'file should be read from base path.');
-+    test.done();
-+  },
-+  'readJSON': function(test) {
-+    test.expect(1);
-+    var obj = {foo: 'Ação é isso aí', bar: ['ømg', 'pønies']};
-+    var fileContent = this.fixtures.readJSON('utf8.json');
-+    test.deepEqual(fileContent, obj, 'file should be read from base path and parsed correctly.');
-+    test.done();
-+  },
-+  'write': function(test) {
-+    test.expect(1);
-+    var str = 'foo bar';
-+    this.env.write('write.txt', str);
-+    test.strictEqual(fs.readFileSync(path.join(tmpdir.path, '/env/scope', 'write.txt'), 'utf8'), str, 'file should be written in the root dir.');
-+    test.done();
-+  },
-+  'copy': function(test) {
-+    test.expect(1);
-+    var root = 'utf8.txt';
-+    var dest = path.join( tmpdir.path, 'copy.txt');
-+    this.fixtures.copy(root, dest);
-+
-+    var initial = this.fixtures.read(root);
-+    var copied = fs.readFileSync(dest, 'utf8');
-+
-+    test.strictEqual(initial, copied, 'File should be copied from the root dir');
-+
-+    test.done();
-+  },
-+  'copy with dest': function(test) {
-+    test.expect(1);
-+    var dest = path.join(tmpdir.path, '/copy');
-+    var env = file.createEnv({
-+      base: path.join(__dirname, 'fixtures'),
-+      dest: dest
-+    });
-+
-+    env.copy('utf8.txt', 'utf-8.txt');
-+
-+    var initial = this.fixtures.read('utf8.txt');
-+    var copied = fs.readFileSync(dest + '/utf-8.txt', 'utf8');
-+    test.strictEqual(initial, copied, 'File should be copied from the root dir to the dest dir');
-+    test.done();
-+  },
-+  'delete': function(test) {
-+    test.expect(3);
-+    this.env.write('delete.txt', 'foo');
-+    test.ok(file.exists(path.join(tmpdir.path, '/env/scope', 'delete.txt')), 'file should exist');
-+    test.ok(this.env.delete('delete.txt'), 'return true if it delete the file');
-+    test.ok(!file.exists(path.join(tmpdir.path, '/env/scope', 'delete.txt')), 'file should\'ve been deleted');
-+    test.done();
-+  },
-+  'mkdir': function(test) {
-+    test.expect(2);
-+
-+    test.doesNotThrow(function() {
-+      this.env.mkdir('aa/bb/cc');
-+    }.bind(this), 'Should also not explode');
-+    test.ok(file.isDir(this.env.fromBase('aa/bb/cc')), 'path should have been created.');
-+
-+    this.env.delete('aa/bb/cc');
-+
-+    test.done();
-+  },
-+  'recurse': function(test) {
-+    test.expect(1);
-+    var rootdir = this.fixtures.fromBase('expand').replace(/\\/g, '/');
-+    var expected = {};
-+    expected[rootdir + '/css/baz.css'] = [rootdir, 'css', 'baz.css'];
-+    expected[rootdir + '/css/qux.css'] = [rootdir, 'css', 'qux.css'];
-+    expected[rootdir + '/deep/deep.txt'] = [rootdir, 'deep', 'deep.txt'];
-+    expected[rootdir + '/deep/deeper/deeper.txt'] = [rootdir, 'deep/deeper', 'deeper.txt'];
-+    expected[rootdir + '/deep/deeper/deepest/deepest.txt'] = [rootdir, 'deep/deeper/deepest', 'deepest.txt'];
-+    expected[rootdir + '/js/bar.js'] = [rootdir, 'js', 'bar.js'];
-+    expected[rootdir + '/js/foo.js'] = [rootdir, 'js', 'foo.js'];
-+    expected[rootdir + '/README.md'] = [rootdir, undefined, 'README.md'];
-+
-+    var actual = {};
-+    this.fixtures.recurse('expand', function(abspath, rootdir, subdir, filename) {
-+      actual[abspath] = [rootdir.replace(/\\/g, '/'), subdir, filename];
-+    });
-+
-+    test.deepEqual(actual, expected, 'paths and arguments should match.');
-+    test.done();
-+  },
-+  'setBase': function(test) {
-+    this.env.setBase('foo');
-+    test.equal(this.env.fromBase('bar').replace(/\\/g, '/'), 'foo/bar');
-+    test.done();
-+  },
-+  'setDestBase': function(test) {
-+    this.env.setDestBase('foo');
-+    test.equal(this.env.fromDestBase('bar').replace(/\\/g, '/'), 'foo/bar');
-+    test.done();
-+  },
-+  'setBase as function': function(test) {
-+    this.env.setBase(function () { return 'foo'; });
-+    test.equal(this.env.fromBase('bar').replace(/\\/g, '/'), 'foo/bar');
-+    test.done();
-+  },
-+  'setDestBase as function': function(test) {
-+    this.env.setDestBase(function () { return 'foo'; });
-+    test.equal(this.env.fromDestBase('bar').replace(/\\/g, '/'), 'foo/bar');
-+    test.done();
-+  }
-+};
-+
-+exports['Env() filters'] = {
-+  'setUp': function(done) {
-+    this.env = file.createEnv({ base: tmpdir.path });
-+    done();
-+  },
-+  '.registerWriteFilter() synchronous and apply output': function(test) {
-+    test.expect(3);
-+    this.env.registerWriteFilter('tmp', function(file) {
-+      test.equal(file.path, 'foo');
-+      test.equal(file.contents, 'bar');
-+      return { path: 'simple-filter', contents: 'test' };
-+    });
-+    this.env.write('foo', 'bar');
-+    var written = this.env.read('simple-filter');
-+    test.equal(written, 'test', 'should have written the filtered file and path');
-+    test.done();
-+  },
-+  'pipe all filters': function(test) {
-+    test.expect(4);
-+    this.env.registerWriteFilter('1', function(file) {
-+      test.equal(file.path, 'foo');
-+      test.equal(file.contents, 'bar');
-+      return { path: 'piped-filter', contents: 'test' };
-+    });
-+    this.env.registerWriteFilter('2', function(file) {
-+      test.equal(file.path, 'piped-filter');
-+      test.equal(file.contents, 'test');
-+      return file;
-+    });
-+    this.env.write('foo', 'bar');
-+    test.done();
-+  },
-+  '.removeWriteFilter()': function(test) {
-+    test.expect(1);
-+    this.env.registerWriteFilter('broke', function(file) {
-+      test.ok(false);
-+      return { path: 'broke', contents: 'broke' };
-+    });
-+    this.env.removeWriteFilter('broke');
-+    this.env.write('no-filter', 'bar');
-+    var written = this.env.read('no-filter');
-+    test.equal(written, 'bar', 'should have removed the filter');
-+    test.done();
-+  },
-+  'Async write filter': function(test) {
-+    test.expect(2);
-+    this.env._actualWrite = function(filepath, contents) {
-+      test.equal(filepath, 'async-write');
-+      test.equal(contents, 'puts async');
-+      test.done();
-+    };
-+
-+    this.env.registerWriteFilter('async', function() {
-+      var done = this.async();
-+      setTimeout(function() {
-+        done({ path: 'async-write', contents: 'puts async' });
-+      }, 10);
-+    });
-+
-+    this.env.write('foo', 'bar');
-+  },
-+  '.registerValidationFilter': {
-+    'setUp': function(done) {
-+      var self = this;
-+      this.env.option('logger', _.extend({}, require('../lib/logger'), {
-+        write: function(msg) {
-+          self.errMsg = msg;
-+        }
-+      }));
-+      done();
-+    },
-+    'passing validation': function(test) {
-+      test.expect(3);
-+      this.env.registerValidationFilter('tmp', function(file) {
-+        test.equal(file.path, 'foo');
-+        test.equal(file.contents, 'bar');
-+        return true;
-+      });
-+      this.env.write('foo', 'bar');
-+      var written = this.env.read('simple-filter');
-+      test.equal(written, 'test', 'should have written the filtered file and path');
-+      test.done();
-+    },
-+    'failing validation': function(test) {
-+      test.expect(2);
-+      this.env.registerValidationFilter('tmp', function(file) { return false; });
-+      this.env.write('failing-filter', 'bar');
-+      test.ok(!file.exists(this.env.fromBase('failing-filter')), 'should have written the filtered file and path');
-+      test.equal(this.errMsg, 'Not actually writing to failing-filter haven\'t pass validation', 'default error message is log');
-+      test.done();
-+    },
-+    'validation with text file': function(test) {
-+      test.expect(1);
-+      this.env.registerValidationFilter('tmp', function(file) {
-+        test.ok(typeof file.contents === 'string');
-+        test.done();
-+        return 'abort';
-+      });
-+      var textPath = path.join(__dirname, 'fixtures/utf8.txt');
-+      this.env.copy(textPath, textPath);
-+    },
-+    'validation with binary file': function(test) {
-+      test.expect(1);
-+      this.env.registerValidationFilter('tmp', function(file) {
-+        test.ok(file.contents instanceof Buffer);
-+        test.done();
-+        return 'abort';
-+      });
-+      var binaryPath = path.join(__dirname, 'fixtures/octocat.png');
-+      this.env.copy(binaryPath, binaryPath);
-+    },
-+    'failing validation and custom error message': function(test) {
-+      test.expect(2);
-+      this.env.registerValidationFilter('tmp', function(file) { return 'a bad error'; });
-+      this.env.write('failing-filter', 'bar');
-+      test.ok(!file.exists(this.env.fromBase('failing-filter')), 'should not have written');
-+      test.equal(this.errMsg, 'a bad error', 'custom error message is log');
-+      test.done();
-+    },
-+    'async validator': function(test) {
-+      var self = this;
-+      test.expect(1);
-+      this.env._actualWrite = function() { test.ok(false, 'should not be call') };
-+      this.env.registerValidationFilter('tmp', function(file) {
-+        var done = this.async();
-+        setTimeout(function() {
-+          done('a bad error');
-+          test.equal(self.errMsg, 'a bad error', 'custom error message is log');
-+          test.done();
-+        }, 10);
-+      });
-+      this.env.write('async-failing-filter', 'bar');
-+    }
-+  },
-+  '.removeValidationFilter': function(test) {
-+    test.expect(1);
-+    this.env.registerValidationFilter('no-run', function() {
-+      test.ok(false, 'shouldn\'t run the filter');
-+    });
-+    this.env.removeValidationFilter('no-run');
-+    this.env.write('removed-validation', 'bar');
-+    test.ok(true);
-+    test.done();
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/file_test.js
-@@ -0,0 +1,679 @@
-+'use strict';
-+
-+var file = require('..');
-+
-+var fs = require('fs');
-+var path = require('path');
-+var helpers = require('./helpers/helpers');
-+
-+var Tempfile = require('temporary/lib/file');
-+var Tempdir = require('temporary/lib/dir');
-+
-+var tmpdir = new Tempdir();
-+fs.symlinkSync(path.resolve('tests/fixtures/octocat.png'), path.join(tmpdir.path, 'octocat.png'), 'file');
-+fs.symlinkSync(path.resolve('tests/fixtures/expand'), path.join(tmpdir.path, 'expand'), 'dir');
-+
-+exports['file.match'] = {
-+  'empty set': function(test) {
-+    test.expect(12);
-+    // Should return empty set if a required argument is missing or an empty set.
-+    test.deepEqual(file.match(null, null), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, null, null), [], 'should return empty set.');
-+    test.deepEqual(file.match(null, 'foo.js'), [], 'should return empty set.');
-+    test.deepEqual(file.match('*.js', null), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, null, 'foo.js'), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, '*.js', null), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, [], 'foo.js'), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, '*.js', []), [], 'should return empty set.');
-+    test.deepEqual(file.match(null, ['foo.js']), [], 'should return empty set.');
-+    test.deepEqual(file.match(['*.js'], null), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, null, ['foo.js']), [], 'should return empty set.');
-+    test.deepEqual(file.match({}, ['*.js'], null), [], 'should return empty set.');
-+    test.done();
-+  },
-+  'basic matching': function(test) {
-+    test.expect(6);
-+    test.deepEqual(file.match('*.js', 'foo.js'), ['foo.js'], 'should match correctly.');
-+    test.deepEqual(file.match('*.js', ['foo.js']), ['foo.js'], 'should match correctly.');
-+    test.deepEqual(file.match('*.js', ['foo.js', 'bar.css']), ['foo.js'], 'should match correctly.');
-+    test.deepEqual(file.match(['*.js', '*.css'], 'foo.js'), ['foo.js'], 'should match correctly.');
-+    test.deepEqual(file.match(['*.js', '*.css'], ['foo.js']), ['foo.js'], 'should match correctly.');
-+    test.deepEqual(file.match(['*.js', '*.css'], ['foo.js', 'bar.css']), ['foo.js', 'bar.css'], 'should match correctly.');
-+    test.done();
-+  },
-+  'no matches': function(test) {
-+    test.expect(2);
-+    test.deepEqual(file.match('*.js', 'foo.css'), [], 'should fail to match.');
-+    test.deepEqual(file.match('*.js', ['foo.css', 'bar.css']), [], 'should fail to match.');
-+    test.done();
-+  },
-+  'unique': function(test) {
-+    test.expect(2);
-+    test.deepEqual(file.match('*.js', ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.');
-+    test.deepEqual(file.match(['*.js', '*.*'], ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.');
-+    test.done();
-+  },
-+  'flatten': function(test) {
-+    test.expect(1);
-+    test.deepEqual(file.match([['*.js', '*.css'], ['*.*', '*.js']], ['foo.js', 'bar.css']), ['foo.js', 'bar.css'], 'should process nested pattern arrays correctly.');
-+    test.done();
-+  },
-+  'exclusion': function(test) {
-+    test.expect(5);
-+    test.deepEqual(file.match(['!*.js'], ['foo.js', 'bar.js']), [], 'solitary exclusion should match nothing');
-+    test.deepEqual(file.match(['*.js', '!*.js'], ['foo.js', 'bar.js']), [], 'exclusion should cancel match');
-+    test.deepEqual(file.match(['*.js', '!f*.js'], ['foo.js', 'bar.js', 'baz.js']), ['bar.js', 'baz.js'], 'partial exclusion should partially cancel match');
-+    test.deepEqual(file.match(['*.js', '!*.js', 'b*.js'], ['foo.js', 'bar.js', 'baz.js']), ['bar.js', 'baz.js'], 'inclusion / exclusion order matters');
-+    test.deepEqual(file.match(['*.js', '!f*.js', '*.js'], ['foo.js', 'bar.js', 'baz.js']), ['bar.js', 'baz.js', 'foo.js'], 'inclusion / exclusion order matters');
-+    test.done();
-+  },
-+  'options.matchBase': function(test) {
-+    test.expect(2);
-+    test.deepEqual(file.match({matchBase: true}, '*.js', ['foo.js', 'bar', 'baz/xyz.js']), ['foo.js', 'baz/xyz.js'], 'should matchBase (minimatch) when specified.');
-+    test.deepEqual(file.match('*.js', ['foo.js', 'bar', 'baz/xyz.js']), ['foo.js'], 'should not matchBase (minimatch) by default.');
-+    test.done();
-+  }
-+};
-+
-+exports['file.isMatch'] = {
-+  'basic matching': function(test) {
-+    test.expect(6);
-+    test.ok(file.isMatch('*.js', 'foo.js'), 'should match correctly.');
-+    test.ok(file.isMatch('*.js', ['foo.js']), 'should match correctly.');
-+    test.ok(file.isMatch('*.js', ['foo.js', 'bar.css']), 'should match correctly.');
-+    test.ok(file.isMatch(['*.js', '*.css'], 'foo.js'), 'should match correctly.');
-+    test.ok(file.isMatch(['*.js', '*.css'], ['foo.js']), 'should match correctly.');
-+    test.ok(file.isMatch(['*.js', '*.css'], ['foo.js', 'bar.css']), 'should match correctly.');
-+    test.done();
-+  },
-+  'no matches': function(test) {
-+    test.expect(6);
-+    test.equal(file.isMatch('*.js', 'foo.css'), false, 'should fail to match.');
-+    test.equal(file.isMatch('*.js', ['foo.css', 'bar.css']), false, 'should fail to match.');
-+    test.equal(file.isMatch(null, 'foo.css'), false, 'should fail to match.');
-+    test.equal(file.isMatch('*.js', null), false, 'should fail to match.');
-+    test.equal(file.isMatch([], 'foo.css'), false, 'should fail to match.');
-+    test.equal(file.isMatch('*.js', []), false, 'should fail to match.');
-+    test.done();
-+  },
-+  'options.matchBase': function(test) {
-+    test.expect(2);
-+    test.ok(file.isMatch({matchBase: true}, '*.js', ['baz/xyz.js']), 'should matchBase (minimatch) when specified.');
-+    test.equal(file.isMatch('*.js', ['baz/xyz.js']), false, 'should not matchBase (minimatch) by default.');
-+    test.done();
-+  }
-+};
-+
-+exports['file.expand*'] = {
-+  setUp: function(done) {
-+    this.cwd = process.cwd();
-+    process.chdir('tests/fixtures/expand');
-+    done();
-+  },
-+  tearDown: function(done) {
-+    process.chdir(this.cwd);
-+    done();
-+  },
-+  'basic matching': function(test) {
-+    test.expect(8);
-+    test.deepEqual(file.expand('**/*.js'), ['js/bar.js', 'js/foo.js'], 'should match.');
-+    test.deepEqual(file.expand('**/*.js', '**/*.css'), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'should match.');
-+    test.deepEqual(file.expand(['**/*.js', '**/*.css']), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'should match.');
-+    test.deepEqual(file.expand('**d*/**'), [
-+      'deep',
-+      'deep/deep.txt',
-+      'deep/deeper',
-+      'deep/deeper/deeper.txt',
-+      'deep/deeper/deepest',
-+      'deep/deeper/deepest/deepest.txt'], 'should match files and directories.');
-+    test.deepEqual(file.expand({mark: true}, '**d*/**'), [
-+      'deep/',
-+      'deep/deep.txt',
-+      'deep/deeper/',
-+      'deep/deeper/deeper.txt',
-+      'deep/deeper/deepest/',
-+      'deep/deeper/deepest/deepest.txt'], 'the minimatch "mark" option ensures directories end in /.');
-+    test.deepEqual(file.expand('**d*/**/'), [
-+      'deep/',
-+      'deep/deeper/',
-+      'deep/deeper/deepest/'], 'should match directories, arbitrary / at the end appears in matches.');
-+    test.deepEqual(file.expand({mark: true}, '**d*/**/'), [
-+      'deep/',
-+      'deep/deeper/',
-+      'deep/deeper/deepest/'], 'should match directories, arbitrary / at the end appears in matches.');
-+    test.deepEqual(file.expand('*.xyz'), [], 'should fail to match.');
-+    test.done();
-+  },
-+  'filter': function(test) {
-+    test.expect(5);
-+    test.deepEqual(file.expand({filter: 'isFile'}, '**d*/**'), [
-+      'deep/deep.txt',
-+      'deep/deeper/deeper.txt',
-+      'deep/deeper/deepest/deepest.txt'
-+    ], 'should match files only.');
-+    test.deepEqual(file.expand({filter: 'isDirectory'}, '**d*/**'), [
-+      'deep',
-+      'deep/deeper',
-+      'deep/deeper/deepest'
-+    ], 'should match directories only.');
-+    test.deepEqual(file.expand({filter: function(filepath) { return (/deepest/).test(filepath); }}, '**'), [
-+      'deep/deeper/deepest',
-+      'deep/deeper/deepest/deepest.txt',
-+    ], 'should filter arbitrarily.');
-+    test.deepEqual(file.expand({filter: 'isFile'}, 'js', 'css'), [], 'should fail to match.');
-+    test.deepEqual(file.expand({filter: 'isDirectory'}, '**/*.js'), [], 'should fail to match.');
-+    test.done();
-+  },
-+  'unique': function(test) {
-+    test.expect(4);
-+    test.deepEqual(file.expand('**/*.js', 'js/*.js'), ['js/bar.js', 'js/foo.js'], 'file list should be uniqed.');
-+    test.deepEqual(file.expand('**/*.js', '**/*.css', 'js/*.js'), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'file list should be uniqed.');
-+    test.deepEqual(file.expand('js', 'js/'), ['js', 'js/'], 'mixed non-ending-/ and ending-/ dirs will not be uniqed by default.');
-+    test.deepEqual(file.expand({mark: true}, 'js', 'js/'), ['js/'], 'mixed non-ending-/ and ending-/ dirs will be uniqed when "mark" is specified.');
-+    test.done();
-+  },
-+  'file order': function(test) {
-+    test.expect(4);
-+    var actual = file.expand('**/*.{js,css}');
-+    var expected = ['css/baz.css', 'css/qux.css', 'js/bar.js', 'js/foo.js'];
-+    test.deepEqual(actual, expected, 'should select 4 files in this order, by default.');
-+
-+    actual = file.expand('js/foo.js', 'js/bar.js', '**/*.{js,css}');
-+    expected = ['js/foo.js', 'js/bar.js', 'css/baz.css', 'css/qux.css'];
-+    test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.');
-+
-+    actual = file.expand('js/bar.js', 'js/foo.js', '**/*.{js,css}');
-+    expected = ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'];
-+    test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.');
-+
-+    actual = file.expand('js/foo.js', '**/*.{js,css}', '!js/bar.js', 'js/bar.js');
-+    expected = ['js/foo.js', 'css/baz.css', 'css/qux.css', 'js/bar.js'];
-+    test.deepEqual(actual, expected, 'if a file is excluded and then re-added, it should be added at the end.');
-+    test.done();
-+  },
-+  'flatten': function(test) {
-+    test.expect(1);
-+    test.deepEqual(file.expand([['**/*.js'], ['**/*.css', 'js/*.js']]), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'should match.');
-+    test.done();
-+  },
-+  'exclusion': function(test) {
-+    test.expect(8);
-+    test.deepEqual(file.expand(['!js/*.js']), [], 'solitary exclusion should match nothing');
-+    test.deepEqual(file.expand(['js/bar.js','!js/bar.js']), [], 'exclusion should cancel match');
-+    test.deepEqual(file.expand(['**/*.js', '!js/foo.js']), ['js/bar.js'], 'should omit single file from matched set');
-+    test.deepEqual(file.expand(['!js/foo.js', '**/*.js']), ['js/bar.js', 'js/foo.js'], 'inclusion / exclusion order matters');
-+    test.deepEqual(file.expand(['**/*.js', '**/*.css', '!js/bar.js', '!css/baz.css']), ['js/foo.js','css/qux.css'], 'multiple exclusions should be removed from the set');
-+    test.deepEqual(file.expand(['**/*.js', '**/*.css', '!**/*.css']), ['js/bar.js', 'js/foo.js'], 'excluded wildcards should be removed from the matched set');
-+    test.deepEqual(file.expand(['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css', '!**/b*.*']), ['js/foo.js', 'css/qux.css'], 'different pattern for exclusion should still work');
-+    test.deepEqual(file.expand(['js/bar.js', '!**/b*.*', 'js/foo.js', 'css/baz.css', 'css/qux.css']), ['js/foo.js', 'css/baz.css', 'css/qux.css'], 'inclusion / exclusion order matters');
-+    test.done();
-+  },
-+  'options.matchBase': function(test) {
-+    test.expect(4);
-+    var opts = {matchBase: true};
-+    test.deepEqual(file.expand('*.js'), [], 'should not matchBase (minimatch) by default.');
-+    test.deepEqual(file.expand(opts, '*.js'), ['js/bar.js', 'js/foo.js'], 'options should be passed through to minimatch.');
-+    test.deepEqual(file.expand(opts, '*.js', '*.css'), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'should match.');
-+    test.deepEqual(file.expand(opts, ['*.js', '*.css']), ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], 'should match.');
-+    test.done();
-+  },
-+  'options.cwd': function(test) {
-+    test.expect(4);
-+    var cwd = path.resolve(process.cwd(), '..');
-+    test.deepEqual(file.expand({cwd: cwd}, ['expand/js', 'expand/js/*']), ['expand/js', 'expand/js/bar.js', 'expand/js/foo.js'], 'should match.');
-+    test.deepEqual(file.expand({cwd: cwd, filter: 'isFile'}, ['expand/js', 'expand/js/*']), ['expand/js/bar.js', 'expand/js/foo.js'], 'should match.');
-+    test.deepEqual(file.expand({cwd: cwd, filter: 'isDirectory'}, ['expand/js', 'expand/js/*']), ['expand/js'], 'should match.');
-+    test.deepEqual(file.expand({cwd: cwd, filter: 'isFile'}, ['expand/js', 'expand/js/*', '!**/b*.js']), ['expand/js/foo.js'], 'should negate properly.');
-+    test.done();
-+  },
-+  'options.nonull': function(test) {
-+    test.expect(2);
-+    var opts = {nonull: true};
-+    test.deepEqual(file.expand(opts, ['js/a*', 'js/b*', 'js/c*']), ['js/a*', 'js/bar.js', 'js/c*'], 'non-matching patterns should be returned in result set.');
-+    test.deepEqual(file.expand(opts, ['js/foo.js', 'js/bar.js', 'js/baz.js']), ['js/foo.js', 'js/bar.js', 'js/baz.js'], 'non-matching filenames should be returned in result set.');
-+    test.done();
-+  },
-+};
-+
-+exports['file.expandMapping'] = {
-+  setUp: function(done) {
-+    this.cwd = process.cwd();
-+    process.chdir('tests/fixtures');
-+    done();
-+  },
-+  tearDown: function(done) {
-+    process.chdir(this.cwd);
-+    done();
-+  },
-+  'basic matching': function(test) {
-+    test.expect(2);
-+
-+    var actual = file.expandMapping(['expand/**/*.txt'], 'dest');
-+    var expected = [
-+      {dest: 'dest/expand/deep/deep.txt', src: ['expand/deep/deep.txt']},
-+      {dest: 'dest/expand/deep/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
-+      {dest: 'dest/expand/deep/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
-+    ];
-+    test.deepEqual(actual, expected, 'basic src-dest options');
-+
-+    actual = file.expandMapping(['expand/**/*.txt'], 'dest/');
-+    test.deepEqual(actual, expected, 'destBase should behave the same both with or without trailing slash');
-+
-+    test.done();
-+  },
-+  'flatten': function(test) {
-+    test.expect(1);
-+    var actual = file.expandMapping(['expand/**/*.txt'], 'dest', {flatten: true});
-+    var expected = [
-+      {dest: 'dest/deep.txt', src: ['expand/deep/deep.txt']},
-+      {dest: 'dest/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
-+      {dest: 'dest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
-+    ];
-+    test.deepEqual(actual, expected, 'dest paths should be flattened pre-destBase+destPath join');
-+    test.done();
-+  },
-+  'ext': function(test) {
-+    test.expect(2);
-+    var actual, expected;
-+    actual = file.expandMapping(['expand/**/*.txt'], 'dest', {ext: '.foo'});
-+    expected = [
-+      {dest: 'dest/expand/deep/deep.foo', src: ['expand/deep/deep.txt']},
-+      {dest: 'dest/expand/deep/deeper/deeper.foo', src: ['expand/deep/deeper/deeper.txt']},
-+      {dest: 'dest/expand/deep/deeper/deepest/deepest.foo', src: ['expand/deep/deeper/deepest/deepest.txt']},
-+    ];
-+    test.deepEqual(actual, expected, 'specified extension should be added');
-+    actual = file.expandMapping(['expand-mapping-ext/**/file*'], 'dest', {ext: '.foo'});
-+    expected = [
-+      {dest: 'dest/expand-mapping-ext/dir.ectory/file-no-extension.foo', src: ['expand-mapping-ext/dir.ectory/file-no-extension']},
-+      {dest: 'dest/expand-mapping-ext/dir.ectory/sub.dir.ectory/file.foo', src: ['expand-mapping-ext/dir.ectory/sub.dir.ectory/file.ext.ension']},
-+      {dest: 'dest/expand-mapping-ext/file.foo', src: ['expand-mapping-ext/file.ext.ension']},
-+    ];
-+    test.deepEqual(actual, expected, 'specified extension should be added');
-+    test.done();
-+  },
-+  'cwd': function(test) {
-+    test.expect(1);
-+    var actual = file.expandMapping(['**/*.txt'], 'dest', {cwd: 'expand'});
-+    var expected = [
-+      {dest: 'dest/deep/deep.txt', src: ['expand/deep/deep.txt']},
-+      {dest: 'dest/deep/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
-+      {dest: 'dest/deep/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
-+    ];
-+    test.deepEqual(actual, expected, 'cwd should be stripped from front of destPath, pre-destBase+destPath join');
-+    test.done();
-+  },
-+  'rename': function(test) {
-+    test.expect(1);
-+    var actual = file.expandMapping(['**/*.txt'], 'dest', {
-+      cwd: 'expand',
-+      flatten: true,
-+      rename: function(destBase, destPath, options) {
-+        return path.join(destBase, options.cwd, 'o-m-g', destPath);
-+      }
-+    });
-+    var expected = [
-+      {dest: 'dest/expand/o-m-g/deep.txt', src: ['expand/deep/deep.txt']},
-+      {dest: 'dest/expand/o-m-g/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
-+      {dest: 'dest/expand/o-m-g/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
-+    ];
-+    test.deepEqual(actual, expected, 'custom rename function should be used to build dest, post-flatten');
-+    test.done();
-+  },
-+  'rename to same dest': function(test) {
-+    test.expect(1);
-+    var actual = file.expandMapping(['**/*'], 'dest', {
-+      filter: 'isFile',
-+      cwd: 'expand',
-+      flatten: true,
-+      rename: function(destBase, destPath) {
-+        return path.join(destBase, 'all' + path.extname(destPath));
-+      }
-+    });
-+    var expected = [
-+      {dest: 'dest/all.md', src: ['expand/README.md']},
-+      {dest: 'dest/all.css', src: ['expand/css/baz.css', 'expand/css/qux.css']},
-+      {dest: 'dest/all.txt', src: ['expand/deep/deep.txt', 'expand/deep/deeper/deeper.txt', 'expand/deep/deeper/deepest/deepest.txt']},
-+      {dest: 'dest/all.js', src: ['expand/js/bar.js', 'expand/js/foo.js']},
-+    ];
-+    test.deepEqual(actual, expected, 'if dest is same for multiple src, create an array of src');
-+    test.done();
-+  },
-+};
-+
-+
-+// Compare two buffers. Returns true if they are equivalent.
-+var compareBuffers = function(buf1, buf2) {
-+  if (!Buffer.isBuffer(buf1) || !Buffer.isBuffer(buf2)) { return false; }
-+  if (buf1.length !== buf2.length) { return false; }
-+  for (var i = 0; i < buf2.length; i++) {
-+    if (buf1[i] !== buf2[i]) { return false; }
-+  }
-+  return true;
-+};
-+
-+// Compare two files. Returns true if they are equivalent.
-+var compareFiles = function(filepath1, filepath2) {
-+  return compareBuffers(fs.readFileSync(filepath1), fs.readFileSync(filepath2));
-+};
-+
-+exports['file'] = {
-+  setUp: function(done) {
-+    this.defaultEncoding = file.option('encoding');
-+    file.option('encoding', 'utf8');
-+    this.string = 'Ação é isso aí\n';
-+    this.object = {foo: 'Ação é isso aí', bar: ['ømg', 'pønies']};
-+    this.writeOption = file.option('write');
-+    done();
-+  },
-+  tearDown: function(done) {
-+    file.option('encoding', this.defaultEncoding);
-+    file.option('write', this.writeOption);
-+    done();
-+  },
-+  'read': function(test) {
-+    test.expect(5);
-+    helpers.assertTextEqual(file.read('tests/fixtures/utf8.txt'), this.string, test, 'file should be read as utf8 by default.');
-+    helpers.assertTextEqual(file.read('tests/fixtures/iso-8859-1.txt', {encoding: 'iso-8859-1'}), this.string,test, 'file should be read using the specified encoding.');
-+    test.ok(compareBuffers(file.read('tests/fixtures/octocat.png', {encoding: null}), fs.readFileSync('tests/fixtures/octocat.png')), 'file should be read as a buffer if encoding is specified as null.');
-+    test.strictEqual(file.read('tests/fixtures/BOM.txt'), 'foo', 'file should have BOM stripped.');
-+
-+    file.option('encoding', 'iso-8859-1');
-+    helpers.assertTextEqual(file.read('tests/fixtures/iso-8859-1.txt'), this.string, test, 'changing the default encoding should work.');
-+    test.done();
-+  },
-+  'readJSON': function(test) {
-+    test.expect(3);
-+    var obj;
-+    obj = file.readJSON('tests/fixtures/utf8.json');
-+    test.deepEqual(obj, this.object, 'file should be read as utf8 by default and parsed correctly.');
-+
-+    obj = file.readJSON('tests/fixtures/iso-8859-1.json', {encoding: 'iso-8859-1'});
-+    test.deepEqual(obj, this.object, 'file should be read using the specified encoding.');
-+
-+    file.option('encoding', 'iso-8859-1');
-+    obj = file.readJSON('tests/fixtures/iso-8859-1.json');
-+    test.deepEqual(obj, this.object, 'changing the default encoding should work.');
-+    test.done();
-+  },
-+  'write': function(test) {
-+    test.expect(5);
-+    var tmpfile;
-+    tmpfile = new Tempfile();
-+    file.write(tmpfile.path, this.string);
-+    test.strictEqual(fs.readFileSync(tmpfile.path, 'utf8'), this.string, 'file should be written as utf8 by default.');
-+    tmpfile.unlinkSync();
-+
-+    tmpfile = new Tempfile();
-+    file.write(tmpfile.path, this.string, {encoding: 'iso-8859-1'});
-+    test.strictEqual(file.read(tmpfile.path, {encoding: 'iso-8859-1'}), this.string, 'file should be written using the specified encoding.');
-+    tmpfile.unlinkSync();
-+
-+    file.option('encoding', 'iso-8859-1');
-+    tmpfile = new Tempfile();
-+    file.write(tmpfile.path, this.string);
-+    file.option('encoding', 'utf8');
-+    test.strictEqual(file.read(tmpfile.path, {encoding: 'iso-8859-1'}), this.string, 'changing the default encoding should work.');
-+    tmpfile.unlinkSync();
-+
-+    tmpfile = new Tempfile();
-+    var octocat = fs.readFileSync('tests/fixtures/octocat.png');
-+    file.write(tmpfile.path, octocat);
-+    test.ok(compareBuffers(fs.readFileSync(tmpfile.path), octocat), 'buffers should always be written as-specified, with no attempt at re-encoding.');
-+    tmpfile.unlinkSync();
-+
-+    file.option('write', false);
-+    var filepath = path.join(tmpdir.path, 'should-not-exist.txt');
-+    file.write(filepath, 'test');
-+    test.equal(file.exists(filepath), false, 'file should NOT be created if `write: false` was specified.');
-+    test.done();
-+  },
-+  'copy': function(test) {
-+    test.expect(4);
-+    var tmpfile;
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/utf8.txt', tmpfile.path);
-+    test.ok(compareFiles(tmpfile.path, 'tests/fixtures/utf8.txt'), 'text files should just be copied as default encoding.');
-+    tmpfile.unlinkSync();
-+
-+    tmpfile = new Tempfile();
-+    file.option('encoding', 'iso-8859-1');
-+    file.copy('tests/fixtures/iso-8859-1.txt', tmpfile.path);
-+    test.ok(compareFiles(tmpfile.path, 'tests/fixtures/iso-8859-1.txt'), 'text files should just be copied as default encoding.');
-+    tmpfile.unlinkSync();
-+    file.option('encoding', 'utf8');
-+
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/octocat.png', tmpfile.path);
-+    test.ok(compareFiles(tmpfile.path, 'tests/fixtures/octocat.png'), 'Binary files should be copied as encoding-agnostic by default.');
-+    tmpfile.unlinkSync();
-+
-+    file.option('write', false);
-+    var filepath = path.join(tmpdir.path, 'should-not-exist.txt');
-+    file.copy('tests/fixtures/utf8.txt', filepath);
-+    test.equal(file.exists(filepath), false, 'file should NOT be created if `write: false` was specified.');
-+
-+    test.done();
-+  },
-+  'copy and process': function(test) {
-+    test.expect(13);
-+    var tmpfile;
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/utf8.txt', tmpfile.path, {
-+      process: function(src, filepath) {
-+        test.equal(filepath.replace(/\\/g, '/'), 'tests/fixtures/utf8.txt', 'filepath should be passed in, as-specified.');
-+        test.equal(Buffer.isBuffer(src), false, 'when no encoding is specified, use default encoding and process src as a string');
-+        test.equal(typeof src, 'string', 'when no encoding is specified, use default encoding and process src as a string');
-+        return 'føø' + src + 'bår';
-+      }
-+    });
-+    helpers.assertTextEqual(file.read(tmpfile.path), 'føø' + this.string + 'bår', test, 'file should be saved as properly encoded processed string.');
-+    tmpfile.unlinkSync();
-+
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/iso-8859-1.txt', tmpfile.path, {
-+      encoding: 'iso-8859-1',
-+      process: function(src) {
-+        test.equal(Buffer.isBuffer(src), false, 'use specified encoding and process src as a string');
-+        test.equal(typeof src, 'string', 'use specified encoding and process src as a string');
-+        return 'føø' + src + 'bår';
-+      }
-+    });
-+    helpers.assertTextEqual(file.read(tmpfile.path, {encoding: 'iso-8859-1'}), 'føø' + this.string + 'bår', test, 'file should be saved as properly encoded processed string.');
-+    tmpfile.unlinkSync();
-+
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/utf8.txt', tmpfile.path, {
-+      encoding: null,
-+      process: function(src) {
-+        test.ok(Buffer.isBuffer(src), 'when encoding is specified as null, process src as a buffer');
-+        return new Buffer('føø' + src.toString() + 'bår');
-+      }
-+    });
-+    helpers.assertTextEqual(file.read(tmpfile.path), 'føø' + this.string + 'bår', test, 'file should be saved as the buffer returned by process.');
-+    tmpfile.unlinkSync();
-+
-+    file.option('encoding', 'iso-8859-1');
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/iso-8859-1.txt', tmpfile.path, {
-+      process: function(src) {
-+        test.equal(Buffer.isBuffer(src), false, 'use non-utf8 default encoding and process src as a string');
-+        test.equal(typeof src, 'string', 'use non-utf8 default encoding and process src as a string');
-+        return 'føø' + src + 'bår';
-+      }
-+    });
-+    helpers.assertTextEqual(file.read(tmpfile.path), 'føø' + this.string + 'bår', test, 'file should be saved as properly encoded processed string');
-+    tmpfile.unlinkSync();
-+
-+    var filepath = path.join(tmpdir.path, 'should-not-exist.txt');
-+    file.copy('tests/fixtures/iso-8859-1.txt', filepath, {
-+      process: function() {
-+        return false;
-+      }
-+    });
-+    test.equal(file.exists(filepath), false, 'file should NOT be created if process returns false.');
-+    test.done();
-+  },
-+  'copy and process, noprocess': function(test) {
-+    test.expect(4);
-+    var tmpfile;
-+    tmpfile = new Tempfile();
-+    file.copy('tests/fixtures/utf8.txt', tmpfile.path, {
-+      noProcess: true,
-+      process: function(src) {
-+        return 'føø' + src + 'bår';
-+      }
-+    });
-+    helpers.assertTextEqual(file.read(tmpfile.path), this.string, test, 'file should not have been processed.');
-+    tmpfile.unlinkSync();
-+
-+    ['process', 'noprocess', 'othernoprocess'].forEach(function(filename) {
-+      var filepath = path.join(tmpdir.path, filename);
-+      file.copy('tests/fixtures/utf8.txt', filepath);
-+      var tmpfile = new Tempfile();
-+      file.copy(filepath, tmpfile.path, {
-+        noProcess: ['**/*no*'],
-+        process: function(src) {
-+          return 'føø' + src + 'bår';
-+        }
-+      });
-+      if (filename === 'process') {
-+        helpers.assertTextEqual(file.read(tmpfile.path), 'føø' + this.string + 'bår', test, 'file should have been processed.');
-+      } else {
-+        helpers.assertTextEqual(file.read(tmpfile.path), this.string, test, 'file should not have been processed.');
-+      }
-+      tmpfile.unlinkSync();
-+    }, this);
-+
-+    test.done();
-+  },
-+  'copy keep file executable bit': function(test) {
-+    test.expect(2);
-+    var testFile = path.join(tmpdir.path, 'copy-perm.txt');
-+    var targetFile = path.join(tmpdir.path, 'subfolder/copy-perm.txt');
-+
-+    fs.writeFileSync(testFile, 'foo', { mode: parseInt(777, 8) });
-+    test.ok(file.isExecutable(testFile));
-+
-+    file.copy(testFile, targetFile);
-+    test.ok(file.isExecutable(targetFile));
-+
-+    fs.unlinkSync(testFile);
-+    test.done();
-+  },
-+  'delete': function(test) {
-+    test.expect(2);
-+    var oldBase = process.cwd();
-+    var cwd = path.resolve(tmpdir.path, 'delete', 'folder');
-+    file.mkdir(cwd);
-+    process.chdir(tmpdir.path);
-+
-+    file.write(path.join(cwd, 'test.js'), 'var test;');
-+    test.ok(file.delete(cwd), 'should return true after deleting file.');
-+    test.equal(file.exists(cwd), false, 'file should have been deleted.');
-+    process.chdir(oldBase);
-+    test.done();
-+  },
-+  'delete nonexistent file': function(test) {
-+    test.expect(1);
-+    var oldWarn = file.log.warn;
-+    file.log.warn = function() {};
-+    test.ok(!file.delete('nonexistent'), 'should return false if file does not exist.');
-+    file.log.warn = oldWarn;
-+    test.done();
-+  },
-+  'delete outside working directory': function(test) {
-+    test.expect(3);
-+    var oldBase = process.cwd();
-+    var oldWarn = file.log.warn;
-+    file.log.warn = function() {};
-+
-+    var cwd = path.resolve(tmpdir.path, 'delete', 'folder');
-+    var outsidecwd = path.resolve(tmpdir.path, 'delete', 'outsidecwd');
-+    file.mkdir(cwd);
-+    file.mkdir(outsidecwd);
-+    process.chdir(cwd);
-+
-+    file.write(path.join(outsidecwd, 'test.js'), 'var test;');
-+    test.equal(file.delete(path.join(outsidecwd, 'test.js')), false, 'should not delete anything outside the cwd.');
-+
-+    test.ok(file.delete(path.join(outsidecwd), {force:true}), 'should delete outside cwd when using the --force.');
-+    test.equal(file.exists(outsidecwd), false, 'file outside cwd should have been deleted when using the --force.');
-+
-+    process.chdir(oldBase);
-+    file.log.warn = oldWarn;
-+    test.done();
-+  },
-+  'dont delete current working directory': function(test) {
-+    test.expect(2);
-+    var oldBase = process.cwd();
-+    var oldWarn = file.log.warn;
-+    file.log.warn = function() {};
-+
-+    var cwd = path.resolve(tmpdir.path, 'dontdelete', 'folder');
-+    file.mkdir(cwd);
-+    process.chdir(cwd);
-+
-+    test.equal(file.delete(cwd), false, 'should not delete the cwd.');
-+    test.ok(file.exists(cwd), 'the cwd should exist.');
-+
-+    process.chdir(oldBase);
-+    file.log.warn = oldWarn;
-+    test.done();
-+  },
-+  'dont actually delete with no-write option on': function(test) {
-+    test.expect(2);
-+    file.option('write', false);
-+
-+    var oldBase = process.cwd();
-+    var cwd = path.resolve(tmpdir.path, 'dontdelete', 'folder');
-+    file.mkdir(cwd);
-+    process.chdir(tmpdir.path);
-+
-+    file.write(path.join(cwd, 'test.js'), 'var test;');
-+    test.ok(file.delete(cwd), 'should return true after not actually deleting file.');
-+    test.equal(file.exists(cwd), true, 'file should NOT be deleted if `write: false` was specified.');
-+    process.chdir(oldBase);
-+
-+    test.done();
-+  },
-+  'mkdir': function(test) {
-+    test.expect(5);
-+    test.doesNotThrow(function() {
-+      file.mkdir(tmpdir.path);
-+    }, 'Should not explode if the directory already exists.');
-+    test.ok(fs.existsSync(tmpdir.path), 'path should still exist.');
-+
-+    test.doesNotThrow(function() {
-+      file.mkdir(path.join(tmpdir.path, 'aa/bb/cc'));
-+    }, 'Should also not explode, otherwise.');
-+    test.ok(path.join(tmpdir.path, 'aa/bb/cc'), 'path should have been created.');
-+
-+    fs.writeFileSync(path.join(tmpdir.path, 'aa/bb/xx'), 'test');
-+    test.throws(function() {
-+      file.mkdir(path.join(tmpdir.path, 'aa/bb/xx/yy'));
-+    }, 'Should throw if a path cannot be created (ENOTDIR).');
-+
-+    test.done();
-+  },
-+  'recurse': function(test) {
-+    test.expect(1);
-+    var rootdir = 'tests/fixtures/expand';
-+    var expected = {};
-+    expected[rootdir + '/css/baz.css'] = [rootdir, 'css', 'baz.css'];
-+    expected[rootdir + '/css/qux.css'] = [rootdir, 'css', 'qux.css'];
-+    expected[rootdir + '/deep/deep.txt'] = [rootdir, 'deep', 'deep.txt'];
-+    expected[rootdir + '/deep/deeper/deeper.txt'] = [rootdir, 'deep/deeper', 'deeper.txt'];
-+    expected[rootdir + '/deep/deeper/deepest/deepest.txt'] = [rootdir, 'deep/deeper/deepest', 'deepest.txt'];
-+    expected[rootdir + '/js/bar.js'] = [rootdir, 'js', 'bar.js'];
-+    expected[rootdir + '/js/foo.js'] = [rootdir, 'js', 'foo.js'];
-+    expected[rootdir + '/README.md'] = [rootdir, undefined, 'README.md'];
-+
-+    var actual = {};
-+    file.recurse(rootdir, function(abspath, rootdir, subdir, filename) {
-+      actual[abspath] = [rootdir, subdir, filename];
-+    });
-+
-+    test.deepEqual(actual, expected, 'paths and arguments should match.');
-+    test.done();
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/BOM.txt
-@@ -0,0 +1 @@
-+foo
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/Gruntfile-print-text.js
-@@ -0,0 +1,8 @@
-+module.exports = function(grunt) {
-+
-+  grunt.registerTask('print', 'Print the specified text.', function(text) {
-+    console.log('OUTPUT: ' + text);
-+    // console.log(process.cwd());
-+  });
-+
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/a.js
-@@ -0,0 +1 @@
-+var a = 1;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/b.js
-@@ -0,0 +1 @@
-+var b = 2;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/banner.js
-@@ -0,0 +1,11 @@
-+
-+/* THIS
-+ * IS
-+ * A
-+ * SAMPLE
-+ * BANNER!
-+ */
-+
-+// Comment
-+
-+/* Comment */
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/banner2.js
-@@ -0,0 +1,7 @@
-+
-+/*! SAMPLE
-+ * BANNER */
-+
-+// Comment
-+
-+/* Comment */
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/banner3.js
-@@ -0,0 +1,10 @@
-+
-+// This is
-+// A sample
-+// Banner
-+
-+// But this is not
-+
-+/* And neither
-+ * is this
-+ */
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/exec.cmd
-@@ -0,0 +1 @@
-+ at echo done
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/exec.sh
-@@ -0,0 +1,2 @@
-+#!/bin/bash
-+echo "done"
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/iso-8859-1.json
-@@ -0,0 +1,4 @@
-+{
-+  "foo": "Ação é isso aí",
-+  "bar": ["ømg", "pønies"]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/iso-8859-1.txt
-@@ -0,0 +1 @@
-+Ação é isso aí
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/iso-8859-1.yaml
-@@ -0,0 +1,4 @@
-+foo: Ação é isso aí
-+bar:
-+  - ømg
-+  - pønies
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/no_BOM.txt
-@@ -0,0 +1 @@
-+foo
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/spawn-multibyte.js
-@@ -0,0 +1,17 @@
-+// This is a test fixture for a case where spawn receives incomplete
-+// multibyte strings in separate data events.
-+
-+// A multibyte buffer containing all our output. We will slice it later.
-+// In this case we are using a Japanese word for hello / good day, where each
-+// character takes three bytes.
-+var fullOutput = new Buffer('こんにちは');
-+
-+// Output one full character and one third of a character
-+process.stdout.write(fullOutput.slice(0, 4));
-+
-+// Output the rest of the string
-+process.stdout.write(fullOutput.slice(4));
-+
-+// Do the same for stderr
-+process.stderr.write(fullOutput.slice(0, 4));
-+process.stderr.write(fullOutput.slice(4));
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/spawn.js
-@@ -0,0 +1,9 @@
-+
-+var code = Number(process.argv[2]);
-+
-+process.stdout.write('stdout\n');
-+process.stderr.write('stderr\n');
-+
-+// Use instead of process.exit to ensure stdout/stderr are flushed
-+// before exiting in Windows (Tested in Node.js v0.8.7)
-+require('../../lib/util/exit').exit(code);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/template.txt
-@@ -0,0 +1 @@
-+Version: <%= grunt.version %>, today: <%= grunt.template.today("yyyy-mm-dd") %>.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/test.json
-@@ -0,0 +1,4 @@
-+{
-+  "foo": "bar",
-+  "baz": [1, 2, 3]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/utf8.json
-@@ -0,0 +1,4 @@
-+{
-+  "foo": "Ação é isso aí",
-+  "bar": ["ømg", "pønies"]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/utf8.txt
-@@ -0,0 +1 @@
-+Ação é isso aí
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/fixtures/utf8.yaml
-@@ -0,0 +1,4 @@
-+foo: Ação é isso aí
-+bar:
-+  - ømg
-+  - pønies
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/helpers/helpers.js
-@@ -0,0 +1,7 @@
-+exports.assertTextEqual = function (value, expected, test, msg) {
-+  function eol(str) {
-+    return str.replace(/\r\n/g, '\n');
-+  }
-+
-+  test.strictEqual(eol(value), eol(expected), msg);
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/module.js
-@@ -0,0 +1,26 @@
-+'use strict';
-+
-+var file = require('..');
-+var File = require('../lib/file');
-+var _ = require('lodash');
-+
-+exports['file module'] = {
-+  'createEnv': function(test) {
-+    test.expect(6);
-+    var logger = { bar: 'foo' };
-+    var src = file.createEnv({
-+      write: false,
-+      encoding: 'usc2',
-+      logger: logger,
-+      base: 'src/'
-+    });
-+
-+    test.equal(src.option('write'), false);
-+    test.equal(src.option('encoding'), 'usc2');
-+    test.equal(src.option('logger'), logger);
-+    test.equal(src.option('base'), 'src/');
-+    test.notEqual(src, file);
-+    test.ok(src instanceof File);
-+    test.done();
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/file-utils/tests/query.js
-@@ -0,0 +1,127 @@
-+'use strict';
-+
-+var fquery = require('..');
-+
-+var fs = require('fs');
-+var path = require('path');
-+
-+var Tempfile = require('temporary/lib/file');
-+var Tempdir = require('temporary/lib/dir');
-+
-+var tmpdir = new Tempdir();
-+fs.symlinkSync(path.resolve('tests/fixtures/octocat.png'), path.join(tmpdir.path, 'octocat.png'), 'file');
-+fs.symlinkSync(path.resolve('tests/fixtures/expand'), path.join(tmpdir.path, 'expand'), 'dir');
-+
-+exports['fquery'] = {
-+  setUp: function(done) {
-+    // Assign the query interface, allow running these tests on other interface
-+    this.fquery = fquery;
-+    done();
-+  },
-+  'exists': function(test) {
-+    test.expect(6);
-+    test.ok(this.fquery.exists('tests/fixtures/octocat.png'), 'files exist.');
-+    test.ok(this.fquery.exists('tests', 'fixtures', 'octocat.png'), 'should work for paths in parts.');
-+    test.ok(this.fquery.exists('tests/fixtures'), 'directories exist.');
-+    test.ok(this.fquery.exists(path.join(tmpdir.path, 'octocat.png')), 'file links exist.');
-+    test.ok(this.fquery.exists(path.join(tmpdir.path, 'expand')), 'directory links exist.');
-+    test.equal(this.fquery.exists('tests/fixtures/does/not/exist'), false, 'nonexistent files do not exist.');
-+    test.done();
-+  },
-+  'isLink': function(test) {
-+    test.expect(6);
-+    test.equals(this.fquery.isLink('tests/fixtures/octocat.png'), false, 'files are not links.');
-+    test.equals(this.fquery.isLink('tests/fixtures'), false, 'directories are not links.');
-+    test.ok(this.fquery.isLink(path.join(tmpdir.path, 'octocat.png')), 'file links are links.');
-+    test.ok(this.fquery.isLink(path.join(tmpdir.path, 'expand')), 'directory links are links.');
-+    test.ok(this.fquery.isLink(tmpdir.path, 'octocat.png'), 'should work for paths in parts.');
-+    test.equals(this.fquery.isLink('tests/fixtures/does/not/exist'), false, 'nonexistent files are not links.');
-+    test.done();
-+  },
-+  'isDir': function(test) {
-+    test.expect(6);
-+    test.equals(this.fquery.isDir('tests/fixtures/octocat.png'), false, 'files are not directories.');
-+    test.ok(this.fquery.isDir('tests/fixtures'), 'directories are directories.');
-+    test.ok(this.fquery.isDir('tests', 'fixtures'), 'should work for paths in parts.');
-+    test.equals(this.fquery.isDir(path.join(tmpdir.path, 'octocat.png')), false, 'file links are not directories.');
-+    test.ok(this.fquery.isDir(path.join(tmpdir.path, 'expand')), 'directory links are directories.');
-+    test.equals(this.fquery.isDir('tests/fixtures/does/not/exist'), false, 'nonexistent files are not directories.');
-+    test.done();
-+  },
-+  'isFile': function(test) {
-+    test.expect(6);
-+    test.ok(this.fquery.isFile('tests/fixtures/octocat.png'), 'files are files.');
-+    test.ok(this.fquery.isFile('tests', 'fixtures', 'octocat.png'), 'should work for paths in parts.');
-+    test.equals(this.fquery.isFile('tests/fixtures'), false, 'directories are not files.');
-+    test.ok(this.fquery.isFile(path.join(tmpdir.path, 'octocat.png')), 'file links are files.');
-+    test.equals(this.fquery.isFile(path.join(tmpdir.path, 'expand')), false, 'directory links are not files.');
-+    test.equals(this.fquery.isFile('tests/fixtures/does/not/exist'), false, 'nonexistent files are not files.');
-+    test.done();
-+  },
-+  'isExecutable': function(test) {
-+    test.expect(2);
-+
-+    var isExec = path.join(tmpdir.path, 'isExecutable-true');
-+    var isNotExec = path.join(tmpdir.path, 'isExecutable-false');
-+
-+    fs.writeFileSync(isExec, 'bar', { mode: parseInt(777, 8) });
-+    fs.writeFileSync(isNotExec, 'bar', { mode: parseInt(666, 8) });
-+
-+    test.ok(this.fquery.isExecutable(isExec));
-+    test.ok(!this.fquery.isExecutable(isNotExec));
-+
-+    test.done();
-+  },
-+  'isPathAbsolute': function(test) {
-+    test.expect(5);
-+    test.ok(this.fquery.isPathAbsolute(path.resolve('/foo')), 'should return true');
-+    test.ok(this.fquery.isPathAbsolute(path.resolve('/foo') + path.sep), 'should return true');
-+    test.equal(this.fquery.isPathAbsolute('foo'), false, 'should return false');
-+    test.ok(this.fquery.isPathAbsolute(path.resolve('tests/fixtures/a.js')), 'should return true');
-+    test.equal(this.fquery.isPathAbsolute('tests/fixtures/a.js'), false, 'should return false');
-+    test.done();
-+  },
-+  'arePathsEquivalent': function(test) {
-+    test.expect(5);
-+    test.ok(this.fquery.arePathsEquivalent('/foo'), 'should return true');
-+    test.ok(this.fquery.arePathsEquivalent('/foo', '/foo/', '/foo/../foo/'), 'should return true');
-+    test.ok(this.fquery.arePathsEquivalent(process.cwd(), '.', './', 'tests/..'), 'should return true');
-+    test.equal(this.fquery.arePathsEquivalent(process.cwd(), '..'), false, 'should return false');
-+    test.equal(this.fquery.arePathsEquivalent('.', '..'), false, 'should return false');
-+    test.done();
-+  },
-+  'doesPathContain': function(test) {
-+    test.expect(6);
-+    test.ok(this.fquery.doesPathContain('/foo', '/foo/bar'), 'should return true');
-+    test.ok(this.fquery.doesPathContain('/foo/', '/foo/bar/baz', '/foo/bar', '/foo/whatever'), 'should return true');
-+    test.equal(this.fquery.doesPathContain('/foo', '/foo'), false, 'should return false');
-+    test.equal(this.fquery.doesPathContain('/foo/xyz', '/foo/xyz/123', '/foo/bar/baz'), false, 'should return false');
-+    test.equal(this.fquery.doesPathContain('/foo/xyz', '/foo'), false, 'should return false');
-+    test.ok(this.fquery.doesPathContain(process.cwd(), 'test', 'tests/fixtures', 'lib'), 'should return true');
-+    test.done();
-+  },
-+  'isPathCwd': function(test) {
-+    test.expect(8);
-+    test.ok(this.fquery.isPathCwd(process.cwd()), 'cwd is cwd');
-+    test.ok(this.fquery.isPathCwd('.'), 'cwd is cwd');
-+    test.equal(this.fquery.isPathCwd('tests'), false, 'subdirectory is not cwd');
-+    test.equal(this.fquery.isPathCwd(path.resolve('test')), false, 'subdirectory is not cwd');
-+    test.equal(this.fquery.isPathCwd('..'), false, 'parent is not cwd');
-+    test.equal(this.fquery.isPathCwd(path.resolve('..')), false, 'parent is not cwd');
-+    test.equal(this.fquery.isPathCwd('/'), false, 'root is not cwd (I hope)');
-+    test.equal(this.fquery.isPathCwd('nonexistent'), false, 'nonexistent path is not cwd');
-+    test.done();
-+  },
-+  'isPathInCwd': function(test) {
-+    test.expect(8);
-+    test.equal(this.fquery.isPathInCwd(process.cwd()), false, 'cwd is not IN cwd');
-+    test.equal(this.fquery.isPathInCwd('.'), false, 'cwd is not IN cwd');
-+    test.ok(this.fquery.isPathInCwd('tests'), 'subdirectory is in cwd');
-+    test.ok(this.fquery.isPathInCwd(path.resolve('tests')), 'subdirectory is in cwd');
-+    test.equal(this.fquery.isPathInCwd('..'), false, 'parent is not in cwd');
-+    test.equal(this.fquery.isPathInCwd(path.resolve('..')), false, 'parent is not in cwd');
-+    test.equal(this.fquery.isPathInCwd('/'), false, 'root is not in cwd (I hope)');
-+    test.equal(this.fquery.isPathInCwd('nonexistent'), false, 'nonexistent path is not in cwd');
-+    test.done();
-+  },
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/.npmignore
-@@ -0,0 +1,3 @@
-+npm-debug.log
-+node_modules/
-+test/tmp/
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/.travis.yml
-@@ -0,0 +1,5 @@
-+language: node_js
-+node_js:
-+  - "0.10"
-+  - "0.8"
-+# - "0.6"
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/LICENSE-MIT
-@@ -0,0 +1,23 @@
-+Copyright (c) 2013 J. Pommerening, 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.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/README.md
-@@ -0,0 +1,100 @@
-+# Lazy Streams
-+
-+> *Create streams lazily when they are read from or written to.*  
-+> `lazystream: 0.0.2` [![Build Status](https://travis-ci.org/jpommerening/node-lazystream.png?branch=master)](https://travis-ci.org/jpommerening/node-lazystream)  
-+
-+## Why?
-+
-+Sometimes you feel the itch to open *all the files* at once. You want to pass a bunch of streams around, so the consumer does not need to worry where the data comes from.
-+From a software design point-of-view this sounds entirely reasonable. Then there is that neat little function `fs.createReadStream()` that opens a file and gives you a nice `fs.ReadStream` to pass around, so you use what the mighty creator deities of node bestowed upon you.
-+
-+> `Error: EMFILE, too many open files`  
-+> ─ *node*
-+
-+This package provides two classes based on the node's new streams API (or `readable-stream` if you are using node a node version earlier than 0.10):
-+
-+## Class: lazystream.Readable
-+
-+A wrapper for readable streams. Extends [`stream.PassThrough`](http://nodejs.org/api/stream.html#stream_class_stream_passthrough).
-+
-+### new lazystream.Readable(fn [, options])
-+
-+* `fn` *{Function}*  
-+  The function that the lazy stream will call to obtain the stream to actually read from.
-+* `options` *{Object}*  
-+  Options for the underlying `PassThrough` stream, accessible by `fn`.
-+
-+Creates a new readable stream. Once the stream is accessed (for example when you call its `read()` method, or attach a `data`-event listener) the `fn` function is called with the outer `lazystream.Readable` instance bound to `this`.
-+
-+If you pass an `options` object to the constuctor, you can access it in your `fn` function.
-+
-+```javascript
-+new lazystream.Readable(function (options) {
-+  return fs.createReadStream('/dev/urandom');
-+});
-+```
-+
-+## Class: lazystream.Writable
-+
-+A wrapper for writable streams. Extends [`stream.PassThrough`](http://nodejs.org/api/stream.html#stream_class_stream_passthrough).
-+
-+### new lazystream.Writable(fn [, options])
-+
-+* `fn` *{Function}*  
-+  The function that the lazy stream will call to obtain the stream to actually write to.
-+* `options` *{Object}*  
-+  Options for the underlying `PassThrough` stream, accessible by `fn`.
-+
-+Creates a new writable stream. Just like the one above but for writable streams.
-+
-+```javascript
-+new lazystream.Writable(function () {
-+  return fs.createWriteStream('/dev/null');
-+});
-+```
-+
-+## Install
-+
-+```console
-+$ npm install lazystream --save
-+npm http GET https://registry.npmjs.org/readable-stream
-+npm http 200 https://registry.npmjs.org/readable-stream
-+npm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.2.tgz
-+npm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.2.tgz
-+lazystream at 0.0.2 node_modules/lazystream
-+└── readable-stream at 1.0.2
-+```
-+
-+## Contributing
-+
-+Fork it, branch it, send me a pull request. We'll work out the rest together.
-+
-+## Credits
-+
-+[Chris Talkington](https://github.com/ctalkington) and his [node-archiver](https://github.com/ctalkington/node-archiver) for providing a use-case.
-+
-+## [License](LICENSE-MIT)
-+
-+Copyright (c) 2013 J. Pommerening, 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.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/lib/lazystream.js
-@@ -0,0 +1,52 @@
-+
-+var util = require('util');
-+var PassThrough = require('stream').PassThrough || require('readable-stream/passthrough');
-+
-+module.exports = {
-+  Readable: Readable,
-+  Writable: Writable
-+};
-+
-+util.inherits(Readable, PassThrough);
-+util.inherits(Writable, PassThrough);
-+
-+// Patch the given method of instance so that the callback
-+// is executed once, before the actual method is called the
-+// first time.
-+function beforeFirstCall(instance, method, callback) {
-+  instance[method] = function() {
-+    delete instance[method];
-+    callback.apply(this, arguments);
-+    return this[method].apply(this, arguments);
-+  };
-+}
-+
-+function Readable(fn, options) {
-+  if (!(this instanceof Readable))
-+    return new Readable(fn, options);
-+
-+  PassThrough.call(this, options);
-+
-+  beforeFirstCall(this, '_read', function() {
-+    var source = fn.call(this, options);
-+    var that = this;
-+    source.pipe(this);
-+  });
-+
-+  this.emit('readable');
-+}
-+
-+function Writable(fn, options) {
-+  if (!(this instanceof Writable))
-+    return new Writable(fn, options);
-+
-+  PassThrough.call(this, options);
-+
-+  beforeFirstCall(this, '_write', function() {
-+    var destination = fn.call(this, options);
-+    this.pipe(destination);
-+  });
-+
-+  this.emit('writable');
-+}
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/package.json
-@@ -0,0 +1,43 @@
-+{
-+  "name": "lazystream",
-+  "version": "0.1.0",
-+  "description": "Open Node Streams on demand.",
-+  "homepage": "https://github.com/jpommerening/node-lazystream",
-+  "author": {
-+    "name": "J. Pommerening"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/jpommerening/node-lazystream.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/jpommerening/node-lazystream/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/jpommerening/node-lazystream/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/lazystream.js",
-+  "engines": {
-+    "node": ">= 0.6.3"
-+  },
-+  "scripts": {
-+    "test": "nodeunit test/readable_test.js test/writable_test.js test/pipe_test.js test/fs_test.js"
-+  },
-+  "dependencies": {
-+    "readable-stream": "~1.0.2"
-+  },
-+  "devDependencies": {
-+    "nodeunit": "~0.7.4"
-+  },
-+  "keywords": [
-+    "streams",
-+    "stream"
-+  ],
-+  "readme": "# Lazy Streams\n\n> *Create streams lazily when they are read from or written to.*  \n> `lazystream: 0.0.2` [![Build Status](https://travis-ci.org/jpommerening/node-lazystream.png?branch=master)](https://travis-ci.org/jpommerening/node-lazystream)  \n\n## Why?\n\nSometimes you feel the itch to open *all the files* at once. You want to pass a bunch of streams around, so the consumer does not need to worry where the data comes from.\nFrom a software design point-of-view this sounds entirely reasonable. Then there is that neat little function `fs.createReadStream()` that opens a file and gives you a nice `fs.ReadStream` to pass around, so you use what the mighty creator deities of node bestowed upon you.\n\n> `Error: EMFILE, too many open files`  \n> ─ *node*\n\nThis package provides two classes based on the node's new streams API (or `readable-stream` if you are using node a node version earlier than 0.10):\n\n## Class: lazystream.Readable\n\nA wrapper for readable streams. Extends [`stream.PassThrough`](http://nodejs.org/api/stream.html#stream_class_stream_passthrough).\n\n### new lazystream.Readable(fn [, options])\n\n* `fn` *{Function}*  \n  The function that the lazy stream will call to obtain the stream to actually read from.\n* `options` *{Object}*  \n  Options for the underlying `PassThrough` stream, accessible by `fn`.\n\nCreates a new readable stream. Once the stream is accessed (for example when you call its `read()` method, or attach a `data`-event listener) the `fn` function is called with the outer `lazystream.Readable` instance bound to `this`.\n\nIf you pass an `options` object to the constuctor, you can access it in your `fn` function.\n\n```javascript\nnew lazystream.Readable(function (options) {\n  return fs.createReadStream('/dev/urandom');\n});\n```\n\n## Class: lazystream.Writable\n\nA wrapper for writable streams. Extends [`stream.PassThrough`](http://nodejs.org/api/stream.html#stream_class_stream_passthrough).\n\n### new lazystream.Writable(fn [, options])\n\n* `fn` *{Function}*  \n  The function that the lazy stream will call to obtain the stream to actually write to.\n* `options` *{Object}*  \n  Options for the underlying `PassThrough` stream, accessible by `fn`.\n\nCreates a new writable stream. Just like the one above but for writable streams.\n\n```javascript\nnew lazystream.Writable(function () {\n  return fs.createWriteStream('/dev/null');\n});\n```\n\n## Install\n\n```console\n$ npm install lazystream --save\nnpm http GET https://registry.npmjs.org/readable-stream\nnpm http 200 https://registry.npmjs.org/readable-stream\nnpm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.2.tgz\nnpm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.2.tgz\nlazystream@0.0.2 node_modules/lazystream\n└── readable-stream at 1.0.2\n```\n\n## Contributing\n\nFork it, branch it, send me a pull request. We'll work out the rest together.\n\n## Credits\n\n[Chris Talkington](https://github.com/ctalkington) and his [node-archiver](https://github.com/ctalkington/node-archiver) for providing a use-case.\n\n## [License](LICENSE-MIT)\n\nCopyright (c) 2013 J. Pommerening, contributors.\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\n",
-+  "readmeFilename": "README.md",
-+  "_id": "lazystream at 0.1.0",
-+  "_from": "lazystream@~0.1.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/data.md
-@@ -0,0 +1,13 @@
-+> Never mind, hey, this is really exciting, so much to find out about, so much to
-+> look forward to, I'm quite dizzy with anticipation . . . Or is it the wind?
-+> 
-+> There really is a lot of that now, isn't there? And wow! Hey! What's this thing
-+> suddenly coming toward me very fast? Very, very fast. So big and flat and round,
-+> it needs a big wide-sounding name like . . . ow . . . ound . . . round . . .
-+> ground! That's it! That's a good name- ground!
-+>
-+> I wonder if it will be friends with me?
-+>
-+> Hello Ground!
-+
-+And the rest, after a sudden wet thud, was silence.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/fs_test.js
-@@ -0,0 +1,69 @@
-+
-+var stream = require('../lib/lazystream');
-+var fs = require('fs');
-+var tmpDir = 'test/tmp/';
-+var readFile = 'test/data.md';
-+var writeFile = tmpDir + 'data.md';
-+
-+exports.fs = {
-+  readwrite: function(test) {
-+    var readfd, writefd;
-+
-+    var readable = new stream.Readable(function() {
-+       return fs.createReadStream(readFile)
-+        .on('open', function(fd) {
-+          readfd = fd;
-+        })
-+        .on('close', function() {
-+           readfd = undefined;
-+           step();
-+        });
-+    });
-+
-+    var writable = new stream.Writable(function() {
-+      return fs.createWriteStream(writeFile)
-+        .on('open', function(fd) {
-+          writefd = fd;
-+        })
-+        .on('close', function() {
-+          writefd = undefined;
-+           step();
-+        });
-+    });
-+
-+    test.expect(3);
-+
-+    test.equal(readfd, undefined, 'Input file should not be opened until read');
-+    test.equal(writefd, undefined, 'Output file should not be opened until write');
-+
-+    if (!fs.existsSync(tmpDir)) {
-+      fs.mkdirSync(tmpDir);
-+    }
-+    if (fs.existsSync(writeFile)) {
-+      fs.unlinkSync(writeFile);
-+    }
-+
-+    readable.on('end', function() { step(); });
-+    writable.on('end', function() { step(); });
-+
-+    var steps = 0;
-+    function step() {
-+      steps += 1;
-+      if (steps == 4) {
-+        var input = fs.readFileSync(readFile);
-+        var output = fs.readFileSync(writeFile);
-+
-+        test.ok(input >= output && input <= output, 'Should be equal');
-+
-+        fs.unlinkSync(writeFile);
-+        fs.rmdirSync(tmpDir);
-+
-+        test.done();
-+      }
-+    };
-+
-+    readable.pipe(writable);
-+  }
-+};
-+
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/helper.js
-@@ -0,0 +1,39 @@
-+
-+var _Readable = require('readable-stream/readable');
-+var _Writable = require('readable-stream/writable');
-+var util = require('util');
-+
-+module.exports = {
-+  DummyReadable: DummyReadable,
-+  DummyWritable: DummyWritable
-+};
-+
-+function DummyReadable(strings) {
-+  _Readable.call(this);
-+  this.strings = strings;
-+  this.emit('readable');
-+}
-+
-+util.inherits(DummyReadable, _Readable);
-+
-+DummyReadable.prototype._read = function _read(n) {
-+  if (this.strings.length) {
-+    this.push(new Buffer(this.strings.shift()));
-+  } else {
-+    this.push(null);
-+  }
-+};
-+
-+function DummyWritable(strings) {
-+  _Writable.call(this);
-+  this.strings = strings;
-+  this.emit('writable');
-+}
-+
-+util.inherits(DummyWritable, _Writable);
-+
-+DummyWritable.prototype._write = function _write(chunk, encoding, callback) {
-+  this.strings.push(chunk.toString());
-+  if (callback) callback();
-+};
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/pipe_test.js
-@@ -0,0 +1,36 @@
-+
-+var stream = require('../lib/lazystream');
-+var helper = require('./helper');
-+
-+exports.pipe = {
-+  readwrite: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+    var readableInstantiated = false;
-+    var writableInstantiated = false;
-+
-+    test.expect(3);
-+
-+    var readable = new stream.Readable(function() {
-+      readableInstantiated = true;
-+      return new helper.DummyReadable([].concat(expected));
-+    });
-+
-+    var writable = new stream.Writable(function() {
-+      writableInstantiated = true;
-+      return new helper.DummyWritable(actual);
-+    });
-+
-+    test.equal(readableInstantiated, false, 'DummyReadable should only be instantiated when it is needed');
-+    test.equal(writableInstantiated, false, 'DummyWritable should only be instantiated when it is needed');
-+
-+    writable.on('end', function() {
-+      test.equal(actual.join(''), expected.join(''), 'Piping on demand streams should keep data intact');
-+      test.done();
-+    });
-+    
-+    readable.pipe(writable);
-+  }
-+};
-+
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/readable_test.js
-@@ -0,0 +1,88 @@
-+
-+var Readable = require('../lib/lazystream').Readable;
-+var DummyReadable = require('./helper').DummyReadable;
-+
-+exports.readable = {
-+  dummy: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+
-+    test.expect(1);
-+
-+    new DummyReadable([].concat(expected))
-+      .on('data', function(chunk) {
-+        actual.push(chunk.toString());
-+      })
-+      .on('end', function() {
-+        test.equal(actual.join(''), expected.join(''), 'DummyReadable should produce the data it was created with');
-+        test.done();
-+      });
-+  },
-+  options: function(test) {
-+    test.expect(3);
-+
-+    var readable = new Readable(function(options) {
-+       test.ok(this instanceof Readable, "Readable should bind itself to callback's this");
-+       test.equal(options.encoding, "utf-8", "Readable should make options accessible to callback");
-+       this.ok = true;
-+       return new DummyReadable(["test"]);
-+    }, {encoding: "utf-8"});
-+
-+    readable.read(4);
-+
-+    test.ok(readable.ok);
-+
-+    test.done();
-+  },
-+  streams2: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+    var instantiated = false;
-+
-+    test.expect(2);
-+
-+    var readable = new Readable(function() {
-+      instantiated = true;
-+      return new DummyReadable([].concat(expected));
-+    });
-+
-+    test.equal(instantiated, false, 'DummyReadable should only be instantiated when it is needed');
-+
-+    readable.on('readable', function() {
-+      var chunk = readable.read();
-+      actual.push(chunk.toString());
-+    });
-+    readable.on('end', function() {
-+      test.equal(actual.join(''), expected.join(''), 'Readable should not change the data of the underlying stream');
-+      test.done();
-+    });
-+
-+    readable.read(0);
-+  },
-+  resume: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+    var instantiated = false;
-+
-+    test.expect(2);
-+
-+    var readable = new Readable(function() {
-+      instantiated = true;
-+      return new DummyReadable([].concat(expected));
-+    });
-+
-+    readable.pause();
-+
-+    readable.on('data', function(chunk) {
-+      actual.push(chunk.toString());
-+    });
-+    readable.on('end', function() {
-+      test.equal(actual.join(''), expected.join(''), 'Readable should not change the data of the underlying stream');
-+      test.done();
-+    });
-+
-+    test.equal(instantiated, false, 'DummyReadable should only be instantiated when it is needed');
-+    
-+    readable.resume();
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lazystream/test/writable_test.js
-@@ -0,0 +1,59 @@
-+
-+var Writable = require('../lib/lazystream').Writable;
-+var DummyWritable = require('./helper').DummyWritable;
-+
-+exports.writable = {
-+  options: function(test) {
-+    test.expect(3);
-+
-+    var writable = new Writable(function(options) {
-+       test.ok(this instanceof Writable, "Writable should bind itself to callback's this");
-+       test.equal(options.encoding, "utf-8", "Writable should make options accessible to callback");
-+       this.ok = true;
-+       return new DummyWritable([]);
-+    }, {encoding: "utf-8"});
-+
-+    writable.write("test");
-+
-+    test.ok(writable.ok);
-+
-+    test.done();
-+  },
-+  dummy: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+    
-+    test.expect(0);
-+
-+    var dummy = new DummyWritable(actual);
-+
-+    expected.forEach(function(item) {
-+      dummy.write(new Buffer(item));
-+    });
-+    test.done();
-+  },
-+  streams2: function(test) {
-+    var expected = [ 'line1\n', 'line2\n' ];
-+    var actual = [];
-+    var instantiated = false;
-+
-+    test.expect(2);
-+
-+    var writable = new Writable(function() {
-+      instantiated = true;
-+      return new DummyWritable(actual);
-+    });
-+
-+    test.equal(instantiated, false, 'DummyWritable should only be instantiated when it is needed');
-+
-+    writable.on('end', function() {
-+      test.equal(actual.join(''), expected.join(''), 'Writable should not change the data of the underlying stream');
-+      test.done();
-+    });
-+
-+    expected.forEach(function(item) {
-+      writable.write(new Buffer(item));
-+    });
-+    writable.end();
-+  }
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/LICENSE.txt
-@@ -0,0 +1,22 @@
-+Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
-+Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas,
-+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
-+
-+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.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/README.md
-@@ -0,0 +1,163 @@
-+# Lo-Dash v2.4.1
-+A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features).
-+
-+## Download
-+
-+Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds.
-+
-+* Modern builds perfect for newer browsers/environments:<br>
-+[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) &
-+[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js)
-+
-+* Compatibility builds for older environment support too:<br>
-+[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) &
-+[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js)
-+
-+* Underscore builds to use as a drop-in replacement:<br>
-+[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) &
-+[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js)
-+
-+CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed.
-+
-+Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method.
-+
-+## Dive in
-+
-+There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).<br>
-+Check out <a href="http://devdocs.io/lodash/">DevDocs</a> as a fast, organized, & searchable interface for our documentation.
-+
-+The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).<br>
-+A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap).
-+
-+## Features *not* in Underscore
-+
-+ * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.)
-+ * [_(…)](http://lodash.com/docs#_) supports intuitive chaining
-+ * [_.at](http://lodash.com/docs#at) for cherry-picking collection values
-+ * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods
-+ * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects
-+ * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects
-+ * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions
-+ * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex`
-+ * [_.create](http://lodash.com/docs#create) for easier object inheritance
-+ * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins
-+ * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions
-+ * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control
-+ * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys
-+ * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early
-+ * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties
-+ * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties
-+ * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object`
-+ * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object
-+ * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions
-+ * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend)
-+ * [_.noop](http://lodash.com/docs#noop) for function placeholders
-+ * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative
-+ * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior
-+ * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays
-+ * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers
-+ * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking
-+ * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties
-+ * [_.support](http://lodash.com/docs#support) for flagging environment features
-+ * [_.template](http://lodash.com/docs#template) supports [*“imports”*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals)
-+ * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects
-+ * [_.where](http://lodash.com/docs#where) supports deep object comparisons
-+ * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union)
-+ * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values
-+ * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), &
-+   [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks
-+ * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), &
-+   [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings
-+ * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), &
-+   [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands
-+ * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), &
-+   [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods
-+
-+## Resources
-+
-+ * Podcasts
-+  - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/)
-+
-+ * Posts
-+  - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
-+  - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/)
-+
-+ * Videos
-+  - [Introduction](https://vimeo.com/44154599)
-+  - [Origins](https://vimeo.com/44154600)
-+  - [Optimizations & builds](https://vimeo.com/44154601)
-+  - [Native method use](https://vimeo.com/48576012)
-+  - [Testing](https://vimeo.com/45865290)
-+  - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk)
-+
-+ A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources).
-+
-+## Support
-+
-+Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.<br>
-+Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash).
-+
-+Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.<br>
-+[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More")
-+
-+## Installation & usage
-+
-+In browsers:
-+
-+```html
-+<script src="lodash.js"></script>
-+```
-+
-+Using [`npm`](http://npmjs.org/):
-+
-+```bash
-+npm i --save lodash
-+
-+{sudo} npm i -g lodash
-+npm ln lodash
-+```
-+
-+In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):
-+
-+```js
-+var _ = require('lodash');
-+// or as Underscore
-+var _ = require('lodash/dist/lodash.underscore');
-+```
-+
-+**Notes:**
-+ * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL
-+ * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it
-+
-+In [Rhino](http://www.mozilla.org/rhino/):
-+
-+```js
-+load('lodash.js');
-+```
-+
-+In an AMD loader:
-+
-+```js
-+require({
-+  'packages': [
-+    { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }
-+  ]
-+},
-+['lodash'], function(_) {
-+  console.log(_.VERSION);
-+});
-+```
-+
-+## Author
-+
-+| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") |
-+|---|
-+| [John-David Dalton](http://allyoucanleet.com/) |
-+
-+## Contributors
-+
-+| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
-+|---|---|---|
-+| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |
-+
-+[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.compat.js
-@@ -0,0 +1,7157 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
-+ * Build: `lodash -o ./dist/lodash.compat.js`
-+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
-+ * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
-+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+ * Available under MIT license <http://lodash.com/license>
-+ */
-+;(function() {
-+
-+  /** Used as a safe reference for `undefined` in pre ES5 environments */
-+  var undefined;
-+
-+  /** Used to pool arrays and objects used internally */
-+  var arrayPool = [],
-+      objectPool = [];
-+
-+  /** Used to generate unique IDs */
-+  var idCounter = 0;
-+
-+  /** Used internally to indicate various things */
-+  var indicatorObject = {};
-+
-+  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
-+  var keyPrefix = +new Date + '';
-+
-+  /** Used as the size when optimizations are enabled for large arrays */
-+  var largeArraySize = 75;
-+
-+  /** Used as the max size of the `arrayPool` and `objectPool` */
-+  var maxPoolSize = 40;
-+
-+  /** Used to detect and test whitespace */
-+  var whitespace = (
-+    // whitespace
-+    ' \t\x0B\f\xA0\ufeff' +
-+
-+    // line terminators
-+    '\n\r\u2028\u2029' +
-+
-+    // unicode category "Zs" space separators
-+    '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-+  );
-+
-+  /** Used to match empty string literals in compiled template source */
-+  var reEmptyStringLeading = /\b__p \+= '';/g,
-+      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
-+      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-+
-+  /**
-+   * Used to match ES6 template delimiters
-+   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
-+   */
-+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-+
-+  /** Used to match regexp flags from their coerced string values */
-+  var reFlags = /\w*$/;
-+
-+  /** Used to detected named functions */
-+  var reFuncName = /^\s*function[ \n\r\t]+\w/;
-+
-+  /** Used to match "interpolate" template delimiters */
-+  var reInterpolate = /<%=([\s\S]+?)%>/g;
-+
-+  /** Used to match leading whitespace and zeros to be removed */
-+  var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-+
-+  /** Used to ensure capturing order of template delimiters */
-+  var reNoMatch = /($^)/;
-+
-+  /** Used to detect functions containing a `this` reference */
-+  var reThis = /\bthis\b/;
-+
-+  /** Used to match unescaped characters in compiled string literals */
-+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-+
-+  /** Used to assign default `context` object properties */
-+  var contextProps = [
-+    'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
-+    'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
-+    'parseInt', 'setTimeout'
-+  ];
-+
-+  /** Used to fix the JScript [[DontEnum]] bug */
-+  var shadowedProps = [
-+    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
-+    'toLocaleString', 'toString', 'valueOf'
-+  ];
-+
-+  /** Used to make template sourceURLs easier to identify */
-+  var templateCounter = 0;
-+
-+  /** `Object#toString` result shortcuts */
-+  var argsClass = '[object Arguments]',
-+      arrayClass = '[object Array]',
-+      boolClass = '[object Boolean]',
-+      dateClass = '[object Date]',
-+      errorClass = '[object Error]',
-+      funcClass = '[object Function]',
-+      numberClass = '[object Number]',
-+      objectClass = '[object Object]',
-+      regexpClass = '[object RegExp]',
-+      stringClass = '[object String]';
-+
-+  /** Used to identify object classifications that `_.clone` supports */
-+  var cloneableClasses = {};
-+  cloneableClasses[funcClass] = false;
-+  cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
-+  cloneableClasses[boolClass] = cloneableClasses[dateClass] =
-+  cloneableClasses[numberClass] = cloneableClasses[objectClass] =
-+  cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-+
-+  /** Used as an internal `_.debounce` options object */
-+  var debounceOptions = {
-+    'leading': false,
-+    'maxWait': 0,
-+    'trailing': false
-+  };
-+
-+  /** Used as the property descriptor for `__bindData__` */
-+  var descriptor = {
-+    'configurable': false,
-+    'enumerable': false,
-+    'value': null,
-+    'writable': false
-+  };
-+
-+  /** Used as the data object for `iteratorTemplate` */
-+  var iteratorData = {
-+    'args': '',
-+    'array': null,
-+    'bottom': '',
-+    'firstArg': '',
-+    'init': '',
-+    'keys': null,
-+    'loop': '',
-+    'shadowedProps': null,
-+    'support': null,
-+    'top': '',
-+    'useHas': false
-+  };
-+
-+  /** Used to determine if values are of the language type Object */
-+  var objectTypes = {
-+    'boolean': false,
-+    'function': true,
-+    'object': true,
-+    'number': false,
-+    'string': false,
-+    'undefined': false
-+  };
-+
-+  /** Used to escape characters for inclusion in compiled string literals */
-+  var stringEscapes = {
-+    '\\': '\\',
-+    "'": "'",
-+    '\n': 'n',
-+    '\r': 'r',
-+    '\t': 't',
-+    '\u2028': 'u2028',
-+    '\u2029': 'u2029'
-+  };
-+
-+  /** Used as a reference to the global object */
-+  var root = (objectTypes[typeof window] && window) || this;
-+
-+  /** Detect free variable `exports` */
-+  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-+
-+  /** Detect free variable `module` */
-+  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-+
-+  /** Detect the popular CommonJS extension `module.exports` */
-+  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-+
-+  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
-+  var freeGlobal = objectTypes[typeof global] && global;
-+  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
-+    root = freeGlobal;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * The base implementation of `_.indexOf` without support for binary searches
-+   * or `fromIndex` constraints.
-+   *
-+   * @private
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {number} [fromIndex=0] The index to search from.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   */
-+  function baseIndexOf(array, value, fromIndex) {
-+    var index = (fromIndex || 0) - 1,
-+        length = array ? array.length : 0;
-+
-+    while (++index < length) {
-+      if (array[index] === value) {
-+        return index;
-+      }
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * An implementation of `_.contains` for cache objects that mimics the return
-+   * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
-+   *
-+   * @private
-+   * @param {Object} cache The cache object to inspect.
-+   * @param {*} value The value to search for.
-+   * @returns {number} Returns `0` if `value` is found, else `-1`.
-+   */
-+  function cacheIndexOf(cache, value) {
-+    var type = typeof value;
-+    cache = cache.cache;
-+
-+    if (type == 'boolean' || value == null) {
-+      return cache[value] ? 0 : -1;
-+    }
-+    if (type != 'number' && type != 'string') {
-+      type = 'object';
-+    }
-+    var key = type == 'number' ? value : keyPrefix + value;
-+    cache = (cache = cache[type]) && cache[key];
-+
-+    return type == 'object'
-+      ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
-+      : (cache ? 0 : -1);
-+  }
-+
-+  /**
-+   * Adds a given value to the corresponding cache object.
-+   *
-+   * @private
-+   * @param {*} value The value to add to the cache.
-+   */
-+  function cachePush(value) {
-+    var cache = this.cache,
-+        type = typeof value;
-+
-+    if (type == 'boolean' || value == null) {
-+      cache[value] = true;
-+    } else {
-+      if (type != 'number' && type != 'string') {
-+        type = 'object';
-+      }
-+      var key = type == 'number' ? value : keyPrefix + value,
-+          typeCache = cache[type] || (cache[type] = {});
-+
-+      if (type == 'object') {
-+        (typeCache[key] || (typeCache[key] = [])).push(value);
-+      } else {
-+        typeCache[key] = true;
-+      }
-+    }
-+  }
-+
-+  /**
-+   * Used by `_.max` and `_.min` as the default callback when a given
-+   * collection is a string value.
-+   *
-+   * @private
-+   * @param {string} value The character to inspect.
-+   * @returns {number} Returns the code unit of given character.
-+   */
-+  function charAtCallback(value) {
-+    return value.charCodeAt(0);
-+  }
-+
-+  /**
-+   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
-+   * them in ascending order.
-+   *
-+   * @private
-+   * @param {Object} a The object to compare to `b`.
-+   * @param {Object} b The object to compare to `a`.
-+   * @returns {number} Returns the sort order indicator of `1` or `-1`.
-+   */
-+  function compareAscending(a, b) {
-+    var ac = a.criteria,
-+        bc = b.criteria,
-+        index = -1,
-+        length = ac.length;
-+
-+    while (++index < length) {
-+      var value = ac[index],
-+          other = bc[index];
-+
-+      if (value !== other) {
-+        if (value > other || typeof value == 'undefined') {
-+          return 1;
-+        }
-+        if (value < other || typeof other == 'undefined') {
-+          return -1;
-+        }
-+      }
-+    }
-+    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-+    // that causes it, under certain circumstances, to return the same value for
-+    // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
-+    //
-+    // This also ensures a stable sort in V8 and other engines.
-+    // See http://code.google.com/p/v8/issues/detail?id=90
-+    return a.index - b.index;
-+  }
-+
-+  /**
-+   * Creates a cache object to optimize linear searches of large arrays.
-+   *
-+   * @private
-+   * @param {Array} [array=[]] The array to search.
-+   * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
-+   */
-+  function createCache(array) {
-+    var index = -1,
-+        length = array.length,
-+        first = array[0],
-+        mid = array[(length / 2) | 0],
-+        last = array[length - 1];
-+
-+    if (first && typeof first == 'object' &&
-+        mid && typeof mid == 'object' && last && typeof last == 'object') {
-+      return false;
-+    }
-+    var cache = getObject();
-+    cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-+
-+    var result = getObject();
-+    result.array = array;
-+    result.cache = cache;
-+    result.push = cachePush;
-+
-+    while (++index < length) {
-+      result.push(array[index]);
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Used by `template` to escape characters for inclusion in compiled
-+   * string literals.
-+   *
-+   * @private
-+   * @param {string} match The matched character to escape.
-+   * @returns {string} Returns the escaped character.
-+   */
-+  function escapeStringChar(match) {
-+    return '\\' + stringEscapes[match];
-+  }
-+
-+  /**
-+   * Gets an array from the array pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Array} The array from the pool.
-+   */
-+  function getArray() {
-+    return arrayPool.pop() || [];
-+  }
-+
-+  /**
-+   * Gets an object from the object pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Object} The object from the pool.
-+   */
-+  function getObject() {
-+    return objectPool.pop() || {
-+      'array': null,
-+      'cache': null,
-+      'criteria': null,
-+      'false': false,
-+      'index': 0,
-+      'null': false,
-+      'number': null,
-+      'object': null,
-+      'push': null,
-+      'string': null,
-+      'true': false,
-+      'undefined': false,
-+      'value': null
-+    };
-+  }
-+
-+  /**
-+   * Checks if `value` is a DOM node in IE < 9.
-+   *
-+   * @private
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
-+   */
-+  function isNode(value) {
-+    // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
-+    // methods that are `typeof` "string" and still can coerce nodes to strings
-+    return typeof value.toString != 'function' && typeof (value + '') == 'string';
-+  }
-+
-+  /**
-+   * Releases the given array back to the array pool.
-+   *
-+   * @private
-+   * @param {Array} [array] The array to release.
-+   */
-+  function releaseArray(array) {
-+    array.length = 0;
-+    if (arrayPool.length < maxPoolSize) {
-+      arrayPool.push(array);
-+    }
-+  }
-+
-+  /**
-+   * Releases the given object back to the object pool.
-+   *
-+   * @private
-+   * @param {Object} [object] The object to release.
-+   */
-+  function releaseObject(object) {
-+    var cache = object.cache;
-+    if (cache) {
-+      releaseObject(cache);
-+    }
-+    object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
-+    if (objectPool.length < maxPoolSize) {
-+      objectPool.push(object);
-+    }
-+  }
-+
-+  /**
-+   * Slices the `collection` from the `start` index up to, but not including,
-+   * the `end` index.
-+   *
-+   * Note: This function is used instead of `Array#slice` to support node lists
-+   * in IE < 9 and to ensure dense arrays are returned.
-+   *
-+   * @private
-+   * @param {Array|Object|string} collection The collection to slice.
-+   * @param {number} start The start index.
-+   * @param {number} end The end index.
-+   * @returns {Array} Returns the new array.
-+   */
-+  function slice(array, start, end) {
-+    start || (start = 0);
-+    if (typeof end == 'undefined') {
-+      end = array ? array.length : 0;
-+    }
-+    var index = -1,
-+        length = end - start || 0,
-+        result = Array(length < 0 ? 0 : length);
-+
-+    while (++index < length) {
-+      result[index] = array[start + index];
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Create a new `lodash` function using the given context object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {Object} [context=root] The context object.
-+   * @returns {Function} Returns the `lodash` function.
-+   */
-+  function runInContext(context) {
-+    // Avoid issues with some ES3 environments that attempt to use values, named
-+    // after built-in constructors like `Object`, for the creation of literals.
-+    // ES5 clears this up by stating that literals must use built-in constructors.
-+    // See http://es5.github.io/#x11.1.5.
-+    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-+
-+    /** Native constructor references */
-+    var Array = context.Array,
-+        Boolean = context.Boolean,
-+        Date = context.Date,
-+        Error = context.Error,
-+        Function = context.Function,
-+        Math = context.Math,
-+        Number = context.Number,
-+        Object = context.Object,
-+        RegExp = context.RegExp,
-+        String = context.String,
-+        TypeError = context.TypeError;
-+
-+    /**
-+     * Used for `Array` method references.
-+     *
-+     * Normally `Array.prototype` would suffice, however, using an array literal
-+     * avoids issues in Narwhal.
-+     */
-+    var arrayRef = [];
-+
-+    /** Used for native method references */
-+    var errorProto = Error.prototype,
-+        objectProto = Object.prototype,
-+        stringProto = String.prototype;
-+
-+    /** Used to restore the original `_` reference in `noConflict` */
-+    var oldDash = context._;
-+
-+    /** Used to resolve the internal [[Class]] of values */
-+    var toString = objectProto.toString;
-+
-+    /** Used to detect if a method is native */
-+    var reNative = RegExp('^' +
-+      String(toString)
-+        .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-+        .replace(/toString| for [^\]]+/g, '.*?') + '$'
-+    );
-+
-+    /** Native method shortcuts */
-+    var ceil = Math.ceil,
-+        clearTimeout = context.clearTimeout,
-+        floor = Math.floor,
-+        fnToString = Function.prototype.toString,
-+        getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
-+        hasOwnProperty = objectProto.hasOwnProperty,
-+        push = arrayRef.push,
-+        propertyIsEnumerable = objectProto.propertyIsEnumerable,
-+        setTimeout = context.setTimeout,
-+        splice = arrayRef.splice,
-+        unshift = arrayRef.unshift;
-+
-+    /** Used to set meta data on functions */
-+    var defineProperty = (function() {
-+      // IE 8 only accepts DOM elements
-+      try {
-+        var o = {},
-+            func = isNative(func = Object.defineProperty) && func,
-+            result = func(o, o, o) && func;
-+      } catch(e) { }
-+      return result;
-+    }());
-+
-+    /* Native method shortcuts for methods with the same name as other `lodash` methods */
-+    var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
-+        nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
-+        nativeIsFinite = context.isFinite,
-+        nativeIsNaN = context.isNaN,
-+        nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
-+        nativeMax = Math.max,
-+        nativeMin = Math.min,
-+        nativeParseInt = context.parseInt,
-+        nativeRandom = Math.random;
-+
-+    /** Used to lookup a built-in constructor by [[Class]] */
-+    var ctorByClass = {};
-+    ctorByClass[arrayClass] = Array;
-+    ctorByClass[boolClass] = Boolean;
-+    ctorByClass[dateClass] = Date;
-+    ctorByClass[funcClass] = Function;
-+    ctorByClass[objectClass] = Object;
-+    ctorByClass[numberClass] = Number;
-+    ctorByClass[regexpClass] = RegExp;
-+    ctorByClass[stringClass] = String;
-+
-+    /** Used to avoid iterating non-enumerable properties in IE < 9 */
-+    var nonEnumProps = {};
-+    nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
-+    nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
-+    nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
-+    nonEnumProps[objectClass] = { 'constructor': true };
-+
-+    (function() {
-+      var length = shadowedProps.length;
-+      while (length--) {
-+        var key = shadowedProps[length];
-+        for (var className in nonEnumProps) {
-+          if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
-+            nonEnumProps[className][key] = false;
-+          }
-+        }
-+      }
-+    }());
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object which wraps the given value to enable intuitive
-+     * method chaining.
-+     *
-+     * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
-+     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
-+     * and `unshift`
-+     *
-+     * Chaining is supported in custom builds as long as the `value` method is
-+     * implicitly or explicitly included in the build.
-+     *
-+     * The chainable wrapper functions are:
-+     * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
-+     * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
-+     * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
-+     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
-+     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
-+     * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
-+     * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
-+     * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
-+     * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
-+     * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
-+     * and `zip`
-+     *
-+     * The non-chainable wrapper functions are:
-+     * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
-+     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
-+     * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
-+     * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
-+     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
-+     * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
-+     * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
-+     * `template`, `unescape`, `uniqueId`, and `value`
-+     *
-+     * The wrapper functions `first` and `last` return wrapped values when `n` is
-+     * provided, otherwise they return unwrapped values.
-+     *
-+     * Explicit chaining can be enabled by using the `_.chain` method.
-+     *
-+     * @name _
-+     * @constructor
-+     * @category Chaining
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @returns {Object} Returns a `lodash` instance.
-+     * @example
-+     *
-+     * var wrapped = _([1, 2, 3]);
-+     *
-+     * // returns an unwrapped value
-+     * wrapped.reduce(function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * // returns a wrapped value
-+     * var squares = wrapped.map(function(num) {
-+     *   return num * num;
-+     * });
-+     *
-+     * _.isArray(squares);
-+     * // => false
-+     *
-+     * _.isArray(squares.value());
-+     * // => true
-+     */
-+    function lodash(value) {
-+      // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
-+      return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
-+       ? value
-+       : new lodashWrapper(value);
-+    }
-+
-+    /**
-+     * A fast path for creating `lodash` wrapper objects.
-+     *
-+     * @private
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @param {boolean} chainAll A flag to enable chaining for all methods
-+     * @returns {Object} Returns a `lodash` instance.
-+     */
-+    function lodashWrapper(value, chainAll) {
-+      this.__chain__ = !!chainAll;
-+      this.__wrapped__ = value;
-+    }
-+    // ensure `new lodashWrapper` is an instance of `lodash`
-+    lodashWrapper.prototype = lodash.prototype;
-+
-+    /**
-+     * An object used to flag environments features.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    var support = lodash.support = {};
-+
-+    (function() {
-+      var ctor = function() { this.x = 1; },
-+          object = { '0': 1, 'length': 1 },
-+          props = [];
-+
-+      ctor.prototype = { 'valueOf': 1, 'y': 1 };
-+      for (var key in new ctor) { props.push(key); }
-+      for (key in arguments) { }
-+
-+      /**
-+       * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.argsClass = toString.call(arguments) == argsClass;
-+
-+      /**
-+       * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
-+
-+      /**
-+       * Detect if `name` or `message` properties of `Error.prototype` are
-+       * enumerable by default. (IE < 9, Safari < 5.1)
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
-+
-+      /**
-+       * Detect if `prototype` properties are enumerable by default.
-+       *
-+       * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
-+       * (if the prototype or a property on the prototype has been set)
-+       * incorrectly sets a function's `prototype` property [[Enumerable]]
-+       * value to `true`.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
-+
-+      /**
-+       * Detect if functions can be decompiled by `Function#toString`
-+       * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-+
-+      /**
-+       * Detect if `Function#name` is supported (all but IE).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.funcNames = typeof Function.name == 'string';
-+
-+      /**
-+       * Detect if `arguments` object indexes are non-enumerable
-+       * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.nonEnumArgs = key != 0;
-+
-+      /**
-+       * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
-+       *
-+       * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
-+       * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.nonEnumShadows = !/valueOf/.test(props);
-+
-+      /**
-+       * Detect if own properties are iterated after inherited properties (all but IE < 9).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.ownLast = props[0] != 'x';
-+
-+      /**
-+       * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
-+       *
-+       * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
-+       * and `splice()` functions that fail to remove the last element, `value[0]`,
-+       * of array-like objects even though the `length` property is set to `0`.
-+       * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
-+       * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-+
-+      /**
-+       * Detect lack of support for accessing string characters by index.
-+       *
-+       * IE < 8 can't access characters by index and IE 8 can only access
-+       * characters by index on string literals.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
-+
-+      /**
-+       * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
-+       * and that the JS engine errors when attempting to coerce an object to
-+       * a string without a `toString` function.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      try {
-+        support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
-+      } catch(e) {
-+        support.nodeClass = true;
-+      }
-+    }(1));
-+
-+    /**
-+     * By default, the template delimiters used by Lo-Dash are similar to those in
-+     * embedded Ruby (ERB). Change the following template settings to use alternative
-+     * delimiters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    lodash.templateSettings = {
-+
-+      /**
-+       * Used to detect `data` property values to be HTML-escaped.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'escape': /<%-([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect code to be evaluated.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'evaluate': /<%([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect `data` property values to inject.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'interpolate': reInterpolate,
-+
-+      /**
-+       * Used to reference the data object in the template text.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type string
-+       */
-+      'variable': '',
-+
-+      /**
-+       * Used to import variables into the compiled template.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type Object
-+       */
-+      'imports': {
-+
-+        /**
-+         * A reference to the `lodash` function.
-+         *
-+         * @memberOf _.templateSettings.imports
-+         * @type Function
-+         */
-+        '_': lodash
-+      }
-+    };
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The template used to create iterator functions.
-+     *
-+     * @private
-+     * @param {Object} data The data object used to populate the text.
-+     * @returns {string} Returns the interpolated text.
-+     */
-+    var iteratorTemplate = function(obj) {
-+
-+      var __p = 'var index, iterable = ' +
-+      (obj.firstArg) +
-+      ', result = ' +
-+      (obj.init) +
-+      ';\nif (!iterable) return result;\n' +
-+      (obj.top) +
-+      ';';
-+       if (obj.array) {
-+      __p += '\nvar length = iterable.length; index = -1;\nif (' +
-+      (obj.array) +
-+      ') {  ';
-+       if (support.unindexedChars) {
-+      __p += '\n  if (isString(iterable)) {\n    iterable = iterable.split(\'\')\n  }  ';
-+       }
-+      __p += '\n  while (++index < length) {\n    ' +
-+      (obj.loop) +
-+      ';\n  }\n}\nelse {  ';
-+       } else if (support.nonEnumArgs) {
-+      __p += '\n  var length = iterable.length; index = -1;\n  if (length && isArguments(iterable)) {\n    while (++index < length) {\n      index += \'\';\n      ' +
-+      (obj.loop) +
-+      ';\n    }\n  } else {  ';
-+       }
-+
-+       if (support.enumPrototypes) {
-+      __p += '\n  var skipProto = typeof iterable == \'function\';\n  ';
-+       }
-+
-+       if (support.enumErrorProps) {
-+      __p += '\n  var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n  ';
-+       }
-+
-+          var conditions = [];    if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); }    if (support.enumErrorProps)  { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
-+
-+       if (obj.useHas && obj.keys) {
-+      __p += '\n  var ownIndex = -1,\n      ownProps = objectTypes[typeof iterable] && keys(iterable),\n      length = ownProps ? ownProps.length : 0;\n\n  while (++ownIndex < length) {\n    index = ownProps[ownIndex];\n';
-+          if (conditions.length) {
-+      __p += '    if (' +
-+      (conditions.join(' && ')) +
-+      ') {\n  ';
-+       }
-+      __p +=
-+      (obj.loop) +
-+      ';    ';
-+       if (conditions.length) {
-+      __p += '\n    }';
-+       }
-+      __p += '\n  }  ';
-+       } else {
-+      __p += '\n  for (index in iterable) {\n';
-+          if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); }    if (conditions.length) {
-+      __p += '    if (' +
-+      (conditions.join(' && ')) +
-+      ') {\n  ';
-+       }
-+      __p +=
-+      (obj.loop) +
-+      ';    ';
-+       if (conditions.length) {
-+      __p += '\n    }';
-+       }
-+      __p += '\n  }    ';
-+       if (support.nonEnumShadows) {
-+      __p += '\n\n  if (iterable !== objectProto) {\n    var ctor = iterable.constructor,\n        isProto = iterable === (ctor && ctor.prototype),\n        className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n        nonEnum = nonEnumProps[className];\n      ';
-+       for (k = 0; k < 7; k++) {
-+      __p += '\n    index = \'' +
-+      (obj.shadowedProps[k]) +
-+      '\';\n    if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
-+              if (!obj.useHas) {
-+      __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
-+       }
-+      __p += ') {\n      ' +
-+      (obj.loop) +
-+      ';\n    }      ';
-+       }
-+      __p += '\n  }    ';
-+       }
-+
-+       }
-+
-+       if (obj.array || support.nonEnumArgs) {
-+      __p += '\n}';
-+       }
-+      __p +=
-+      (obj.bottom) +
-+      ';\nreturn result';
-+
-+      return __p
-+    };
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The base implementation of `_.bind` that creates the bound function and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new bound function.
-+     */
-+    function baseBind(bindData) {
-+      var func = bindData[0],
-+          partialArgs = bindData[2],
-+          thisArg = bindData[4];
-+
-+      function bound() {
-+        // `Function#bind` spec
-+        // http://es5.github.io/#x15.3.4.5
-+        if (partialArgs) {
-+          // avoid `arguments` object deoptimizations by using `slice` instead
-+          // of `Array.prototype.slice.call` and not assigning `arguments` to a
-+          // variable as a ternary expression
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        // mimic the constructor's `return` behavior
-+        // http://es5.github.io/#x13.2.2
-+        if (this instanceof bound) {
-+          // ensure `new bound` is an instance of `func`
-+          var thisBinding = baseCreate(func.prototype),
-+              result = func.apply(thisBinding, args || arguments);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisArg, args || arguments);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.clone` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates clones with source counterparts.
-+     * @returns {*} Returns the cloned value.
-+     */
-+    function baseClone(value, isDeep, callback, stackA, stackB) {
-+      if (callback) {
-+        var result = callback(value);
-+        if (typeof result != 'undefined') {
-+          return result;
-+        }
-+      }
-+      // inspect [[Class]]
-+      var isObj = isObject(value);
-+      if (isObj) {
-+        var className = toString.call(value);
-+        if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
-+          return value;
-+        }
-+        var ctor = ctorByClass[className];
-+        switch (className) {
-+          case boolClass:
-+          case dateClass:
-+            return new ctor(+value);
-+
-+          case numberClass:
-+          case stringClass:
-+            return new ctor(value);
-+
-+          case regexpClass:
-+            result = ctor(value.source, reFlags.exec(value));
-+            result.lastIndex = value.lastIndex;
-+            return result;
-+        }
-+      } else {
-+        return value;
-+      }
-+      var isArr = isArray(value);
-+      if (isDeep) {
-+        // check for circular references and return corresponding clone
-+        var initedStack = !stackA;
-+        stackA || (stackA = getArray());
-+        stackB || (stackB = getArray());
-+
-+        var length = stackA.length;
-+        while (length--) {
-+          if (stackA[length] == value) {
-+            return stackB[length];
-+          }
-+        }
-+        result = isArr ? ctor(value.length) : {};
-+      }
-+      else {
-+        result = isArr ? slice(value) : assign({}, value);
-+      }
-+      // add array properties assigned by `RegExp#exec`
-+      if (isArr) {
-+        if (hasOwnProperty.call(value, 'index')) {
-+          result.index = value.index;
-+        }
-+        if (hasOwnProperty.call(value, 'input')) {
-+          result.input = value.input;
-+        }
-+      }
-+      // exit for shallow clone
-+      if (!isDeep) {
-+        return result;
-+      }
-+      // add the source value to the stack of traversed objects
-+      // and associate it with its clone
-+      stackA.push(value);
-+      stackB.push(result);
-+
-+      // recursively populate clone (susceptible to call stack limits)
-+      (isArr ? baseEach : forOwn)(value, function(objValue, key) {
-+        result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
-+      });
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.create` without support for assigning
-+     * properties to the created object.
-+     *
-+     * @private
-+     * @param {Object} prototype The object to inherit from.
-+     * @returns {Object} Returns the new object.
-+     */
-+    function baseCreate(prototype, properties) {
-+      return isObject(prototype) ? nativeCreate(prototype) : {};
-+    }
-+    // fallback for browsers without `Object.create`
-+    if (!nativeCreate) {
-+      baseCreate = (function() {
-+        function Object() {}
-+        return function(prototype) {
-+          if (isObject(prototype)) {
-+            Object.prototype = prototype;
-+            var result = new Object;
-+            Object.prototype = null;
-+          }
-+          return result || context.Object();
-+        };
-+      }());
-+    }
-+
-+    /**
-+     * The base implementation of `_.createCallback` without support for creating
-+     * "_.pluck" or "_.where" style callbacks.
-+     *
-+     * @private
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     */
-+    function baseCreateCallback(func, thisArg, argCount) {
-+      if (typeof func != 'function') {
-+        return identity;
-+      }
-+      // exit early for no `thisArg` or already bound by `Function#bind`
-+      if (typeof thisArg == 'undefined' || !('prototype' in func)) {
-+        return func;
-+      }
-+      var bindData = func.__bindData__;
-+      if (typeof bindData == 'undefined') {
-+        if (support.funcNames) {
-+          bindData = !func.name;
-+        }
-+        bindData = bindData || !support.funcDecomp;
-+        if (!bindData) {
-+          var source = fnToString.call(func);
-+          if (!support.funcNames) {
-+            bindData = !reFuncName.test(source);
-+          }
-+          if (!bindData) {
-+            // checks if `func` references the `this` keyword and stores the result
-+            bindData = reThis.test(source);
-+            setBindData(func, bindData);
-+          }
-+        }
-+      }
-+      // exit early if there are no `this` references or `func` is bound
-+      if (bindData === false || (bindData !== true && bindData[1] & 1)) {
-+        return func;
-+      }
-+      switch (argCount) {
-+        case 1: return function(value) {
-+          return func.call(thisArg, value);
-+        };
-+        case 2: return function(a, b) {
-+          return func.call(thisArg, a, b);
-+        };
-+        case 3: return function(value, index, collection) {
-+          return func.call(thisArg, value, index, collection);
-+        };
-+        case 4: return function(accumulator, value, index, collection) {
-+          return func.call(thisArg, accumulator, value, index, collection);
-+        };
-+      }
-+      return bind(func, thisArg);
-+    }
-+
-+    /**
-+     * The base implementation of `createWrapper` that creates the wrapper and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function baseCreateWrapper(bindData) {
-+      var func = bindData[0],
-+          bitmask = bindData[1],
-+          partialArgs = bindData[2],
-+          partialRightArgs = bindData[3],
-+          thisArg = bindData[4],
-+          arity = bindData[5];
-+
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          key = func;
-+
-+      function bound() {
-+        var thisBinding = isBind ? thisArg : this;
-+        if (partialArgs) {
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        if (partialRightArgs || isCurry) {
-+          args || (args = slice(arguments));
-+          if (partialRightArgs) {
-+            push.apply(args, partialRightArgs);
-+          }
-+          if (isCurry && args.length < arity) {
-+            bitmask |= 16 & ~32;
-+            return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
-+          }
-+        }
-+        args || (args = arguments);
-+        if (isBindKey) {
-+          func = thisBinding[key];
-+        }
-+        if (this instanceof bound) {
-+          thisBinding = baseCreate(func.prototype);
-+          var result = func.apply(thisBinding, args);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisBinding, args);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.difference` that accepts a single array
-+     * of values to exclude.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {Array} [values] The array of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     */
-+    function baseDifference(array, values) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          isLarge = length >= largeArraySize && indexOf === baseIndexOf,
-+          result = [];
-+
-+      if (isLarge) {
-+        var cache = createCache(values);
-+        if (cache) {
-+          indexOf = cacheIndexOf;
-+          values = cache;
-+        } else {
-+          isLarge = false;
-+        }
-+      }
-+      while (++index < length) {
-+        var value = array[index];
-+        if (indexOf(values, value) < 0) {
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseObject(values);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.flatten` without support for callback
-+     * shorthands or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
-+     * @param {number} [fromIndex=0] The index to start from.
-+     * @returns {Array} Returns a new flattened array.
-+     */
-+    function baseFlatten(array, isShallow, isStrict, fromIndex) {
-+      var index = (fromIndex || 0) - 1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+
-+        if (value && typeof value == 'object' && typeof value.length == 'number'
-+            && (isArray(value) || isArguments(value))) {
-+          // recursively flatten arrays (susceptible to call stack limits)
-+          if (!isShallow) {
-+            value = baseFlatten(value, isShallow, isStrict);
-+          }
-+          var valIndex = -1,
-+              valLength = value.length,
-+              resIndex = result.length;
-+
-+          result.length += valLength;
-+          while (++valIndex < valLength) {
-+            result[resIndex++] = value[valIndex];
-+          }
-+        } else if (!isStrict) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.isEqual`, without support for `thisArg` binding,
-+     * that allows partial "_.where" style comparisons.
-+     *
-+     * @private
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
-+     * @param {Array} [stackA=[]] Tracks traversed `a` objects.
-+     * @param {Array} [stackB=[]] Tracks traversed `b` objects.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     */
-+    function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
-+      // used to indicate that when comparing objects, `a` has at least the properties of `b`
-+      if (callback) {
-+        var result = callback(a, b);
-+        if (typeof result != 'undefined') {
-+          return !!result;
-+        }
-+      }
-+      // exit early for identical values
-+      if (a === b) {
-+        // treat `+0` vs. `-0` as not equal
-+        return a !== 0 || (1 / a == 1 / b);
-+      }
-+      var type = typeof a,
-+          otherType = typeof b;
-+
-+      // exit early for unlike primitive values
-+      if (a === a &&
-+          !(a && objectTypes[type]) &&
-+          !(b && objectTypes[otherType])) {
-+        return false;
-+      }
-+      // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
-+      // http://es5.github.io/#x15.3.4.4
-+      if (a == null || b == null) {
-+        return a === b;
-+      }
-+      // compare [[Class]] names
-+      var className = toString.call(a),
-+          otherClass = toString.call(b);
-+
-+      if (className == argsClass) {
-+        className = objectClass;
-+      }
-+      if (otherClass == argsClass) {
-+        otherClass = objectClass;
-+      }
-+      if (className != otherClass) {
-+        return false;
-+      }
-+      switch (className) {
-+        case boolClass:
-+        case dateClass:
-+          // coerce dates and booleans to numbers, dates to milliseconds and booleans
-+          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
-+          return +a == +b;
-+
-+        case numberClass:
-+          // treat `NaN` vs. `NaN` as equal
-+          return (a != +a)
-+            ? b != +b
-+            // but treat `+0` vs. `-0` as not equal
-+            : (a == 0 ? (1 / a == 1 / b) : a == +b);
-+
-+        case regexpClass:
-+        case stringClass:
-+          // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
-+          // treat string primitives and their corresponding object instances as equal
-+          return a == String(b);
-+      }
-+      var isArr = className == arrayClass;
-+      if (!isArr) {
-+        // unwrap any `lodash` wrapped values
-+        var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
-+            bWrapped = hasOwnProperty.call(b, '__wrapped__');
-+
-+        if (aWrapped || bWrapped) {
-+          return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
-+        }
-+        // exit for functions and DOM nodes
-+        if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
-+          return false;
-+        }
-+        // in older versions of Opera, `arguments` objects have `Array` constructors
-+        var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
-+            ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
-+
-+        // non `Object` object instances with different constructors are not equal
-+        if (ctorA != ctorB &&
-+              !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
-+              ('constructor' in a && 'constructor' in b)
-+            ) {
-+          return false;
-+        }
-+      }
-+      // assume cyclic structures are equal
-+      // the algorithm for detecting cyclic structures is adapted from ES 5.1
-+      // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
-+      var initedStack = !stackA;
-+      stackA || (stackA = getArray());
-+      stackB || (stackB = getArray());
-+
-+      var length = stackA.length;
-+      while (length--) {
-+        if (stackA[length] == a) {
-+          return stackB[length] == b;
-+        }
-+      }
-+      var size = 0;
-+      result = true;
-+
-+      // add `a` and `b` to the stack of traversed objects
-+      stackA.push(a);
-+      stackB.push(b);
-+
-+      // recursively compare objects and arrays (susceptible to call stack limits)
-+      if (isArr) {
-+        // compare lengths to determine if a deep comparison is necessary
-+        length = a.length;
-+        size = b.length;
-+        result = size == length;
-+
-+        if (result || isWhere) {
-+          // deep compare the contents, ignoring non-numeric properties
-+          while (size--) {
-+            var index = length,
-+                value = b[size];
-+
-+            if (isWhere) {
-+              while (index--) {
-+                if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
-+                  break;
-+                }
-+              }
-+            } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
-+              break;
-+            }
-+          }
-+        }
-+      }
-+      else {
-+        // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
-+        // which, in this case, is more costly
-+        forIn(b, function(value, key, b) {
-+          if (hasOwnProperty.call(b, key)) {
-+            // count the number of properties.
-+            size++;
-+            // deep compare each property value.
-+            return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
-+          }
-+        });
-+
-+        if (result && !isWhere) {
-+          // ensure both objects have the same number of properties
-+          forIn(a, function(value, key, a) {
-+            if (hasOwnProperty.call(a, key)) {
-+              // `size` will be `-1` if `a` has more properties than `b`
-+              return (result = --size > -1);
-+            }
-+          });
-+        }
-+      }
-+      stackA.pop();
-+      stackB.pop();
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.merge` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Object} object The destination object.
-+     * @param {Object} source The source object.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates values with source counterparts.
-+     */
-+    function baseMerge(object, source, callback, stackA, stackB) {
-+      (isArray(source) ? forEach : forOwn)(source, function(source, key) {
-+        var found,
-+            isArr,
-+            result = source,
-+            value = object[key];
-+
-+        if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
-+          // avoid merging previously merged cyclic sources
-+          var stackLength = stackA.length;
-+          while (stackLength--) {
-+            if ((found = stackA[stackLength] == source)) {
-+              value = stackB[stackLength];
-+              break;
-+            }
-+          }
-+          if (!found) {
-+            var isShallow;
-+            if (callback) {
-+              result = callback(value, source);
-+              if ((isShallow = typeof result != 'undefined')) {
-+                value = result;
-+              }
-+            }
-+            if (!isShallow) {
-+              value = isArr
-+                ? (isArray(value) ? value : [])
-+                : (isPlainObject(value) ? value : {});
-+            }
-+            // add `source` and associated `value` to the stack of traversed objects
-+            stackA.push(source);
-+            stackB.push(value);
-+
-+            // recursively merge objects and arrays (susceptible to call stack limits)
-+            if (!isShallow) {
-+              baseMerge(value, source, callback, stackA, stackB);
-+            }
-+          }
-+        }
-+        else {
-+          if (callback) {
-+            result = callback(value, source);
-+            if (typeof result == 'undefined') {
-+              result = source;
-+            }
-+          }
-+          if (typeof result != 'undefined') {
-+            value = result;
-+          }
-+        }
-+        object[key] = value;
-+      });
-+    }
-+
-+    /**
-+     * The base implementation of `_.random` without argument juggling or support
-+     * for returning floating-point numbers.
-+     *
-+     * @private
-+     * @param {number} min The minimum possible value.
-+     * @param {number} max The maximum possible value.
-+     * @returns {number} Returns a random number.
-+     */
-+    function baseRandom(min, max) {
-+      return min + floor(nativeRandom() * (max - min + 1));
-+    }
-+
-+    /**
-+     * The base implementation of `_.uniq` without support for callback shorthands
-+     * or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function} [callback] The function called per iteration.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     */
-+    function baseUniq(array, isSorted, callback) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
-+          seen = (callback || isLarge) ? getArray() : result;
-+
-+      if (isLarge) {
-+        var cache = createCache(seen);
-+        indexOf = cacheIndexOf;
-+        seen = cache;
-+      }
-+      while (++index < length) {
-+        var value = array[index],
-+            computed = callback ? callback(value, index, array) : value;
-+
-+        if (isSorted
-+              ? !index || seen[seen.length - 1] !== computed
-+              : indexOf(seen, computed) < 0
-+            ) {
-+          if (callback || isLarge) {
-+            seen.push(computed);
-+          }
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseArray(seen.array);
-+        releaseObject(seen);
-+      } else if (callback) {
-+        releaseArray(seen);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a function that aggregates a collection, creating an object composed
-+     * of keys generated from the results of running each element of the collection
-+     * through a callback. The given `setter` function sets the keys and values
-+     * of the composed object.
-+     *
-+     * @private
-+     * @param {Function} setter The setter function.
-+     * @returns {Function} Returns the new aggregator function.
-+     */
-+    function createAggregator(setter) {
-+      return function(collection, callback, thisArg) {
-+        var result = {};
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+
-+        if (isArray(collection)) {
-+          var index = -1,
-+              length = collection.length;
-+
-+          while (++index < length) {
-+            var value = collection[index];
-+            setter(result, value, callback(value, index, collection), collection);
-+          }
-+        } else {
-+          baseEach(collection, function(value, key, collection) {
-+            setter(result, value, callback(value, key, collection), collection);
-+          });
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, either curries or invokes `func`
-+     * with an optional `this` binding and partially applied arguments.
-+     *
-+     * @private
-+     * @param {Function|string} func The function or method name to reference.
-+     * @param {number} bitmask The bitmask of method flags to compose.
-+     *  The bitmask may be composed of the following flags:
-+     *  1 - `_.bind`
-+     *  2 - `_.bindKey`
-+     *  4 - `_.curry`
-+     *  8 - `_.curry` (bound)
-+     *  16 - `_.partial`
-+     *  32 - `_.partialRight`
-+     * @param {Array} [partialArgs] An array of arguments to prepend to those
-+     *  provided to the new function.
-+     * @param {Array} [partialRightArgs] An array of arguments to append to those
-+     *  provided to the new function.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {number} [arity] The arity of `func`.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          isPartial = bitmask & 16,
-+          isPartialRight = bitmask & 32;
-+
-+      if (!isBindKey && !isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (isPartial && !partialArgs.length) {
-+        bitmask &= ~16;
-+        isPartial = partialArgs = false;
-+      }
-+      if (isPartialRight && !partialRightArgs.length) {
-+        bitmask &= ~32;
-+        isPartialRight = partialRightArgs = false;
-+      }
-+      var bindData = func && func.__bindData__;
-+      if (bindData && bindData !== true) {
-+        // clone `bindData`
-+        bindData = slice(bindData);
-+        if (bindData[2]) {
-+          bindData[2] = slice(bindData[2]);
-+        }
-+        if (bindData[3]) {
-+          bindData[3] = slice(bindData[3]);
-+        }
-+        // set `thisBinding` is not previously bound
-+        if (isBind && !(bindData[1] & 1)) {
-+          bindData[4] = thisArg;
-+        }
-+        // set if previously bound but not currently (subsequent curried functions)
-+        if (!isBind && bindData[1] & 1) {
-+          bitmask |= 8;
-+        }
-+        // set curried arity if not yet set
-+        if (isCurry && !(bindData[1] & 4)) {
-+          bindData[5] = arity;
-+        }
-+        // append partial left arguments
-+        if (isPartial) {
-+          push.apply(bindData[2] || (bindData[2] = []), partialArgs);
-+        }
-+        // append partial right arguments
-+        if (isPartialRight) {
-+          unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
-+        }
-+        // merge flags
-+        bindData[1] |= bitmask;
-+        return createWrapper.apply(null, bindData);
-+      }
-+      // fast path for `_.bind`
-+      var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
-+      return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
-+    }
-+
-+    /**
-+     * Creates compiled iteration functions.
-+     *
-+     * @private
-+     * @param {...Object} [options] The compile options object(s).
-+     * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
-+     * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
-+     * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
-+     * @param {string} [options.args] A comma separated string of iteration function arguments.
-+     * @param {string} [options.top] Code to execute before the iteration branches.
-+     * @param {string} [options.loop] Code to execute in the object loop.
-+     * @param {string} [options.bottom] Code to execute after the iteration branches.
-+     * @returns {Function} Returns the compiled function.
-+     */
-+    function createIterator() {
-+      // data properties
-+      iteratorData.shadowedProps = shadowedProps;
-+
-+      // iterator options
-+      iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
-+      iteratorData.init = 'iterable';
-+      iteratorData.useHas = true;
-+
-+      // merge options into a template data object
-+      for (var object, index = 0; object = arguments[index]; index++) {
-+        for (var key in object) {
-+          iteratorData[key] = object[key];
-+        }
-+      }
-+      var args = iteratorData.args;
-+      iteratorData.firstArg = /^[^,]+/.exec(args)[0];
-+
-+      // create the function factory
-+      var factory = Function(
-+          'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
-+          'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
-+          'objectTypes, nonEnumProps, stringClass, stringProto, toString',
-+        'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
-+      );
-+
-+      // return the compiled function
-+      return factory(
-+        baseCreateCallback, errorClass, errorProto, hasOwnProperty,
-+        indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
-+        objectTypes, nonEnumProps, stringClass, stringProto, toString
-+      );
-+    }
-+
-+    /**
-+     * Used by `escape` to convert characters to HTML entities.
-+     *
-+     * @private
-+     * @param {string} match The matched character to escape.
-+     * @returns {string} Returns the escaped character.
-+     */
-+    function escapeHtmlChar(match) {
-+      return htmlEscapes[match];
-+    }
-+
-+    /**
-+     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
-+     * customized, this method returns the custom method, otherwise it returns
-+     * the `baseIndexOf` function.
-+     *
-+     * @private
-+     * @returns {Function} Returns the "indexOf" function.
-+     */
-+    function getIndexOf() {
-+      var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a native function.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
-+     */
-+    function isNative(value) {
-+      return typeof value == 'function' && reNative.test(value);
-+    }
-+
-+    /**
-+     * Sets `this` binding data on a given function.
-+     *
-+     * @private
-+     * @param {Function} func The function to set data on.
-+     * @param {Array} value The data array to set.
-+     */
-+    var setBindData = !defineProperty ? noop : function(func, value) {
-+      descriptor.value = value;
-+      defineProperty(func, '__bindData__', descriptor);
-+    };
-+
-+    /**
-+     * A fallback implementation of `isPlainObject` which checks if a given value
-+     * is an object created by the `Object` constructor, assuming objects created
-+     * by the `Object` constructor have no inherited enumerable properties and that
-+     * there are no `Object.prototype` extensions.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     */
-+    function shimIsPlainObject(value) {
-+      var ctor,
-+          result;
-+
-+      // avoid non Object objects, `arguments` objects, and DOM elements
-+      if (!(value && toString.call(value) == objectClass) ||
-+          (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
-+          (!support.argsClass && isArguments(value)) ||
-+          (!support.nodeClass && isNode(value))) {
-+        return false;
-+      }
-+      // IE < 9 iterates inherited properties before own properties. If the first
-+      // iterated property is an object's own property then there are no inherited
-+      // enumerable properties.
-+      if (support.ownLast) {
-+        forIn(value, function(value, key, object) {
-+          result = hasOwnProperty.call(object, key);
-+          return false;
-+        });
-+        return result !== false;
-+      }
-+      // In most environments an object's own properties are iterated before
-+      // its inherited properties. If the last iterated property is an object's
-+      // own property then there are no inherited enumerable properties.
-+      forIn(value, function(value, key) {
-+        result = key;
-+      });
-+      return typeof result == 'undefined' || hasOwnProperty.call(value, result);
-+    }
-+
-+    /**
-+     * Used by `unescape` to convert HTML entities to characters.
-+     *
-+     * @private
-+     * @param {string} match The matched character to unescape.
-+     * @returns {string} Returns the unescaped character.
-+     */
-+    function unescapeHtmlChar(match) {
-+      return htmlUnescapes[match];
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Checks if `value` is an `arguments` object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArguments(arguments); })(1, 2, 3);
-+     * // => true
-+     *
-+     * _.isArguments([1, 2, 3]);
-+     * // => false
-+     */
-+    function isArguments(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == argsClass || false;
-+    }
-+    // fallback for browsers that can't detect `arguments` objects by [[Class]]
-+    if (!support.argsClass) {
-+      isArguments = function(value) {
-+        return value && typeof value == 'object' && typeof value.length == 'number' &&
-+          hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
-+      };
-+    }
-+
-+    /**
-+     * Checks if `value` is an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArray(arguments); })();
-+     * // => false
-+     *
-+     * _.isArray([1, 2, 3]);
-+     * // => true
-+     */
-+    var isArray = nativeIsArray || function(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == arrayClass || false;
-+    };
-+
-+    /**
-+     * A fallback implementation of `Object.keys` which produces an array of the
-+     * given object's own enumerable property names.
-+     *
-+     * @private
-+     * @type Function
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     */
-+    var shimKeys = createIterator({
-+      'args': 'object',
-+      'init': '[]',
-+      'top': 'if (!(objectTypes[typeof object])) return result',
-+      'loop': 'result.push(index)'
-+    });
-+
-+    /**
-+     * Creates an array composed of the own enumerable property names of an object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     * @example
-+     *
-+     * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
-+     */
-+    var keys = !nativeKeys ? shimKeys : function(object) {
-+      if (!isObject(object)) {
-+        return [];
-+      }
-+      if ((support.enumPrototypes && typeof object == 'function') ||
-+          (support.nonEnumArgs && object.length && isArguments(object))) {
-+        return shimKeys(object);
-+      }
-+      return nativeKeys(object);
-+    };
-+
-+    /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
-+    var eachIteratorOptions = {
-+      'args': 'collection, callback, thisArg',
-+      'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
-+      'array': "typeof length == 'number'",
-+      'keys': keys,
-+      'loop': 'if (callback(iterable[index], index, collection) === false) return result'
-+    };
-+
-+    /** Reusable iterator options for `assign` and `defaults` */
-+    var defaultsIteratorOptions = {
-+      'args': 'object, source, guard',
-+      'top':
-+        'var args = arguments,\n' +
-+        '    argsIndex = 0,\n' +
-+        "    argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
-+        'while (++argsIndex < argsLength) {\n' +
-+        '  iterable = args[argsIndex];\n' +
-+        '  if (iterable && objectTypes[typeof iterable]) {',
-+      'keys': keys,
-+      'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
-+      'bottom': '  }\n}'
-+    };
-+
-+    /** Reusable iterator options for `forIn` and `forOwn` */
-+    var forOwnIteratorOptions = {
-+      'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
-+      'array': false
-+    };
-+
-+    /**
-+     * Used to convert characters to HTML entities:
-+     *
-+     * Though the `>` character is escaped for symmetry, characters like `>` and `/`
-+     * don't require escaping in HTML and have no special meaning unless they're part
-+     * of a tag or an unquoted attribute value.
-+     * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
-+     */
-+    var htmlEscapes = {
-+      '&': '&',
-+      '<': '<',
-+      '>': '>',
-+      '"': '"',
-+      "'": '''
-+    };
-+
-+    /** Used to convert HTML entities to characters */
-+    var htmlUnescapes = invert(htmlEscapes);
-+
-+    /** Used to match HTML entities and HTML characters */
-+    var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
-+        reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-+
-+    /**
-+     * A function compiled to iterate `arguments` objects, arrays, objects, and
-+     * strings consistenly across environments, executing the callback for each
-+     * element in the collection. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index|key, collection). Callbacks may exit
-+     * iteration early by explicitly returning `false`.
-+     *
-+     * @private
-+     * @type Function
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     */
-+    var baseEach = createIterator(eachIteratorOptions);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object. Subsequent sources will overwrite property assignments of previous
-+     * sources. If a callback is provided it will be executed to produce the
-+     * assigned values. The callback is bound to `thisArg` and invoked with two
-+     * arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @alias extend
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize assigning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
-+     * // => { 'name': 'fred', 'employer': 'slate' }
-+     *
-+     * var defaults = _.partialRight(_.assign, function(a, b) {
-+     *   return typeof a == 'undefined' ? b : a;
-+     * });
-+     *
-+     * var object = { 'name': 'barney' };
-+     * defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var assign = createIterator(defaultsIteratorOptions, {
-+      'top':
-+        defaultsIteratorOptions.top.replace(';',
-+          ';\n' +
-+          "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
-+          '  var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
-+          "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
-+          '  callback = args[--argsLength];\n' +
-+          '}'
-+        ),
-+      'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
-+    });
-+
-+    /**
-+     * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
-+     * be cloned, otherwise they will be assigned by reference. If a callback
-+     * is provided it will be executed to produce the cloned values. If the
-+     * callback returns `undefined` cloning will be handled by the method instead.
-+     * The callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var shallow = _.clone(characters);
-+     * shallow[0] === characters[0];
-+     * // => true
-+     *
-+     * var deep = _.clone(characters, true);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * _.mixin({
-+     *   'clone': _.partialRight(_.clone, function(value) {
-+     *     return _.isElement(value) ? value.cloneNode(false) : undefined;
-+     *   })
-+     * });
-+     *
-+     * var clone = _.clone(document.body);
-+     * clone.childNodes.length;
-+     * // => 0
-+     */
-+    function clone(value, isDeep, callback, thisArg) {
-+      // allows working with "Collections" methods without using their `index`
-+      // and `collection` arguments for `isDeep` and `callback`
-+      if (typeof isDeep != 'boolean' && isDeep != null) {
-+        thisArg = callback;
-+        callback = isDeep;
-+        isDeep = false;
-+      }
-+      return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates a deep clone of `value`. If a callback is provided it will be
-+     * executed to produce the cloned values. If the callback returns `undefined`
-+     * cloning will be handled by the method instead. The callback is bound to
-+     * `thisArg` and invoked with one argument; (value).
-+     *
-+     * Note: This method is loosely based on the structured clone algorithm. Functions
-+     * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
-+     * objects created by constructors other than `Object` are cloned to plain `Object` objects.
-+     * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the deep cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var deep = _.cloneDeep(characters);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'node': element
-+     * };
-+     *
-+     * var clone = _.cloneDeep(view, function(value) {
-+     *   return _.isElement(value) ? value.cloneNode(true) : undefined;
-+     * });
-+     *
-+     * clone.node == view.node;
-+     * // => false
-+     */
-+    function cloneDeep(value, callback, thisArg) {
-+      return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates an object that inherits from the given `prototype` object. If a
-+     * `properties` object is provided its own enumerable properties are assigned
-+     * to the created object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} prototype The object to inherit from.
-+     * @param {Object} [properties] The properties to assign to the object.
-+     * @returns {Object} Returns the new object.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * function Circle() {
-+     *   Shape.call(this);
-+     * }
-+     *
-+     * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
-+     *
-+     * var circle = new Circle;
-+     * circle instanceof Circle;
-+     * // => true
-+     *
-+     * circle instanceof Shape;
-+     * // => true
-+     */
-+    function create(prototype, properties) {
-+      var result = baseCreate(prototype);
-+      return properties ? assign(result, properties) : result;
-+    }
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object for all destination properties that resolve to `undefined`. Once a
-+     * property is set, additional defaults of the same property will be ignored.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param- {Object} [guard] Allows working with `_.reduce` without using its
-+     *  `key` and `object` arguments as sources.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var object = { 'name': 'barney' };
-+     * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var defaults = createIterator(defaultsIteratorOptions);
-+
-+    /**
-+     * This method is like `_.findIndex` except that it returns the key of the
-+     * first element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': false },
-+     *   'fred': {    'age': 40, 'blocked': true },
-+     *   'pebbles': { 'age': 1,  'blocked': false }
-+     * };
-+     *
-+     * _.findKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => 'barney' (property order is not guaranteed across environments)
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findKey(characters, { 'age': 1 });
-+     * // => 'pebbles'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findKey(characters, 'blocked');
-+     * // => 'fred'
-+     */
-+    function findKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwn(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * This method is like `_.findKey` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': true },
-+     *   'fred': {    'age': 40, 'blocked': false },
-+     *   'pebbles': { 'age': 1,  'blocked': true }
-+     * };
-+     *
-+     * _.findLastKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => returns `pebbles`, assuming `_.findKey` returns `barney`
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastKey(characters, { 'age': 40 });
-+     * // => 'fred'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastKey(characters, 'blocked');
-+     * // => 'pebbles'
-+     */
-+    function findLastKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwnRight(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over own and inherited enumerable properties of an object,
-+     * executing the callback for each property. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, key, object). Callbacks may exit
-+     * iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forIn(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
-+     */
-+    var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
-+      'useHas': false
-+    });
-+
-+    /**
-+     * This method is like `_.forIn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forInRight(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
-+     */
-+    function forInRight(object, callback, thisArg) {
-+      var pairs = [];
-+
-+      forIn(object, function(value, key) {
-+        pairs.push(key, value);
-+      });
-+
-+      var length = pairs.length;
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(pairs[length--], pairs[length], object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Iterates over own enumerable properties of an object, executing the callback
-+     * for each property. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, key, object). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
-+     */
-+    var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
-+
-+    /**
-+     * This method is like `_.forOwn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
-+     */
-+    function forOwnRight(object, callback, thisArg) {
-+      var props = keys(object),
-+          length = props.length;
-+
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        var key = props[length];
-+        if (callback(object[key], key, object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a sorted array of property names of all enumerable properties,
-+     * own and inherited, of `object` that have function values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias methods
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names that have function values.
-+     * @example
-+     *
-+     * _.functions(_);
-+     * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
-+     */
-+    function functions(object) {
-+      var result = [];
-+      forIn(object, function(value, key) {
-+        if (isFunction(value)) {
-+          result.push(key);
-+        }
-+      });
-+      return result.sort();
-+    }
-+
-+    /**
-+     * Checks if the specified property name exists as a direct property of `object`,
-+     * instead of an inherited property.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to check.
-+     * @returns {boolean} Returns `true` if key is a direct property, else `false`.
-+     * @example
-+     *
-+     * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
-+     * // => true
-+     */
-+    function has(object, key) {
-+      return object ? hasOwnProperty.call(object, key) : false;
-+    }
-+
-+    /**
-+     * Creates an object composed of the inverted keys and values of the given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to invert.
-+     * @returns {Object} Returns the created inverted object.
-+     * @example
-+     *
-+     * _.invert({ 'first': 'fred', 'second': 'barney' });
-+     * // => { 'fred': 'first', 'barney': 'second' }
-+     */
-+    function invert(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = {};
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[object[key]] = key;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a boolean value.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
-+     * @example
-+     *
-+     * _.isBoolean(null);
-+     * // => false
-+     */
-+    function isBoolean(value) {
-+      return value === true || value === false ||
-+        value && typeof value == 'object' && toString.call(value) == boolClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a date.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
-+     * @example
-+     *
-+     * _.isDate(new Date);
-+     * // => true
-+     */
-+    function isDate(value) {
-+      return value && typeof value == 'object' && toString.call(value) == dateClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a DOM element.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
-+     * @example
-+     *
-+     * _.isElement(document.body);
-+     * // => true
-+     */
-+    function isElement(value) {
-+      return value && value.nodeType === 1 || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
-+     * length of `0` and objects with no own enumerable properties are considered
-+     * "empty".
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object|string} value The value to inspect.
-+     * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
-+     * @example
-+     *
-+     * _.isEmpty([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isEmpty({});
-+     * // => true
-+     *
-+     * _.isEmpty('');
-+     * // => true
-+     */
-+    function isEmpty(value) {
-+      var result = true;
-+      if (!value) {
-+        return result;
-+      }
-+      var className = toString.call(value),
-+          length = value.length;
-+
-+      if ((className == arrayClass || className == stringClass ||
-+          (support.argsClass ? className == argsClass : isArguments(value))) ||
-+          (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
-+        return !length;
-+      }
-+      forOwn(value, function() {
-+        return (result = false);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Performs a deep comparison between two values to determine if they are
-+     * equivalent to each other. If a callback is provided it will be executed
-+     * to compare values. If the callback returns `undefined` comparisons will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (a, b).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var copy = { 'name': 'fred' };
-+     *
-+     * object == copy;
-+     * // => false
-+     *
-+     * _.isEqual(object, copy);
-+     * // => true
-+     *
-+     * var words = ['hello', 'goodbye'];
-+     * var otherWords = ['hi', 'goodbye'];
-+     *
-+     * _.isEqual(words, otherWords, function(a, b) {
-+     *   var reGreet = /^(?:hello|hi)$/i,
-+     *       aGreet = _.isString(a) && reGreet.test(a),
-+     *       bGreet = _.isString(b) && reGreet.test(b);
-+     *
-+     *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
-+     * });
-+     * // => true
-+     */
-+    function isEqual(a, b, callback, thisArg) {
-+      return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
-+    }
-+
-+    /**
-+     * Checks if `value` is, or can be coerced to, a finite number.
-+     *
-+     * Note: This is not the same as native `isFinite` which will return true for
-+     * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
-+     * @example
-+     *
-+     * _.isFinite(-101);
-+     * // => true
-+     *
-+     * _.isFinite('10');
-+     * // => true
-+     *
-+     * _.isFinite(true);
-+     * // => false
-+     *
-+     * _.isFinite('');
-+     * // => false
-+     *
-+     * _.isFinite(Infinity);
-+     * // => false
-+     */
-+    function isFinite(value) {
-+      return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
-+    }
-+
-+    /**
-+     * Checks if `value` is a function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
-+     * @example
-+     *
-+     * _.isFunction(_);
-+     * // => true
-+     */
-+    function isFunction(value) {
-+      return typeof value == 'function';
-+    }
-+    // fallback for older versions of Chrome and Safari
-+    if (isFunction(/x/)) {
-+      isFunction = function(value) {
-+        return typeof value == 'function' && toString.call(value) == funcClass;
-+      };
-+    }
-+
-+    /**
-+     * Checks if `value` is the language type of Object.
-+     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
-+     * @example
-+     *
-+     * _.isObject({});
-+     * // => true
-+     *
-+     * _.isObject([1, 2, 3]);
-+     * // => true
-+     *
-+     * _.isObject(1);
-+     * // => false
-+     */
-+    function isObject(value) {
-+      // check if the value is the ECMAScript language type of Object
-+      // http://es5.github.io/#x8
-+      // and avoid a V8 bug
-+      // http://code.google.com/p/v8/issues/detail?id=2291
-+      return !!(value && objectTypes[typeof value]);
-+    }
-+
-+    /**
-+     * Checks if `value` is `NaN`.
-+     *
-+     * Note: This is not the same as native `isNaN` which will return `true` for
-+     * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
-+     * @example
-+     *
-+     * _.isNaN(NaN);
-+     * // => true
-+     *
-+     * _.isNaN(new Number(NaN));
-+     * // => true
-+     *
-+     * isNaN(undefined);
-+     * // => true
-+     *
-+     * _.isNaN(undefined);
-+     * // => false
-+     */
-+    function isNaN(value) {
-+      // `NaN` as a primitive is the only value that is not equal to itself
-+      // (perform the [[Class]] check first to avoid errors with some host objects in IE)
-+      return isNumber(value) && value != +value;
-+    }
-+
-+    /**
-+     * Checks if `value` is `null`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
-+     * @example
-+     *
-+     * _.isNull(null);
-+     * // => true
-+     *
-+     * _.isNull(undefined);
-+     * // => false
-+     */
-+    function isNull(value) {
-+      return value === null;
-+    }
-+
-+    /**
-+     * Checks if `value` is a number.
-+     *
-+     * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
-+     * @example
-+     *
-+     * _.isNumber(8.4 * 5);
-+     * // => true
-+     */
-+    function isNumber(value) {
-+      return typeof value == 'number' ||
-+        value && typeof value == 'object' && toString.call(value) == numberClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is an object created by the `Object` constructor.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * _.isPlainObject(new Shape);
-+     * // => false
-+     *
-+     * _.isPlainObject([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isPlainObject({ 'x': 0, 'y': 0 });
-+     * // => true
-+     */
-+    var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
-+      if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
-+        return false;
-+      }
-+      var valueOf = value.valueOf,
-+          objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-+
-+      return objProto
-+        ? (value == objProto || getPrototypeOf(value) == objProto)
-+        : shimIsPlainObject(value);
-+    };
-+
-+    /**
-+     * Checks if `value` is a regular expression.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
-+     * @example
-+     *
-+     * _.isRegExp(/fred/);
-+     * // => true
-+     */
-+    function isRegExp(value) {
-+      return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a string.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
-+     * @example
-+     *
-+     * _.isString('fred');
-+     * // => true
-+     */
-+    function isString(value) {
-+      return typeof value == 'string' ||
-+        value && typeof value == 'object' && toString.call(value) == stringClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is `undefined`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
-+     * @example
-+     *
-+     * _.isUndefined(void 0);
-+     * // => true
-+     */
-+    function isUndefined(value) {
-+      return typeof value == 'undefined';
-+    }
-+
-+    /**
-+     * Creates an object with the same keys as `object` and values generated by
-+     * running each own enumerable property of `object` through the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new object with values of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     *
-+     * var characters = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.mapValues(characters, 'age');
-+     * // => { 'fred': 40, 'pebbles': 1 }
-+     */
-+    function mapValues(object, callback, thisArg) {
-+      var result = {};
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      forOwn(object, function(value, key, object) {
-+        result[key] = callback(value, key, object);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Recursively merges own enumerable properties of the source object(s), that
-+     * don't resolve to `undefined` into the destination object. Subsequent sources
-+     * will overwrite property assignments of previous sources. If a callback is
-+     * provided it will be executed to produce the merged values of the destination
-+     * and source properties. If the callback returns `undefined` merging will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var names = {
-+     *   'characters': [
-+     *     { 'name': 'barney' },
-+     *     { 'name': 'fred' }
-+     *   ]
-+     * };
-+     *
-+     * var ages = {
-+     *   'characters': [
-+     *     { 'age': 36 },
-+     *     { 'age': 40 }
-+     *   ]
-+     * };
-+     *
-+     * _.merge(names, ages);
-+     * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
-+     *
-+     * var food = {
-+     *   'fruits': ['apple'],
-+     *   'vegetables': ['beet']
-+     * };
-+     *
-+     * var otherFood = {
-+     *   'fruits': ['banana'],
-+     *   'vegetables': ['carrot']
-+     * };
-+     *
-+     * _.merge(food, otherFood, function(a, b) {
-+     *   return _.isArray(a) ? a.concat(b) : undefined;
-+     * });
-+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
-+     */
-+    function merge(object) {
-+      var args = arguments,
-+          length = 2;
-+
-+      if (!isObject(object)) {
-+        return object;
-+      }
-+      // allows working with `_.reduce` and `_.reduceRight` without using
-+      // their `index` and `collection` arguments
-+      if (typeof args[2] != 'number') {
-+        length = args.length;
-+      }
-+      if (length > 3 && typeof args[length - 2] == 'function') {
-+        var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
-+      } else if (length > 2 && typeof args[length - 1] == 'function') {
-+        callback = args[--length];
-+      }
-+      var sources = slice(arguments, 1, length),
-+          index = -1,
-+          stackA = getArray(),
-+          stackB = getArray();
-+
-+      while (++index < length) {
-+        baseMerge(object, sources[index], callback, stackA, stackB);
-+      }
-+      releaseArray(stackA);
-+      releaseArray(stackB);
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` excluding the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` omitting the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The properties to omit or the
-+     *  function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object without the omitted properties.
-+     * @example
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
-+     *   return typeof value == 'number';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function omit(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var props = [];
-+        forIn(object, function(value, key) {
-+          props.push(key);
-+        });
-+        props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-+
-+        var index = -1,
-+            length = props.length;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          result[key] = object[key];
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (!callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a two dimensional array of an object's key-value pairs,
-+     * i.e. `[[key1, value1], [key2, value2]]`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns new array of key-value pairs.
-+     * @example
-+     *
-+     * _.pairs({ 'barney': 36, 'fred': 40 });
-+     * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
-+     */
-+    function pairs(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[index] = [key, object[key]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` composed of the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` picking the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The function called per
-+     *  iteration or property names to pick, specified as individual property
-+     *  names or arrays of property names.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object composed of the picked properties.
-+     * @example
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
-+     *   return key.charAt(0) != '_';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function pick(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var index = -1,
-+            props = baseFlatten(arguments, true, false, 1),
-+            length = isObject(object) ? props.length : 0;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          if (key in object) {
-+            result[key] = object[key];
-+          }
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * An alternative to `_.reduce` this method transforms `object` to a new
-+     * `accumulator` object which is the result of running each of its own
-+     * enumerable properties through a callback, with each callback execution
-+     * potentially mutating the `accumulator` object. The callback is bound to
-+     * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
-+     * Callbacks may exit iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] The custom accumulator value.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
-+     *   num *= num;
-+     *   if (num % 2) {
-+     *     return result.push(num) < 3;
-+     *   }
-+     * });
-+     * // => [1, 9, 25]
-+     *
-+     * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     * });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function transform(object, callback, accumulator, thisArg) {
-+      var isArr = isArray(object);
-+      if (accumulator == null) {
-+        if (isArr) {
-+          accumulator = [];
-+        } else {
-+          var ctor = object && object.constructor,
-+              proto = ctor && ctor.prototype;
-+
-+          accumulator = baseCreate(proto);
-+        }
-+      }
-+      if (callback) {
-+        callback = lodash.createCallback(callback, thisArg, 4);
-+        (isArr ? baseEach : forOwn)(object, function(value, index, object) {
-+          return callback(accumulator, value, index, object);
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * Creates an array composed of the own enumerable property values of `object`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property values.
-+     * @example
-+     *
-+     * _.values({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => [1, 2, 3] (property order is not guaranteed across environments)
-+     */
-+    function values(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = object[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array of elements from the specified indexes, or keys, of the
-+     * `collection`. Indexes may be specified as individual arguments or as arrays
-+     * of indexes.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
-+     *   to retrieve, specified as individual indexes or arrays of indexes.
-+     * @returns {Array} Returns a new array of elements corresponding to the
-+     *  provided indexes.
-+     * @example
-+     *
-+     * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
-+     * // => ['a', 'c', 'e']
-+     *
-+     * _.at(['fred', 'barney', 'pebbles'], 0, 2);
-+     * // => ['fred', 'pebbles']
-+     */
-+    function at(collection) {
-+      var args = arguments,
-+          index = -1,
-+          props = baseFlatten(args, true, false, 1),
-+          length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
-+          result = Array(length);
-+
-+      if (support.unindexedChars && isString(collection)) {
-+        collection = collection.split('');
-+      }
-+      while(++index < length) {
-+        result[index] = collection[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if a given value is present in a collection using strict equality
-+     * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
-+     * offset from the end of the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias include
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {*} target The value to check for.
-+     * @param {number} [fromIndex=0] The index to search from.
-+     * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
-+     * @example
-+     *
-+     * _.contains([1, 2, 3], 1);
-+     * // => true
-+     *
-+     * _.contains([1, 2, 3], 1, 2);
-+     * // => false
-+     *
-+     * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
-+     * // => true
-+     *
-+     * _.contains('pebbles', 'eb');
-+     * // => true
-+     */
-+    function contains(collection, target, fromIndex) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = collection ? collection.length : 0,
-+          result = false;
-+
-+      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
-+      if (isArray(collection)) {
-+        result = indexOf(collection, target, fromIndex) > -1;
-+      } else if (typeof length == 'number') {
-+        result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
-+      } else {
-+        baseEach(collection, function(value) {
-+          if (++index >= fromIndex) {
-+            return !(result = value === target);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of `collection` through the callback. The corresponding value
-+     * of each key is the number of times the key was returned by the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': 2, '5': 1 }
-+     */
-+    var countBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
-+    });
-+
-+    /**
-+     * Checks if the given callback returns truey value for **all** elements of
-+     * a collection. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias all
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if all elements passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.every([true, 1, null, 'yes']);
-+     * // => false
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.every(characters, 'age');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.every(characters, { 'age': 36 });
-+     * // => false
-+     */
-+    function every(collection, callback, thisArg) {
-+      var result = true;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if (!(result = !!callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          return (result = !!callback(value, index, collection));
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning an array of all elements
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias select
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that passed the callback check.
-+     * @example
-+     *
-+     * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [2, 4, 6]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.filter(characters, 'blocked');
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.filter(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     */
-+    function filter(collection, callback, thisArg) {
-+      var result = [];
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning the first element that
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias detect, findWhere
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.find(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => { 'name': 'barney', 'age': 36, 'blocked': false }
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.find(characters, { 'age': 1 });
-+     * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.find(characters, 'blocked');
-+     * // => { 'name': 'fred', 'age': 40, 'blocked': true }
-+     */
-+    function find(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            return value;
-+          }
-+        }
-+      } else {
-+        var result;
-+        baseEach(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result = value;
-+            return false;
-+          }
-+        });
-+        return result;
-+      }
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * _.findLast([1, 2, 3, 4], function(num) {
-+     *   return num % 2 == 1;
-+     * });
-+     * // => 3
-+     */
-+    function findLast(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forEachRight(collection, function(value, index, collection) {
-+        if (callback(value, index, collection)) {
-+          result = value;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, executing the callback for each
-+     * element. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * Note: As with other "Collections" methods, objects with a `length` property
-+     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
-+     * may be used for object iteration.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias each
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
-+     * // => logs each number and returns '1,2,3'
-+     *
-+     * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
-+     * // => logs each number and returns the object (property order is not guaranteed across environments)
-+     */
-+    function forEach(collection, callback, thisArg) {
-+      if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if (callback(collection[index], index, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, callback, thisArg);
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * This method is like `_.forEach` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias eachRight
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
-+     * // => logs each number from right to left and returns '3,2,1'
-+     */
-+    function forEachRight(collection, callback, thisArg) {
-+      var iterable = collection,
-+          length = collection ? collection.length : 0;
-+
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+      if (isArray(collection)) {
-+        while (length--) {
-+          if (callback(collection[length], length, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        if (typeof length != 'number') {
-+          var props = keys(collection);
-+          length = props.length;
-+        } else if (support.unindexedChars && isString(collection)) {
-+          iterable = collection.split('');
-+        }
-+        baseEach(collection, function(value, key, collection) {
-+          key = props ? props[--length] : --length;
-+          return callback(iterable[key], key, collection);
-+        });
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of a collection through the callback. The corresponding value
-+     * of each key is an array of the elements responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.groupBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': ['one', 'two'], '5': ['three'] }
-+     */
-+    var groupBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
-+    });
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of the collection through the given callback. The corresponding
-+     * value of each key is the last element responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * var keys = [
-+     *   { 'dir': 'left', 'code': 97 },
-+     *   { 'dir': 'right', 'code': 100 }
-+     * ];
-+     *
-+     * _.indexBy(keys, 'dir');
-+     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     */
-+    var indexBy = createAggregator(function(result, value, key) {
-+      result[key] = value;
-+    });
-+
-+    /**
-+     * Invokes the method named by `methodName` on each element in the `collection`
-+     * returning an array of the results of each invoked method. Additional arguments
-+     * will be provided to each invoked method. If `methodName` is a function it
-+     * will be invoked for, and `this` bound to, each element in the `collection`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|string} methodName The name of the method to invoke or
-+     *  the function invoked per iteration.
-+     * @param {...*} [arg] Arguments to invoke the method with.
-+     * @returns {Array} Returns a new array of the results of each invoked method.
-+     * @example
-+     *
-+     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-+     * // => [[1, 5, 7], [1, 2, 3]]
-+     *
-+     * _.invoke([123, 456], String.prototype.split, '');
-+     * // => [['1', '2', '3'], ['4', '5', '6']]
-+     */
-+    function invoke(collection, methodName) {
-+      var args = slice(arguments, 2),
-+          index = -1,
-+          isFunc = typeof methodName == 'function',
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of values by running each element in the collection
-+     * through the callback. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias collect
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.map([1, 2, 3], function(num) { return num * 3; });
-+     * // => [3, 6, 9]
-+     *
-+     * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
-+     * // => [3, 6, 9] (property order is not guaranteed across environments)
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function map(collection, callback, thisArg) {
-+      var index = -1,
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      if (isArray(collection)) {
-+        while (++index < length) {
-+          result[index] = callback(collection[index], index, collection);
-+        }
-+      } else {
-+        baseEach(collection, function(value, key, collection) {
-+          result[++index] = callback(value, key, collection);
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the maximum value of a collection. If the collection is empty or
-+     * falsey `-Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the maximum value.
-+     * @example
-+     *
-+     * _.max([4, 2, 8, 6]);
-+     * // => 8
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.max(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'fred', 'age': 40 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.max(characters, 'age');
-+     * // => { 'name': 'fred', 'age': 40 };
-+     */
-+    function max(collection, callback, thisArg) {
-+      var computed = -Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value > result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        baseEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current > computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the minimum value of a collection. If the collection is empty or
-+     * falsey `Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the minimum value.
-+     * @example
-+     *
-+     * _.min([4, 2, 8, 6]);
-+     * // => 2
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.min(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'barney', 'age': 36 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.min(characters, 'age');
-+     * // => { 'name': 'barney', 'age': 36 };
-+     */
-+    function min(collection, callback, thisArg) {
-+      var computed = Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value < result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        baseEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current < computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the value of a specified property from all elements in the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {string} property The name of the property to pluck.
-+     * @returns {Array} Returns a new array of property values.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.pluck(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    var pluck = map;
-+
-+    /**
-+     * Reduces a collection to a value which is the accumulated result of running
-+     * each element in the collection through the callback, where each successive
-+     * callback execution consumes the return value of the previous execution. If
-+     * `accumulator` is not provided the first element of the collection will be
-+     * used as the initial `accumulator` value. The callback is bound to `thisArg`
-+     * and invoked with four arguments; (accumulator, value, index|key, collection).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldl, inject
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var sum = _.reduce([1, 2, 3], function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     *   return result;
-+     * }, {});
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function reduce(collection, callback, accumulator, thisArg) {
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        if (noaccum) {
-+          accumulator = collection[++index];
-+        }
-+        while (++index < length) {
-+          accumulator = callback(accumulator, collection[index], index, collection);
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          accumulator = noaccum
-+            ? (noaccum = false, value)
-+            : callback(accumulator, value, index, collection)
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * This method is like `_.reduce` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldr
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var list = [[0, 1], [2, 3], [4, 5]];
-+     * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-+     * // => [4, 5, 2, 3, 0, 1]
-+     */
-+    function reduceRight(collection, callback, accumulator, thisArg) {
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+      forEachRight(collection, function(value, index, collection) {
-+        accumulator = noaccum
-+          ? (noaccum = false, value)
-+          : callback(accumulator, value, index, collection);
-+      });
-+      return accumulator;
-+    }
-+
-+    /**
-+     * The opposite of `_.filter` this method returns the elements of a
-+     * collection that the callback does **not** return truey for.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that failed the callback check.
-+     * @example
-+     *
-+     * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [1, 3, 5]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.reject(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.reject(characters, { 'age': 36 });
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     */
-+    function reject(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      return filter(collection, function(value, index, collection) {
-+        return !callback(value, index, collection);
-+      });
-+    }
-+
-+    /**
-+     * Retrieves a random element or `n` random elements from a collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to sample.
-+     * @param {number} [n] The number of elements to sample.
-+     * @param- {Object} [guard] Allows working with functions like `_.map`
-+     *  without using their `index` arguments as `n`.
-+     * @returns {Array} Returns the random sample(s) of `collection`.
-+     * @example
-+     *
-+     * _.sample([1, 2, 3, 4]);
-+     * // => 2
-+     *
-+     * _.sample([1, 2, 3, 4], 2);
-+     * // => [3, 1]
-+     */
-+    function sample(collection, n, guard) {
-+      if (collection && typeof collection.length != 'number') {
-+        collection = values(collection);
-+      } else if (support.unindexedChars && isString(collection)) {
-+        collection = collection.split('');
-+      }
-+      if (n == null || guard) {
-+        return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
-+      }
-+      var result = shuffle(collection);
-+      result.length = nativeMin(nativeMax(0, n), result.length);
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of shuffled values, using a version of the Fisher-Yates
-+     * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to shuffle.
-+     * @returns {Array} Returns a new shuffled collection.
-+     * @example
-+     *
-+     * _.shuffle([1, 2, 3, 4, 5, 6]);
-+     * // => [4, 1, 6, 3, 5, 2]
-+     */
-+    function shuffle(collection) {
-+      var index = -1,
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        var rand = baseRandom(0, ++index);
-+        result[index] = result[rand];
-+        result[rand] = value;
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the size of the `collection` by returning `collection.length` for arrays
-+     * and array-like objects or the number of own enumerable properties for objects.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to inspect.
-+     * @returns {number} Returns `collection.length` or number of own enumerable properties.
-+     * @example
-+     *
-+     * _.size([1, 2]);
-+     * // => 2
-+     *
-+     * _.size({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => 3
-+     *
-+     * _.size('pebbles');
-+     * // => 7
-+     */
-+    function size(collection) {
-+      var length = collection ? collection.length : 0;
-+      return typeof length == 'number' ? length : keys(collection).length;
-+    }
-+
-+    /**
-+     * Checks if the callback returns a truey value for **any** element of a
-+     * collection. The function returns as soon as it finds a passing value and
-+     * does not iterate over the entire collection. The callback is bound to
-+     * `thisArg` and invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias any
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if any element passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.some([null, 0, 'yes', false], Boolean);
-+     * // => true
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.some(characters, 'blocked');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.some(characters, { 'age': 1 });
-+     * // => false
-+     */
-+    function some(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if ((result = callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          return !(result = callback(value, index, collection));
-+        });
-+      }
-+      return !!result;
-+    }
-+
-+    /**
-+     * Creates an array of elements, sorted in ascending order by the results of
-+     * running each element in a collection through the callback. This method
-+     * performs a stable sort, that is, it will preserve the original sort order
-+     * of equal elements. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an array of property names is provided for `callback` the collection
-+     * will be sorted by each property value.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Array|Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of sorted elements.
-+     * @example
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
-+     * // => [3, 1, 2]
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
-+     * // => [3, 1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'barney',  'age': 26 },
-+     *   { 'name': 'fred',    'age': 30 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(_.sortBy(characters, 'age'), _.values);
-+     * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
-+     *
-+     * // sorting by multiple properties
-+     * _.map(_.sortBy(characters, ['name', 'age']), _.values);
-+     * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
-+     */
-+    function sortBy(collection, callback, thisArg) {
-+      var index = -1,
-+          isArr = isArray(callback),
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      if (!isArr) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      forEach(collection, function(value, key, collection) {
-+        var object = result[++index] = getObject();
-+        if (isArr) {
-+          object.criteria = map(callback, function(key) { return value[key]; });
-+        } else {
-+          (object.criteria = getArray())[0] = callback(value, key, collection);
-+        }
-+        object.index = index;
-+        object.value = value;
-+      });
-+
-+      length = result.length;
-+      result.sort(compareAscending);
-+      while (length--) {
-+        var object = result[length];
-+        result[length] = object.value;
-+        if (!isArr) {
-+          releaseArray(object.criteria);
-+        }
-+        releaseObject(object);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Converts the `collection` to an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to convert.
-+     * @returns {Array} Returns the new converted array.
-+     * @example
-+     *
-+     * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-+     * // => [2, 3, 4]
-+     */
-+    function toArray(collection) {
-+      if (collection && typeof collection.length == 'number') {
-+        return (support.unindexedChars && isString(collection))
-+          ? collection.split('')
-+          : slice(collection);
-+      }
-+      return values(collection);
-+    }
-+
-+    /**
-+     * Performs a deep comparison of each element in a `collection` to the given
-+     * `properties` object, returning an array of all elements that have equivalent
-+     * property values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Object} props The object of property values to filter by.
-+     * @returns {Array} Returns a new array of elements that have the given properties.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * _.where(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
-+     *
-+     * _.where(characters, { 'pets': ['dino'] });
-+     * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
-+     */
-+    var where = filter;
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array with all falsey values removed. The values `false`, `null`,
-+     * `0`, `""`, `undefined`, and `NaN` are all falsey.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to compact.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.compact([0, 1, false, 2, '', 3]);
-+     * // => [1, 2, 3]
-+     */
-+    function compact(array) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+        if (value) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array excluding all values of the provided arrays using strict
-+     * equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {...Array} [values] The arrays of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-+     * // => [1, 3, 4]
-+     */
-+    function difference(array) {
-+      return baseDifference(array, baseFlatten(arguments, true, true, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it returns the index of the first
-+     * element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.findIndex(characters, function(chr) {
-+     *   return chr.age < 20;
-+     * });
-+     * // => 2
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findIndex(characters, 'blocked');
-+     * // => 1
-+     */
-+    function findIndex(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0;
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        if (callback(array[index], index, array)) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * This method is like `_.findIndex` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': true },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': false },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
-+     * ];
-+     *
-+     * _.findLastIndex(characters, function(chr) {
-+     *   return chr.age > 30;
-+     * });
-+     * // => 1
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastIndex(characters, 'blocked');
-+     * // => 2
-+     */
-+    function findLastIndex(array, callback, thisArg) {
-+      var length = array ? array.length : 0;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(array[length], length, array)) {
-+          return length;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Gets the first element or first `n` elements of an array. If a callback
-+     * is provided elements at the beginning of the array are returned as long
-+     * as the callback returns truey. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias head, take
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the first element(s) of `array`.
-+     * @example
-+     *
-+     * _.first([1, 2, 3]);
-+     * // => 1
-+     *
-+     * _.first([1, 2, 3], 2);
-+     * // => [1, 2]
-+     *
-+     * _.first([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.first(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function first(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = -1;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[0] : undefined;
-+        }
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, n), length));
-+    }
-+
-+    /**
-+     * Flattens a nested array (the nesting can be to any depth). If `isShallow`
-+     * is truey, the array will only be flattened a single level. If a callback
-+     * is provided each element of the array is passed through the callback before
-+     * flattening. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new flattened array.
-+     * @example
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]]);
-+     * // => [1, 2, 3, 4];
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]], true);
-+     * // => [1, 2, 3, [[4]]];
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.flatten(characters, 'pets');
-+     * // => ['hoppy', 'baby puss', 'dino']
-+     */
-+    function flatten(array, isShallow, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isShallow != 'boolean' && isShallow != null) {
-+        thisArg = callback;
-+        callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
-+        isShallow = false;
-+      }
-+      if (callback != null) {
-+        array = map(array, callback, thisArg);
-+      }
-+      return baseFlatten(array, isShallow);
-+    }
-+
-+    /**
-+     * Gets the index at which the first occurrence of `value` is found using
-+     * strict equality for comparisons, i.e. `===`. If the array is already sorted
-+     * providing `true` for `fromIndex` will run a faster binary search.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
-+     *  to perform a binary search on a sorted array.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 1
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 4
-+     *
-+     * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
-+     * // => 2
-+     */
-+    function indexOf(array, value, fromIndex) {
-+      if (typeof fromIndex == 'number') {
-+        var length = array ? array.length : 0;
-+        fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
-+      } else if (fromIndex) {
-+        var index = sortedIndex(array, value);
-+        return array[index] === value ? index : -1;
-+      }
-+      return baseIndexOf(array, value, fromIndex);
-+    }
-+
-+    /**
-+     * Gets all but the last element or last `n` elements of an array. If a
-+     * callback is provided elements at the end of the array are excluded from
-+     * the result as long as the callback returns truey. The callback is bound
-+     * to `thisArg` and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.initial([1, 2, 3]);
-+     * // => [1, 2]
-+     *
-+     * _.initial([1, 2, 3], 2);
-+     * // => [1]
-+     *
-+     * _.initial([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [1]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.initial(characters, 'blocked');
-+     * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function initial(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : callback || n;
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
-+    }
-+
-+    /**
-+     * Creates an array of unique values present in all provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of shared values.
-+     * @example
-+     *
-+     * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2]
-+     */
-+    function intersection() {
-+      var args = [],
-+          argsIndex = -1,
-+          argsLength = arguments.length,
-+          caches = getArray(),
-+          indexOf = getIndexOf(),
-+          trustIndexOf = indexOf === baseIndexOf,
-+          seen = getArray();
-+
-+      while (++argsIndex < argsLength) {
-+        var value = arguments[argsIndex];
-+        if (isArray(value) || isArguments(value)) {
-+          args.push(value);
-+          caches.push(trustIndexOf && value.length >= largeArraySize &&
-+            createCache(argsIndex ? args[argsIndex] : seen));
-+        }
-+      }
-+      var array = args[0],
-+          index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      outer:
-+      while (++index < length) {
-+        var cache = caches[0];
-+        value = array[index];
-+
-+        if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
-+          argsIndex = argsLength;
-+          (cache || seen).push(value);
-+          while (--argsIndex) {
-+            cache = caches[argsIndex];
-+            if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
-+              continue outer;
-+            }
-+          }
-+          result.push(value);
-+        }
-+      }
-+      while (argsLength--) {
-+        cache = caches[argsLength];
-+        if (cache) {
-+          releaseObject(cache);
-+        }
-+      }
-+      releaseArray(caches);
-+      releaseArray(seen);
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the last element or last `n` elements of an array. If a callback is
-+     * provided elements at the end of the array are returned as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the last element(s) of `array`.
-+     * @example
-+     *
-+     * _.last([1, 2, 3]);
-+     * // => 3
-+     *
-+     * _.last([1, 2, 3], 2);
-+     * // => [2, 3]
-+     *
-+     * _.last([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [2, 3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.last(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.last(characters, { 'employer': 'na' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function last(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[length - 1] : undefined;
-+        }
-+      }
-+      return slice(array, nativeMax(0, length - n));
-+    }
-+
-+    /**
-+     * Gets the index at which the last occurrence of `value` is found using strict
-+     * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
-+     * as the offset from the end of the collection.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {number} [fromIndex=array.length-1] The index to search from.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 4
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 1
-+     */
-+    function lastIndexOf(array, value, fromIndex) {
-+      var index = array ? array.length : 0;
-+      if (typeof fromIndex == 'number') {
-+        index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
-+      }
-+      while (index--) {
-+        if (array[index] === value) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Removes all provided values from the given array using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {...*} [value] The values to remove.
-+     * @returns {Array} Returns `array`.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 1, 2, 3];
-+     * _.pull(array, 2, 3);
-+     * console.log(array);
-+     * // => [1, 1]
-+     */
-+    function pull(array) {
-+      var args = arguments,
-+          argsIndex = 0,
-+          argsLength = args.length,
-+          length = array ? array.length : 0;
-+
-+      while (++argsIndex < argsLength) {
-+        var index = -1,
-+            value = args[argsIndex];
-+        while (++index < length) {
-+          if (array[index] === value) {
-+            splice.call(array, index--, 1);
-+            length--;
-+          }
-+        }
-+      }
-+      return array;
-+    }
-+
-+    /**
-+     * Creates an array of numbers (positive and/or negative) progressing from
-+     * `start` up to but not including `end`. If `start` is less than `stop` a
-+     * zero-length range is created unless a negative `step` is specified.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {number} [start=0] The start of the range.
-+     * @param {number} end The end of the range.
-+     * @param {number} [step=1] The value to increment or decrement by.
-+     * @returns {Array} Returns a new range array.
-+     * @example
-+     *
-+     * _.range(4);
-+     * // => [0, 1, 2, 3]
-+     *
-+     * _.range(1, 5);
-+     * // => [1, 2, 3, 4]
-+     *
-+     * _.range(0, 20, 5);
-+     * // => [0, 5, 10, 15]
-+     *
-+     * _.range(0, -4, -1);
-+     * // => [0, -1, -2, -3]
-+     *
-+     * _.range(1, 4, 0);
-+     * // => [1, 1, 1]
-+     *
-+     * _.range(0);
-+     * // => []
-+     */
-+    function range(start, end, step) {
-+      start = +start || 0;
-+      step = typeof step == 'number' ? step : (+step || 1);
-+
-+      if (end == null) {
-+        end = start;
-+        start = 0;
-+      }
-+      // use `Array(length)` so engines like Chakra and V8 avoid slower modes
-+      // http://youtu.be/XAqIpGU8ZZk#t=17m25s
-+      var index = -1,
-+          length = nativeMax(0, ceil((end - start) / (step || 1))),
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = start;
-+        start += step;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Removes all elements from an array that the callback returns truey for
-+     * and returns an array of removed elements. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of removed elements.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 4, 5, 6];
-+     * var evens = _.remove(array, function(num) { return num % 2 == 0; });
-+     *
-+     * console.log(array);
-+     * // => [1, 3, 5]
-+     *
-+     * console.log(evens);
-+     * // => [2, 4, 6]
-+     */
-+    function remove(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        var value = array[index];
-+        if (callback(value, index, array)) {
-+          result.push(value);
-+          splice.call(array, index--, 1);
-+          length--;
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The opposite of `_.initial` this method gets all but the first element or
-+     * first `n` elements of an array. If a callback function is provided elements
-+     * at the beginning of the array are excluded from the result as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias drop, tail
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.rest([1, 2, 3]);
-+     * // => [2, 3]
-+     *
-+     * _.rest([1, 2, 3], 2);
-+     * // => [3]
-+     *
-+     * _.rest([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.rest(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.rest(characters, { 'employer': 'slate' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function rest(array, callback, thisArg) {
-+      if (typeof callback != 'number' && callback != null) {
-+        var n = 0,
-+            index = -1,
-+            length = array ? array.length : 0;
-+
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
-+      }
-+      return slice(array, n);
-+    }
-+
-+    /**
-+     * Uses a binary search to determine the smallest index at which a value
-+     * should be inserted into a given sorted array in order to maintain the sort
-+     * order of the array. If a callback is provided it will be executed for
-+     * `value` and each element of `array` to compute their sort ranking. The
-+     * callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to inspect.
-+     * @param {*} value The value to evaluate.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index at which `value` should be inserted
-+     *  into `array`.
-+     * @example
-+     *
-+     * _.sortedIndex([20, 30, 50], 40);
-+     * // => 2
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
-+     * // => 2
-+     *
-+     * var dict = {
-+     *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
-+     * };
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return dict.wordToNumber[word];
-+     * });
-+     * // => 2
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return this.wordToNumber[word];
-+     * }, dict);
-+     * // => 2
-+     */
-+    function sortedIndex(array, value, callback, thisArg) {
-+      var low = 0,
-+          high = array ? array.length : low;
-+
-+      // explicitly reference `identity` for better inlining in Firefox
-+      callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
-+      value = callback(value);
-+
-+      while (low < high) {
-+        var mid = (low + high) >>> 1;
-+        (callback(array[mid]) < value)
-+          ? low = mid + 1
-+          : high = mid;
-+      }
-+      return low;
-+    }
-+
-+    /**
-+     * Creates an array of unique values, in order, of the provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of combined values.
-+     * @example
-+     *
-+     * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2, 3, 5, 4]
-+     */
-+    function union() {
-+      return baseUniq(baseFlatten(arguments, true, true));
-+    }
-+
-+    /**
-+     * Creates a duplicate-value-free version of an array using strict equality
-+     * for comparisons, i.e. `===`. If the array is sorted, providing
-+     * `true` for `isSorted` will use a faster algorithm. If a callback is provided
-+     * each element of `array` is passed through the callback before uniqueness
-+     * is computed. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unique
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     * @example
-+     *
-+     * _.uniq([1, 2, 1, 3, 1]);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq([1, 1, 2, 2, 3], true);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
-+     * // => ['A', 'b', 'C']
-+     *
-+     * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
-+     * // => [1, 2.5, 3]
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
-+     * // => [{ 'x': 1 }, { 'x': 2 }]
-+     */
-+    function uniq(array, isSorted, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isSorted != 'boolean' && isSorted != null) {
-+        thisArg = callback;
-+        callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
-+        isSorted = false;
-+      }
-+      if (callback != null) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      return baseUniq(array, isSorted, callback);
-+    }
-+
-+    /**
-+     * Creates an array excluding all provided values using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to filter.
-+     * @param {...*} [value] The values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-+     * // => [2, 3, 4]
-+     */
-+    function without(array) {
-+      return baseDifference(array, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates an array that is the symmetric difference of the provided arrays.
-+     * See http://en.wikipedia.org/wiki/Symmetric_difference.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of values.
-+     * @example
-+     *
-+     * _.xor([1, 2, 3], [5, 2, 1, 4]);
-+     * // => [3, 5, 4]
-+     *
-+     * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
-+     * // => [1, 4, 5]
-+     */
-+    function xor() {
-+      var index = -1,
-+          length = arguments.length;
-+
-+      while (++index < length) {
-+        var array = arguments[index];
-+        if (isArray(array) || isArguments(array)) {
-+          var result = result
-+            ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
-+            : array;
-+        }
-+      }
-+      return result || [];
-+    }
-+
-+    /**
-+     * Creates an array of grouped elements, the first of which contains the first
-+     * elements of the given arrays, the second of which contains the second
-+     * elements of the given arrays, and so on.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unzip
-+     * @category Arrays
-+     * @param {...Array} [array] Arrays to process.
-+     * @returns {Array} Returns a new array of grouped elements.
-+     * @example
-+     *
-+     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
-+     * // => [['fred', 30, true], ['barney', 40, false]]
-+     */
-+    function zip() {
-+      var array = arguments.length > 1 ? arguments : arguments[0],
-+          index = -1,
-+          length = array ? max(pluck(array, 'length')) : 0,
-+          result = Array(length < 0 ? 0 : length);
-+
-+      while (++index < length) {
-+        result[index] = pluck(array, index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed from arrays of `keys` and `values`. Provide
-+     * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
-+     * or two arrays, one of `keys` and one of corresponding `values`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias object
-+     * @category Arrays
-+     * @param {Array} keys The array of keys.
-+     * @param {Array} [values=[]] The array of values.
-+     * @returns {Object} Returns an object composed of the given keys and
-+     *  corresponding values.
-+     * @example
-+     *
-+     * _.zipObject(['fred', 'barney'], [30, 40]);
-+     * // => { 'fred': 30, 'barney': 40 }
-+     */
-+    function zipObject(keys, values) {
-+      var index = -1,
-+          length = keys ? keys.length : 0,
-+          result = {};
-+
-+      if (!values && length && !isArray(keys[0])) {
-+        values = [];
-+      }
-+      while (++index < length) {
-+        var key = keys[index];
-+        if (values) {
-+          result[key] = values[index];
-+        } else if (key) {
-+          result[key[0]] = key[1];
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that executes `func`, with  the `this` binding and
-+     * arguments of the created function, only after being called `n` times.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {number} n The number of times the function must be called before
-+     *  `func` is executed.
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var saves = ['profile', 'settings'];
-+     *
-+     * var done = _.after(saves.length, function() {
-+     *   console.log('Done saving!');
-+     * });
-+     *
-+     * _.forEach(saves, function(type) {
-+     *   asyncSave({ 'type': type, 'complete': done });
-+     * });
-+     * // => logs 'Done saving!', after all saves have completed
-+     */
-+    function after(n, func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (--n < 1) {
-+          return func.apply(this, arguments);
-+        }
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with the `this`
-+     * binding of `thisArg` and prepends any additional `bind` arguments to those
-+     * provided to the bound function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to bind.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var func = function(greeting) {
-+     *   return greeting + ' ' + this.name;
-+     * };
-+     *
-+     * func = _.bind(func, { 'name': 'fred' }, 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     */
-+    function bind(func, thisArg) {
-+      return arguments.length > 2
-+        ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
-+        : createWrapper(func, 1, null, null, thisArg);
-+    }
-+
-+    /**
-+     * Binds methods of an object to the object itself, overwriting the existing
-+     * method. Method names may be specified as individual arguments or as arrays
-+     * of method names. If no method names are provided all the function properties
-+     * of `object` will be bound.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object to bind and assign the bound methods to.
-+     * @param {...string} [methodName] The object method names to
-+     *  bind, specified as individual method names or arrays of method names.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'onClick': function() { console.log('clicked ' + this.label); }
-+     * };
-+     *
-+     * _.bindAll(view);
-+     * jQuery('#docs').on('click', view.onClick);
-+     * // => logs 'clicked docs', when the button is clicked
-+     */
-+    function bindAll(object) {
-+      var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
-+          index = -1,
-+          length = funcs.length;
-+
-+      while (++index < length) {
-+        var key = funcs[index];
-+        object[key] = createWrapper(object[key], 1, null, null, object);
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes the method at `object[key]`
-+     * and prepends any additional `bindKey` arguments to those provided to the bound
-+     * function. This method differs from `_.bind` by allowing bound functions to
-+     * reference methods that will be redefined or don't yet exist.
-+     * See http://michaux.ca/articles/lazy-function-definition-pattern.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object the method belongs to.
-+     * @param {string} key The key of the method.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var object = {
-+     *   'name': 'fred',
-+     *   'greet': function(greeting) {
-+     *     return greeting + ' ' + this.name;
-+     *   }
-+     * };
-+     *
-+     * var func = _.bindKey(object, 'greet', 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     *
-+     * object.greet = function(greeting) {
-+     *   return greeting + 'ya ' + this.name + '!';
-+     * };
-+     *
-+     * func();
-+     * // => 'hiya fred!'
-+     */
-+    function bindKey(object, key) {
-+      return arguments.length > 2
-+        ? createWrapper(key, 19, slice(arguments, 2), null, object)
-+        : createWrapper(key, 3, null, null, object);
-+    }
-+
-+    /**
-+     * Creates a function that is the composition of the provided functions,
-+     * where each function consumes the return value of the function that follows.
-+     * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
-+     * Each function is executed with the `this` binding of the composed function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {...Function} [func] Functions to compose.
-+     * @returns {Function} Returns the new composed function.
-+     * @example
-+     *
-+     * var realNameMap = {
-+     *   'pebbles': 'penelope'
-+     * };
-+     *
-+     * var format = function(name) {
-+     *   name = realNameMap[name.toLowerCase()] || name;
-+     *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
-+     * };
-+     *
-+     * var greet = function(formatted) {
-+     *   return 'Hiya ' + formatted + '!';
-+     * };
-+     *
-+     * var welcome = _.compose(greet, format);
-+     * welcome('pebbles');
-+     * // => 'Hiya Penelope!'
-+     */
-+    function compose() {
-+      var funcs = arguments,
-+          length = funcs.length;
-+
-+      while (length--) {
-+        if (!isFunction(funcs[length])) {
-+          throw new TypeError;
-+        }
-+      }
-+      return function() {
-+        var args = arguments,
-+            length = funcs.length;
-+
-+        while (length--) {
-+          args = [funcs[length].apply(this, args)];
-+        }
-+        return args[0];
-+      };
-+    }
-+
-+    /**
-+     * Creates a function which accepts one or more arguments of `func` that when
-+     * invoked either executes `func` returning its result, if all `func` arguments
-+     * have been provided, or returns a function that accepts one or more of the
-+     * remaining `func` arguments, and so on. The arity of `func` can be specified
-+     * if `func.length` is not sufficient.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to curry.
-+     * @param {number} [arity=func.length] The arity of `func`.
-+     * @returns {Function} Returns the new curried function.
-+     * @example
-+     *
-+     * var curried = _.curry(function(a, b, c) {
-+     *   console.log(a + b + c);
-+     * });
-+     *
-+     * curried(1)(2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2, 3);
-+     * // => 6
-+     */
-+    function curry(func, arity) {
-+      arity = typeof arity == 'number' ? arity : (+arity || func.length);
-+      return createWrapper(func, 4, null, null, null, arity);
-+    }
-+
-+    /**
-+     * Creates a function that will delay the execution of `func` until after
-+     * `wait` milliseconds have elapsed since the last time it was invoked.
-+     * Provide an options object to indicate that `func` should be invoked on
-+     * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
-+     * to the debounced function will return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the debounced function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to debounce.
-+     * @param {number} wait The number of milliseconds to delay.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
-+     * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new debounced function.
-+     * @example
-+     *
-+     * // avoid costly calculations while the window size is in flux
-+     * var lazyLayout = _.debounce(calculateLayout, 150);
-+     * jQuery(window).on('resize', lazyLayout);
-+     *
-+     * // execute `sendMail` when the click event is fired, debouncing subsequent calls
-+     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
-+     *   'leading': true,
-+     *   'trailing': false
-+     * });
-+     *
-+     * // ensure `batchLog` is executed once after 1 second of debounced calls
-+     * var source = new EventSource('/stream');
-+     * source.addEventListener('message', _.debounce(batchLog, 250, {
-+     *   'maxWait': 1000
-+     * }, false);
-+     */
-+    function debounce(func, wait, options) {
-+      var args,
-+          maxTimeoutId,
-+          result,
-+          stamp,
-+          thisArg,
-+          timeoutId,
-+          trailingCall,
-+          lastCalled = 0,
-+          maxWait = false,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      wait = nativeMax(0, wait) || 0;
-+      if (options === true) {
-+        var leading = true;
-+        trailing = false;
-+      } else if (isObject(options)) {
-+        leading = options.leading;
-+        maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      var delayed = function() {
-+        var remaining = wait - (now() - stamp);
-+        if (remaining <= 0) {
-+          if (maxTimeoutId) {
-+            clearTimeout(maxTimeoutId);
-+          }
-+          var isCalled = trailingCall;
-+          maxTimeoutId = timeoutId = trailingCall = undefined;
-+          if (isCalled) {
-+            lastCalled = now();
-+            result = func.apply(thisArg, args);
-+            if (!timeoutId && !maxTimeoutId) {
-+              args = thisArg = null;
-+            }
-+          }
-+        } else {
-+          timeoutId = setTimeout(delayed, remaining);
-+        }
-+      };
-+
-+      var maxDelayed = function() {
-+        if (timeoutId) {
-+          clearTimeout(timeoutId);
-+        }
-+        maxTimeoutId = timeoutId = trailingCall = undefined;
-+        if (trailing || (maxWait !== wait)) {
-+          lastCalled = now();
-+          result = func.apply(thisArg, args);
-+          if (!timeoutId && !maxTimeoutId) {
-+            args = thisArg = null;
-+          }
-+        }
-+      };
-+
-+      return function() {
-+        args = arguments;
-+        stamp = now();
-+        thisArg = this;
-+        trailingCall = trailing && (timeoutId || !leading);
-+
-+        if (maxWait === false) {
-+          var leadingCall = leading && !timeoutId;
-+        } else {
-+          if (!maxTimeoutId && !leading) {
-+            lastCalled = stamp;
-+          }
-+          var remaining = maxWait - (stamp - lastCalled),
-+              isCalled = remaining <= 0;
-+
-+          if (isCalled) {
-+            if (maxTimeoutId) {
-+              maxTimeoutId = clearTimeout(maxTimeoutId);
-+            }
-+            lastCalled = stamp;
-+            result = func.apply(thisArg, args);
-+          }
-+          else if (!maxTimeoutId) {
-+            maxTimeoutId = setTimeout(maxDelayed, remaining);
-+          }
-+        }
-+        if (isCalled && timeoutId) {
-+          timeoutId = clearTimeout(timeoutId);
-+        }
-+        else if (!timeoutId && wait !== maxWait) {
-+          timeoutId = setTimeout(delayed, wait);
-+        }
-+        if (leadingCall) {
-+          isCalled = true;
-+          result = func.apply(thisArg, args);
-+        }
-+        if (isCalled && !timeoutId && !maxTimeoutId) {
-+          args = thisArg = null;
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Defers executing the `func` function until the current call stack has cleared.
-+     * Additional arguments will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to defer.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.defer(function(text) { console.log(text); }, 'deferred');
-+     * // logs 'deferred' after one or more milliseconds
-+     */
-+    function defer(func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 1);
-+      return setTimeout(function() { func.apply(undefined, args); }, 1);
-+    }
-+
-+    /**
-+     * Executes the `func` function after `wait` milliseconds. Additional arguments
-+     * will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to delay.
-+     * @param {number} wait The number of milliseconds to delay execution.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.delay(function(text) { console.log(text); }, 1000, 'later');
-+     * // => logs 'later' after one second
-+     */
-+    function delay(func, wait) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 2);
-+      return setTimeout(function() { func.apply(undefined, args); }, wait);
-+    }
-+
-+    /**
-+     * Creates a function that memoizes the result of `func`. If `resolver` is
-+     * provided it will be used to determine the cache key for storing the result
-+     * based on the arguments provided to the memoized function. By default, the
-+     * first argument provided to the memoized function is used as the cache key.
-+     * The `func` is executed with the `this` binding of the memoized function.
-+     * The result cache is exposed as the `cache` property on the memoized function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to have its output memoized.
-+     * @param {Function} [resolver] A function used to resolve the cache key.
-+     * @returns {Function} Returns the new memoizing function.
-+     * @example
-+     *
-+     * var fibonacci = _.memoize(function(n) {
-+     *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-+     * });
-+     *
-+     * fibonacci(9)
-+     * // => 34
-+     *
-+     * var data = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // modifying the result cache
-+     * var get = _.memoize(function(name) { return data[name]; }, _.identity);
-+     * get('pebbles');
-+     * // => { 'name': 'pebbles', 'age': 1 }
-+     *
-+     * get.cache.pebbles.name = 'penelope';
-+     * get('pebbles');
-+     * // => { 'name': 'penelope', 'age': 1 }
-+     */
-+    function memoize(func, resolver) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var memoized = function() {
-+        var cache = memoized.cache,
-+            key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-+
-+        return hasOwnProperty.call(cache, key)
-+          ? cache[key]
-+          : (cache[key] = func.apply(this, arguments));
-+      }
-+      memoized.cache = {};
-+      return memoized;
-+    }
-+
-+    /**
-+     * Creates a function that is restricted to execute `func` once. Repeat calls to
-+     * the function will return the value of the first call. The `func` is executed
-+     * with the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var initialize = _.once(createApplication);
-+     * initialize();
-+     * initialize();
-+     * // `initialize` executes `createApplication` once
-+     */
-+    function once(func) {
-+      var ran,
-+          result;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (ran) {
-+          return result;
-+        }
-+        ran = true;
-+        result = func.apply(this, arguments);
-+
-+        // clear the `func` variable so the function may be garbage collected
-+        func = null;
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with any additional
-+     * `partial` arguments prepended to those provided to the new function. This
-+     * method is similar to `_.bind` except it does **not** alter the `this` binding.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var greet = function(greeting, name) { return greeting + ' ' + name; };
-+     * var hi = _.partial(greet, 'hi');
-+     * hi('fred');
-+     * // => 'hi fred'
-+     */
-+    function partial(func) {
-+      return createWrapper(func, 16, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.partial` except that `partial` arguments are
-+     * appended to those provided to the new function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var defaultsDeep = _.partialRight(_.merge, _.defaults);
-+     *
-+     * var options = {
-+     *   'variable': 'data',
-+     *   'imports': { 'jq': $ }
-+     * };
-+     *
-+     * defaultsDeep(options, _.templateSettings);
-+     *
-+     * options.variable
-+     * // => 'data'
-+     *
-+     * options.imports
-+     * // => { '_': _, 'jq': $ }
-+     */
-+    function partialRight(func) {
-+      return createWrapper(func, 32, null, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates a function that, when executed, will only call the `func` function
-+     * at most once per every `wait` milliseconds. Provide an options object to
-+     * indicate that `func` should be invoked on the leading and/or trailing edge
-+     * of the `wait` timeout. Subsequent calls to the throttled function will
-+     * return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the throttled function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to throttle.
-+     * @param {number} wait The number of milliseconds to throttle executions to.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new throttled function.
-+     * @example
-+     *
-+     * // avoid excessively updating the position while scrolling
-+     * var throttled = _.throttle(updatePosition, 100);
-+     * jQuery(window).on('scroll', throttled);
-+     *
-+     * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
-+     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
-+     *   'trailing': false
-+     * }));
-+     */
-+    function throttle(func, wait, options) {
-+      var leading = true,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (options === false) {
-+        leading = false;
-+      } else if (isObject(options)) {
-+        leading = 'leading' in options ? options.leading : leading;
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      debounceOptions.leading = leading;
-+      debounceOptions.maxWait = wait;
-+      debounceOptions.trailing = trailing;
-+
-+      return debounce(func, wait, debounceOptions);
-+    }
-+
-+    /**
-+     * Creates a function that provides `value` to the wrapper function as its
-+     * first argument. Additional arguments provided to the function are appended
-+     * to those provided to the wrapper function. The wrapper is executed with
-+     * the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {*} value The value to wrap.
-+     * @param {Function} wrapper The wrapper function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var p = _.wrap(_.escape, function(func, text) {
-+     *   return '<p>' + func(text) + '</p>';
-+     * });
-+     *
-+     * p('Fred, Wilma, & Pebbles');
-+     * // => '<p>Fred, Wilma, & Pebbles</p>'
-+     */
-+    function wrap(value, wrapper) {
-+      return createWrapper(wrapper, 16, [value]);
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that returns `value`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value The value to return from the new function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var getter = _.constant(object);
-+     * getter() === object;
-+     * // => true
-+     */
-+    function constant(value) {
-+      return function() {
-+        return value;
-+      };
-+    }
-+
-+    /**
-+     * Produces a callback bound to an optional `thisArg`. If `func` is a property
-+     * name the created callback will return the property value for a given element.
-+     * If `func` is an object the created callback will return `true` for elements
-+     * that contain the equivalent object properties, otherwise it will return `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // wrap to create custom callback shorthands
-+     * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
-+     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
-+     *   return !match ? func(callback, thisArg) : function(object) {
-+     *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
-+     *   };
-+     * });
-+     *
-+     * _.filter(characters, 'age__gt38');
-+     * // => [{ 'name': 'fred', 'age': 40 }]
-+     */
-+    function createCallback(func, thisArg, argCount) {
-+      var type = typeof func;
-+      if (func == null || type == 'function') {
-+        return baseCreateCallback(func, thisArg, argCount);
-+      }
-+      // handle "_.pluck" style callback shorthands
-+      if (type != 'object') {
-+        return property(func);
-+      }
-+      var props = keys(func),
-+          key = props[0],
-+          a = func[key];
-+
-+      // handle "_.where" style callback shorthands
-+      if (props.length == 1 && a === a && !isObject(a)) {
-+        // fast path the common case of providing an object with a single
-+        // property containing a primitive value
-+        return function(object) {
-+          var b = object[key];
-+          return a === b && (a !== 0 || (1 / a == 1 / b));
-+        };
-+      }
-+      return function(object) {
-+        var length = props.length,
-+            result = false;
-+
-+        while (length--) {
-+          if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
-+            break;
-+          }
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding HTML entities.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to escape.
-+     * @returns {string} Returns the escaped string.
-+     * @example
-+     *
-+     * _.escape('Fred, Wilma, & Pebbles');
-+     * // => 'Fred, Wilma, & Pebbles'
-+     */
-+    function escape(string) {
-+      return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
-+    }
-+
-+    /**
-+     * This method returns the first argument provided to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value Any value.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.identity(object) === object;
-+     * // => true
-+     */
-+    function identity(value) {
-+      return value;
-+    }
-+
-+    /**
-+     * Adds function properties of a source object to the destination object.
-+     * If `object` is a function methods will be added to its prototype as well.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Function|Object} [object=lodash] object The destination object.
-+     * @param {Object} source The object of functions to add.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
-+     * @example
-+     *
-+     * function capitalize(string) {
-+     *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
-+     * }
-+     *
-+     * _.mixin({ 'capitalize': capitalize });
-+     * _.capitalize('fred');
-+     * // => 'Fred'
-+     *
-+     * _('fred').capitalize().value();
-+     * // => 'Fred'
-+     *
-+     * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
-+     * _('fred').capitalize();
-+     * // => 'Fred'
-+     */
-+    function mixin(object, source, options) {
-+      var chain = true,
-+          methodNames = source && functions(source);
-+
-+      if (!source || (!options && !methodNames.length)) {
-+        if (options == null) {
-+          options = source;
-+        }
-+        ctor = lodashWrapper;
-+        source = object;
-+        object = lodash;
-+        methodNames = functions(source);
-+      }
-+      if (options === false) {
-+        chain = false;
-+      } else if (isObject(options) && 'chain' in options) {
-+        chain = options.chain;
-+      }
-+      var ctor = object,
-+          isFunc = isFunction(ctor);
-+
-+      forEach(methodNames, function(methodName) {
-+        var func = object[methodName] = source[methodName];
-+        if (isFunc) {
-+          ctor.prototype[methodName] = function() {
-+            var chainAll = this.__chain__,
-+                value = this.__wrapped__,
-+                args = [value];
-+
-+            push.apply(args, arguments);
-+            var result = func.apply(object, args);
-+            if (chain || chainAll) {
-+              if (value === result && isObject(result)) {
-+                return this;
-+              }
-+              result = new ctor(result);
-+              result.__chain__ = chainAll;
-+            }
-+            return result;
-+          };
-+        }
-+      });
-+    }
-+
-+    /**
-+     * Reverts the '_' variable to its previous value and returns a reference to
-+     * the `lodash` function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @returns {Function} Returns the `lodash` function.
-+     * @example
-+     *
-+     * var lodash = _.noConflict();
-+     */
-+    function noConflict() {
-+      context._ = oldDash;
-+      return this;
-+    }
-+
-+    /**
-+     * A no-operation function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.noop(object) === undefined;
-+     * // => true
-+     */
-+    function noop() {
-+      // no operation performed
-+    }
-+
-+    /**
-+     * Gets the number of milliseconds that have elapsed since the Unix epoch
-+     * (1 January 1970 00:00:00 UTC).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var stamp = _.now();
-+     * _.defer(function() { console.log(_.now() - stamp); });
-+     * // => logs the number of milliseconds it took for the deferred function to be called
-+     */
-+    var now = isNative(now = Date.now) && now || function() {
-+      return new Date().getTime();
-+    };
-+
-+    /**
-+     * Converts the given value into an integer of the specified radix.
-+     * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
-+     * `value` is a hexadecimal, in which case a `radix` of `16` is used.
-+     *
-+     * Note: This method avoids differences in native ES3 and ES5 `parseInt`
-+     * implementations. See http://es5.github.io/#E.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} value The value to parse.
-+     * @param {number} [radix] The radix used to interpret the value to parse.
-+     * @returns {number} Returns the new integer value.
-+     * @example
-+     *
-+     * _.parseInt('08');
-+     * // => 8
-+     */
-+    var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
-+      // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
-+      return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
-+    };
-+
-+    /**
-+     * Creates a "_.pluck" style function, which returns the `key` value of a
-+     * given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} key The name of the property to retrieve.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'fred',   'age': 40 },
-+     *   { 'name': 'barney', 'age': 36 }
-+     * ];
-+     *
-+     * var getName = _.property('name');
-+     *
-+     * _.map(characters, getName);
-+     * // => ['barney', 'fred']
-+     *
-+     * _.sortBy(characters, getName);
-+     * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
-+     */
-+    function property(key) {
-+      return function(object) {
-+        return object[key];
-+      };
-+    }
-+
-+    /**
-+     * Produces a random number between `min` and `max` (inclusive). If only one
-+     * argument is provided a number between `0` and the given number will be
-+     * returned. If `floating` is truey or either `min` or `max` are floats a
-+     * floating-point number will be returned instead of an integer.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} [min=0] The minimum possible value.
-+     * @param {number} [max=1] The maximum possible value.
-+     * @param {boolean} [floating=false] Specify returning a floating-point number.
-+     * @returns {number} Returns a random number.
-+     * @example
-+     *
-+     * _.random(0, 5);
-+     * // => an integer between 0 and 5
-+     *
-+     * _.random(5);
-+     * // => also an integer between 0 and 5
-+     *
-+     * _.random(5, true);
-+     * // => a floating-point number between 0 and 5
-+     *
-+     * _.random(1.2, 5.2);
-+     * // => a floating-point number between 1.2 and 5.2
-+     */
-+    function random(min, max, floating) {
-+      var noMin = min == null,
-+          noMax = max == null;
-+
-+      if (floating == null) {
-+        if (typeof min == 'boolean' && noMax) {
-+          floating = min;
-+          min = 1;
-+        }
-+        else if (!noMax && typeof max == 'boolean') {
-+          floating = max;
-+          noMax = true;
-+        }
-+      }
-+      if (noMin && noMax) {
-+        max = 1;
-+      }
-+      min = +min || 0;
-+      if (noMax) {
-+        max = min;
-+        min = 0;
-+      } else {
-+        max = +max || 0;
-+      }
-+      if (floating || min % 1 || max % 1) {
-+        var rand = nativeRandom();
-+        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
-+      }
-+      return baseRandom(min, max);
-+    }
-+
-+    /**
-+     * Resolves the value of property `key` on `object`. If `key` is a function
-+     * it will be invoked with the `this` binding of `object` and its result returned,
-+     * else the property value is returned. If `object` is falsey then `undefined`
-+     * is returned.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to resolve.
-+     * @returns {*} Returns the resolved value.
-+     * @example
-+     *
-+     * var object = {
-+     *   'cheese': 'crumpets',
-+     *   'stuff': function() {
-+     *     return 'nonsense';
-+     *   }
-+     * };
-+     *
-+     * _.result(object, 'cheese');
-+     * // => 'crumpets'
-+     *
-+     * _.result(object, 'stuff');
-+     * // => 'nonsense'
-+     */
-+    function result(object, key) {
-+      if (object) {
-+        var value = object[key];
-+        return isFunction(value) ? object[key]() : value;
-+      }
-+    }
-+
-+    /**
-+     * A micro-templating method that handles arbitrary delimiters, preserves
-+     * whitespace, and correctly escapes quotes within interpolated code.
-+     *
-+     * Note: In the development build, `_.template` utilizes sourceURLs for easier
-+     * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+     *
-+     * For more information on precompiling templates see:
-+     * http://lodash.com/custom-builds
-+     *
-+     * For more information on Chrome extension sandboxes see:
-+     * http://developer.chrome.com/stable/extensions/sandboxingEval.html
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} text The template text.
-+     * @param {Object} data The data object used to populate the text.
-+     * @param {Object} [options] The options object.
-+     * @param {RegExp} [options.escape] The "escape" delimiter.
-+     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
-+     * @param {Object} [options.imports] An object to import into the template as local variables.
-+     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
-+     * @param {string} [sourceURL] The sourceURL of the template's compiled source.
-+     * @param {string} [variable] The data object variable name.
-+     * @returns {Function|string} Returns a compiled function when no `data` object
-+     *  is given, else it returns the interpolated text.
-+     * @example
-+     *
-+     * // using the "interpolate" delimiter to create a compiled template
-+     * var compiled = _.template('hello <%= name %>');
-+     * compiled({ 'name': 'fred' });
-+     * // => 'hello fred'
-+     *
-+     * // using the "escape" delimiter to escape HTML in data property values
-+     * _.template('<b><%- value %></b>', { 'value': '<script>' });
-+     * // => '<b><script></b>'
-+     *
-+     * // using the "evaluate" delimiter to generate HTML
-+     * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
-+     * _.template('hello ${ name }', { 'name': 'pebbles' });
-+     * // => 'hello pebbles'
-+     *
-+     * // using the internal `print` function in "evaluate" delimiters
-+     * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
-+     * // => 'hello barney!'
-+     *
-+     * // using a custom template delimiters
-+     * _.templateSettings = {
-+     *   'interpolate': /{{([\s\S]+?)}}/g
-+     * };
-+     *
-+     * _.template('hello {{ name }}!', { 'name': 'mustache' });
-+     * // => 'hello mustache!'
-+     *
-+     * // using the `imports` option to import jQuery
-+     * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the `sourceURL` option to specify a custom sourceURL for the template
-+     * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
-+     * compiled(data);
-+     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
-+     *
-+     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
-+     * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
-+     * compiled.source;
-+     * // => function(data) {
-+     *   var __t, __p = '', __e = _.escape;
-+     *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
-+     *   return __p;
-+     * }
-+     *
-+     * // using the `source` property to inline compiled templates for meaningful
-+     * // line numbers in error messages and a stack trace
-+     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
-+     *   var JST = {\
-+     *     "main": ' + _.template(mainText).source + '\
-+     *   };\
-+     * ');
-+     */
-+    function template(text, data, options) {
-+      // based on John Resig's `tmpl` implementation
-+      // http://ejohn.org/blog/javascript-micro-templating/
-+      // and Laura Doktorova's doT.js
-+      // https://github.com/olado/doT
-+      var settings = lodash.templateSettings;
-+      text = String(text || '');
-+
-+      // avoid missing dependencies when `iteratorTemplate` is not defined
-+      options = defaults({}, options, settings);
-+
-+      var imports = defaults({}, options.imports, settings.imports),
-+          importsKeys = keys(imports),
-+          importsValues = values(imports);
-+
-+      var isEvaluating,
-+          index = 0,
-+          interpolate = options.interpolate || reNoMatch,
-+          source = "__p += '";
-+
-+      // compile the regexp to match each delimiter
-+      var reDelimiters = RegExp(
-+        (options.escape || reNoMatch).source + '|' +
-+        interpolate.source + '|' +
-+        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
-+        (options.evaluate || reNoMatch).source + '|$'
-+      , 'g');
-+
-+      text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
-+        interpolateValue || (interpolateValue = esTemplateValue);
-+
-+        // escape characters that cannot be included in string literals
-+        source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
-+
-+        // replace delimiters with snippets
-+        if (escapeValue) {
-+          source += "' +\n__e(" + escapeValue + ") +\n'";
-+        }
-+        if (evaluateValue) {
-+          isEvaluating = true;
-+          source += "';\n" + evaluateValue + ";\n__p += '";
-+        }
-+        if (interpolateValue) {
-+          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
-+        }
-+        index = offset + match.length;
-+
-+        // the JS engine embedded in Adobe products requires returning the `match`
-+        // string in order to produce the correct `offset` value
-+        return match;
-+      });
-+
-+      source += "';\n";
-+
-+      // if `variable` is not specified, wrap a with-statement around the generated
-+      // code to add the data object to the top of the scope chain
-+      var variable = options.variable,
-+          hasVariable = variable;
-+
-+      if (!hasVariable) {
-+        variable = 'obj';
-+        source = 'with (' + variable + ') {\n' + source + '\n}\n';
-+      }
-+      // cleanup code by stripping empty strings
-+      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
-+        .replace(reEmptyStringMiddle, '$1')
-+        .replace(reEmptyStringTrailing, '$1;');
-+
-+      // frame code as the function body
-+      source = 'function(' + variable + ') {\n' +
-+        (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
-+        "var __t, __p = '', __e = _.escape" +
-+        (isEvaluating
-+          ? ', __j = Array.prototype.join;\n' +
-+            "function print() { __p += __j.call(arguments, '') }\n"
-+          : ';\n'
-+        ) +
-+        source +
-+        'return __p\n}';
-+
-+      // Use a sourceURL for easier debugging.
-+      // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+      var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
-+
-+      try {
-+        var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
-+      } catch(e) {
-+        e.source = source;
-+        throw e;
-+      }
-+      if (data) {
-+        return result(data);
-+      }
-+      // provide the compiled function's source by its `toString` method, in
-+      // supported environments, or the `source` property as a convenience for
-+      // inlining compiled templates during the build process
-+      result.source = source;
-+      return result;
-+    }
-+
-+    /**
-+     * Executes the callback `n` times, returning an array of the results
-+     * of each callback execution. The callback is bound to `thisArg` and invoked
-+     * with one argument; (index).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} n The number of times to execute the callback.
-+     * @param {Function} callback The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns an array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
-+     * // => [3, 6, 4]
-+     *
-+     * _.times(3, function(n) { mage.castSpell(n); });
-+     * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
-+     *
-+     * _.times(3, function(n) { this.cast(n); }, mage);
-+     * // => also calls `mage.castSpell(n)` three times
-+     */
-+    function times(n, callback, thisArg) {
-+      n = (n = +n) > -1 ? n : 0;
-+      var index = -1,
-+          result = Array(n);
-+
-+      callback = baseCreateCallback(callback, thisArg, 1);
-+      while (++index < n) {
-+        result[index] = callback(index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The inverse of `_.escape` this method converts the HTML entities
-+     * `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding characters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to unescape.
-+     * @returns {string} Returns the unescaped string.
-+     * @example
-+     *
-+     * _.unescape('Fred, Barney & Pebbles');
-+     * // => 'Fred, Barney & Pebbles'
-+     */
-+    function unescape(string) {
-+      return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
-+    }
-+
-+    /**
-+     * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} [prefix] The value to prefix the ID with.
-+     * @returns {string} Returns the unique ID.
-+     * @example
-+     *
-+     * _.uniqueId('contact_');
-+     * // => 'contact_104'
-+     *
-+     * _.uniqueId();
-+     * // => '105'
-+     */
-+    function uniqueId(prefix) {
-+      var id = ++idCounter;
-+      return String(prefix == null ? '' : prefix) + id;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object that wraps the given value with explicit
-+     * method chaining enabled.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to wrap.
-+     * @returns {Object} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'pebbles', 'age': 1 }
-+     * ];
-+     *
-+     * var youngest = _.chain(characters)
-+     *     .sortBy('age')
-+     *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
-+     *     .first()
-+     *     .value();
-+     * // => 'pebbles is 1'
-+     */
-+    function chain(value) {
-+      value = new lodashWrapper(value);
-+      value.__chain__ = true;
-+      return value;
-+    }
-+
-+    /**
-+     * Invokes `interceptor` with the `value` as the first argument and then
-+     * returns `value`. The purpose of this method is to "tap into" a method
-+     * chain in order to perform operations on intermediate results within
-+     * the chain.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to provide to `interceptor`.
-+     * @param {Function} interceptor The function to invoke.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * _([1, 2, 3, 4])
-+     *  .tap(function(array) { array.pop(); })
-+     *  .reverse()
-+     *  .value();
-+     * // => [3, 2, 1]
-+     */
-+    function tap(value, interceptor) {
-+      interceptor(value);
-+      return value;
-+    }
-+
-+    /**
-+     * Enables explicit method chaining on the wrapper object.
-+     *
-+     * @name chain
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {*} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // without explicit chaining
-+     * _(characters).first();
-+     * // => { 'name': 'barney', 'age': 36 }
-+     *
-+     * // with explicit chaining
-+     * _(characters).chain()
-+     *   .first()
-+     *   .pick('age')
-+     *   .value();
-+     * // => { 'age': 36 }
-+     */
-+    function wrapperChain() {
-+      this.__chain__ = true;
-+      return this;
-+    }
-+
-+    /**
-+     * Produces the `toString` result of the wrapped value.
-+     *
-+     * @name toString
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {string} Returns the string result.
-+     * @example
-+     *
-+     * _([1, 2, 3]).toString();
-+     * // => '1,2,3'
-+     */
-+    function wrapperToString() {
-+      return String(this.__wrapped__);
-+    }
-+
-+    /**
-+     * Extracts the wrapped value.
-+     *
-+     * @name valueOf
-+     * @memberOf _
-+     * @alias value
-+     * @category Chaining
-+     * @returns {*} Returns the wrapped value.
-+     * @example
-+     *
-+     * _([1, 2, 3]).valueOf();
-+     * // => [1, 2, 3]
-+     */
-+    function wrapperValueOf() {
-+      return this.__wrapped__;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return wrapped values when chaining
-+    lodash.after = after;
-+    lodash.assign = assign;
-+    lodash.at = at;
-+    lodash.bind = bind;
-+    lodash.bindAll = bindAll;
-+    lodash.bindKey = bindKey;
-+    lodash.chain = chain;
-+    lodash.compact = compact;
-+    lodash.compose = compose;
-+    lodash.constant = constant;
-+    lodash.countBy = countBy;
-+    lodash.create = create;
-+    lodash.createCallback = createCallback;
-+    lodash.curry = curry;
-+    lodash.debounce = debounce;
-+    lodash.defaults = defaults;
-+    lodash.defer = defer;
-+    lodash.delay = delay;
-+    lodash.difference = difference;
-+    lodash.filter = filter;
-+    lodash.flatten = flatten;
-+    lodash.forEach = forEach;
-+    lodash.forEachRight = forEachRight;
-+    lodash.forIn = forIn;
-+    lodash.forInRight = forInRight;
-+    lodash.forOwn = forOwn;
-+    lodash.forOwnRight = forOwnRight;
-+    lodash.functions = functions;
-+    lodash.groupBy = groupBy;
-+    lodash.indexBy = indexBy;
-+    lodash.initial = initial;
-+    lodash.intersection = intersection;
-+    lodash.invert = invert;
-+    lodash.invoke = invoke;
-+    lodash.keys = keys;
-+    lodash.map = map;
-+    lodash.mapValues = mapValues;
-+    lodash.max = max;
-+    lodash.memoize = memoize;
-+    lodash.merge = merge;
-+    lodash.min = min;
-+    lodash.omit = omit;
-+    lodash.once = once;
-+    lodash.pairs = pairs;
-+    lodash.partial = partial;
-+    lodash.partialRight = partialRight;
-+    lodash.pick = pick;
-+    lodash.pluck = pluck;
-+    lodash.property = property;
-+    lodash.pull = pull;
-+    lodash.range = range;
-+    lodash.reject = reject;
-+    lodash.remove = remove;
-+    lodash.rest = rest;
-+    lodash.shuffle = shuffle;
-+    lodash.sortBy = sortBy;
-+    lodash.tap = tap;
-+    lodash.throttle = throttle;
-+    lodash.times = times;
-+    lodash.toArray = toArray;
-+    lodash.transform = transform;
-+    lodash.union = union;
-+    lodash.uniq = uniq;
-+    lodash.values = values;
-+    lodash.where = where;
-+    lodash.without = without;
-+    lodash.wrap = wrap;
-+    lodash.xor = xor;
-+    lodash.zip = zip;
-+    lodash.zipObject = zipObject;
-+
-+    // add aliases
-+    lodash.collect = map;
-+    lodash.drop = rest;
-+    lodash.each = forEach;
-+    lodash.eachRight = forEachRight;
-+    lodash.extend = assign;
-+    lodash.methods = functions;
-+    lodash.object = zipObject;
-+    lodash.select = filter;
-+    lodash.tail = rest;
-+    lodash.unique = uniq;
-+    lodash.unzip = zip;
-+
-+    // add functions to `lodash.prototype`
-+    mixin(lodash);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return unwrapped values when chaining
-+    lodash.clone = clone;
-+    lodash.cloneDeep = cloneDeep;
-+    lodash.contains = contains;
-+    lodash.escape = escape;
-+    lodash.every = every;
-+    lodash.find = find;
-+    lodash.findIndex = findIndex;
-+    lodash.findKey = findKey;
-+    lodash.findLast = findLast;
-+    lodash.findLastIndex = findLastIndex;
-+    lodash.findLastKey = findLastKey;
-+    lodash.has = has;
-+    lodash.identity = identity;
-+    lodash.indexOf = indexOf;
-+    lodash.isArguments = isArguments;
-+    lodash.isArray = isArray;
-+    lodash.isBoolean = isBoolean;
-+    lodash.isDate = isDate;
-+    lodash.isElement = isElement;
-+    lodash.isEmpty = isEmpty;
-+    lodash.isEqual = isEqual;
-+    lodash.isFinite = isFinite;
-+    lodash.isFunction = isFunction;
-+    lodash.isNaN = isNaN;
-+    lodash.isNull = isNull;
-+    lodash.isNumber = isNumber;
-+    lodash.isObject = isObject;
-+    lodash.isPlainObject = isPlainObject;
-+    lodash.isRegExp = isRegExp;
-+    lodash.isString = isString;
-+    lodash.isUndefined = isUndefined;
-+    lodash.lastIndexOf = lastIndexOf;
-+    lodash.mixin = mixin;
-+    lodash.noConflict = noConflict;
-+    lodash.noop = noop;
-+    lodash.now = now;
-+    lodash.parseInt = parseInt;
-+    lodash.random = random;
-+    lodash.reduce = reduce;
-+    lodash.reduceRight = reduceRight;
-+    lodash.result = result;
-+    lodash.runInContext = runInContext;
-+    lodash.size = size;
-+    lodash.some = some;
-+    lodash.sortedIndex = sortedIndex;
-+    lodash.template = template;
-+    lodash.unescape = unescape;
-+    lodash.uniqueId = uniqueId;
-+
-+    // add aliases
-+    lodash.all = every;
-+    lodash.any = some;
-+    lodash.detect = find;
-+    lodash.findWhere = find;
-+    lodash.foldl = reduce;
-+    lodash.foldr = reduceRight;
-+    lodash.include = contains;
-+    lodash.inject = reduce;
-+
-+    mixin(function() {
-+      var source = {}
-+      forOwn(lodash, function(func, methodName) {
-+        if (!lodash.prototype[methodName]) {
-+          source[methodName] = func;
-+        }
-+      });
-+      return source;
-+    }(), false);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions capable of returning wrapped and unwrapped values when chaining
-+    lodash.first = first;
-+    lodash.last = last;
-+    lodash.sample = sample;
-+
-+    // add aliases
-+    lodash.take = first;
-+    lodash.head = first;
-+
-+    forOwn(lodash, function(func, methodName) {
-+      var callbackable = methodName !== 'sample';
-+      if (!lodash.prototype[methodName]) {
-+        lodash.prototype[methodName]= function(n, guard) {
-+          var chainAll = this.__chain__,
-+              result = func(this.__wrapped__, n, guard);
-+
-+          return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
-+            ? result
-+            : new lodashWrapper(result, chainAll);
-+        };
-+      }
-+    });
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The semantic version number.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type string
-+     */
-+    lodash.VERSION = '2.4.1';
-+
-+    // add "Chaining" functions to the wrapper
-+    lodash.prototype.chain = wrapperChain;
-+    lodash.prototype.toString = wrapperToString;
-+    lodash.prototype.value = wrapperValueOf;
-+    lodash.prototype.valueOf = wrapperValueOf;
-+
-+    // add `Array` functions that return unwrapped values
-+    baseEach(['join', 'pop', 'shift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        var chainAll = this.__chain__,
-+            result = func.apply(this.__wrapped__, arguments);
-+
-+        return chainAll
-+          ? new lodashWrapper(result, chainAll)
-+          : result;
-+      };
-+    });
-+
-+    // add `Array` functions that return the existing wrapped value
-+    baseEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        func.apply(this.__wrapped__, arguments);
-+        return this;
-+      };
-+    });
-+
-+    // add `Array` functions that return new wrapped values
-+    baseEach(['concat', 'slice', 'splice'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
-+      };
-+    });
-+
-+    // avoid array-like object bugs with `Array#shift` and `Array#splice`
-+    // in IE < 9, Firefox < 10, Narwhal, and RingoJS
-+    if (!support.spliceObjects) {
-+      baseEach(['pop', 'shift', 'splice'], function(methodName) {
-+        var func = arrayRef[methodName],
-+            isSplice = methodName == 'splice';
-+
-+        lodash.prototype[methodName] = function() {
-+          var chainAll = this.__chain__,
-+              value = this.__wrapped__,
-+              result = func.apply(value, arguments);
-+
-+          if (value.length === 0) {
-+            delete value[0];
-+          }
-+          return (chainAll || isSplice)
-+            ? new lodashWrapper(result, chainAll)
-+            : result;
-+        };
-+      });
-+    }
-+
-+    return lodash;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // expose Lo-Dash
-+  var _ = runInContext();
-+
-+  // some AMD build optimizers like r.js check for condition patterns like the following:
-+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
-+    // Expose Lo-Dash to the global object even when an AMD loader is present in
-+    // case Lo-Dash is loaded with a RequireJS shim config.
-+    // See http://requirejs.org/docs/api.html#config-shim
-+    root._ = _;
-+
-+    // define as an anonymous module so, through path mapping, it can be
-+    // referenced as the "underscore" module
-+    define(function() {
-+      return _;
-+    });
-+  }
-+  // check for `exports` after `define` in case a build optimizer adds an `exports` object
-+  else if (freeExports && freeModule) {
-+    // in Node.js or RingoJS
-+    if (moduleExports) {
-+      (freeModule.exports = _)._ = _;
-+    }
-+    // in Narwhal or Rhino -require
-+    else {
-+      freeExports._ = _;
-+    }
-+  }
-+  else {
-+    // in a browser or Rhino
-+    root._ = _;
-+  }
-+}.call(this));
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.compat.min.js
-@@ -0,0 +1,61 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
-+ * Build: `lodash -o ./dist/lodash.compat.js`
-+ */
-+;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:b+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:b+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true
-+}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var a=e[u],i=r[u];if(a!==i){if(a>i||typeof a=="undefined")return 1;if(a<i||typeof i=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],a=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&a&&typeof a=="object")return false;for(u=l(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=l(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function a(n){return"\\"+Y[n]
-+}function i(){return v.pop()||[]}function l(){return y.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function f(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function c(n){n.length=0,v.length<w&&v.push(n)}function p(n){var t=n.l;t&&p(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,y.length<w&&y.push(n)}function s(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r];
-+return u}function g(e){function v(n){return n&&typeof n=="object"&&!qe(n)&&we.call(n,"__wrapped__")?n:new y(n)}function y(n,t){this.__chain__=!!t,this.__wrapped__=n}function w(n){function t(){if(r){var n=s(r);je.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return xt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return ze(t,n),t}function Y(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!xt(n))return n;var a=he.call(n);if(!V[a]||!Le.nodeClass&&f(n))return n;
-+var l=Te[a];switch(a){case L:case z:return new l(+n);case W:case M:return new l(n);case J:return o=l(n.source,S.exec(n)),o.lastIndex=n.lastIndex,o}if(a=qe(n),t){var p=!r;r||(r=i()),u||(u=i());for(var g=r.length;g--;)if(r[g]==n)return u[g];o=a?l(n.length):{}}else o=a?s(n):Ye({},n);return a&&(we.call(n,"index")&&(o.index=n.index),we.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(a?Xe:tr)(n,function(n,a){o[a]=Y(n,t,e,r,u)}),p&&(c(r),c(u)),o):o}function nt(n){return xt(n)?Se(n):{}}function tt(n,t,e){if(typeof n!="function")return Ht;
-+if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(Le.funcNames&&(r=!n.name),r=r||!Le.funcDecomp,!r)){var u=be.call(n);Le.funcNames||(r=!A.test(u)),r||(r=B.test(u),ze(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=l?a:this;
-+if(u){var h=s(u);je.apply(h,arguments)}return(o||c)&&(h||(h=s(arguments)),o&&je.apply(h,o),c&&h.length<i)?(r|=16,et([e,p?r:-4&r,h,null,a,i])):(h||(h=arguments),f&&(e=n[g]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),xt(h)?h:n):e.apply(n,h))}var e=n[0],r=n[1],u=n[2],o=n[3],a=n[4],i=n[5],l=1&r,f=2&r,c=4&r,p=8&r,g=e;return ze(t,n),t}function rt(e,r){var u=-1,a=ht(),i=e?e.length:0,l=i>=_&&a===n,f=[];if(l){var c=o(r);c?(a=t,r=c):l=false}for(;++u<i;)c=e[u],0>a(r,c)&&f.push(c);return l&&p(r),f}function ot(n,t,e,r){r=(r||0)-1;
-+for(var u=n?n.length:0,o=[];++r<u;){var a=n[r];if(a&&typeof a=="object"&&typeof a.length=="number"&&(qe(a)||dt(a))){t||(a=ot(a,t,e));var i=-1,l=a.length,f=o.length;for(o.length+=l;++i<l;)o[f++]=a[i]}else e||o.push(a)}return o}function at(n,t,e,r,u,o){if(e){var a=e(n,t);if(typeof a!="undefined")return!!a}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&X[typeof n]||t&&X[typeof t]))return false;if(null==n||null==t)return n===t;var l=he.call(n),p=he.call(t);if(l==T&&(l=G),p==T&&(p=G),l!=p)return false;switch(l){case L:case z:return+n==+t;
-+case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case J:case M:return n==ie(t)}if(p=l==$,!p){var s=we.call(n,"__wrapped__"),g=we.call(t,"__wrapped__");if(s||g)return at(s?n.__wrapped__:n,g?t.__wrapped__:t,e,r,u,o);if(l!=G||!Le.nodeClass&&(f(n)||f(t)))return false;if(l=!Le.argsObject&&dt(n)?oe:n.constructor,s=!Le.argsObject&&dt(t)?oe:t.constructor,l!=s&&!(jt(l)&&l instanceof l&&jt(s)&&s instanceof s)&&"constructor"in n&&"constructor"in t)return false}for(l=!u,u||(u=i()),o||(o=i()),s=u.length;s--;)if(u[s]==n)return o[s]==t;
-+var h=0,a=true;if(u.push(n),o.push(t),p){if(s=n.length,h=t.length,(a=h==s)||r)for(;h--;)if(p=s,g=t[h],r)for(;p--&&!(a=at(n[p],g,e,r,u,o)););else if(!(a=at(n[h],g,e,r,u,o)))break}else nr(t,function(t,i,l){return we.call(l,i)?(h++,a=we.call(n,i)&&at(n[i],t,e,r,u,o)):void 0}),a&&!r&&nr(n,function(n,t,e){return we.call(e,t)?a=-1<--h:void 0});return u.pop(),o.pop(),l&&(c(u),c(o)),a}function it(n,t,e,r,u){(qe(t)?Dt:tr)(t,function(t,o){var a,i,l=t,f=n[o];if(t&&((i=qe(t))||er(t))){for(l=r.length;l--;)if(a=r[l]==t){f=u[l];
-+break}if(!a){var c;e&&(l=e(f,t),c=typeof l!="undefined")&&(f=l),c||(f=i?qe(f)?f:[]:er(f)?f:{}),r.push(t),u.push(f),c||it(f,t,e,r,u)}}else e&&(l=e(f,t),typeof l=="undefined"&&(l=t)),typeof l!="undefined"&&(f=l);n[o]=f})}function lt(n,t){return n+de(Fe()*(t-n+1))}function ft(e,r,u){var a=-1,l=ht(),f=e?e.length:0,s=[],g=!r&&f>=_&&l===n,h=u||g?i():s;for(g&&(h=o(h),l=t);++a<f;){var v=e[a],y=u?u(v,a,e):v;(r?!a||h[h.length-1]!==y:0>l(h,y))&&((u||g)&&h.push(y),s.push(v))}return g?(c(h.k),p(h)):u&&c(h),s}function ct(n){return function(t,e,r){var u={};
-+if(e=v.createCallback(e,r,3),qe(t)){r=-1;for(var o=t.length;++r<o;){var a=t[r];n(u,a,e(a,r,t),t)}}else Xe(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function pt(n,t,e,r,u,o){var a=1&t,i=4&t,l=16&t,f=32&t;if(!(2&t||jt(n)))throw new le;l&&!e.length&&(t&=-17,l=e=false),f&&!r.length&&(t&=-33,f=r=false);var c=n&&n.__bindData__;return c&&true!==c?(c=s(c),c[2]&&(c[2]=s(c[2])),c[3]&&(c[3]=s(c[3])),!a||1&c[1]||(c[4]=u),!a&&1&c[1]&&(t|=8),!i||4&c[1]||(c[5]=o),l&&je.apply(c[2]||(c[2]=[]),e),f&&Ee.apply(c[3]||(c[3]=[]),r),c[1]|=t,pt.apply(null,c)):(1==t||17===t?w:et)([n,t,e,r,u,o])
-+}function st(){Q.h=F,Q.b=Q.c=Q.g=Q.i="",Q.e="t",Q.j=true;for(var n,t=0;n=arguments[t];t++)for(var e in n)Q[e]=n[e];t=Q.a,Q.d=/^[^,]+/.exec(t)[0],n=ee,t="return function("+t+"){",e=Q;var r="var n,t="+e.d+",E="+e.e+";if(!t)return E;"+e.i+";";e.b?(r+="var u=t.length;n=-1;if("+e.b+"){",Le.unindexedChars&&(r+="if(s(t)){t=t.split('')}"),r+="while(++n<u){"+e.g+";}}else{"):Le.nonEnumArgs&&(r+="var u=t.length;n=-1;if(u&&p(t)){while(++n<u){n+='';"+e.g+";}}else{"),Le.enumPrototypes&&(r+="var G=typeof t=='function';"),Le.enumErrorProps&&(r+="var F=t===k||t instanceof Error;");
-+var u=[];if(Le.enumPrototypes&&u.push('!(G&&n=="prototype")'),Le.enumErrorProps&&u.push('!(F&&(n=="message"||n=="name"))'),e.j&&e.f)r+="var C=-1,D=B[typeof t]&&v(t),u=D?D.length:0;while(++C<u){n=D[C];",u.length&&(r+="if("+u.join("&&")+"){"),r+=e.g+";",u.length&&(r+="}"),r+="}";else if(r+="for(n in t){",e.j&&u.push("m.call(t, n)"),u.length&&(r+="if("+u.join("&&")+"){"),r+=e.g+";",u.length&&(r+="}"),r+="}",Le.nonEnumShadows){for(r+="if(t!==A){var i=t.constructor,r=t===(i&&i.prototype),f=t===J?I:t===k?j:L.call(t),x=y[f];",k=0;7>k;k++)r+="n='"+e.h[k]+"';if((!(r&&x[n])&&m.call(t,n))",e.j||(r+="||(!x[n]&&t[n]!==A[n])"),r+="){"+e.g+"}";
-+r+="}"}return(e.b||Le.nonEnumArgs)&&(r+="}"),r+=e.c+";return E",n("d,j,k,m,o,p,q,s,v,A,B,y,I,J,L",t+r+"}")(tt,q,ce,we,d,dt,qe,kt,Q.f,pe,X,$e,M,se,he)}function gt(n){return Ve[n]}function ht(){var t=(t=v.indexOf)===zt?n:t;return t}function vt(n){return typeof n=="function"&&ve.test(n)}function yt(n){var t,e;return!n||he.call(n)!=G||(t=n.constructor,jt(t)&&!(t instanceof t))||!Le.argsClass&&dt(n)||!Le.nodeClass&&f(n)?false:Le.ownLast?(nr(n,function(n,t,r){return e=we.call(r,t),false}),false!==e):(nr(n,function(n,t){e=t
-+}),typeof e=="undefined"||we.call(n,e))}function mt(n){return He[n]}function dt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&he.call(n)==T||false}function bt(n,t,e){var r=We(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function _t(n){var t=[];return nr(n,function(n,e){jt(n)&&t.push(e)}),t.sort()}function wt(n){for(var t=-1,e=We(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function jt(n){return typeof n=="function"}function xt(n){return!(!n||!X[typeof n])
-+}function Ct(n){return typeof n=="number"||n&&typeof n=="object"&&he.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&he.call(n)==M||false}function Et(n){for(var t=-1,e=We(n),r=e.length,u=Zt(r);++t<r;)u[t]=n[e[t]];return u}function Ot(n,t,e){var r=-1,u=ht(),o=n?n.length:0,a=false;return e=(0>e?Be(0,o+e):e)||0,qe(n)?a=-1<u(n,t,e):typeof o=="number"?a=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):Xe(n,function(n){return++r<e?void 0:!(a=n===t)}),a}function St(n,t,e){var r=true;if(t=v.createCallback(t,e,3),qe(n)){e=-1;
-+for(var u=n.length;++e<u&&(r=!!t(n[e],e,n)););}else Xe(n,function(n,e,u){return r=!!t(n,e,u)});return r}function At(n,t,e){var r=[];if(t=v.createCallback(t,e,3),qe(n)){e=-1;for(var u=n.length;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}}else Xe(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){if(t=v.createCallback(t,e,3),!qe(n)){var r;return Xe(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0}),r}e=-1;for(var u=n.length;++e<u;){var o=n[e];if(t(o,e,n))return o}}function Dt(n,t,e){if(t&&typeof e=="undefined"&&qe(n)){e=-1;
-+for(var r=n.length;++e<r&&false!==t(n[e],e,n););}else Xe(n,t,e);return n}function Nt(n,t,e){var r=n,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),qe(n))for(;u--&&false!==t(n[u],u,n););else{if(typeof u!="number")var o=We(n),u=o.length;else Le.unindexedChars&&kt(n)&&(r=n.split(""));Xe(n,function(n,e,a){return e=o?o[--u]:--u,t(r[e],e,a)})}return n}function Bt(n,t,e){var r=-1,u=n?n.length:0,o=Zt(typeof u=="number"?u:0);if(t=v.createCallback(t,e,3),qe(n))for(;++r<u;)o[r]=t(n[r],r,n);else Xe(n,function(n,e,u){o[++r]=t(n,e,u)
-+});return o}function Pt(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&qe(n)){e=-1;for(var a=n.length;++e<a;){var i=n[e];i>o&&(o=i)}}else t=null==t&&kt(n)?r:v.createCallback(t,e,3),Xe(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Rt(n,t,e,r){var u=3>arguments.length;if(t=v.createCallback(t,r,4),qe(n)){var o=-1,a=n.length;for(u&&(e=n[++o]);++o<a;)e=t(e,n[o],o,n)}else Xe(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)});return e}function Ft(n,t,e,r){var u=3>arguments.length;
-+return t=v.createCallback(t,r,4),Nt(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Zt(typeof e=="number"?e:0);return Dt(n,function(n){var e=lt(0,++t);r[t]=r[e],r[e]=n}),r}function $t(n,t,e){var r;if(t=v.createCallback(t,e,3),qe(n)){e=-1;for(var u=n.length;++e<u&&!(r=t(n[e],e,n)););}else Xe(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Lt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1;for(t=v.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++
-+}else if(r=t,null==r||e)return n?n[0]:h;return s(n,0,Pe(Be(0,r),u))}function zt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Be(0,u+r):r||0}else if(r)return r=Kt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=v.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Be(0,t);return s(n,r)}function Kt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?v.createCallback(e,r,1):Ht,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;
-+return u}function Wt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=v.createCallback(e,r,3)),ft(n,t,e)}function Gt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?Pt(ar(n,"length")):0,r=Zt(0>e?0:e);++t<e;)r[t]=ar(n,t);return r}function Jt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||qe(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?pt(n,17,s(arguments,2),null,t):pt(n,1,null,null,t)
-+}function Vt(n,t,e){var r,u,o,a,i,l,f,c=0,p=false,s=true;if(!jt(n))throw new le;if(t=Be(0,t)||0,true===e)var g=true,s=false;else xt(e)&&(g=e.leading,p="maxWait"in e&&(Be(t,e.maxWait)||0),s="trailing"in e?e.trailing:s);var v=function(){var e=t-(ir()-a);0<e?l=Ce(v,e):(u&&me(u),e=f,u=l=f=h,e&&(c=ir(),o=n.apply(i,r),l||u||(r=i=null)))},y=function(){l&&me(l),u=l=f=h,(s||p!==t)&&(c=ir(),o=n.apply(i,r),l||u||(r=i=null))};return function(){if(r=arguments,a=ir(),i=this,f=s&&(l||!g),false===p)var e=g&&!l;else{u||g||(c=a);
-+var h=p-(a-c),m=0>=h;m?(u&&(u=me(u)),c=a,o=n.apply(i,r)):u||(u=Ce(y,h))}return m&&l?l=me(l):l||t===p||(l=Ce(v,t)),e&&(m=true,o=n.apply(i,r)),!m||l||u||(r=i=null),o}}function Ht(n){return n}function Ut(n,t,e){var r=true,u=t&&_t(t);t&&(e||u.length)||(null==e&&(e=t),o=y,t=n,n=v,u=_t(t)),false===e?r=false:xt(e)&&"chain"in e&&(r=e.chain);var o=n,a=jt(o);Dt(u,function(e){var u=n[e]=t[e];a&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,a=[e];if(je.apply(a,arguments),a=u.apply(n,a),r||t){if(e===a&&xt(a))return this;
-+a=new o(a),a.__chain__=t}return a})})}function Qt(){}function Xt(n){return function(t){return t[n]}}function Yt(){return this.__wrapped__}e=e?ut.defaults(Z.Object(),e,ut.pick(Z,R)):Z;var Zt=e.Array,ne=e.Boolean,te=e.Date,ee=e.Function,re=e.Math,ue=e.Number,oe=e.Object,ae=e.RegExp,ie=e.String,le=e.TypeError,fe=[],ce=e.Error.prototype,pe=oe.prototype,se=ie.prototype,ge=e._,he=pe.toString,ve=ae("^"+ie(he).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),ye=re.ceil,me=e.clearTimeout,de=re.floor,be=ee.prototype.toString,_e=vt(_e=oe.getPrototypeOf)&&_e,we=pe.hasOwnProperty,je=fe.push,xe=pe.propertyIsEnumerable,Ce=e.setTimeout,ke=fe.splice,Ee=fe.unshift,Oe=function(){try{var n={},t=vt(t=oe.defineProperty)&&t,e=t(n,n,n)&&t
-+}catch(r){}return e}(),Se=vt(Se=oe.create)&&Se,Ae=vt(Ae=Zt.isArray)&&Ae,Ie=e.isFinite,De=e.isNaN,Ne=vt(Ne=oe.keys)&&Ne,Be=re.max,Pe=re.min,Re=e.parseInt,Fe=re.random,Te={};Te[$]=Zt,Te[L]=ne,Te[z]=te,Te[K]=ee,Te[G]=oe,Te[W]=ue,Te[J]=ae,Te[M]=ie;var $e={};$e[$]=$e[z]=$e[W]={constructor:true,toLocaleString:true,toString:true,valueOf:true},$e[L]=$e[M]={constructor:true,toString:true,valueOf:true},$e[q]=$e[K]=$e[J]={constructor:true,toString:true},$e[G]={constructor:true},function(){for(var n=F.length;n--;){var t,e=F[n];
-+for(t in $e)we.call($e,t)&&!we.call($e[t],e)&&($e[t][e]=false)}}(),y.prototype=v.prototype;var Le=v.support={};!function(){var n=function(){this.x=1},t={0:1,length:1},r=[];n.prototype={valueOf:1,y:1};for(var u in new n)r.push(u);for(u in arguments);Le.argsClass=he.call(arguments)==T,Le.argsObject=arguments.constructor==oe&&!(arguments instanceof Zt),Le.enumErrorProps=xe.call(ce,"message")||xe.call(ce,"name"),Le.enumPrototypes=xe.call(n,"prototype"),Le.funcDecomp=!vt(e.WinRTError)&&B.test(g),Le.funcNames=typeof ee.name=="string",Le.nonEnumArgs=0!=u,Le.nonEnumShadows=!/valueOf/.test(r),Le.ownLast="x"!=r[0],Le.spliceObjects=(fe.splice.call(t,0,1),!t[0]),Le.unindexedChars="xx"!="x"[0]+oe("x")[0];
-+try{Le.nodeClass=!(he.call(document)==G&&!({toString:0}+""))}catch(o){Le.nodeClass=true}}(1),v.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:I,variable:"",imports:{_:v}},Se||(nt=function(){function n(){}return function(t){if(xt(t)){n.prototype=t;var r=new n;n.prototype=null}return r||e.Object()}}());var ze=Oe?function(n,t){U.value=t,Oe(n,"__bindData__",U)}:Qt;Le.argsClass||(dt=function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&we.call(n,"callee")&&!xe.call(n,"callee")||false
-+});var qe=Ae||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&he.call(n)==$||false},Ke=st({a:"z",e:"[]",i:"if(!(B[typeof z]))return E",g:"E.push(n)"}),We=Ne?function(n){return xt(n)?Le.enumPrototypes&&typeof n=="function"||Le.nonEnumArgs&&n.length&&dt(n)?Ke(n):Ne(n):[]}:Ke,Ge={a:"g,e,K",i:"e=e&&typeof K=='undefined'?e:d(e,K,3)",b:"typeof u=='number'",v:We,g:"if(e(t[n],n,g)===false)return E"},Je={a:"z,H,l",i:"var a=arguments,b=0,c=typeof l=='number'?2:a.length;while(++b<c){t=a[b];if(t&&B[typeof t]){",v:We,g:"if(typeof E[n]=='undefined')E[n]=t[n]",c:"}}"},Me={i:"if(!B[typeof t])return E;"+Ge.i,b:false},Ve={"&":"&","<":"<",">":">",'"':""","'":"'"},He=wt(Ve),Ue=ae("("+We(He).join("|")+")","g"),Qe=ae("["+We(Ve).join("")+"]","g"),Xe=st(Ge),Ye=st(Je,{i:Je.i.replace(";",";if(c>3&&typeof a[c-2]=='function'){var e=d(a[--c-1],a[c--],2)}else if(c>2&&typeof a[c-1]=='function'){e=a[--c]}"),g:"E[n]=e?e(E[n],t[n]):t[n]"}),Ze=st(Je),nr=st(Ge,Me,{j:false}),tr=st(Ge,Me);
-+jt(/x/)&&(jt=function(n){return typeof n=="function"&&he.call(n)==K});var er=_e?function(n){if(!n||he.call(n)!=G||!Le.argsClass&&dt(n))return false;var t=n.valueOf,e=vt(t)&&(e=_e(t))&&_e(e);return e?n==e||_e(n)==e:yt(n)}:yt,rr=ct(function(n,t,e){we.call(n,e)?n[e]++:n[e]=1}),ur=ct(function(n,t,e){(we.call(n,e)?n[e]:n[e]=[]).push(t)}),or=ct(function(n,t,e){n[e]=t}),ar=Bt,ir=vt(ir=te.now)&&ir||function(){return(new te).getTime()},lr=8==Re(j+"08")?Re:function(n,t){return Re(kt(n)?n.replace(D,""):n,t||0)};
-+return v.after=function(n,t){if(!jt(t))throw new le;return function(){return 1>--n?t.apply(this,arguments):void 0}},v.assign=Ye,v.at=function(n){var t=arguments,e=-1,r=ot(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Zt(t);for(Le.unindexedChars&&kt(n)&&(n=n.split(""));++e<t;)u[e]=n[r[e]];return u},v.bind=Mt,v.bindAll=function(n){for(var t=1<arguments.length?ot(arguments,true,false,1):_t(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=pt(n[u],1,null,null,n)}return n},v.bindKey=function(n,t){return 2<arguments.length?pt(t,19,s(arguments,2),null,n):pt(t,3,null,null,n)
-+},v.chain=function(n){return n=new y(n),n.__chain__=true,n},v.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},v.compose=function(){for(var n=arguments,t=n.length;t--;)if(!jt(n[t]))throw new le;return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},v.constant=function(n){return function(){return n}},v.countBy=rr,v.create=function(n,t){var e=nt(n);return t?Ye(e,t):e},v.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e);
-+if("object"!=r)return Xt(n);var u=We(n),o=u[0],a=n[o];return 1!=u.length||a!==a||xt(a)?function(t){for(var e=u.length,r=false;e--&&(r=at(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],a===n&&(0!==a||1/a==1/n)}},v.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,pt(n,4,null,null,null,t)},v.debounce=Vt,v.defaults=Ze,v.defer=function(n){if(!jt(n))throw new le;var t=s(arguments,1);return Ce(function(){n.apply(h,t)},1)},v.delay=function(n,t){if(!jt(n))throw new le;var e=s(arguments,2);
-+return Ce(function(){n.apply(h,e)},t)},v.difference=function(n){return rt(n,ot(arguments,true,true,1))},v.filter=At,v.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Bt(n,e,r)),ot(n,t)},v.forEach=Dt,v.forEachRight=Nt,v.forIn=nr,v.forInRight=function(n,t,e){var r=[];nr(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},v.forOwn=tr,v.forOwnRight=bt,v.functions=_t,v.groupBy=ur,v.indexBy=or,v.initial=function(n,t,e){var r=0,u=n?n.length:0;
-+if(typeof t!="number"&&null!=t){var o=u;for(t=v.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return s(n,0,Pe(Be(0,u-r),u))},v.intersection=function(){for(var e=[],r=-1,u=arguments.length,a=i(),l=ht(),f=l===n,s=i();++r<u;){var g=arguments[r];(qe(g)||dt(g))&&(e.push(g),a.push(f&&g.length>=_&&o(r?e[r]:s)))}var f=e[0],h=-1,v=f?f.length:0,y=[];n:for(;++h<v;){var m=a[0],g=f[h];if(0>(m?t(m,g):l(s,g))){for(r=u,(m||s).push(g);--r;)if(m=a[r],0>(m?t(m,g):l(e[r],g)))continue n;y.push(g)
-+}}for(;u--;)(m=a[u])&&p(m);return c(a),c(s),y},v.invert=wt,v.invoke=function(n,t){var e=s(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,a=Zt(typeof o=="number"?o:0);return Dt(n,function(n){a[++r]=(u?t:n[t]).apply(n,e)}),a},v.keys=We,v.map=Bt,v.mapValues=function(n,t,e){var r={};return t=v.createCallback(t,e,3),tr(n,function(n,e,u){r[e]=t(n,e,u)}),r},v.max=Pt,v.memoize=function(n,t){if(!jt(n))throw new le;var e=function(){var r=e.cache,u=t?t.apply(this,arguments):b+arguments[0];return we.call(r,u)?r[u]:r[u]=n.apply(this,arguments)
-+};return e.cache={},e},v.merge=function(n){var t=arguments,e=2;if(!xt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=s(arguments,1,e),u=-1,o=i(),a=i();++u<e;)it(n,t[u],r,o,a);return c(o),c(a),n},v.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&qe(n)){e=-1;for(var a=n.length;++e<a;){var i=n[e];i<o&&(o=i)}}else t=null==t&&kt(n)?r:v.createCallback(t,e,3),Xe(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n)
-+});return o},v.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];nr(n,function(n,t){u.push(t)});for(var u=rt(u,ot(arguments,true,false,1)),o=-1,a=u.length;++o<a;){var i=u[o];r[i]=n[i]}}else t=v.createCallback(t,e,3),nr(n,function(n,e,u){t(n,e,u)||(r[e]=n)});return r},v.once=function(n){var t,e;if(!jt(n))throw new le;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},v.pairs=function(n){for(var t=-1,e=We(n),r=e.length,u=Zt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u
-+},v.partial=function(n){return pt(n,16,s(arguments,1))},v.partialRight=function(n){return pt(n,32,null,s(arguments,1))},v.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ot(arguments,true,false,1),a=xt(n)?o.length:0;++u<a;){var i=o[u];i in n&&(r[i]=n[i])}else t=v.createCallback(t,e,3),nr(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},v.pluck=ar,v.property=Xt,v.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,a=t[e];++o<u;)n[o]===a&&(ke.call(n,o--,1),u--);
-+return n},v.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Be(0,ye((t-n)/(e||1)));for(var u=Zt(t);++r<t;)u[r]=n,n+=e;return u},v.reject=function(n,t,e){return t=v.createCallback(t,e,3),At(n,function(n,e,r){return!t(n,e,r)})},v.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=v.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),ke.call(n,r--,1),u--);return o},v.rest=qt,v.shuffle=Tt,v.sortBy=function(n,t,e){var r=-1,o=qe(t),a=n?n.length:0,f=Zt(typeof a=="number"?a:0);
-+for(o||(t=v.createCallback(t,e,3)),Dt(n,function(n,e,u){var a=f[++r]=l();o?a.m=Bt(t,function(t){return n[t]}):(a.m=i())[0]=t(n,e,u),a.n=r,a.o=n}),a=f.length,f.sort(u);a--;)n=f[a],f[a]=n.o,o||c(n.m),p(n);return f},v.tap=function(n,t){return t(n),n},v.throttle=function(n,t,e){var r=true,u=true;if(!jt(n))throw new le;return false===e?r=false:xt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),H.leading=r,H.maxWait=t,H.trailing=u,Vt(n,t,H)},v.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Zt(n);
-+for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},v.toArray=function(n){return n&&typeof n.length=="number"?Le.unindexedChars&&kt(n)?n.split(""):s(n):Et(n)},v.transform=function(n,t,e,r){var u=qe(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=v.createCallback(t,r,4),(u?Xe:tr)(n,function(n,r,u){return t(e,n,r,u)})),e},v.union=function(){return ft(ot(arguments,true,true))},v.uniq=Wt,v.values=Et,v.where=At,v.without=function(n){return rt(n,s(arguments,1))},v.wrap=function(n,t){return pt(t,16,[n])
-+},v.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(qe(e)||dt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},v.zip=Gt,v.zipObject=Jt,v.collect=Bt,v.drop=qt,v.each=Dt,v.eachRight=Nt,v.extend=Ye,v.methods=_t,v.object=Jt,v.select=At,v.tail=qt,v.unique=Wt,v.unzip=Gt,Ut(v),v.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Y(n,t,typeof e=="function"&&tt(e,r,1))},v.cloneDeep=function(n,t,e){return Y(n,true,typeof t=="function"&&tt(t,e,1))},v.contains=Ot,v.escape=function(n){return null==n?"":ie(n).replace(Qe,gt)
-+},v.every=St,v.find=It,v.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=v.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},v.findKey=function(n,t,e){var r;return t=v.createCallback(t,e,3),tr(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},v.findLast=function(n,t,e){var r;return t=v.createCallback(t,e,3),Nt(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0}),r},v.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=v.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r;
-+return-1},v.findLastKey=function(n,t,e){var r;return t=v.createCallback(t,e,3),bt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},v.has=function(n,t){return n?we.call(n,t):false},v.identity=Ht,v.indexOf=zt,v.isArguments=dt,v.isArray=qe,v.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&he.call(n)==L||false},v.isDate=function(n){return n&&typeof n=="object"&&he.call(n)==z||false},v.isElement=function(n){return n&&1===n.nodeType||false},v.isEmpty=function(n){var t=true;if(!n)return t;var e=he.call(n),r=n.length;
-+return e==$||e==M||(Le.argsClass?e==T:dt(n))||e==G&&typeof r=="number"&&jt(n.splice)?!r:(tr(n,function(){return t=false}),t)},v.isEqual=function(n,t,e,r){return at(n,t,typeof e=="function"&&tt(e,r,2))},v.isFinite=function(n){return Ie(n)&&!De(parseFloat(n))},v.isFunction=jt,v.isNaN=function(n){return Ct(n)&&n!=+n},v.isNull=function(n){return null===n},v.isNumber=Ct,v.isObject=xt,v.isPlainObject=er,v.isRegExp=function(n){return n&&X[typeof n]&&he.call(n)==J||false},v.isString=kt,v.isUndefined=function(n){return typeof n=="undefined"
-+},v.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Be(0,r+e):Pe(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},v.mixin=Ut,v.noConflict=function(){return e._=ge,this},v.noop=Qt,v.now=ir,v.parseInt=lr,v.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Fe(),Pe(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):lt(n,t)},v.reduce=Rt,v.reduceRight=Ft,v.result=function(n,t){if(n){var e=n[t];
-+return jt(e)?n[t]():e}},v.runInContext=g,v.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:We(n).length},v.some=$t,v.sortedIndex=Kt,v.template=function(n,t,e){var r=v.templateSettings;n=ie(n||""),e=Ze({},e,r);var u,o=Ze({},e.imports,r.imports),r=We(o),o=Et(o),i=0,l=e.interpolate||N,f="__p+='",l=ae((e.escape||N).source+"|"+l.source+"|"+(l===I?O:N).source+"|"+(e.evaluate||N).source+"|$","g");n.replace(l,function(t,e,r,o,l,c){return r||(r=o),f+=n.slice(i,c).replace(P,a),e&&(f+="'+__e("+e+")+'"),l&&(u=true,f+="';"+l+";\n__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),i=c+t.length,t
-+}),f+="';",l=e=e.variable,l||(e="obj",f="with("+e+"){"+f+"}"),f=(u?f.replace(x,""):f).replace(C,"$1").replace(E,"$1;"),f="function("+e+"){"+(l?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var c=ee(r,"return "+f).apply(h,o)}catch(p){throw p.source=f,p}return t?c(t):(c.source=f,c)},v.unescape=function(n){return null==n?"":ie(n).replace(Ue,mt)},v.uniqueId=function(n){var t=++m;return ie(null==n?"":n)+t
-+},v.all=St,v.any=$t,v.detect=It,v.findWhere=It,v.foldl=Rt,v.foldr=Ft,v.include=Ot,v.inject=Rt,Ut(function(){var n={};return tr(v,function(t,e){v.prototype[e]||(n[e]=t)}),n}(),false),v.first=Lt,v.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=v.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:h;return s(n,Be(0,u-r))},v.sample=function(n,t,e){return n&&typeof n.length!="number"?n=Et(n):Le.unindexedChars&&kt(n)&&(n=n.split("")),null==t||e?n?n[lt(0,n.length-1)]:h:(n=Tt(n),n.length=Pe(Be(0,t),n.length),n)
-+},v.take=Lt,v.head=Lt,tr(v,function(n,t){var e="sample"!==t;v.prototype[t]||(v.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new y(o,u):o})}),v.VERSION="2.4.1",v.prototype.chain=function(){return this.__chain__=true,this},v.prototype.toString=function(){return ie(this.__wrapped__)},v.prototype.value=Yt,v.prototype.valueOf=Yt,Xe(["join","pop","shift"],function(n){var t=fe[n];v.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments);
-+return n?new y(e,n):e}}),Xe(["push","reverse","sort","unshift"],function(n){var t=fe[n];v.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),Xe(["concat","slice","splice"],function(n){var t=fe[n];v.prototype[n]=function(){return new y(t.apply(this.__wrapped__,arguments),this.__chain__)}}),Le.spliceObjects||Xe(["pop","shift","splice"],function(n){var t=fe[n],e="splice"==n;v.prototype[n]=function(){var n=this.__chain__,r=this.__wrapped__,u=t.apply(r,arguments);return 0===r.length&&delete r[0],n||e?new y(u,n):u
-+}}),v}var h,v=[],y=[],m=0,d={},b=+new Date+"",_=75,w=40,j=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",x=/\b__p\+='';/g,C=/\b(__p\+=)''\+/g,E=/(__e\(.*?\)|\b__t\))\+'';/g,O=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,S=/\w*$/,A=/^\s*function[ \n\r\t]+\w/,I=/<%=([\s\S]+?)%>/g,D=RegExp("^["+j+"]*0+(?=.$)"),N=/($^)/,B=/\bthis\b/,P=/['\n\r\t\u2028\u2029\\]/g,R="Array Boolean Date Error Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),F="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="[object Arguments]",$="[object Array]",L="[object Boolean]",z="[object Date]",q="[object Error]",K="[object Function]",W="[object Number]",G="[object Object]",J="[object RegExp]",M="[object String]",V={};
-+V[K]=false,V[T]=V[$]=V[L]=V[z]=V[W]=V[G]=V[J]=V[M]=true;var H={leading:false,maxWait:0,trailing:false},U={configurable:false,enumerable:false,value:null,writable:false},Q={a:"",b:null,c:"",d:"",e:"",v:null,g:"",h:null,support:null,i:"",j:false},X={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},Y={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},Z=X[typeof window]&&window||this,nt=X[typeof exports]&&exports&&!exports.nodeType&&exports,tt=X[typeof module]&&module&&!module.nodeType&&module,et=tt&&tt.exports===nt&&nt,rt=X[typeof global]&&global;
-+!rt||rt.global!==rt&&rt.window!==rt||(Z=rt);var ut=g();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Z._=ut, define(function(){return ut})):nt&&tt?et?(tt.exports=ut)._=ut:nt._=ut:Z._=ut}).call(this);
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.js
-@@ -0,0 +1,6785 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
-+ * Build: `lodash modern -o ./dist/lodash.js`
-+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
-+ * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
-+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+ * Available under MIT license <http://lodash.com/license>
-+ */
-+;(function() {
-+
-+  /** Used as a safe reference for `undefined` in pre ES5 environments */
-+  var undefined;
-+
-+  /** Used to pool arrays and objects used internally */
-+  var arrayPool = [],
-+      objectPool = [];
-+
-+  /** Used to generate unique IDs */
-+  var idCounter = 0;
-+
-+  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
-+  var keyPrefix = +new Date + '';
-+
-+  /** Used as the size when optimizations are enabled for large arrays */
-+  var largeArraySize = 75;
-+
-+  /** Used as the max size of the `arrayPool` and `objectPool` */
-+  var maxPoolSize = 40;
-+
-+  /** Used to detect and test whitespace */
-+  var whitespace = (
-+    // whitespace
-+    ' \t\x0B\f\xA0\ufeff' +
-+
-+    // line terminators
-+    '\n\r\u2028\u2029' +
-+
-+    // unicode category "Zs" space separators
-+    '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-+  );
-+
-+  /** Used to match empty string literals in compiled template source */
-+  var reEmptyStringLeading = /\b__p \+= '';/g,
-+      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
-+      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-+
-+  /**
-+   * Used to match ES6 template delimiters
-+   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
-+   */
-+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-+
-+  /** Used to match regexp flags from their coerced string values */
-+  var reFlags = /\w*$/;
-+
-+  /** Used to detected named functions */
-+  var reFuncName = /^\s*function[ \n\r\t]+\w/;
-+
-+  /** Used to match "interpolate" template delimiters */
-+  var reInterpolate = /<%=([\s\S]+?)%>/g;
-+
-+  /** Used to match leading whitespace and zeros to be removed */
-+  var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-+
-+  /** Used to ensure capturing order of template delimiters */
-+  var reNoMatch = /($^)/;
-+
-+  /** Used to detect functions containing a `this` reference */
-+  var reThis = /\bthis\b/;
-+
-+  /** Used to match unescaped characters in compiled string literals */
-+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-+
-+  /** Used to assign default `context` object properties */
-+  var contextProps = [
-+    'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
-+    'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
-+    'parseInt', 'setTimeout'
-+  ];
-+
-+  /** Used to make template sourceURLs easier to identify */
-+  var templateCounter = 0;
-+
-+  /** `Object#toString` result shortcuts */
-+  var argsClass = '[object Arguments]',
-+      arrayClass = '[object Array]',
-+      boolClass = '[object Boolean]',
-+      dateClass = '[object Date]',
-+      funcClass = '[object Function]',
-+      numberClass = '[object Number]',
-+      objectClass = '[object Object]',
-+      regexpClass = '[object RegExp]',
-+      stringClass = '[object String]';
-+
-+  /** Used to identify object classifications that `_.clone` supports */
-+  var cloneableClasses = {};
-+  cloneableClasses[funcClass] = false;
-+  cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
-+  cloneableClasses[boolClass] = cloneableClasses[dateClass] =
-+  cloneableClasses[numberClass] = cloneableClasses[objectClass] =
-+  cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-+
-+  /** Used as an internal `_.debounce` options object */
-+  var debounceOptions = {
-+    'leading': false,
-+    'maxWait': 0,
-+    'trailing': false
-+  };
-+
-+  /** Used as the property descriptor for `__bindData__` */
-+  var descriptor = {
-+    'configurable': false,
-+    'enumerable': false,
-+    'value': null,
-+    'writable': false
-+  };
-+
-+  /** Used to determine if values are of the language type Object */
-+  var objectTypes = {
-+    'boolean': false,
-+    'function': true,
-+    'object': true,
-+    'number': false,
-+    'string': false,
-+    'undefined': false
-+  };
-+
-+  /** Used to escape characters for inclusion in compiled string literals */
-+  var stringEscapes = {
-+    '\\': '\\',
-+    "'": "'",
-+    '\n': 'n',
-+    '\r': 'r',
-+    '\t': 't',
-+    '\u2028': 'u2028',
-+    '\u2029': 'u2029'
-+  };
-+
-+  /** Used as a reference to the global object */
-+  var root = (objectTypes[typeof window] && window) || this;
-+
-+  /** Detect free variable `exports` */
-+  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-+
-+  /** Detect free variable `module` */
-+  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-+
-+  /** Detect the popular CommonJS extension `module.exports` */
-+  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-+
-+  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
-+  var freeGlobal = objectTypes[typeof global] && global;
-+  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
-+    root = freeGlobal;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * The base implementation of `_.indexOf` without support for binary searches
-+   * or `fromIndex` constraints.
-+   *
-+   * @private
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {number} [fromIndex=0] The index to search from.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   */
-+  function baseIndexOf(array, value, fromIndex) {
-+    var index = (fromIndex || 0) - 1,
-+        length = array ? array.length : 0;
-+
-+    while (++index < length) {
-+      if (array[index] === value) {
-+        return index;
-+      }
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * An implementation of `_.contains` for cache objects that mimics the return
-+   * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
-+   *
-+   * @private
-+   * @param {Object} cache The cache object to inspect.
-+   * @param {*} value The value to search for.
-+   * @returns {number} Returns `0` if `value` is found, else `-1`.
-+   */
-+  function cacheIndexOf(cache, value) {
-+    var type = typeof value;
-+    cache = cache.cache;
-+
-+    if (type == 'boolean' || value == null) {
-+      return cache[value] ? 0 : -1;
-+    }
-+    if (type != 'number' && type != 'string') {
-+      type = 'object';
-+    }
-+    var key = type == 'number' ? value : keyPrefix + value;
-+    cache = (cache = cache[type]) && cache[key];
-+
-+    return type == 'object'
-+      ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
-+      : (cache ? 0 : -1);
-+  }
-+
-+  /**
-+   * Adds a given value to the corresponding cache object.
-+   *
-+   * @private
-+   * @param {*} value The value to add to the cache.
-+   */
-+  function cachePush(value) {
-+    var cache = this.cache,
-+        type = typeof value;
-+
-+    if (type == 'boolean' || value == null) {
-+      cache[value] = true;
-+    } else {
-+      if (type != 'number' && type != 'string') {
-+        type = 'object';
-+      }
-+      var key = type == 'number' ? value : keyPrefix + value,
-+          typeCache = cache[type] || (cache[type] = {});
-+
-+      if (type == 'object') {
-+        (typeCache[key] || (typeCache[key] = [])).push(value);
-+      } else {
-+        typeCache[key] = true;
-+      }
-+    }
-+  }
-+
-+  /**
-+   * Used by `_.max` and `_.min` as the default callback when a given
-+   * collection is a string value.
-+   *
-+   * @private
-+   * @param {string} value The character to inspect.
-+   * @returns {number} Returns the code unit of given character.
-+   */
-+  function charAtCallback(value) {
-+    return value.charCodeAt(0);
-+  }
-+
-+  /**
-+   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
-+   * them in ascending order.
-+   *
-+   * @private
-+   * @param {Object} a The object to compare to `b`.
-+   * @param {Object} b The object to compare to `a`.
-+   * @returns {number} Returns the sort order indicator of `1` or `-1`.
-+   */
-+  function compareAscending(a, b) {
-+    var ac = a.criteria,
-+        bc = b.criteria,
-+        index = -1,
-+        length = ac.length;
-+
-+    while (++index < length) {
-+      var value = ac[index],
-+          other = bc[index];
-+
-+      if (value !== other) {
-+        if (value > other || typeof value == 'undefined') {
-+          return 1;
-+        }
-+        if (value < other || typeof other == 'undefined') {
-+          return -1;
-+        }
-+      }
-+    }
-+    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-+    // that causes it, under certain circumstances, to return the same value for
-+    // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
-+    //
-+    // This also ensures a stable sort in V8 and other engines.
-+    // See http://code.google.com/p/v8/issues/detail?id=90
-+    return a.index - b.index;
-+  }
-+
-+  /**
-+   * Creates a cache object to optimize linear searches of large arrays.
-+   *
-+   * @private
-+   * @param {Array} [array=[]] The array to search.
-+   * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
-+   */
-+  function createCache(array) {
-+    var index = -1,
-+        length = array.length,
-+        first = array[0],
-+        mid = array[(length / 2) | 0],
-+        last = array[length - 1];
-+
-+    if (first && typeof first == 'object' &&
-+        mid && typeof mid == 'object' && last && typeof last == 'object') {
-+      return false;
-+    }
-+    var cache = getObject();
-+    cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-+
-+    var result = getObject();
-+    result.array = array;
-+    result.cache = cache;
-+    result.push = cachePush;
-+
-+    while (++index < length) {
-+      result.push(array[index]);
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Used by `template` to escape characters for inclusion in compiled
-+   * string literals.
-+   *
-+   * @private
-+   * @param {string} match The matched character to escape.
-+   * @returns {string} Returns the escaped character.
-+   */
-+  function escapeStringChar(match) {
-+    return '\\' + stringEscapes[match];
-+  }
-+
-+  /**
-+   * Gets an array from the array pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Array} The array from the pool.
-+   */
-+  function getArray() {
-+    return arrayPool.pop() || [];
-+  }
-+
-+  /**
-+   * Gets an object from the object pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Object} The object from the pool.
-+   */
-+  function getObject() {
-+    return objectPool.pop() || {
-+      'array': null,
-+      'cache': null,
-+      'criteria': null,
-+      'false': false,
-+      'index': 0,
-+      'null': false,
-+      'number': null,
-+      'object': null,
-+      'push': null,
-+      'string': null,
-+      'true': false,
-+      'undefined': false,
-+      'value': null
-+    };
-+  }
-+
-+  /**
-+   * Releases the given array back to the array pool.
-+   *
-+   * @private
-+   * @param {Array} [array] The array to release.
-+   */
-+  function releaseArray(array) {
-+    array.length = 0;
-+    if (arrayPool.length < maxPoolSize) {
-+      arrayPool.push(array);
-+    }
-+  }
-+
-+  /**
-+   * Releases the given object back to the object pool.
-+   *
-+   * @private
-+   * @param {Object} [object] The object to release.
-+   */
-+  function releaseObject(object) {
-+    var cache = object.cache;
-+    if (cache) {
-+      releaseObject(cache);
-+    }
-+    object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
-+    if (objectPool.length < maxPoolSize) {
-+      objectPool.push(object);
-+    }
-+  }
-+
-+  /**
-+   * Slices the `collection` from the `start` index up to, but not including,
-+   * the `end` index.
-+   *
-+   * Note: This function is used instead of `Array#slice` to support node lists
-+   * in IE < 9 and to ensure dense arrays are returned.
-+   *
-+   * @private
-+   * @param {Array|Object|string} collection The collection to slice.
-+   * @param {number} start The start index.
-+   * @param {number} end The end index.
-+   * @returns {Array} Returns the new array.
-+   */
-+  function slice(array, start, end) {
-+    start || (start = 0);
-+    if (typeof end == 'undefined') {
-+      end = array ? array.length : 0;
-+    }
-+    var index = -1,
-+        length = end - start || 0,
-+        result = Array(length < 0 ? 0 : length);
-+
-+    while (++index < length) {
-+      result[index] = array[start + index];
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Create a new `lodash` function using the given context object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {Object} [context=root] The context object.
-+   * @returns {Function} Returns the `lodash` function.
-+   */
-+  function runInContext(context) {
-+    // Avoid issues with some ES3 environments that attempt to use values, named
-+    // after built-in constructors like `Object`, for the creation of literals.
-+    // ES5 clears this up by stating that literals must use built-in constructors.
-+    // See http://es5.github.io/#x11.1.5.
-+    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-+
-+    /** Native constructor references */
-+    var Array = context.Array,
-+        Boolean = context.Boolean,
-+        Date = context.Date,
-+        Function = context.Function,
-+        Math = context.Math,
-+        Number = context.Number,
-+        Object = context.Object,
-+        RegExp = context.RegExp,
-+        String = context.String,
-+        TypeError = context.TypeError;
-+
-+    /**
-+     * Used for `Array` method references.
-+     *
-+     * Normally `Array.prototype` would suffice, however, using an array literal
-+     * avoids issues in Narwhal.
-+     */
-+    var arrayRef = [];
-+
-+    /** Used for native method references */
-+    var objectProto = Object.prototype;
-+
-+    /** Used to restore the original `_` reference in `noConflict` */
-+    var oldDash = context._;
-+
-+    /** Used to resolve the internal [[Class]] of values */
-+    var toString = objectProto.toString;
-+
-+    /** Used to detect if a method is native */
-+    var reNative = RegExp('^' +
-+      String(toString)
-+        .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-+        .replace(/toString| for [^\]]+/g, '.*?') + '$'
-+    );
-+
-+    /** Native method shortcuts */
-+    var ceil = Math.ceil,
-+        clearTimeout = context.clearTimeout,
-+        floor = Math.floor,
-+        fnToString = Function.prototype.toString,
-+        getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
-+        hasOwnProperty = objectProto.hasOwnProperty,
-+        push = arrayRef.push,
-+        setTimeout = context.setTimeout,
-+        splice = arrayRef.splice,
-+        unshift = arrayRef.unshift;
-+
-+    /** Used to set meta data on functions */
-+    var defineProperty = (function() {
-+      // IE 8 only accepts DOM elements
-+      try {
-+        var o = {},
-+            func = isNative(func = Object.defineProperty) && func,
-+            result = func(o, o, o) && func;
-+      } catch(e) { }
-+      return result;
-+    }());
-+
-+    /* Native method shortcuts for methods with the same name as other `lodash` methods */
-+    var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
-+        nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
-+        nativeIsFinite = context.isFinite,
-+        nativeIsNaN = context.isNaN,
-+        nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
-+        nativeMax = Math.max,
-+        nativeMin = Math.min,
-+        nativeParseInt = context.parseInt,
-+        nativeRandom = Math.random;
-+
-+    /** Used to lookup a built-in constructor by [[Class]] */
-+    var ctorByClass = {};
-+    ctorByClass[arrayClass] = Array;
-+    ctorByClass[boolClass] = Boolean;
-+    ctorByClass[dateClass] = Date;
-+    ctorByClass[funcClass] = Function;
-+    ctorByClass[objectClass] = Object;
-+    ctorByClass[numberClass] = Number;
-+    ctorByClass[regexpClass] = RegExp;
-+    ctorByClass[stringClass] = String;
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object which wraps the given value to enable intuitive
-+     * method chaining.
-+     *
-+     * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
-+     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
-+     * and `unshift`
-+     *
-+     * Chaining is supported in custom builds as long as the `value` method is
-+     * implicitly or explicitly included in the build.
-+     *
-+     * The chainable wrapper functions are:
-+     * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
-+     * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
-+     * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
-+     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
-+     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
-+     * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
-+     * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
-+     * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
-+     * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
-+     * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
-+     * and `zip`
-+     *
-+     * The non-chainable wrapper functions are:
-+     * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
-+     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
-+     * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
-+     * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
-+     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
-+     * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
-+     * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
-+     * `template`, `unescape`, `uniqueId`, and `value`
-+     *
-+     * The wrapper functions `first` and `last` return wrapped values when `n` is
-+     * provided, otherwise they return unwrapped values.
-+     *
-+     * Explicit chaining can be enabled by using the `_.chain` method.
-+     *
-+     * @name _
-+     * @constructor
-+     * @category Chaining
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @returns {Object} Returns a `lodash` instance.
-+     * @example
-+     *
-+     * var wrapped = _([1, 2, 3]);
-+     *
-+     * // returns an unwrapped value
-+     * wrapped.reduce(function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * // returns a wrapped value
-+     * var squares = wrapped.map(function(num) {
-+     *   return num * num;
-+     * });
-+     *
-+     * _.isArray(squares);
-+     * // => false
-+     *
-+     * _.isArray(squares.value());
-+     * // => true
-+     */
-+    function lodash(value) {
-+      // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
-+      return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
-+       ? value
-+       : new lodashWrapper(value);
-+    }
-+
-+    /**
-+     * A fast path for creating `lodash` wrapper objects.
-+     *
-+     * @private
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @param {boolean} chainAll A flag to enable chaining for all methods
-+     * @returns {Object} Returns a `lodash` instance.
-+     */
-+    function lodashWrapper(value, chainAll) {
-+      this.__chain__ = !!chainAll;
-+      this.__wrapped__ = value;
-+    }
-+    // ensure `new lodashWrapper` is an instance of `lodash`
-+    lodashWrapper.prototype = lodash.prototype;
-+
-+    /**
-+     * An object used to flag environments features.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    var support = lodash.support = {};
-+
-+    /**
-+     * Detect if functions can be decompiled by `Function#toString`
-+     * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
-+     *
-+     * @memberOf _.support
-+     * @type boolean
-+     */
-+    support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-+
-+    /**
-+     * Detect if `Function#name` is supported (all but IE).
-+     *
-+     * @memberOf _.support
-+     * @type boolean
-+     */
-+    support.funcNames = typeof Function.name == 'string';
-+
-+    /**
-+     * By default, the template delimiters used by Lo-Dash are similar to those in
-+     * embedded Ruby (ERB). Change the following template settings to use alternative
-+     * delimiters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    lodash.templateSettings = {
-+
-+      /**
-+       * Used to detect `data` property values to be HTML-escaped.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'escape': /<%-([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect code to be evaluated.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'evaluate': /<%([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect `data` property values to inject.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'interpolate': reInterpolate,
-+
-+      /**
-+       * Used to reference the data object in the template text.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type string
-+       */
-+      'variable': '',
-+
-+      /**
-+       * Used to import variables into the compiled template.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type Object
-+       */
-+      'imports': {
-+
-+        /**
-+         * A reference to the `lodash` function.
-+         *
-+         * @memberOf _.templateSettings.imports
-+         * @type Function
-+         */
-+        '_': lodash
-+      }
-+    };
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The base implementation of `_.bind` that creates the bound function and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new bound function.
-+     */
-+    function baseBind(bindData) {
-+      var func = bindData[0],
-+          partialArgs = bindData[2],
-+          thisArg = bindData[4];
-+
-+      function bound() {
-+        // `Function#bind` spec
-+        // http://es5.github.io/#x15.3.4.5
-+        if (partialArgs) {
-+          // avoid `arguments` object deoptimizations by using `slice` instead
-+          // of `Array.prototype.slice.call` and not assigning `arguments` to a
-+          // variable as a ternary expression
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        // mimic the constructor's `return` behavior
-+        // http://es5.github.io/#x13.2.2
-+        if (this instanceof bound) {
-+          // ensure `new bound` is an instance of `func`
-+          var thisBinding = baseCreate(func.prototype),
-+              result = func.apply(thisBinding, args || arguments);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisArg, args || arguments);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.clone` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates clones with source counterparts.
-+     * @returns {*} Returns the cloned value.
-+     */
-+    function baseClone(value, isDeep, callback, stackA, stackB) {
-+      if (callback) {
-+        var result = callback(value);
-+        if (typeof result != 'undefined') {
-+          return result;
-+        }
-+      }
-+      // inspect [[Class]]
-+      var isObj = isObject(value);
-+      if (isObj) {
-+        var className = toString.call(value);
-+        if (!cloneableClasses[className]) {
-+          return value;
-+        }
-+        var ctor = ctorByClass[className];
-+        switch (className) {
-+          case boolClass:
-+          case dateClass:
-+            return new ctor(+value);
-+
-+          case numberClass:
-+          case stringClass:
-+            return new ctor(value);
-+
-+          case regexpClass:
-+            result = ctor(value.source, reFlags.exec(value));
-+            result.lastIndex = value.lastIndex;
-+            return result;
-+        }
-+      } else {
-+        return value;
-+      }
-+      var isArr = isArray(value);
-+      if (isDeep) {
-+        // check for circular references and return corresponding clone
-+        var initedStack = !stackA;
-+        stackA || (stackA = getArray());
-+        stackB || (stackB = getArray());
-+
-+        var length = stackA.length;
-+        while (length--) {
-+          if (stackA[length] == value) {
-+            return stackB[length];
-+          }
-+        }
-+        result = isArr ? ctor(value.length) : {};
-+      }
-+      else {
-+        result = isArr ? slice(value) : assign({}, value);
-+      }
-+      // add array properties assigned by `RegExp#exec`
-+      if (isArr) {
-+        if (hasOwnProperty.call(value, 'index')) {
-+          result.index = value.index;
-+        }
-+        if (hasOwnProperty.call(value, 'input')) {
-+          result.input = value.input;
-+        }
-+      }
-+      // exit for shallow clone
-+      if (!isDeep) {
-+        return result;
-+      }
-+      // add the source value to the stack of traversed objects
-+      // and associate it with its clone
-+      stackA.push(value);
-+      stackB.push(result);
-+
-+      // recursively populate clone (susceptible to call stack limits)
-+      (isArr ? forEach : forOwn)(value, function(objValue, key) {
-+        result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
-+      });
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.create` without support for assigning
-+     * properties to the created object.
-+     *
-+     * @private
-+     * @param {Object} prototype The object to inherit from.
-+     * @returns {Object} Returns the new object.
-+     */
-+    function baseCreate(prototype, properties) {
-+      return isObject(prototype) ? nativeCreate(prototype) : {};
-+    }
-+    // fallback for browsers without `Object.create`
-+    if (!nativeCreate) {
-+      baseCreate = (function() {
-+        function Object() {}
-+        return function(prototype) {
-+          if (isObject(prototype)) {
-+            Object.prototype = prototype;
-+            var result = new Object;
-+            Object.prototype = null;
-+          }
-+          return result || context.Object();
-+        };
-+      }());
-+    }
-+
-+    /**
-+     * The base implementation of `_.createCallback` without support for creating
-+     * "_.pluck" or "_.where" style callbacks.
-+     *
-+     * @private
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     */
-+    function baseCreateCallback(func, thisArg, argCount) {
-+      if (typeof func != 'function') {
-+        return identity;
-+      }
-+      // exit early for no `thisArg` or already bound by `Function#bind`
-+      if (typeof thisArg == 'undefined' || !('prototype' in func)) {
-+        return func;
-+      }
-+      var bindData = func.__bindData__;
-+      if (typeof bindData == 'undefined') {
-+        if (support.funcNames) {
-+          bindData = !func.name;
-+        }
-+        bindData = bindData || !support.funcDecomp;
-+        if (!bindData) {
-+          var source = fnToString.call(func);
-+          if (!support.funcNames) {
-+            bindData = !reFuncName.test(source);
-+          }
-+          if (!bindData) {
-+            // checks if `func` references the `this` keyword and stores the result
-+            bindData = reThis.test(source);
-+            setBindData(func, bindData);
-+          }
-+        }
-+      }
-+      // exit early if there are no `this` references or `func` is bound
-+      if (bindData === false || (bindData !== true && bindData[1] & 1)) {
-+        return func;
-+      }
-+      switch (argCount) {
-+        case 1: return function(value) {
-+          return func.call(thisArg, value);
-+        };
-+        case 2: return function(a, b) {
-+          return func.call(thisArg, a, b);
-+        };
-+        case 3: return function(value, index, collection) {
-+          return func.call(thisArg, value, index, collection);
-+        };
-+        case 4: return function(accumulator, value, index, collection) {
-+          return func.call(thisArg, accumulator, value, index, collection);
-+        };
-+      }
-+      return bind(func, thisArg);
-+    }
-+
-+    /**
-+     * The base implementation of `createWrapper` that creates the wrapper and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function baseCreateWrapper(bindData) {
-+      var func = bindData[0],
-+          bitmask = bindData[1],
-+          partialArgs = bindData[2],
-+          partialRightArgs = bindData[3],
-+          thisArg = bindData[4],
-+          arity = bindData[5];
-+
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          key = func;
-+
-+      function bound() {
-+        var thisBinding = isBind ? thisArg : this;
-+        if (partialArgs) {
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        if (partialRightArgs || isCurry) {
-+          args || (args = slice(arguments));
-+          if (partialRightArgs) {
-+            push.apply(args, partialRightArgs);
-+          }
-+          if (isCurry && args.length < arity) {
-+            bitmask |= 16 & ~32;
-+            return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
-+          }
-+        }
-+        args || (args = arguments);
-+        if (isBindKey) {
-+          func = thisBinding[key];
-+        }
-+        if (this instanceof bound) {
-+          thisBinding = baseCreate(func.prototype);
-+          var result = func.apply(thisBinding, args);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisBinding, args);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.difference` that accepts a single array
-+     * of values to exclude.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {Array} [values] The array of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     */
-+    function baseDifference(array, values) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          isLarge = length >= largeArraySize && indexOf === baseIndexOf,
-+          result = [];
-+
-+      if (isLarge) {
-+        var cache = createCache(values);
-+        if (cache) {
-+          indexOf = cacheIndexOf;
-+          values = cache;
-+        } else {
-+          isLarge = false;
-+        }
-+      }
-+      while (++index < length) {
-+        var value = array[index];
-+        if (indexOf(values, value) < 0) {
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseObject(values);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.flatten` without support for callback
-+     * shorthands or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
-+     * @param {number} [fromIndex=0] The index to start from.
-+     * @returns {Array} Returns a new flattened array.
-+     */
-+    function baseFlatten(array, isShallow, isStrict, fromIndex) {
-+      var index = (fromIndex || 0) - 1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+
-+        if (value && typeof value == 'object' && typeof value.length == 'number'
-+            && (isArray(value) || isArguments(value))) {
-+          // recursively flatten arrays (susceptible to call stack limits)
-+          if (!isShallow) {
-+            value = baseFlatten(value, isShallow, isStrict);
-+          }
-+          var valIndex = -1,
-+              valLength = value.length,
-+              resIndex = result.length;
-+
-+          result.length += valLength;
-+          while (++valIndex < valLength) {
-+            result[resIndex++] = value[valIndex];
-+          }
-+        } else if (!isStrict) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.isEqual`, without support for `thisArg` binding,
-+     * that allows partial "_.where" style comparisons.
-+     *
-+     * @private
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
-+     * @param {Array} [stackA=[]] Tracks traversed `a` objects.
-+     * @param {Array} [stackB=[]] Tracks traversed `b` objects.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     */
-+    function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
-+      // used to indicate that when comparing objects, `a` has at least the properties of `b`
-+      if (callback) {
-+        var result = callback(a, b);
-+        if (typeof result != 'undefined') {
-+          return !!result;
-+        }
-+      }
-+      // exit early for identical values
-+      if (a === b) {
-+        // treat `+0` vs. `-0` as not equal
-+        return a !== 0 || (1 / a == 1 / b);
-+      }
-+      var type = typeof a,
-+          otherType = typeof b;
-+
-+      // exit early for unlike primitive values
-+      if (a === a &&
-+          !(a && objectTypes[type]) &&
-+          !(b && objectTypes[otherType])) {
-+        return false;
-+      }
-+      // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
-+      // http://es5.github.io/#x15.3.4.4
-+      if (a == null || b == null) {
-+        return a === b;
-+      }
-+      // compare [[Class]] names
-+      var className = toString.call(a),
-+          otherClass = toString.call(b);
-+
-+      if (className == argsClass) {
-+        className = objectClass;
-+      }
-+      if (otherClass == argsClass) {
-+        otherClass = objectClass;
-+      }
-+      if (className != otherClass) {
-+        return false;
-+      }
-+      switch (className) {
-+        case boolClass:
-+        case dateClass:
-+          // coerce dates and booleans to numbers, dates to milliseconds and booleans
-+          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
-+          return +a == +b;
-+
-+        case numberClass:
-+          // treat `NaN` vs. `NaN` as equal
-+          return (a != +a)
-+            ? b != +b
-+            // but treat `+0` vs. `-0` as not equal
-+            : (a == 0 ? (1 / a == 1 / b) : a == +b);
-+
-+        case regexpClass:
-+        case stringClass:
-+          // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
-+          // treat string primitives and their corresponding object instances as equal
-+          return a == String(b);
-+      }
-+      var isArr = className == arrayClass;
-+      if (!isArr) {
-+        // unwrap any `lodash` wrapped values
-+        var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
-+            bWrapped = hasOwnProperty.call(b, '__wrapped__');
-+
-+        if (aWrapped || bWrapped) {
-+          return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
-+        }
-+        // exit for functions and DOM nodes
-+        if (className != objectClass) {
-+          return false;
-+        }
-+        // in older versions of Opera, `arguments` objects have `Array` constructors
-+        var ctorA = a.constructor,
-+            ctorB = b.constructor;
-+
-+        // non `Object` object instances with different constructors are not equal
-+        if (ctorA != ctorB &&
-+              !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
-+              ('constructor' in a && 'constructor' in b)
-+            ) {
-+          return false;
-+        }
-+      }
-+      // assume cyclic structures are equal
-+      // the algorithm for detecting cyclic structures is adapted from ES 5.1
-+      // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
-+      var initedStack = !stackA;
-+      stackA || (stackA = getArray());
-+      stackB || (stackB = getArray());
-+
-+      var length = stackA.length;
-+      while (length--) {
-+        if (stackA[length] == a) {
-+          return stackB[length] == b;
-+        }
-+      }
-+      var size = 0;
-+      result = true;
-+
-+      // add `a` and `b` to the stack of traversed objects
-+      stackA.push(a);
-+      stackB.push(b);
-+
-+      // recursively compare objects and arrays (susceptible to call stack limits)
-+      if (isArr) {
-+        // compare lengths to determine if a deep comparison is necessary
-+        length = a.length;
-+        size = b.length;
-+        result = size == length;
-+
-+        if (result || isWhere) {
-+          // deep compare the contents, ignoring non-numeric properties
-+          while (size--) {
-+            var index = length,
-+                value = b[size];
-+
-+            if (isWhere) {
-+              while (index--) {
-+                if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
-+                  break;
-+                }
-+              }
-+            } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
-+              break;
-+            }
-+          }
-+        }
-+      }
-+      else {
-+        // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
-+        // which, in this case, is more costly
-+        forIn(b, function(value, key, b) {
-+          if (hasOwnProperty.call(b, key)) {
-+            // count the number of properties.
-+            size++;
-+            // deep compare each property value.
-+            return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
-+          }
-+        });
-+
-+        if (result && !isWhere) {
-+          // ensure both objects have the same number of properties
-+          forIn(a, function(value, key, a) {
-+            if (hasOwnProperty.call(a, key)) {
-+              // `size` will be `-1` if `a` has more properties than `b`
-+              return (result = --size > -1);
-+            }
-+          });
-+        }
-+      }
-+      stackA.pop();
-+      stackB.pop();
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.merge` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Object} object The destination object.
-+     * @param {Object} source The source object.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates values with source counterparts.
-+     */
-+    function baseMerge(object, source, callback, stackA, stackB) {
-+      (isArray(source) ? forEach : forOwn)(source, function(source, key) {
-+        var found,
-+            isArr,
-+            result = source,
-+            value = object[key];
-+
-+        if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
-+          // avoid merging previously merged cyclic sources
-+          var stackLength = stackA.length;
-+          while (stackLength--) {
-+            if ((found = stackA[stackLength] == source)) {
-+              value = stackB[stackLength];
-+              break;
-+            }
-+          }
-+          if (!found) {
-+            var isShallow;
-+            if (callback) {
-+              result = callback(value, source);
-+              if ((isShallow = typeof result != 'undefined')) {
-+                value = result;
-+              }
-+            }
-+            if (!isShallow) {
-+              value = isArr
-+                ? (isArray(value) ? value : [])
-+                : (isPlainObject(value) ? value : {});
-+            }
-+            // add `source` and associated `value` to the stack of traversed objects
-+            stackA.push(source);
-+            stackB.push(value);
-+
-+            // recursively merge objects and arrays (susceptible to call stack limits)
-+            if (!isShallow) {
-+              baseMerge(value, source, callback, stackA, stackB);
-+            }
-+          }
-+        }
-+        else {
-+          if (callback) {
-+            result = callback(value, source);
-+            if (typeof result == 'undefined') {
-+              result = source;
-+            }
-+          }
-+          if (typeof result != 'undefined') {
-+            value = result;
-+          }
-+        }
-+        object[key] = value;
-+      });
-+    }
-+
-+    /**
-+     * The base implementation of `_.random` without argument juggling or support
-+     * for returning floating-point numbers.
-+     *
-+     * @private
-+     * @param {number} min The minimum possible value.
-+     * @param {number} max The maximum possible value.
-+     * @returns {number} Returns a random number.
-+     */
-+    function baseRandom(min, max) {
-+      return min + floor(nativeRandom() * (max - min + 1));
-+    }
-+
-+    /**
-+     * The base implementation of `_.uniq` without support for callback shorthands
-+     * or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function} [callback] The function called per iteration.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     */
-+    function baseUniq(array, isSorted, callback) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
-+          seen = (callback || isLarge) ? getArray() : result;
-+
-+      if (isLarge) {
-+        var cache = createCache(seen);
-+        indexOf = cacheIndexOf;
-+        seen = cache;
-+      }
-+      while (++index < length) {
-+        var value = array[index],
-+            computed = callback ? callback(value, index, array) : value;
-+
-+        if (isSorted
-+              ? !index || seen[seen.length - 1] !== computed
-+              : indexOf(seen, computed) < 0
-+            ) {
-+          if (callback || isLarge) {
-+            seen.push(computed);
-+          }
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseArray(seen.array);
-+        releaseObject(seen);
-+      } else if (callback) {
-+        releaseArray(seen);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a function that aggregates a collection, creating an object composed
-+     * of keys generated from the results of running each element of the collection
-+     * through a callback. The given `setter` function sets the keys and values
-+     * of the composed object.
-+     *
-+     * @private
-+     * @param {Function} setter The setter function.
-+     * @returns {Function} Returns the new aggregator function.
-+     */
-+    function createAggregator(setter) {
-+      return function(collection, callback, thisArg) {
-+        var result = {};
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+
-+        var index = -1,
-+            length = collection ? collection.length : 0;
-+
-+        if (typeof length == 'number') {
-+          while (++index < length) {
-+            var value = collection[index];
-+            setter(result, value, callback(value, index, collection), collection);
-+          }
-+        } else {
-+          forOwn(collection, function(value, key, collection) {
-+            setter(result, value, callback(value, key, collection), collection);
-+          });
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, either curries or invokes `func`
-+     * with an optional `this` binding and partially applied arguments.
-+     *
-+     * @private
-+     * @param {Function|string} func The function or method name to reference.
-+     * @param {number} bitmask The bitmask of method flags to compose.
-+     *  The bitmask may be composed of the following flags:
-+     *  1 - `_.bind`
-+     *  2 - `_.bindKey`
-+     *  4 - `_.curry`
-+     *  8 - `_.curry` (bound)
-+     *  16 - `_.partial`
-+     *  32 - `_.partialRight`
-+     * @param {Array} [partialArgs] An array of arguments to prepend to those
-+     *  provided to the new function.
-+     * @param {Array} [partialRightArgs] An array of arguments to append to those
-+     *  provided to the new function.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {number} [arity] The arity of `func`.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          isPartial = bitmask & 16,
-+          isPartialRight = bitmask & 32;
-+
-+      if (!isBindKey && !isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (isPartial && !partialArgs.length) {
-+        bitmask &= ~16;
-+        isPartial = partialArgs = false;
-+      }
-+      if (isPartialRight && !partialRightArgs.length) {
-+        bitmask &= ~32;
-+        isPartialRight = partialRightArgs = false;
-+      }
-+      var bindData = func && func.__bindData__;
-+      if (bindData && bindData !== true) {
-+        // clone `bindData`
-+        bindData = slice(bindData);
-+        if (bindData[2]) {
-+          bindData[2] = slice(bindData[2]);
-+        }
-+        if (bindData[3]) {
-+          bindData[3] = slice(bindData[3]);
-+        }
-+        // set `thisBinding` is not previously bound
-+        if (isBind && !(bindData[1] & 1)) {
-+          bindData[4] = thisArg;
-+        }
-+        // set if previously bound but not currently (subsequent curried functions)
-+        if (!isBind && bindData[1] & 1) {
-+          bitmask |= 8;
-+        }
-+        // set curried arity if not yet set
-+        if (isCurry && !(bindData[1] & 4)) {
-+          bindData[5] = arity;
-+        }
-+        // append partial left arguments
-+        if (isPartial) {
-+          push.apply(bindData[2] || (bindData[2] = []), partialArgs);
-+        }
-+        // append partial right arguments
-+        if (isPartialRight) {
-+          unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
-+        }
-+        // merge flags
-+        bindData[1] |= bitmask;
-+        return createWrapper.apply(null, bindData);
-+      }
-+      // fast path for `_.bind`
-+      var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
-+      return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
-+    }
-+
-+    /**
-+     * Used by `escape` to convert characters to HTML entities.
-+     *
-+     * @private
-+     * @param {string} match The matched character to escape.
-+     * @returns {string} Returns the escaped character.
-+     */
-+    function escapeHtmlChar(match) {
-+      return htmlEscapes[match];
-+    }
-+
-+    /**
-+     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
-+     * customized, this method returns the custom method, otherwise it returns
-+     * the `baseIndexOf` function.
-+     *
-+     * @private
-+     * @returns {Function} Returns the "indexOf" function.
-+     */
-+    function getIndexOf() {
-+      var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a native function.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
-+     */
-+    function isNative(value) {
-+      return typeof value == 'function' && reNative.test(value);
-+    }
-+
-+    /**
-+     * Sets `this` binding data on a given function.
-+     *
-+     * @private
-+     * @param {Function} func The function to set data on.
-+     * @param {Array} value The data array to set.
-+     */
-+    var setBindData = !defineProperty ? noop : function(func, value) {
-+      descriptor.value = value;
-+      defineProperty(func, '__bindData__', descriptor);
-+    };
-+
-+    /**
-+     * A fallback implementation of `isPlainObject` which checks if a given value
-+     * is an object created by the `Object` constructor, assuming objects created
-+     * by the `Object` constructor have no inherited enumerable properties and that
-+     * there are no `Object.prototype` extensions.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     */
-+    function shimIsPlainObject(value) {
-+      var ctor,
-+          result;
-+
-+      // avoid non Object objects, `arguments` objects, and DOM elements
-+      if (!(value && toString.call(value) == objectClass) ||
-+          (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
-+        return false;
-+      }
-+      // In most environments an object's own properties are iterated before
-+      // its inherited properties. If the last iterated property is an object's
-+      // own property then there are no inherited enumerable properties.
-+      forIn(value, function(value, key) {
-+        result = key;
-+      });
-+      return typeof result == 'undefined' || hasOwnProperty.call(value, result);
-+    }
-+
-+    /**
-+     * Used by `unescape` to convert HTML entities to characters.
-+     *
-+     * @private
-+     * @param {string} match The matched character to unescape.
-+     * @returns {string} Returns the unescaped character.
-+     */
-+    function unescapeHtmlChar(match) {
-+      return htmlUnescapes[match];
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Checks if `value` is an `arguments` object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArguments(arguments); })(1, 2, 3);
-+     * // => true
-+     *
-+     * _.isArguments([1, 2, 3]);
-+     * // => false
-+     */
-+    function isArguments(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == argsClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArray(arguments); })();
-+     * // => false
-+     *
-+     * _.isArray([1, 2, 3]);
-+     * // => true
-+     */
-+    var isArray = nativeIsArray || function(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == arrayClass || false;
-+    };
-+
-+    /**
-+     * A fallback implementation of `Object.keys` which produces an array of the
-+     * given object's own enumerable property names.
-+     *
-+     * @private
-+     * @type Function
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     */
-+    var shimKeys = function(object) {
-+      var index, iterable = object, result = [];
-+      if (!iterable) return result;
-+      if (!(objectTypes[typeof object])) return result;
-+        for (index in iterable) {
-+          if (hasOwnProperty.call(iterable, index)) {
-+            result.push(index);
-+          }
-+        }
-+      return result
-+    };
-+
-+    /**
-+     * Creates an array composed of the own enumerable property names of an object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     * @example
-+     *
-+     * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
-+     */
-+    var keys = !nativeKeys ? shimKeys : function(object) {
-+      if (!isObject(object)) {
-+        return [];
-+      }
-+      return nativeKeys(object);
-+    };
-+
-+    /**
-+     * Used to convert characters to HTML entities:
-+     *
-+     * Though the `>` character is escaped for symmetry, characters like `>` and `/`
-+     * don't require escaping in HTML and have no special meaning unless they're part
-+     * of a tag or an unquoted attribute value.
-+     * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
-+     */
-+    var htmlEscapes = {
-+      '&': '&',
-+      '<': '<',
-+      '>': '>',
-+      '"': '"',
-+      "'": '''
-+    };
-+
-+    /** Used to convert HTML entities to characters */
-+    var htmlUnescapes = invert(htmlEscapes);
-+
-+    /** Used to match HTML entities and HTML characters */
-+    var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
-+        reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object. Subsequent sources will overwrite property assignments of previous
-+     * sources. If a callback is provided it will be executed to produce the
-+     * assigned values. The callback is bound to `thisArg` and invoked with two
-+     * arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @alias extend
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize assigning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
-+     * // => { 'name': 'fred', 'employer': 'slate' }
-+     *
-+     * var defaults = _.partialRight(_.assign, function(a, b) {
-+     *   return typeof a == 'undefined' ? b : a;
-+     * });
-+     *
-+     * var object = { 'name': 'barney' };
-+     * defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var assign = function(object, source, guard) {
-+      var index, iterable = object, result = iterable;
-+      if (!iterable) return result;
-+      var args = arguments,
-+          argsIndex = 0,
-+          argsLength = typeof guard == 'number' ? 2 : args.length;
-+      if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
-+        var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
-+      } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
-+        callback = args[--argsLength];
-+      }
-+      while (++argsIndex < argsLength) {
-+        iterable = args[argsIndex];
-+        if (iterable && objectTypes[typeof iterable]) {
-+        var ownIndex = -1,
-+            ownProps = objectTypes[typeof iterable] && keys(iterable),
-+            length = ownProps ? ownProps.length : 0;
-+
-+        while (++ownIndex < length) {
-+          index = ownProps[ownIndex];
-+          result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
-+        }
-+        }
-+      }
-+      return result
-+    };
-+
-+    /**
-+     * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
-+     * be cloned, otherwise they will be assigned by reference. If a callback
-+     * is provided it will be executed to produce the cloned values. If the
-+     * callback returns `undefined` cloning will be handled by the method instead.
-+     * The callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var shallow = _.clone(characters);
-+     * shallow[0] === characters[0];
-+     * // => true
-+     *
-+     * var deep = _.clone(characters, true);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * _.mixin({
-+     *   'clone': _.partialRight(_.clone, function(value) {
-+     *     return _.isElement(value) ? value.cloneNode(false) : undefined;
-+     *   })
-+     * });
-+     *
-+     * var clone = _.clone(document.body);
-+     * clone.childNodes.length;
-+     * // => 0
-+     */
-+    function clone(value, isDeep, callback, thisArg) {
-+      // allows working with "Collections" methods without using their `index`
-+      // and `collection` arguments for `isDeep` and `callback`
-+      if (typeof isDeep != 'boolean' && isDeep != null) {
-+        thisArg = callback;
-+        callback = isDeep;
-+        isDeep = false;
-+      }
-+      return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates a deep clone of `value`. If a callback is provided it will be
-+     * executed to produce the cloned values. If the callback returns `undefined`
-+     * cloning will be handled by the method instead. The callback is bound to
-+     * `thisArg` and invoked with one argument; (value).
-+     *
-+     * Note: This method is loosely based on the structured clone algorithm. Functions
-+     * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
-+     * objects created by constructors other than `Object` are cloned to plain `Object` objects.
-+     * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the deep cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var deep = _.cloneDeep(characters);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'node': element
-+     * };
-+     *
-+     * var clone = _.cloneDeep(view, function(value) {
-+     *   return _.isElement(value) ? value.cloneNode(true) : undefined;
-+     * });
-+     *
-+     * clone.node == view.node;
-+     * // => false
-+     */
-+    function cloneDeep(value, callback, thisArg) {
-+      return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates an object that inherits from the given `prototype` object. If a
-+     * `properties` object is provided its own enumerable properties are assigned
-+     * to the created object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} prototype The object to inherit from.
-+     * @param {Object} [properties] The properties to assign to the object.
-+     * @returns {Object} Returns the new object.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * function Circle() {
-+     *   Shape.call(this);
-+     * }
-+     *
-+     * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
-+     *
-+     * var circle = new Circle;
-+     * circle instanceof Circle;
-+     * // => true
-+     *
-+     * circle instanceof Shape;
-+     * // => true
-+     */
-+    function create(prototype, properties) {
-+      var result = baseCreate(prototype);
-+      return properties ? assign(result, properties) : result;
-+    }
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object for all destination properties that resolve to `undefined`. Once a
-+     * property is set, additional defaults of the same property will be ignored.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param- {Object} [guard] Allows working with `_.reduce` without using its
-+     *  `key` and `object` arguments as sources.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var object = { 'name': 'barney' };
-+     * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var defaults = function(object, source, guard) {
-+      var index, iterable = object, result = iterable;
-+      if (!iterable) return result;
-+      var args = arguments,
-+          argsIndex = 0,
-+          argsLength = typeof guard == 'number' ? 2 : args.length;
-+      while (++argsIndex < argsLength) {
-+        iterable = args[argsIndex];
-+        if (iterable && objectTypes[typeof iterable]) {
-+        var ownIndex = -1,
-+            ownProps = objectTypes[typeof iterable] && keys(iterable),
-+            length = ownProps ? ownProps.length : 0;
-+
-+        while (++ownIndex < length) {
-+          index = ownProps[ownIndex];
-+          if (typeof result[index] == 'undefined') result[index] = iterable[index];
-+        }
-+        }
-+      }
-+      return result
-+    };
-+
-+    /**
-+     * This method is like `_.findIndex` except that it returns the key of the
-+     * first element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': false },
-+     *   'fred': {    'age': 40, 'blocked': true },
-+     *   'pebbles': { 'age': 1,  'blocked': false }
-+     * };
-+     *
-+     * _.findKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => 'barney' (property order is not guaranteed across environments)
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findKey(characters, { 'age': 1 });
-+     * // => 'pebbles'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findKey(characters, 'blocked');
-+     * // => 'fred'
-+     */
-+    function findKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwn(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * This method is like `_.findKey` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': true },
-+     *   'fred': {    'age': 40, 'blocked': false },
-+     *   'pebbles': { 'age': 1,  'blocked': true }
-+     * };
-+     *
-+     * _.findLastKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => returns `pebbles`, assuming `_.findKey` returns `barney`
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastKey(characters, { 'age': 40 });
-+     * // => 'fred'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastKey(characters, 'blocked');
-+     * // => 'pebbles'
-+     */
-+    function findLastKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwnRight(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over own and inherited enumerable properties of an object,
-+     * executing the callback for each property. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, key, object). Callbacks may exit
-+     * iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forIn(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
-+     */
-+    var forIn = function(collection, callback, thisArg) {
-+      var index, iterable = collection, result = iterable;
-+      if (!iterable) return result;
-+      if (!objectTypes[typeof iterable]) return result;
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+        for (index in iterable) {
-+          if (callback(iterable[index], index, collection) === false) return result;
-+        }
-+      return result
-+    };
-+
-+    /**
-+     * This method is like `_.forIn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forInRight(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
-+     */
-+    function forInRight(object, callback, thisArg) {
-+      var pairs = [];
-+
-+      forIn(object, function(value, key) {
-+        pairs.push(key, value);
-+      });
-+
-+      var length = pairs.length;
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(pairs[length--], pairs[length], object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Iterates over own enumerable properties of an object, executing the callback
-+     * for each property. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, key, object). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
-+     */
-+    var forOwn = function(collection, callback, thisArg) {
-+      var index, iterable = collection, result = iterable;
-+      if (!iterable) return result;
-+      if (!objectTypes[typeof iterable]) return result;
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+        var ownIndex = -1,
-+            ownProps = objectTypes[typeof iterable] && keys(iterable),
-+            length = ownProps ? ownProps.length : 0;
-+
-+        while (++ownIndex < length) {
-+          index = ownProps[ownIndex];
-+          if (callback(iterable[index], index, collection) === false) return result;
-+        }
-+      return result
-+    };
-+
-+    /**
-+     * This method is like `_.forOwn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
-+     */
-+    function forOwnRight(object, callback, thisArg) {
-+      var props = keys(object),
-+          length = props.length;
-+
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        var key = props[length];
-+        if (callback(object[key], key, object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a sorted array of property names of all enumerable properties,
-+     * own and inherited, of `object` that have function values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias methods
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names that have function values.
-+     * @example
-+     *
-+     * _.functions(_);
-+     * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
-+     */
-+    function functions(object) {
-+      var result = [];
-+      forIn(object, function(value, key) {
-+        if (isFunction(value)) {
-+          result.push(key);
-+        }
-+      });
-+      return result.sort();
-+    }
-+
-+    /**
-+     * Checks if the specified property name exists as a direct property of `object`,
-+     * instead of an inherited property.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to check.
-+     * @returns {boolean} Returns `true` if key is a direct property, else `false`.
-+     * @example
-+     *
-+     * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
-+     * // => true
-+     */
-+    function has(object, key) {
-+      return object ? hasOwnProperty.call(object, key) : false;
-+    }
-+
-+    /**
-+     * Creates an object composed of the inverted keys and values of the given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to invert.
-+     * @returns {Object} Returns the created inverted object.
-+     * @example
-+     *
-+     * _.invert({ 'first': 'fred', 'second': 'barney' });
-+     * // => { 'fred': 'first', 'barney': 'second' }
-+     */
-+    function invert(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = {};
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[object[key]] = key;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a boolean value.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
-+     * @example
-+     *
-+     * _.isBoolean(null);
-+     * // => false
-+     */
-+    function isBoolean(value) {
-+      return value === true || value === false ||
-+        value && typeof value == 'object' && toString.call(value) == boolClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a date.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
-+     * @example
-+     *
-+     * _.isDate(new Date);
-+     * // => true
-+     */
-+    function isDate(value) {
-+      return value && typeof value == 'object' && toString.call(value) == dateClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a DOM element.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
-+     * @example
-+     *
-+     * _.isElement(document.body);
-+     * // => true
-+     */
-+    function isElement(value) {
-+      return value && value.nodeType === 1 || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
-+     * length of `0` and objects with no own enumerable properties are considered
-+     * "empty".
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object|string} value The value to inspect.
-+     * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
-+     * @example
-+     *
-+     * _.isEmpty([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isEmpty({});
-+     * // => true
-+     *
-+     * _.isEmpty('');
-+     * // => true
-+     */
-+    function isEmpty(value) {
-+      var result = true;
-+      if (!value) {
-+        return result;
-+      }
-+      var className = toString.call(value),
-+          length = value.length;
-+
-+      if ((className == arrayClass || className == stringClass || className == argsClass ) ||
-+          (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
-+        return !length;
-+      }
-+      forOwn(value, function() {
-+        return (result = false);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Performs a deep comparison between two values to determine if they are
-+     * equivalent to each other. If a callback is provided it will be executed
-+     * to compare values. If the callback returns `undefined` comparisons will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (a, b).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var copy = { 'name': 'fred' };
-+     *
-+     * object == copy;
-+     * // => false
-+     *
-+     * _.isEqual(object, copy);
-+     * // => true
-+     *
-+     * var words = ['hello', 'goodbye'];
-+     * var otherWords = ['hi', 'goodbye'];
-+     *
-+     * _.isEqual(words, otherWords, function(a, b) {
-+     *   var reGreet = /^(?:hello|hi)$/i,
-+     *       aGreet = _.isString(a) && reGreet.test(a),
-+     *       bGreet = _.isString(b) && reGreet.test(b);
-+     *
-+     *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
-+     * });
-+     * // => true
-+     */
-+    function isEqual(a, b, callback, thisArg) {
-+      return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
-+    }
-+
-+    /**
-+     * Checks if `value` is, or can be coerced to, a finite number.
-+     *
-+     * Note: This is not the same as native `isFinite` which will return true for
-+     * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
-+     * @example
-+     *
-+     * _.isFinite(-101);
-+     * // => true
-+     *
-+     * _.isFinite('10');
-+     * // => true
-+     *
-+     * _.isFinite(true);
-+     * // => false
-+     *
-+     * _.isFinite('');
-+     * // => false
-+     *
-+     * _.isFinite(Infinity);
-+     * // => false
-+     */
-+    function isFinite(value) {
-+      return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
-+    }
-+
-+    /**
-+     * Checks if `value` is a function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
-+     * @example
-+     *
-+     * _.isFunction(_);
-+     * // => true
-+     */
-+    function isFunction(value) {
-+      return typeof value == 'function';
-+    }
-+
-+    /**
-+     * Checks if `value` is the language type of Object.
-+     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
-+     * @example
-+     *
-+     * _.isObject({});
-+     * // => true
-+     *
-+     * _.isObject([1, 2, 3]);
-+     * // => true
-+     *
-+     * _.isObject(1);
-+     * // => false
-+     */
-+    function isObject(value) {
-+      // check if the value is the ECMAScript language type of Object
-+      // http://es5.github.io/#x8
-+      // and avoid a V8 bug
-+      // http://code.google.com/p/v8/issues/detail?id=2291
-+      return !!(value && objectTypes[typeof value]);
-+    }
-+
-+    /**
-+     * Checks if `value` is `NaN`.
-+     *
-+     * Note: This is not the same as native `isNaN` which will return `true` for
-+     * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
-+     * @example
-+     *
-+     * _.isNaN(NaN);
-+     * // => true
-+     *
-+     * _.isNaN(new Number(NaN));
-+     * // => true
-+     *
-+     * isNaN(undefined);
-+     * // => true
-+     *
-+     * _.isNaN(undefined);
-+     * // => false
-+     */
-+    function isNaN(value) {
-+      // `NaN` as a primitive is the only value that is not equal to itself
-+      // (perform the [[Class]] check first to avoid errors with some host objects in IE)
-+      return isNumber(value) && value != +value;
-+    }
-+
-+    /**
-+     * Checks if `value` is `null`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
-+     * @example
-+     *
-+     * _.isNull(null);
-+     * // => true
-+     *
-+     * _.isNull(undefined);
-+     * // => false
-+     */
-+    function isNull(value) {
-+      return value === null;
-+    }
-+
-+    /**
-+     * Checks if `value` is a number.
-+     *
-+     * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
-+     * @example
-+     *
-+     * _.isNumber(8.4 * 5);
-+     * // => true
-+     */
-+    function isNumber(value) {
-+      return typeof value == 'number' ||
-+        value && typeof value == 'object' && toString.call(value) == numberClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is an object created by the `Object` constructor.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * _.isPlainObject(new Shape);
-+     * // => false
-+     *
-+     * _.isPlainObject([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isPlainObject({ 'x': 0, 'y': 0 });
-+     * // => true
-+     */
-+    var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
-+      if (!(value && toString.call(value) == objectClass)) {
-+        return false;
-+      }
-+      var valueOf = value.valueOf,
-+          objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-+
-+      return objProto
-+        ? (value == objProto || getPrototypeOf(value) == objProto)
-+        : shimIsPlainObject(value);
-+    };
-+
-+    /**
-+     * Checks if `value` is a regular expression.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
-+     * @example
-+     *
-+     * _.isRegExp(/fred/);
-+     * // => true
-+     */
-+    function isRegExp(value) {
-+      return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a string.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
-+     * @example
-+     *
-+     * _.isString('fred');
-+     * // => true
-+     */
-+    function isString(value) {
-+      return typeof value == 'string' ||
-+        value && typeof value == 'object' && toString.call(value) == stringClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is `undefined`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
-+     * @example
-+     *
-+     * _.isUndefined(void 0);
-+     * // => true
-+     */
-+    function isUndefined(value) {
-+      return typeof value == 'undefined';
-+    }
-+
-+    /**
-+     * Creates an object with the same keys as `object` and values generated by
-+     * running each own enumerable property of `object` through the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new object with values of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     *
-+     * var characters = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.mapValues(characters, 'age');
-+     * // => { 'fred': 40, 'pebbles': 1 }
-+     */
-+    function mapValues(object, callback, thisArg) {
-+      var result = {};
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      forOwn(object, function(value, key, object) {
-+        result[key] = callback(value, key, object);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Recursively merges own enumerable properties of the source object(s), that
-+     * don't resolve to `undefined` into the destination object. Subsequent sources
-+     * will overwrite property assignments of previous sources. If a callback is
-+     * provided it will be executed to produce the merged values of the destination
-+     * and source properties. If the callback returns `undefined` merging will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var names = {
-+     *   'characters': [
-+     *     { 'name': 'barney' },
-+     *     { 'name': 'fred' }
-+     *   ]
-+     * };
-+     *
-+     * var ages = {
-+     *   'characters': [
-+     *     { 'age': 36 },
-+     *     { 'age': 40 }
-+     *   ]
-+     * };
-+     *
-+     * _.merge(names, ages);
-+     * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
-+     *
-+     * var food = {
-+     *   'fruits': ['apple'],
-+     *   'vegetables': ['beet']
-+     * };
-+     *
-+     * var otherFood = {
-+     *   'fruits': ['banana'],
-+     *   'vegetables': ['carrot']
-+     * };
-+     *
-+     * _.merge(food, otherFood, function(a, b) {
-+     *   return _.isArray(a) ? a.concat(b) : undefined;
-+     * });
-+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
-+     */
-+    function merge(object) {
-+      var args = arguments,
-+          length = 2;
-+
-+      if (!isObject(object)) {
-+        return object;
-+      }
-+      // allows working with `_.reduce` and `_.reduceRight` without using
-+      // their `index` and `collection` arguments
-+      if (typeof args[2] != 'number') {
-+        length = args.length;
-+      }
-+      if (length > 3 && typeof args[length - 2] == 'function') {
-+        var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
-+      } else if (length > 2 && typeof args[length - 1] == 'function') {
-+        callback = args[--length];
-+      }
-+      var sources = slice(arguments, 1, length),
-+          index = -1,
-+          stackA = getArray(),
-+          stackB = getArray();
-+
-+      while (++index < length) {
-+        baseMerge(object, sources[index], callback, stackA, stackB);
-+      }
-+      releaseArray(stackA);
-+      releaseArray(stackB);
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` excluding the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` omitting the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The properties to omit or the
-+     *  function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object without the omitted properties.
-+     * @example
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
-+     *   return typeof value == 'number';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function omit(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var props = [];
-+        forIn(object, function(value, key) {
-+          props.push(key);
-+        });
-+        props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-+
-+        var index = -1,
-+            length = props.length;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          result[key] = object[key];
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (!callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a two dimensional array of an object's key-value pairs,
-+     * i.e. `[[key1, value1], [key2, value2]]`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns new array of key-value pairs.
-+     * @example
-+     *
-+     * _.pairs({ 'barney': 36, 'fred': 40 });
-+     * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
-+     */
-+    function pairs(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[index] = [key, object[key]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` composed of the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` picking the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The function called per
-+     *  iteration or property names to pick, specified as individual property
-+     *  names or arrays of property names.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object composed of the picked properties.
-+     * @example
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
-+     *   return key.charAt(0) != '_';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function pick(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var index = -1,
-+            props = baseFlatten(arguments, true, false, 1),
-+            length = isObject(object) ? props.length : 0;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          if (key in object) {
-+            result[key] = object[key];
-+          }
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * An alternative to `_.reduce` this method transforms `object` to a new
-+     * `accumulator` object which is the result of running each of its own
-+     * enumerable properties through a callback, with each callback execution
-+     * potentially mutating the `accumulator` object. The callback is bound to
-+     * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
-+     * Callbacks may exit iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] The custom accumulator value.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
-+     *   num *= num;
-+     *   if (num % 2) {
-+     *     return result.push(num) < 3;
-+     *   }
-+     * });
-+     * // => [1, 9, 25]
-+     *
-+     * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     * });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function transform(object, callback, accumulator, thisArg) {
-+      var isArr = isArray(object);
-+      if (accumulator == null) {
-+        if (isArr) {
-+          accumulator = [];
-+        } else {
-+          var ctor = object && object.constructor,
-+              proto = ctor && ctor.prototype;
-+
-+          accumulator = baseCreate(proto);
-+        }
-+      }
-+      if (callback) {
-+        callback = lodash.createCallback(callback, thisArg, 4);
-+        (isArr ? forEach : forOwn)(object, function(value, index, object) {
-+          return callback(accumulator, value, index, object);
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * Creates an array composed of the own enumerable property values of `object`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property values.
-+     * @example
-+     *
-+     * _.values({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => [1, 2, 3] (property order is not guaranteed across environments)
-+     */
-+    function values(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = object[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array of elements from the specified indexes, or keys, of the
-+     * `collection`. Indexes may be specified as individual arguments or as arrays
-+     * of indexes.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
-+     *   to retrieve, specified as individual indexes or arrays of indexes.
-+     * @returns {Array} Returns a new array of elements corresponding to the
-+     *  provided indexes.
-+     * @example
-+     *
-+     * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
-+     * // => ['a', 'c', 'e']
-+     *
-+     * _.at(['fred', 'barney', 'pebbles'], 0, 2);
-+     * // => ['fred', 'pebbles']
-+     */
-+    function at(collection) {
-+      var args = arguments,
-+          index = -1,
-+          props = baseFlatten(args, true, false, 1),
-+          length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
-+          result = Array(length);
-+
-+      while(++index < length) {
-+        result[index] = collection[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if a given value is present in a collection using strict equality
-+     * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
-+     * offset from the end of the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias include
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {*} target The value to check for.
-+     * @param {number} [fromIndex=0] The index to search from.
-+     * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
-+     * @example
-+     *
-+     * _.contains([1, 2, 3], 1);
-+     * // => true
-+     *
-+     * _.contains([1, 2, 3], 1, 2);
-+     * // => false
-+     *
-+     * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
-+     * // => true
-+     *
-+     * _.contains('pebbles', 'eb');
-+     * // => true
-+     */
-+    function contains(collection, target, fromIndex) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = collection ? collection.length : 0,
-+          result = false;
-+
-+      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
-+      if (isArray(collection)) {
-+        result = indexOf(collection, target, fromIndex) > -1;
-+      } else if (typeof length == 'number') {
-+        result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
-+      } else {
-+        forOwn(collection, function(value) {
-+          if (++index >= fromIndex) {
-+            return !(result = value === target);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of `collection` through the callback. The corresponding value
-+     * of each key is the number of times the key was returned by the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': 2, '5': 1 }
-+     */
-+    var countBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
-+    });
-+
-+    /**
-+     * Checks if the given callback returns truey value for **all** elements of
-+     * a collection. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias all
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if all elements passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.every([true, 1, null, 'yes']);
-+     * // => false
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.every(characters, 'age');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.every(characters, { 'age': 36 });
-+     * // => false
-+     */
-+    function every(collection, callback, thisArg) {
-+      var result = true;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          if (!(result = !!callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        forOwn(collection, function(value, index, collection) {
-+          return (result = !!callback(value, index, collection));
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning an array of all elements
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias select
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that passed the callback check.
-+     * @example
-+     *
-+     * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [2, 4, 6]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.filter(characters, 'blocked');
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.filter(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     */
-+    function filter(collection, callback, thisArg) {
-+      var result = [];
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        }
-+      } else {
-+        forOwn(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning the first element that
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias detect, findWhere
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.find(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => { 'name': 'barney', 'age': 36, 'blocked': false }
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.find(characters, { 'age': 1 });
-+     * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.find(characters, 'blocked');
-+     * // => { 'name': 'fred', 'age': 40, 'blocked': true }
-+     */
-+    function find(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            return value;
-+          }
-+        }
-+      } else {
-+        var result;
-+        forOwn(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result = value;
-+            return false;
-+          }
-+        });
-+        return result;
-+      }
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * _.findLast([1, 2, 3, 4], function(num) {
-+     *   return num % 2 == 1;
-+     * });
-+     * // => 3
-+     */
-+    function findLast(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forEachRight(collection, function(value, index, collection) {
-+        if (callback(value, index, collection)) {
-+          result = value;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, executing the callback for each
-+     * element. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * Note: As with other "Collections" methods, objects with a `length` property
-+     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
-+     * may be used for object iteration.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias each
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
-+     * // => logs each number and returns '1,2,3'
-+     *
-+     * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
-+     * // => logs each number and returns the object (property order is not guaranteed across environments)
-+     */
-+    function forEach(collection, callback, thisArg) {
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          if (callback(collection[index], index, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        forOwn(collection, callback);
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * This method is like `_.forEach` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias eachRight
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
-+     * // => logs each number from right to left and returns '3,2,1'
-+     */
-+    function forEachRight(collection, callback, thisArg) {
-+      var length = collection ? collection.length : 0;
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+      if (typeof length == 'number') {
-+        while (length--) {
-+          if (callback(collection[length], length, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        var props = keys(collection);
-+        length = props.length;
-+        forOwn(collection, function(value, key, collection) {
-+          key = props ? props[--length] : --length;
-+          return callback(collection[key], key, collection);
-+        });
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of a collection through the callback. The corresponding value
-+     * of each key is an array of the elements responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.groupBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': ['one', 'two'], '5': ['three'] }
-+     */
-+    var groupBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
-+    });
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of the collection through the given callback. The corresponding
-+     * value of each key is the last element responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * var keys = [
-+     *   { 'dir': 'left', 'code': 97 },
-+     *   { 'dir': 'right', 'code': 100 }
-+     * ];
-+     *
-+     * _.indexBy(keys, 'dir');
-+     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     */
-+    var indexBy = createAggregator(function(result, value, key) {
-+      result[key] = value;
-+    });
-+
-+    /**
-+     * Invokes the method named by `methodName` on each element in the `collection`
-+     * returning an array of the results of each invoked method. Additional arguments
-+     * will be provided to each invoked method. If `methodName` is a function it
-+     * will be invoked for, and `this` bound to, each element in the `collection`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|string} methodName The name of the method to invoke or
-+     *  the function invoked per iteration.
-+     * @param {...*} [arg] Arguments to invoke the method with.
-+     * @returns {Array} Returns a new array of the results of each invoked method.
-+     * @example
-+     *
-+     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-+     * // => [[1, 5, 7], [1, 2, 3]]
-+     *
-+     * _.invoke([123, 456], String.prototype.split, '');
-+     * // => [['1', '2', '3'], ['4', '5', '6']]
-+     */
-+    function invoke(collection, methodName) {
-+      var args = slice(arguments, 2),
-+          index = -1,
-+          isFunc = typeof methodName == 'function',
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of values by running each element in the collection
-+     * through the callback. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias collect
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.map([1, 2, 3], function(num) { return num * 3; });
-+     * // => [3, 6, 9]
-+     *
-+     * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
-+     * // => [3, 6, 9] (property order is not guaranteed across environments)
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function map(collection, callback, thisArg) {
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      if (typeof length == 'number') {
-+        var result = Array(length);
-+        while (++index < length) {
-+          result[index] = callback(collection[index], index, collection);
-+        }
-+      } else {
-+        result = [];
-+        forOwn(collection, function(value, key, collection) {
-+          result[++index] = callback(value, key, collection);
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the maximum value of a collection. If the collection is empty or
-+     * falsey `-Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the maximum value.
-+     * @example
-+     *
-+     * _.max([4, 2, 8, 6]);
-+     * // => 8
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.max(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'fred', 'age': 40 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.max(characters, 'age');
-+     * // => { 'name': 'fred', 'age': 40 };
-+     */
-+    function max(collection, callback, thisArg) {
-+      var computed = -Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value > result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        forEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current > computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the minimum value of a collection. If the collection is empty or
-+     * falsey `Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the minimum value.
-+     * @example
-+     *
-+     * _.min([4, 2, 8, 6]);
-+     * // => 2
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.min(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'barney', 'age': 36 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.min(characters, 'age');
-+     * // => { 'name': 'barney', 'age': 36 };
-+     */
-+    function min(collection, callback, thisArg) {
-+      var computed = Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value < result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        forEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current < computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the value of a specified property from all elements in the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {string} property The name of the property to pluck.
-+     * @returns {Array} Returns a new array of property values.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.pluck(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    var pluck = map;
-+
-+    /**
-+     * Reduces a collection to a value which is the accumulated result of running
-+     * each element in the collection through the callback, where each successive
-+     * callback execution consumes the return value of the previous execution. If
-+     * `accumulator` is not provided the first element of the collection will be
-+     * used as the initial `accumulator` value. The callback is bound to `thisArg`
-+     * and invoked with four arguments; (accumulator, value, index|key, collection).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldl, inject
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var sum = _.reduce([1, 2, 3], function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     *   return result;
-+     * }, {});
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function reduce(collection, callback, accumulator, thisArg) {
-+      if (!collection) return accumulator;
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+
-+      var index = -1,
-+          length = collection.length;
-+
-+      if (typeof length == 'number') {
-+        if (noaccum) {
-+          accumulator = collection[++index];
-+        }
-+        while (++index < length) {
-+          accumulator = callback(accumulator, collection[index], index, collection);
-+        }
-+      } else {
-+        forOwn(collection, function(value, index, collection) {
-+          accumulator = noaccum
-+            ? (noaccum = false, value)
-+            : callback(accumulator, value, index, collection)
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * This method is like `_.reduce` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldr
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var list = [[0, 1], [2, 3], [4, 5]];
-+     * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-+     * // => [4, 5, 2, 3, 0, 1]
-+     */
-+    function reduceRight(collection, callback, accumulator, thisArg) {
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+      forEachRight(collection, function(value, index, collection) {
-+        accumulator = noaccum
-+          ? (noaccum = false, value)
-+          : callback(accumulator, value, index, collection);
-+      });
-+      return accumulator;
-+    }
-+
-+    /**
-+     * The opposite of `_.filter` this method returns the elements of a
-+     * collection that the callback does **not** return truey for.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that failed the callback check.
-+     * @example
-+     *
-+     * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [1, 3, 5]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.reject(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.reject(characters, { 'age': 36 });
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     */
-+    function reject(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      return filter(collection, function(value, index, collection) {
-+        return !callback(value, index, collection);
-+      });
-+    }
-+
-+    /**
-+     * Retrieves a random element or `n` random elements from a collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to sample.
-+     * @param {number} [n] The number of elements to sample.
-+     * @param- {Object} [guard] Allows working with functions like `_.map`
-+     *  without using their `index` arguments as `n`.
-+     * @returns {Array} Returns the random sample(s) of `collection`.
-+     * @example
-+     *
-+     * _.sample([1, 2, 3, 4]);
-+     * // => 2
-+     *
-+     * _.sample([1, 2, 3, 4], 2);
-+     * // => [3, 1]
-+     */
-+    function sample(collection, n, guard) {
-+      if (collection && typeof collection.length != 'number') {
-+        collection = values(collection);
-+      }
-+      if (n == null || guard) {
-+        return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
-+      }
-+      var result = shuffle(collection);
-+      result.length = nativeMin(nativeMax(0, n), result.length);
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of shuffled values, using a version of the Fisher-Yates
-+     * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to shuffle.
-+     * @returns {Array} Returns a new shuffled collection.
-+     * @example
-+     *
-+     * _.shuffle([1, 2, 3, 4, 5, 6]);
-+     * // => [4, 1, 6, 3, 5, 2]
-+     */
-+    function shuffle(collection) {
-+      var index = -1,
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        var rand = baseRandom(0, ++index);
-+        result[index] = result[rand];
-+        result[rand] = value;
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the size of the `collection` by returning `collection.length` for arrays
-+     * and array-like objects or the number of own enumerable properties for objects.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to inspect.
-+     * @returns {number} Returns `collection.length` or number of own enumerable properties.
-+     * @example
-+     *
-+     * _.size([1, 2]);
-+     * // => 2
-+     *
-+     * _.size({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => 3
-+     *
-+     * _.size('pebbles');
-+     * // => 7
-+     */
-+    function size(collection) {
-+      var length = collection ? collection.length : 0;
-+      return typeof length == 'number' ? length : keys(collection).length;
-+    }
-+
-+    /**
-+     * Checks if the callback returns a truey value for **any** element of a
-+     * collection. The function returns as soon as it finds a passing value and
-+     * does not iterate over the entire collection. The callback is bound to
-+     * `thisArg` and invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias any
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if any element passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.some([null, 0, 'yes', false], Boolean);
-+     * // => true
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.some(characters, 'blocked');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.some(characters, { 'age': 1 });
-+     * // => false
-+     */
-+    function some(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          if ((result = callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        forOwn(collection, function(value, index, collection) {
-+          return !(result = callback(value, index, collection));
-+        });
-+      }
-+      return !!result;
-+    }
-+
-+    /**
-+     * Creates an array of elements, sorted in ascending order by the results of
-+     * running each element in a collection through the callback. This method
-+     * performs a stable sort, that is, it will preserve the original sort order
-+     * of equal elements. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an array of property names is provided for `callback` the collection
-+     * will be sorted by each property value.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Array|Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of sorted elements.
-+     * @example
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
-+     * // => [3, 1, 2]
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
-+     * // => [3, 1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'barney',  'age': 26 },
-+     *   { 'name': 'fred',    'age': 30 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(_.sortBy(characters, 'age'), _.values);
-+     * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
-+     *
-+     * // sorting by multiple properties
-+     * _.map(_.sortBy(characters, ['name', 'age']), _.values);
-+     * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
-+     */
-+    function sortBy(collection, callback, thisArg) {
-+      var index = -1,
-+          isArr = isArray(callback),
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      if (!isArr) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      forEach(collection, function(value, key, collection) {
-+        var object = result[++index] = getObject();
-+        if (isArr) {
-+          object.criteria = map(callback, function(key) { return value[key]; });
-+        } else {
-+          (object.criteria = getArray())[0] = callback(value, key, collection);
-+        }
-+        object.index = index;
-+        object.value = value;
-+      });
-+
-+      length = result.length;
-+      result.sort(compareAscending);
-+      while (length--) {
-+        var object = result[length];
-+        result[length] = object.value;
-+        if (!isArr) {
-+          releaseArray(object.criteria);
-+        }
-+        releaseObject(object);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Converts the `collection` to an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to convert.
-+     * @returns {Array} Returns the new converted array.
-+     * @example
-+     *
-+     * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-+     * // => [2, 3, 4]
-+     */
-+    function toArray(collection) {
-+      if (collection && typeof collection.length == 'number') {
-+        return slice(collection);
-+      }
-+      return values(collection);
-+    }
-+
-+    /**
-+     * Performs a deep comparison of each element in a `collection` to the given
-+     * `properties` object, returning an array of all elements that have equivalent
-+     * property values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Object} props The object of property values to filter by.
-+     * @returns {Array} Returns a new array of elements that have the given properties.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * _.where(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
-+     *
-+     * _.where(characters, { 'pets': ['dino'] });
-+     * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
-+     */
-+    var where = filter;
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array with all falsey values removed. The values `false`, `null`,
-+     * `0`, `""`, `undefined`, and `NaN` are all falsey.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to compact.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.compact([0, 1, false, 2, '', 3]);
-+     * // => [1, 2, 3]
-+     */
-+    function compact(array) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+        if (value) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array excluding all values of the provided arrays using strict
-+     * equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {...Array} [values] The arrays of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-+     * // => [1, 3, 4]
-+     */
-+    function difference(array) {
-+      return baseDifference(array, baseFlatten(arguments, true, true, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it returns the index of the first
-+     * element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.findIndex(characters, function(chr) {
-+     *   return chr.age < 20;
-+     * });
-+     * // => 2
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findIndex(characters, 'blocked');
-+     * // => 1
-+     */
-+    function findIndex(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0;
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        if (callback(array[index], index, array)) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * This method is like `_.findIndex` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': true },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': false },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
-+     * ];
-+     *
-+     * _.findLastIndex(characters, function(chr) {
-+     *   return chr.age > 30;
-+     * });
-+     * // => 1
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastIndex(characters, 'blocked');
-+     * // => 2
-+     */
-+    function findLastIndex(array, callback, thisArg) {
-+      var length = array ? array.length : 0;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(array[length], length, array)) {
-+          return length;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Gets the first element or first `n` elements of an array. If a callback
-+     * is provided elements at the beginning of the array are returned as long
-+     * as the callback returns truey. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias head, take
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the first element(s) of `array`.
-+     * @example
-+     *
-+     * _.first([1, 2, 3]);
-+     * // => 1
-+     *
-+     * _.first([1, 2, 3], 2);
-+     * // => [1, 2]
-+     *
-+     * _.first([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.first(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function first(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = -1;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[0] : undefined;
-+        }
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, n), length));
-+    }
-+
-+    /**
-+     * Flattens a nested array (the nesting can be to any depth). If `isShallow`
-+     * is truey, the array will only be flattened a single level. If a callback
-+     * is provided each element of the array is passed through the callback before
-+     * flattening. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new flattened array.
-+     * @example
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]]);
-+     * // => [1, 2, 3, 4];
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]], true);
-+     * // => [1, 2, 3, [[4]]];
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.flatten(characters, 'pets');
-+     * // => ['hoppy', 'baby puss', 'dino']
-+     */
-+    function flatten(array, isShallow, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isShallow != 'boolean' && isShallow != null) {
-+        thisArg = callback;
-+        callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
-+        isShallow = false;
-+      }
-+      if (callback != null) {
-+        array = map(array, callback, thisArg);
-+      }
-+      return baseFlatten(array, isShallow);
-+    }
-+
-+    /**
-+     * Gets the index at which the first occurrence of `value` is found using
-+     * strict equality for comparisons, i.e. `===`. If the array is already sorted
-+     * providing `true` for `fromIndex` will run a faster binary search.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
-+     *  to perform a binary search on a sorted array.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 1
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 4
-+     *
-+     * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
-+     * // => 2
-+     */
-+    function indexOf(array, value, fromIndex) {
-+      if (typeof fromIndex == 'number') {
-+        var length = array ? array.length : 0;
-+        fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
-+      } else if (fromIndex) {
-+        var index = sortedIndex(array, value);
-+        return array[index] === value ? index : -1;
-+      }
-+      return baseIndexOf(array, value, fromIndex);
-+    }
-+
-+    /**
-+     * Gets all but the last element or last `n` elements of an array. If a
-+     * callback is provided elements at the end of the array are excluded from
-+     * the result as long as the callback returns truey. The callback is bound
-+     * to `thisArg` and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.initial([1, 2, 3]);
-+     * // => [1, 2]
-+     *
-+     * _.initial([1, 2, 3], 2);
-+     * // => [1]
-+     *
-+     * _.initial([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [1]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.initial(characters, 'blocked');
-+     * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function initial(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : callback || n;
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
-+    }
-+
-+    /**
-+     * Creates an array of unique values present in all provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of shared values.
-+     * @example
-+     *
-+     * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2]
-+     */
-+    function intersection() {
-+      var args = [],
-+          argsIndex = -1,
-+          argsLength = arguments.length,
-+          caches = getArray(),
-+          indexOf = getIndexOf(),
-+          trustIndexOf = indexOf === baseIndexOf,
-+          seen = getArray();
-+
-+      while (++argsIndex < argsLength) {
-+        var value = arguments[argsIndex];
-+        if (isArray(value) || isArguments(value)) {
-+          args.push(value);
-+          caches.push(trustIndexOf && value.length >= largeArraySize &&
-+            createCache(argsIndex ? args[argsIndex] : seen));
-+        }
-+      }
-+      var array = args[0],
-+          index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      outer:
-+      while (++index < length) {
-+        var cache = caches[0];
-+        value = array[index];
-+
-+        if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
-+          argsIndex = argsLength;
-+          (cache || seen).push(value);
-+          while (--argsIndex) {
-+            cache = caches[argsIndex];
-+            if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
-+              continue outer;
-+            }
-+          }
-+          result.push(value);
-+        }
-+      }
-+      while (argsLength--) {
-+        cache = caches[argsLength];
-+        if (cache) {
-+          releaseObject(cache);
-+        }
-+      }
-+      releaseArray(caches);
-+      releaseArray(seen);
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the last element or last `n` elements of an array. If a callback is
-+     * provided elements at the end of the array are returned as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the last element(s) of `array`.
-+     * @example
-+     *
-+     * _.last([1, 2, 3]);
-+     * // => 3
-+     *
-+     * _.last([1, 2, 3], 2);
-+     * // => [2, 3]
-+     *
-+     * _.last([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [2, 3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.last(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.last(characters, { 'employer': 'na' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function last(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[length - 1] : undefined;
-+        }
-+      }
-+      return slice(array, nativeMax(0, length - n));
-+    }
-+
-+    /**
-+     * Gets the index at which the last occurrence of `value` is found using strict
-+     * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
-+     * as the offset from the end of the collection.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {number} [fromIndex=array.length-1] The index to search from.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 4
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 1
-+     */
-+    function lastIndexOf(array, value, fromIndex) {
-+      var index = array ? array.length : 0;
-+      if (typeof fromIndex == 'number') {
-+        index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
-+      }
-+      while (index--) {
-+        if (array[index] === value) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Removes all provided values from the given array using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {...*} [value] The values to remove.
-+     * @returns {Array} Returns `array`.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 1, 2, 3];
-+     * _.pull(array, 2, 3);
-+     * console.log(array);
-+     * // => [1, 1]
-+     */
-+    function pull(array) {
-+      var args = arguments,
-+          argsIndex = 0,
-+          argsLength = args.length,
-+          length = array ? array.length : 0;
-+
-+      while (++argsIndex < argsLength) {
-+        var index = -1,
-+            value = args[argsIndex];
-+        while (++index < length) {
-+          if (array[index] === value) {
-+            splice.call(array, index--, 1);
-+            length--;
-+          }
-+        }
-+      }
-+      return array;
-+    }
-+
-+    /**
-+     * Creates an array of numbers (positive and/or negative) progressing from
-+     * `start` up to but not including `end`. If `start` is less than `stop` a
-+     * zero-length range is created unless a negative `step` is specified.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {number} [start=0] The start of the range.
-+     * @param {number} end The end of the range.
-+     * @param {number} [step=1] The value to increment or decrement by.
-+     * @returns {Array} Returns a new range array.
-+     * @example
-+     *
-+     * _.range(4);
-+     * // => [0, 1, 2, 3]
-+     *
-+     * _.range(1, 5);
-+     * // => [1, 2, 3, 4]
-+     *
-+     * _.range(0, 20, 5);
-+     * // => [0, 5, 10, 15]
-+     *
-+     * _.range(0, -4, -1);
-+     * // => [0, -1, -2, -3]
-+     *
-+     * _.range(1, 4, 0);
-+     * // => [1, 1, 1]
-+     *
-+     * _.range(0);
-+     * // => []
-+     */
-+    function range(start, end, step) {
-+      start = +start || 0;
-+      step = typeof step == 'number' ? step : (+step || 1);
-+
-+      if (end == null) {
-+        end = start;
-+        start = 0;
-+      }
-+      // use `Array(length)` so engines like Chakra and V8 avoid slower modes
-+      // http://youtu.be/XAqIpGU8ZZk#t=17m25s
-+      var index = -1,
-+          length = nativeMax(0, ceil((end - start) / (step || 1))),
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = start;
-+        start += step;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Removes all elements from an array that the callback returns truey for
-+     * and returns an array of removed elements. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of removed elements.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 4, 5, 6];
-+     * var evens = _.remove(array, function(num) { return num % 2 == 0; });
-+     *
-+     * console.log(array);
-+     * // => [1, 3, 5]
-+     *
-+     * console.log(evens);
-+     * // => [2, 4, 6]
-+     */
-+    function remove(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        var value = array[index];
-+        if (callback(value, index, array)) {
-+          result.push(value);
-+          splice.call(array, index--, 1);
-+          length--;
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The opposite of `_.initial` this method gets all but the first element or
-+     * first `n` elements of an array. If a callback function is provided elements
-+     * at the beginning of the array are excluded from the result as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias drop, tail
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.rest([1, 2, 3]);
-+     * // => [2, 3]
-+     *
-+     * _.rest([1, 2, 3], 2);
-+     * // => [3]
-+     *
-+     * _.rest([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.rest(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.rest(characters, { 'employer': 'slate' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function rest(array, callback, thisArg) {
-+      if (typeof callback != 'number' && callback != null) {
-+        var n = 0,
-+            index = -1,
-+            length = array ? array.length : 0;
-+
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
-+      }
-+      return slice(array, n);
-+    }
-+
-+    /**
-+     * Uses a binary search to determine the smallest index at which a value
-+     * should be inserted into a given sorted array in order to maintain the sort
-+     * order of the array. If a callback is provided it will be executed for
-+     * `value` and each element of `array` to compute their sort ranking. The
-+     * callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to inspect.
-+     * @param {*} value The value to evaluate.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index at which `value` should be inserted
-+     *  into `array`.
-+     * @example
-+     *
-+     * _.sortedIndex([20, 30, 50], 40);
-+     * // => 2
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
-+     * // => 2
-+     *
-+     * var dict = {
-+     *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
-+     * };
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return dict.wordToNumber[word];
-+     * });
-+     * // => 2
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return this.wordToNumber[word];
-+     * }, dict);
-+     * // => 2
-+     */
-+    function sortedIndex(array, value, callback, thisArg) {
-+      var low = 0,
-+          high = array ? array.length : low;
-+
-+      // explicitly reference `identity` for better inlining in Firefox
-+      callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
-+      value = callback(value);
-+
-+      while (low < high) {
-+        var mid = (low + high) >>> 1;
-+        (callback(array[mid]) < value)
-+          ? low = mid + 1
-+          : high = mid;
-+      }
-+      return low;
-+    }
-+
-+    /**
-+     * Creates an array of unique values, in order, of the provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of combined values.
-+     * @example
-+     *
-+     * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2, 3, 5, 4]
-+     */
-+    function union() {
-+      return baseUniq(baseFlatten(arguments, true, true));
-+    }
-+
-+    /**
-+     * Creates a duplicate-value-free version of an array using strict equality
-+     * for comparisons, i.e. `===`. If the array is sorted, providing
-+     * `true` for `isSorted` will use a faster algorithm. If a callback is provided
-+     * each element of `array` is passed through the callback before uniqueness
-+     * is computed. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unique
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     * @example
-+     *
-+     * _.uniq([1, 2, 1, 3, 1]);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq([1, 1, 2, 2, 3], true);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
-+     * // => ['A', 'b', 'C']
-+     *
-+     * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
-+     * // => [1, 2.5, 3]
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
-+     * // => [{ 'x': 1 }, { 'x': 2 }]
-+     */
-+    function uniq(array, isSorted, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isSorted != 'boolean' && isSorted != null) {
-+        thisArg = callback;
-+        callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
-+        isSorted = false;
-+      }
-+      if (callback != null) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      return baseUniq(array, isSorted, callback);
-+    }
-+
-+    /**
-+     * Creates an array excluding all provided values using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to filter.
-+     * @param {...*} [value] The values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-+     * // => [2, 3, 4]
-+     */
-+    function without(array) {
-+      return baseDifference(array, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates an array that is the symmetric difference of the provided arrays.
-+     * See http://en.wikipedia.org/wiki/Symmetric_difference.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of values.
-+     * @example
-+     *
-+     * _.xor([1, 2, 3], [5, 2, 1, 4]);
-+     * // => [3, 5, 4]
-+     *
-+     * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
-+     * // => [1, 4, 5]
-+     */
-+    function xor() {
-+      var index = -1,
-+          length = arguments.length;
-+
-+      while (++index < length) {
-+        var array = arguments[index];
-+        if (isArray(array) || isArguments(array)) {
-+          var result = result
-+            ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
-+            : array;
-+        }
-+      }
-+      return result || [];
-+    }
-+
-+    /**
-+     * Creates an array of grouped elements, the first of which contains the first
-+     * elements of the given arrays, the second of which contains the second
-+     * elements of the given arrays, and so on.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unzip
-+     * @category Arrays
-+     * @param {...Array} [array] Arrays to process.
-+     * @returns {Array} Returns a new array of grouped elements.
-+     * @example
-+     *
-+     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
-+     * // => [['fred', 30, true], ['barney', 40, false]]
-+     */
-+    function zip() {
-+      var array = arguments.length > 1 ? arguments : arguments[0],
-+          index = -1,
-+          length = array ? max(pluck(array, 'length')) : 0,
-+          result = Array(length < 0 ? 0 : length);
-+
-+      while (++index < length) {
-+        result[index] = pluck(array, index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed from arrays of `keys` and `values`. Provide
-+     * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
-+     * or two arrays, one of `keys` and one of corresponding `values`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias object
-+     * @category Arrays
-+     * @param {Array} keys The array of keys.
-+     * @param {Array} [values=[]] The array of values.
-+     * @returns {Object} Returns an object composed of the given keys and
-+     *  corresponding values.
-+     * @example
-+     *
-+     * _.zipObject(['fred', 'barney'], [30, 40]);
-+     * // => { 'fred': 30, 'barney': 40 }
-+     */
-+    function zipObject(keys, values) {
-+      var index = -1,
-+          length = keys ? keys.length : 0,
-+          result = {};
-+
-+      if (!values && length && !isArray(keys[0])) {
-+        values = [];
-+      }
-+      while (++index < length) {
-+        var key = keys[index];
-+        if (values) {
-+          result[key] = values[index];
-+        } else if (key) {
-+          result[key[0]] = key[1];
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that executes `func`, with  the `this` binding and
-+     * arguments of the created function, only after being called `n` times.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {number} n The number of times the function must be called before
-+     *  `func` is executed.
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var saves = ['profile', 'settings'];
-+     *
-+     * var done = _.after(saves.length, function() {
-+     *   console.log('Done saving!');
-+     * });
-+     *
-+     * _.forEach(saves, function(type) {
-+     *   asyncSave({ 'type': type, 'complete': done });
-+     * });
-+     * // => logs 'Done saving!', after all saves have completed
-+     */
-+    function after(n, func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (--n < 1) {
-+          return func.apply(this, arguments);
-+        }
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with the `this`
-+     * binding of `thisArg` and prepends any additional `bind` arguments to those
-+     * provided to the bound function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to bind.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var func = function(greeting) {
-+     *   return greeting + ' ' + this.name;
-+     * };
-+     *
-+     * func = _.bind(func, { 'name': 'fred' }, 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     */
-+    function bind(func, thisArg) {
-+      return arguments.length > 2
-+        ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
-+        : createWrapper(func, 1, null, null, thisArg);
-+    }
-+
-+    /**
-+     * Binds methods of an object to the object itself, overwriting the existing
-+     * method. Method names may be specified as individual arguments or as arrays
-+     * of method names. If no method names are provided all the function properties
-+     * of `object` will be bound.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object to bind and assign the bound methods to.
-+     * @param {...string} [methodName] The object method names to
-+     *  bind, specified as individual method names or arrays of method names.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'onClick': function() { console.log('clicked ' + this.label); }
-+     * };
-+     *
-+     * _.bindAll(view);
-+     * jQuery('#docs').on('click', view.onClick);
-+     * // => logs 'clicked docs', when the button is clicked
-+     */
-+    function bindAll(object) {
-+      var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
-+          index = -1,
-+          length = funcs.length;
-+
-+      while (++index < length) {
-+        var key = funcs[index];
-+        object[key] = createWrapper(object[key], 1, null, null, object);
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes the method at `object[key]`
-+     * and prepends any additional `bindKey` arguments to those provided to the bound
-+     * function. This method differs from `_.bind` by allowing bound functions to
-+     * reference methods that will be redefined or don't yet exist.
-+     * See http://michaux.ca/articles/lazy-function-definition-pattern.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object the method belongs to.
-+     * @param {string} key The key of the method.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var object = {
-+     *   'name': 'fred',
-+     *   'greet': function(greeting) {
-+     *     return greeting + ' ' + this.name;
-+     *   }
-+     * };
-+     *
-+     * var func = _.bindKey(object, 'greet', 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     *
-+     * object.greet = function(greeting) {
-+     *   return greeting + 'ya ' + this.name + '!';
-+     * };
-+     *
-+     * func();
-+     * // => 'hiya fred!'
-+     */
-+    function bindKey(object, key) {
-+      return arguments.length > 2
-+        ? createWrapper(key, 19, slice(arguments, 2), null, object)
-+        : createWrapper(key, 3, null, null, object);
-+    }
-+
-+    /**
-+     * Creates a function that is the composition of the provided functions,
-+     * where each function consumes the return value of the function that follows.
-+     * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
-+     * Each function is executed with the `this` binding of the composed function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {...Function} [func] Functions to compose.
-+     * @returns {Function} Returns the new composed function.
-+     * @example
-+     *
-+     * var realNameMap = {
-+     *   'pebbles': 'penelope'
-+     * };
-+     *
-+     * var format = function(name) {
-+     *   name = realNameMap[name.toLowerCase()] || name;
-+     *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
-+     * };
-+     *
-+     * var greet = function(formatted) {
-+     *   return 'Hiya ' + formatted + '!';
-+     * };
-+     *
-+     * var welcome = _.compose(greet, format);
-+     * welcome('pebbles');
-+     * // => 'Hiya Penelope!'
-+     */
-+    function compose() {
-+      var funcs = arguments,
-+          length = funcs.length;
-+
-+      while (length--) {
-+        if (!isFunction(funcs[length])) {
-+          throw new TypeError;
-+        }
-+      }
-+      return function() {
-+        var args = arguments,
-+            length = funcs.length;
-+
-+        while (length--) {
-+          args = [funcs[length].apply(this, args)];
-+        }
-+        return args[0];
-+      };
-+    }
-+
-+    /**
-+     * Creates a function which accepts one or more arguments of `func` that when
-+     * invoked either executes `func` returning its result, if all `func` arguments
-+     * have been provided, or returns a function that accepts one or more of the
-+     * remaining `func` arguments, and so on. The arity of `func` can be specified
-+     * if `func.length` is not sufficient.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to curry.
-+     * @param {number} [arity=func.length] The arity of `func`.
-+     * @returns {Function} Returns the new curried function.
-+     * @example
-+     *
-+     * var curried = _.curry(function(a, b, c) {
-+     *   console.log(a + b + c);
-+     * });
-+     *
-+     * curried(1)(2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2, 3);
-+     * // => 6
-+     */
-+    function curry(func, arity) {
-+      arity = typeof arity == 'number' ? arity : (+arity || func.length);
-+      return createWrapper(func, 4, null, null, null, arity);
-+    }
-+
-+    /**
-+     * Creates a function that will delay the execution of `func` until after
-+     * `wait` milliseconds have elapsed since the last time it was invoked.
-+     * Provide an options object to indicate that `func` should be invoked on
-+     * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
-+     * to the debounced function will return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the debounced function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to debounce.
-+     * @param {number} wait The number of milliseconds to delay.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
-+     * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new debounced function.
-+     * @example
-+     *
-+     * // avoid costly calculations while the window size is in flux
-+     * var lazyLayout = _.debounce(calculateLayout, 150);
-+     * jQuery(window).on('resize', lazyLayout);
-+     *
-+     * // execute `sendMail` when the click event is fired, debouncing subsequent calls
-+     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
-+     *   'leading': true,
-+     *   'trailing': false
-+     * });
-+     *
-+     * // ensure `batchLog` is executed once after 1 second of debounced calls
-+     * var source = new EventSource('/stream');
-+     * source.addEventListener('message', _.debounce(batchLog, 250, {
-+     *   'maxWait': 1000
-+     * }, false);
-+     */
-+    function debounce(func, wait, options) {
-+      var args,
-+          maxTimeoutId,
-+          result,
-+          stamp,
-+          thisArg,
-+          timeoutId,
-+          trailingCall,
-+          lastCalled = 0,
-+          maxWait = false,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      wait = nativeMax(0, wait) || 0;
-+      if (options === true) {
-+        var leading = true;
-+        trailing = false;
-+      } else if (isObject(options)) {
-+        leading = options.leading;
-+        maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      var delayed = function() {
-+        var remaining = wait - (now() - stamp);
-+        if (remaining <= 0) {
-+          if (maxTimeoutId) {
-+            clearTimeout(maxTimeoutId);
-+          }
-+          var isCalled = trailingCall;
-+          maxTimeoutId = timeoutId = trailingCall = undefined;
-+          if (isCalled) {
-+            lastCalled = now();
-+            result = func.apply(thisArg, args);
-+            if (!timeoutId && !maxTimeoutId) {
-+              args = thisArg = null;
-+            }
-+          }
-+        } else {
-+          timeoutId = setTimeout(delayed, remaining);
-+        }
-+      };
-+
-+      var maxDelayed = function() {
-+        if (timeoutId) {
-+          clearTimeout(timeoutId);
-+        }
-+        maxTimeoutId = timeoutId = trailingCall = undefined;
-+        if (trailing || (maxWait !== wait)) {
-+          lastCalled = now();
-+          result = func.apply(thisArg, args);
-+          if (!timeoutId && !maxTimeoutId) {
-+            args = thisArg = null;
-+          }
-+        }
-+      };
-+
-+      return function() {
-+        args = arguments;
-+        stamp = now();
-+        thisArg = this;
-+        trailingCall = trailing && (timeoutId || !leading);
-+
-+        if (maxWait === false) {
-+          var leadingCall = leading && !timeoutId;
-+        } else {
-+          if (!maxTimeoutId && !leading) {
-+            lastCalled = stamp;
-+          }
-+          var remaining = maxWait - (stamp - lastCalled),
-+              isCalled = remaining <= 0;
-+
-+          if (isCalled) {
-+            if (maxTimeoutId) {
-+              maxTimeoutId = clearTimeout(maxTimeoutId);
-+            }
-+            lastCalled = stamp;
-+            result = func.apply(thisArg, args);
-+          }
-+          else if (!maxTimeoutId) {
-+            maxTimeoutId = setTimeout(maxDelayed, remaining);
-+          }
-+        }
-+        if (isCalled && timeoutId) {
-+          timeoutId = clearTimeout(timeoutId);
-+        }
-+        else if (!timeoutId && wait !== maxWait) {
-+          timeoutId = setTimeout(delayed, wait);
-+        }
-+        if (leadingCall) {
-+          isCalled = true;
-+          result = func.apply(thisArg, args);
-+        }
-+        if (isCalled && !timeoutId && !maxTimeoutId) {
-+          args = thisArg = null;
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Defers executing the `func` function until the current call stack has cleared.
-+     * Additional arguments will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to defer.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.defer(function(text) { console.log(text); }, 'deferred');
-+     * // logs 'deferred' after one or more milliseconds
-+     */
-+    function defer(func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 1);
-+      return setTimeout(function() { func.apply(undefined, args); }, 1);
-+    }
-+
-+    /**
-+     * Executes the `func` function after `wait` milliseconds. Additional arguments
-+     * will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to delay.
-+     * @param {number} wait The number of milliseconds to delay execution.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.delay(function(text) { console.log(text); }, 1000, 'later');
-+     * // => logs 'later' after one second
-+     */
-+    function delay(func, wait) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 2);
-+      return setTimeout(function() { func.apply(undefined, args); }, wait);
-+    }
-+
-+    /**
-+     * Creates a function that memoizes the result of `func`. If `resolver` is
-+     * provided it will be used to determine the cache key for storing the result
-+     * based on the arguments provided to the memoized function. By default, the
-+     * first argument provided to the memoized function is used as the cache key.
-+     * The `func` is executed with the `this` binding of the memoized function.
-+     * The result cache is exposed as the `cache` property on the memoized function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to have its output memoized.
-+     * @param {Function} [resolver] A function used to resolve the cache key.
-+     * @returns {Function} Returns the new memoizing function.
-+     * @example
-+     *
-+     * var fibonacci = _.memoize(function(n) {
-+     *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-+     * });
-+     *
-+     * fibonacci(9)
-+     * // => 34
-+     *
-+     * var data = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // modifying the result cache
-+     * var get = _.memoize(function(name) { return data[name]; }, _.identity);
-+     * get('pebbles');
-+     * // => { 'name': 'pebbles', 'age': 1 }
-+     *
-+     * get.cache.pebbles.name = 'penelope';
-+     * get('pebbles');
-+     * // => { 'name': 'penelope', 'age': 1 }
-+     */
-+    function memoize(func, resolver) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var memoized = function() {
-+        var cache = memoized.cache,
-+            key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-+
-+        return hasOwnProperty.call(cache, key)
-+          ? cache[key]
-+          : (cache[key] = func.apply(this, arguments));
-+      }
-+      memoized.cache = {};
-+      return memoized;
-+    }
-+
-+    /**
-+     * Creates a function that is restricted to execute `func` once. Repeat calls to
-+     * the function will return the value of the first call. The `func` is executed
-+     * with the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var initialize = _.once(createApplication);
-+     * initialize();
-+     * initialize();
-+     * // `initialize` executes `createApplication` once
-+     */
-+    function once(func) {
-+      var ran,
-+          result;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (ran) {
-+          return result;
-+        }
-+        ran = true;
-+        result = func.apply(this, arguments);
-+
-+        // clear the `func` variable so the function may be garbage collected
-+        func = null;
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with any additional
-+     * `partial` arguments prepended to those provided to the new function. This
-+     * method is similar to `_.bind` except it does **not** alter the `this` binding.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var greet = function(greeting, name) { return greeting + ' ' + name; };
-+     * var hi = _.partial(greet, 'hi');
-+     * hi('fred');
-+     * // => 'hi fred'
-+     */
-+    function partial(func) {
-+      return createWrapper(func, 16, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.partial` except that `partial` arguments are
-+     * appended to those provided to the new function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var defaultsDeep = _.partialRight(_.merge, _.defaults);
-+     *
-+     * var options = {
-+     *   'variable': 'data',
-+     *   'imports': { 'jq': $ }
-+     * };
-+     *
-+     * defaultsDeep(options, _.templateSettings);
-+     *
-+     * options.variable
-+     * // => 'data'
-+     *
-+     * options.imports
-+     * // => { '_': _, 'jq': $ }
-+     */
-+    function partialRight(func) {
-+      return createWrapper(func, 32, null, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates a function that, when executed, will only call the `func` function
-+     * at most once per every `wait` milliseconds. Provide an options object to
-+     * indicate that `func` should be invoked on the leading and/or trailing edge
-+     * of the `wait` timeout. Subsequent calls to the throttled function will
-+     * return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the throttled function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to throttle.
-+     * @param {number} wait The number of milliseconds to throttle executions to.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new throttled function.
-+     * @example
-+     *
-+     * // avoid excessively updating the position while scrolling
-+     * var throttled = _.throttle(updatePosition, 100);
-+     * jQuery(window).on('scroll', throttled);
-+     *
-+     * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
-+     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
-+     *   'trailing': false
-+     * }));
-+     */
-+    function throttle(func, wait, options) {
-+      var leading = true,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (options === false) {
-+        leading = false;
-+      } else if (isObject(options)) {
-+        leading = 'leading' in options ? options.leading : leading;
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      debounceOptions.leading = leading;
-+      debounceOptions.maxWait = wait;
-+      debounceOptions.trailing = trailing;
-+
-+      return debounce(func, wait, debounceOptions);
-+    }
-+
-+    /**
-+     * Creates a function that provides `value` to the wrapper function as its
-+     * first argument. Additional arguments provided to the function are appended
-+     * to those provided to the wrapper function. The wrapper is executed with
-+     * the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {*} value The value to wrap.
-+     * @param {Function} wrapper The wrapper function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var p = _.wrap(_.escape, function(func, text) {
-+     *   return '<p>' + func(text) + '</p>';
-+     * });
-+     *
-+     * p('Fred, Wilma, & Pebbles');
-+     * // => '<p>Fred, Wilma, & Pebbles</p>'
-+     */
-+    function wrap(value, wrapper) {
-+      return createWrapper(wrapper, 16, [value]);
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that returns `value`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value The value to return from the new function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var getter = _.constant(object);
-+     * getter() === object;
-+     * // => true
-+     */
-+    function constant(value) {
-+      return function() {
-+        return value;
-+      };
-+    }
-+
-+    /**
-+     * Produces a callback bound to an optional `thisArg`. If `func` is a property
-+     * name the created callback will return the property value for a given element.
-+     * If `func` is an object the created callback will return `true` for elements
-+     * that contain the equivalent object properties, otherwise it will return `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // wrap to create custom callback shorthands
-+     * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
-+     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
-+     *   return !match ? func(callback, thisArg) : function(object) {
-+     *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
-+     *   };
-+     * });
-+     *
-+     * _.filter(characters, 'age__gt38');
-+     * // => [{ 'name': 'fred', 'age': 40 }]
-+     */
-+    function createCallback(func, thisArg, argCount) {
-+      var type = typeof func;
-+      if (func == null || type == 'function') {
-+        return baseCreateCallback(func, thisArg, argCount);
-+      }
-+      // handle "_.pluck" style callback shorthands
-+      if (type != 'object') {
-+        return property(func);
-+      }
-+      var props = keys(func),
-+          key = props[0],
-+          a = func[key];
-+
-+      // handle "_.where" style callback shorthands
-+      if (props.length == 1 && a === a && !isObject(a)) {
-+        // fast path the common case of providing an object with a single
-+        // property containing a primitive value
-+        return function(object) {
-+          var b = object[key];
-+          return a === b && (a !== 0 || (1 / a == 1 / b));
-+        };
-+      }
-+      return function(object) {
-+        var length = props.length,
-+            result = false;
-+
-+        while (length--) {
-+          if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
-+            break;
-+          }
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding HTML entities.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to escape.
-+     * @returns {string} Returns the escaped string.
-+     * @example
-+     *
-+     * _.escape('Fred, Wilma, & Pebbles');
-+     * // => 'Fred, Wilma, & Pebbles'
-+     */
-+    function escape(string) {
-+      return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
-+    }
-+
-+    /**
-+     * This method returns the first argument provided to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value Any value.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.identity(object) === object;
-+     * // => true
-+     */
-+    function identity(value) {
-+      return value;
-+    }
-+
-+    /**
-+     * Adds function properties of a source object to the destination object.
-+     * If `object` is a function methods will be added to its prototype as well.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Function|Object} [object=lodash] object The destination object.
-+     * @param {Object} source The object of functions to add.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
-+     * @example
-+     *
-+     * function capitalize(string) {
-+     *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
-+     * }
-+     *
-+     * _.mixin({ 'capitalize': capitalize });
-+     * _.capitalize('fred');
-+     * // => 'Fred'
-+     *
-+     * _('fred').capitalize().value();
-+     * // => 'Fred'
-+     *
-+     * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
-+     * _('fred').capitalize();
-+     * // => 'Fred'
-+     */
-+    function mixin(object, source, options) {
-+      var chain = true,
-+          methodNames = source && functions(source);
-+
-+      if (!source || (!options && !methodNames.length)) {
-+        if (options == null) {
-+          options = source;
-+        }
-+        ctor = lodashWrapper;
-+        source = object;
-+        object = lodash;
-+        methodNames = functions(source);
-+      }
-+      if (options === false) {
-+        chain = false;
-+      } else if (isObject(options) && 'chain' in options) {
-+        chain = options.chain;
-+      }
-+      var ctor = object,
-+          isFunc = isFunction(ctor);
-+
-+      forEach(methodNames, function(methodName) {
-+        var func = object[methodName] = source[methodName];
-+        if (isFunc) {
-+          ctor.prototype[methodName] = function() {
-+            var chainAll = this.__chain__,
-+                value = this.__wrapped__,
-+                args = [value];
-+
-+            push.apply(args, arguments);
-+            var result = func.apply(object, args);
-+            if (chain || chainAll) {
-+              if (value === result && isObject(result)) {
-+                return this;
-+              }
-+              result = new ctor(result);
-+              result.__chain__ = chainAll;
-+            }
-+            return result;
-+          };
-+        }
-+      });
-+    }
-+
-+    /**
-+     * Reverts the '_' variable to its previous value and returns a reference to
-+     * the `lodash` function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @returns {Function} Returns the `lodash` function.
-+     * @example
-+     *
-+     * var lodash = _.noConflict();
-+     */
-+    function noConflict() {
-+      context._ = oldDash;
-+      return this;
-+    }
-+
-+    /**
-+     * A no-operation function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.noop(object) === undefined;
-+     * // => true
-+     */
-+    function noop() {
-+      // no operation performed
-+    }
-+
-+    /**
-+     * Gets the number of milliseconds that have elapsed since the Unix epoch
-+     * (1 January 1970 00:00:00 UTC).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var stamp = _.now();
-+     * _.defer(function() { console.log(_.now() - stamp); });
-+     * // => logs the number of milliseconds it took for the deferred function to be called
-+     */
-+    var now = isNative(now = Date.now) && now || function() {
-+      return new Date().getTime();
-+    };
-+
-+    /**
-+     * Converts the given value into an integer of the specified radix.
-+     * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
-+     * `value` is a hexadecimal, in which case a `radix` of `16` is used.
-+     *
-+     * Note: This method avoids differences in native ES3 and ES5 `parseInt`
-+     * implementations. See http://es5.github.io/#E.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} value The value to parse.
-+     * @param {number} [radix] The radix used to interpret the value to parse.
-+     * @returns {number} Returns the new integer value.
-+     * @example
-+     *
-+     * _.parseInt('08');
-+     * // => 8
-+     */
-+    var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
-+      // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
-+      return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
-+    };
-+
-+    /**
-+     * Creates a "_.pluck" style function, which returns the `key` value of a
-+     * given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} key The name of the property to retrieve.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'fred',   'age': 40 },
-+     *   { 'name': 'barney', 'age': 36 }
-+     * ];
-+     *
-+     * var getName = _.property('name');
-+     *
-+     * _.map(characters, getName);
-+     * // => ['barney', 'fred']
-+     *
-+     * _.sortBy(characters, getName);
-+     * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
-+     */
-+    function property(key) {
-+      return function(object) {
-+        return object[key];
-+      };
-+    }
-+
-+    /**
-+     * Produces a random number between `min` and `max` (inclusive). If only one
-+     * argument is provided a number between `0` and the given number will be
-+     * returned. If `floating` is truey or either `min` or `max` are floats a
-+     * floating-point number will be returned instead of an integer.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} [min=0] The minimum possible value.
-+     * @param {number} [max=1] The maximum possible value.
-+     * @param {boolean} [floating=false] Specify returning a floating-point number.
-+     * @returns {number} Returns a random number.
-+     * @example
-+     *
-+     * _.random(0, 5);
-+     * // => an integer between 0 and 5
-+     *
-+     * _.random(5);
-+     * // => also an integer between 0 and 5
-+     *
-+     * _.random(5, true);
-+     * // => a floating-point number between 0 and 5
-+     *
-+     * _.random(1.2, 5.2);
-+     * // => a floating-point number between 1.2 and 5.2
-+     */
-+    function random(min, max, floating) {
-+      var noMin = min == null,
-+          noMax = max == null;
-+
-+      if (floating == null) {
-+        if (typeof min == 'boolean' && noMax) {
-+          floating = min;
-+          min = 1;
-+        }
-+        else if (!noMax && typeof max == 'boolean') {
-+          floating = max;
-+          noMax = true;
-+        }
-+      }
-+      if (noMin && noMax) {
-+        max = 1;
-+      }
-+      min = +min || 0;
-+      if (noMax) {
-+        max = min;
-+        min = 0;
-+      } else {
-+        max = +max || 0;
-+      }
-+      if (floating || min % 1 || max % 1) {
-+        var rand = nativeRandom();
-+        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
-+      }
-+      return baseRandom(min, max);
-+    }
-+
-+    /**
-+     * Resolves the value of property `key` on `object`. If `key` is a function
-+     * it will be invoked with the `this` binding of `object` and its result returned,
-+     * else the property value is returned. If `object` is falsey then `undefined`
-+     * is returned.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to resolve.
-+     * @returns {*} Returns the resolved value.
-+     * @example
-+     *
-+     * var object = {
-+     *   'cheese': 'crumpets',
-+     *   'stuff': function() {
-+     *     return 'nonsense';
-+     *   }
-+     * };
-+     *
-+     * _.result(object, 'cheese');
-+     * // => 'crumpets'
-+     *
-+     * _.result(object, 'stuff');
-+     * // => 'nonsense'
-+     */
-+    function result(object, key) {
-+      if (object) {
-+        var value = object[key];
-+        return isFunction(value) ? object[key]() : value;
-+      }
-+    }
-+
-+    /**
-+     * A micro-templating method that handles arbitrary delimiters, preserves
-+     * whitespace, and correctly escapes quotes within interpolated code.
-+     *
-+     * Note: In the development build, `_.template` utilizes sourceURLs for easier
-+     * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+     *
-+     * For more information on precompiling templates see:
-+     * http://lodash.com/custom-builds
-+     *
-+     * For more information on Chrome extension sandboxes see:
-+     * http://developer.chrome.com/stable/extensions/sandboxingEval.html
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} text The template text.
-+     * @param {Object} data The data object used to populate the text.
-+     * @param {Object} [options] The options object.
-+     * @param {RegExp} [options.escape] The "escape" delimiter.
-+     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
-+     * @param {Object} [options.imports] An object to import into the template as local variables.
-+     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
-+     * @param {string} [sourceURL] The sourceURL of the template's compiled source.
-+     * @param {string} [variable] The data object variable name.
-+     * @returns {Function|string} Returns a compiled function when no `data` object
-+     *  is given, else it returns the interpolated text.
-+     * @example
-+     *
-+     * // using the "interpolate" delimiter to create a compiled template
-+     * var compiled = _.template('hello <%= name %>');
-+     * compiled({ 'name': 'fred' });
-+     * // => 'hello fred'
-+     *
-+     * // using the "escape" delimiter to escape HTML in data property values
-+     * _.template('<b><%- value %></b>', { 'value': '<script>' });
-+     * // => '<b><script></b>'
-+     *
-+     * // using the "evaluate" delimiter to generate HTML
-+     * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
-+     * _.template('hello ${ name }', { 'name': 'pebbles' });
-+     * // => 'hello pebbles'
-+     *
-+     * // using the internal `print` function in "evaluate" delimiters
-+     * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
-+     * // => 'hello barney!'
-+     *
-+     * // using a custom template delimiters
-+     * _.templateSettings = {
-+     *   'interpolate': /{{([\s\S]+?)}}/g
-+     * };
-+     *
-+     * _.template('hello {{ name }}!', { 'name': 'mustache' });
-+     * // => 'hello mustache!'
-+     *
-+     * // using the `imports` option to import jQuery
-+     * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the `sourceURL` option to specify a custom sourceURL for the template
-+     * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
-+     * compiled(data);
-+     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
-+     *
-+     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
-+     * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
-+     * compiled.source;
-+     * // => function(data) {
-+     *   var __t, __p = '', __e = _.escape;
-+     *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
-+     *   return __p;
-+     * }
-+     *
-+     * // using the `source` property to inline compiled templates for meaningful
-+     * // line numbers in error messages and a stack trace
-+     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
-+     *   var JST = {\
-+     *     "main": ' + _.template(mainText).source + '\
-+     *   };\
-+     * ');
-+     */
-+    function template(text, data, options) {
-+      // based on John Resig's `tmpl` implementation
-+      // http://ejohn.org/blog/javascript-micro-templating/
-+      // and Laura Doktorova's doT.js
-+      // https://github.com/olado/doT
-+      var settings = lodash.templateSettings;
-+      text = String(text || '');
-+
-+      // avoid missing dependencies when `iteratorTemplate` is not defined
-+      options = defaults({}, options, settings);
-+
-+      var imports = defaults({}, options.imports, settings.imports),
-+          importsKeys = keys(imports),
-+          importsValues = values(imports);
-+
-+      var isEvaluating,
-+          index = 0,
-+          interpolate = options.interpolate || reNoMatch,
-+          source = "__p += '";
-+
-+      // compile the regexp to match each delimiter
-+      var reDelimiters = RegExp(
-+        (options.escape || reNoMatch).source + '|' +
-+        interpolate.source + '|' +
-+        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
-+        (options.evaluate || reNoMatch).source + '|$'
-+      , 'g');
-+
-+      text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
-+        interpolateValue || (interpolateValue = esTemplateValue);
-+
-+        // escape characters that cannot be included in string literals
-+        source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
-+
-+        // replace delimiters with snippets
-+        if (escapeValue) {
-+          source += "' +\n__e(" + escapeValue + ") +\n'";
-+        }
-+        if (evaluateValue) {
-+          isEvaluating = true;
-+          source += "';\n" + evaluateValue + ";\n__p += '";
-+        }
-+        if (interpolateValue) {
-+          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
-+        }
-+        index = offset + match.length;
-+
-+        // the JS engine embedded in Adobe products requires returning the `match`
-+        // string in order to produce the correct `offset` value
-+        return match;
-+      });
-+
-+      source += "';\n";
-+
-+      // if `variable` is not specified, wrap a with-statement around the generated
-+      // code to add the data object to the top of the scope chain
-+      var variable = options.variable,
-+          hasVariable = variable;
-+
-+      if (!hasVariable) {
-+        variable = 'obj';
-+        source = 'with (' + variable + ') {\n' + source + '\n}\n';
-+      }
-+      // cleanup code by stripping empty strings
-+      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
-+        .replace(reEmptyStringMiddle, '$1')
-+        .replace(reEmptyStringTrailing, '$1;');
-+
-+      // frame code as the function body
-+      source = 'function(' + variable + ') {\n' +
-+        (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
-+        "var __t, __p = '', __e = _.escape" +
-+        (isEvaluating
-+          ? ', __j = Array.prototype.join;\n' +
-+            "function print() { __p += __j.call(arguments, '') }\n"
-+          : ';\n'
-+        ) +
-+        source +
-+        'return __p\n}';
-+
-+      // Use a sourceURL for easier debugging.
-+      // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+      var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
-+
-+      try {
-+        var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
-+      } catch(e) {
-+        e.source = source;
-+        throw e;
-+      }
-+      if (data) {
-+        return result(data);
-+      }
-+      // provide the compiled function's source by its `toString` method, in
-+      // supported environments, or the `source` property as a convenience for
-+      // inlining compiled templates during the build process
-+      result.source = source;
-+      return result;
-+    }
-+
-+    /**
-+     * Executes the callback `n` times, returning an array of the results
-+     * of each callback execution. The callback is bound to `thisArg` and invoked
-+     * with one argument; (index).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} n The number of times to execute the callback.
-+     * @param {Function} callback The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns an array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
-+     * // => [3, 6, 4]
-+     *
-+     * _.times(3, function(n) { mage.castSpell(n); });
-+     * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
-+     *
-+     * _.times(3, function(n) { this.cast(n); }, mage);
-+     * // => also calls `mage.castSpell(n)` three times
-+     */
-+    function times(n, callback, thisArg) {
-+      n = (n = +n) > -1 ? n : 0;
-+      var index = -1,
-+          result = Array(n);
-+
-+      callback = baseCreateCallback(callback, thisArg, 1);
-+      while (++index < n) {
-+        result[index] = callback(index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The inverse of `_.escape` this method converts the HTML entities
-+     * `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding characters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to unescape.
-+     * @returns {string} Returns the unescaped string.
-+     * @example
-+     *
-+     * _.unescape('Fred, Barney & Pebbles');
-+     * // => 'Fred, Barney & Pebbles'
-+     */
-+    function unescape(string) {
-+      return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
-+    }
-+
-+    /**
-+     * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} [prefix] The value to prefix the ID with.
-+     * @returns {string} Returns the unique ID.
-+     * @example
-+     *
-+     * _.uniqueId('contact_');
-+     * // => 'contact_104'
-+     *
-+     * _.uniqueId();
-+     * // => '105'
-+     */
-+    function uniqueId(prefix) {
-+      var id = ++idCounter;
-+      return String(prefix == null ? '' : prefix) + id;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object that wraps the given value with explicit
-+     * method chaining enabled.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to wrap.
-+     * @returns {Object} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'pebbles', 'age': 1 }
-+     * ];
-+     *
-+     * var youngest = _.chain(characters)
-+     *     .sortBy('age')
-+     *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
-+     *     .first()
-+     *     .value();
-+     * // => 'pebbles is 1'
-+     */
-+    function chain(value) {
-+      value = new lodashWrapper(value);
-+      value.__chain__ = true;
-+      return value;
-+    }
-+
-+    /**
-+     * Invokes `interceptor` with the `value` as the first argument and then
-+     * returns `value`. The purpose of this method is to "tap into" a method
-+     * chain in order to perform operations on intermediate results within
-+     * the chain.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to provide to `interceptor`.
-+     * @param {Function} interceptor The function to invoke.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * _([1, 2, 3, 4])
-+     *  .tap(function(array) { array.pop(); })
-+     *  .reverse()
-+     *  .value();
-+     * // => [3, 2, 1]
-+     */
-+    function tap(value, interceptor) {
-+      interceptor(value);
-+      return value;
-+    }
-+
-+    /**
-+     * Enables explicit method chaining on the wrapper object.
-+     *
-+     * @name chain
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {*} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // without explicit chaining
-+     * _(characters).first();
-+     * // => { 'name': 'barney', 'age': 36 }
-+     *
-+     * // with explicit chaining
-+     * _(characters).chain()
-+     *   .first()
-+     *   .pick('age')
-+     *   .value();
-+     * // => { 'age': 36 }
-+     */
-+    function wrapperChain() {
-+      this.__chain__ = true;
-+      return this;
-+    }
-+
-+    /**
-+     * Produces the `toString` result of the wrapped value.
-+     *
-+     * @name toString
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {string} Returns the string result.
-+     * @example
-+     *
-+     * _([1, 2, 3]).toString();
-+     * // => '1,2,3'
-+     */
-+    function wrapperToString() {
-+      return String(this.__wrapped__);
-+    }
-+
-+    /**
-+     * Extracts the wrapped value.
-+     *
-+     * @name valueOf
-+     * @memberOf _
-+     * @alias value
-+     * @category Chaining
-+     * @returns {*} Returns the wrapped value.
-+     * @example
-+     *
-+     * _([1, 2, 3]).valueOf();
-+     * // => [1, 2, 3]
-+     */
-+    function wrapperValueOf() {
-+      return this.__wrapped__;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return wrapped values when chaining
-+    lodash.after = after;
-+    lodash.assign = assign;
-+    lodash.at = at;
-+    lodash.bind = bind;
-+    lodash.bindAll = bindAll;
-+    lodash.bindKey = bindKey;
-+    lodash.chain = chain;
-+    lodash.compact = compact;
-+    lodash.compose = compose;
-+    lodash.constant = constant;
-+    lodash.countBy = countBy;
-+    lodash.create = create;
-+    lodash.createCallback = createCallback;
-+    lodash.curry = curry;
-+    lodash.debounce = debounce;
-+    lodash.defaults = defaults;
-+    lodash.defer = defer;
-+    lodash.delay = delay;
-+    lodash.difference = difference;
-+    lodash.filter = filter;
-+    lodash.flatten = flatten;
-+    lodash.forEach = forEach;
-+    lodash.forEachRight = forEachRight;
-+    lodash.forIn = forIn;
-+    lodash.forInRight = forInRight;
-+    lodash.forOwn = forOwn;
-+    lodash.forOwnRight = forOwnRight;
-+    lodash.functions = functions;
-+    lodash.groupBy = groupBy;
-+    lodash.indexBy = indexBy;
-+    lodash.initial = initial;
-+    lodash.intersection = intersection;
-+    lodash.invert = invert;
-+    lodash.invoke = invoke;
-+    lodash.keys = keys;
-+    lodash.map = map;
-+    lodash.mapValues = mapValues;
-+    lodash.max = max;
-+    lodash.memoize = memoize;
-+    lodash.merge = merge;
-+    lodash.min = min;
-+    lodash.omit = omit;
-+    lodash.once = once;
-+    lodash.pairs = pairs;
-+    lodash.partial = partial;
-+    lodash.partialRight = partialRight;
-+    lodash.pick = pick;
-+    lodash.pluck = pluck;
-+    lodash.property = property;
-+    lodash.pull = pull;
-+    lodash.range = range;
-+    lodash.reject = reject;
-+    lodash.remove = remove;
-+    lodash.rest = rest;
-+    lodash.shuffle = shuffle;
-+    lodash.sortBy = sortBy;
-+    lodash.tap = tap;
-+    lodash.throttle = throttle;
-+    lodash.times = times;
-+    lodash.toArray = toArray;
-+    lodash.transform = transform;
-+    lodash.union = union;
-+    lodash.uniq = uniq;
-+    lodash.values = values;
-+    lodash.where = where;
-+    lodash.without = without;
-+    lodash.wrap = wrap;
-+    lodash.xor = xor;
-+    lodash.zip = zip;
-+    lodash.zipObject = zipObject;
-+
-+    // add aliases
-+    lodash.collect = map;
-+    lodash.drop = rest;
-+    lodash.each = forEach;
-+    lodash.eachRight = forEachRight;
-+    lodash.extend = assign;
-+    lodash.methods = functions;
-+    lodash.object = zipObject;
-+    lodash.select = filter;
-+    lodash.tail = rest;
-+    lodash.unique = uniq;
-+    lodash.unzip = zip;
-+
-+    // add functions to `lodash.prototype`
-+    mixin(lodash);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return unwrapped values when chaining
-+    lodash.clone = clone;
-+    lodash.cloneDeep = cloneDeep;
-+    lodash.contains = contains;
-+    lodash.escape = escape;
-+    lodash.every = every;
-+    lodash.find = find;
-+    lodash.findIndex = findIndex;
-+    lodash.findKey = findKey;
-+    lodash.findLast = findLast;
-+    lodash.findLastIndex = findLastIndex;
-+    lodash.findLastKey = findLastKey;
-+    lodash.has = has;
-+    lodash.identity = identity;
-+    lodash.indexOf = indexOf;
-+    lodash.isArguments = isArguments;
-+    lodash.isArray = isArray;
-+    lodash.isBoolean = isBoolean;
-+    lodash.isDate = isDate;
-+    lodash.isElement = isElement;
-+    lodash.isEmpty = isEmpty;
-+    lodash.isEqual = isEqual;
-+    lodash.isFinite = isFinite;
-+    lodash.isFunction = isFunction;
-+    lodash.isNaN = isNaN;
-+    lodash.isNull = isNull;
-+    lodash.isNumber = isNumber;
-+    lodash.isObject = isObject;
-+    lodash.isPlainObject = isPlainObject;
-+    lodash.isRegExp = isRegExp;
-+    lodash.isString = isString;
-+    lodash.isUndefined = isUndefined;
-+    lodash.lastIndexOf = lastIndexOf;
-+    lodash.mixin = mixin;
-+    lodash.noConflict = noConflict;
-+    lodash.noop = noop;
-+    lodash.now = now;
-+    lodash.parseInt = parseInt;
-+    lodash.random = random;
-+    lodash.reduce = reduce;
-+    lodash.reduceRight = reduceRight;
-+    lodash.result = result;
-+    lodash.runInContext = runInContext;
-+    lodash.size = size;
-+    lodash.some = some;
-+    lodash.sortedIndex = sortedIndex;
-+    lodash.template = template;
-+    lodash.unescape = unescape;
-+    lodash.uniqueId = uniqueId;
-+
-+    // add aliases
-+    lodash.all = every;
-+    lodash.any = some;
-+    lodash.detect = find;
-+    lodash.findWhere = find;
-+    lodash.foldl = reduce;
-+    lodash.foldr = reduceRight;
-+    lodash.include = contains;
-+    lodash.inject = reduce;
-+
-+    mixin(function() {
-+      var source = {}
-+      forOwn(lodash, function(func, methodName) {
-+        if (!lodash.prototype[methodName]) {
-+          source[methodName] = func;
-+        }
-+      });
-+      return source;
-+    }(), false);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions capable of returning wrapped and unwrapped values when chaining
-+    lodash.first = first;
-+    lodash.last = last;
-+    lodash.sample = sample;
-+
-+    // add aliases
-+    lodash.take = first;
-+    lodash.head = first;
-+
-+    forOwn(lodash, function(func, methodName) {
-+      var callbackable = methodName !== 'sample';
-+      if (!lodash.prototype[methodName]) {
-+        lodash.prototype[methodName]= function(n, guard) {
-+          var chainAll = this.__chain__,
-+              result = func(this.__wrapped__, n, guard);
-+
-+          return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
-+            ? result
-+            : new lodashWrapper(result, chainAll);
-+        };
-+      }
-+    });
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The semantic version number.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type string
-+     */
-+    lodash.VERSION = '2.4.1';
-+
-+    // add "Chaining" functions to the wrapper
-+    lodash.prototype.chain = wrapperChain;
-+    lodash.prototype.toString = wrapperToString;
-+    lodash.prototype.value = wrapperValueOf;
-+    lodash.prototype.valueOf = wrapperValueOf;
-+
-+    // add `Array` functions that return unwrapped values
-+    forEach(['join', 'pop', 'shift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        var chainAll = this.__chain__,
-+            result = func.apply(this.__wrapped__, arguments);
-+
-+        return chainAll
-+          ? new lodashWrapper(result, chainAll)
-+          : result;
-+      };
-+    });
-+
-+    // add `Array` functions that return the existing wrapped value
-+    forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        func.apply(this.__wrapped__, arguments);
-+        return this;
-+      };
-+    });
-+
-+    // add `Array` functions that return new wrapped values
-+    forEach(['concat', 'slice', 'splice'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
-+      };
-+    });
-+
-+    return lodash;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // expose Lo-Dash
-+  var _ = runInContext();
-+
-+  // some AMD build optimizers like r.js check for condition patterns like the following:
-+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
-+    // Expose Lo-Dash to the global object even when an AMD loader is present in
-+    // case Lo-Dash is loaded with a RequireJS shim config.
-+    // See http://requirejs.org/docs/api.html#config-shim
-+    root._ = _;
-+
-+    // define as an anonymous module so, through path mapping, it can be
-+    // referenced as the "underscore" module
-+    define(function() {
-+      return _;
-+    });
-+  }
-+  // check for `exports` after `define` in case a build optimizer adds an `exports` object
-+  else if (freeExports && freeModule) {
-+    // in Node.js or RingoJS
-+    if (moduleExports) {
-+      (freeModule.exports = _)._ = _;
-+    }
-+    // in Narwhal or Rhino -require
-+    else {
-+      freeExports._ = _;
-+    }
-+  }
-+  else {
-+    // in a browser or Rhino
-+    root._ = _;
-+  }
-+}.call(this));
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.min.js
-@@ -0,0 +1,56 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
-+ * Build: `lodash modern -o ./dist/lodash.js`
-+ */
-+;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:m+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:m+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true
-+}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var i=e[u],a=r[u];if(i!==a){if(i>a||typeof i=="undefined")return 1;if(i<a||typeof a=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&i&&typeof i=="object")return false;for(u=f(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=f(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function i(n){return"\\"+U[n]
-+}function a(){return h.pop()||[]}function f(){return g.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function l(n){n.length=0,h.length<_&&h.push(n)}function c(n){var t=n.l;t&&c(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,g.length<_&&g.push(n)}function p(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function s(e){function h(n,t,e){if(!n||!V[typeof n])return n;
-+t=t&&typeof e=="undefined"?t:tt(t,e,3);for(var r=-1,u=V[typeof n]&&Fe(n),o=u?u.length:0;++r<o&&(e=u[r],false!==t(n[e],e,n)););return n}function g(n,t,e){var r;if(!n||!V[typeof n])return n;t=t&&typeof e=="undefined"?t:tt(t,e,3);for(r in n)if(false===t(n[r],r,n))break;return n}function _(n,t,e){var r,u=n,o=u;if(!u)return o;for(var i=arguments,a=0,f=typeof e=="number"?2:i.length;++a<f;)if((u=i[a])&&V[typeof u])for(var l=-1,c=V[typeof u]&&Fe(u),p=c?c.length:0;++l<p;)r=c[l],"undefined"==typeof o[r]&&(o[r]=u[r]);
-+return o}function U(n,t,e){var r,u=n,o=u;if(!u)return o;var i=arguments,a=0,f=typeof e=="number"?2:i.length;if(3<f&&"function"==typeof i[f-2])var l=tt(i[--f-1],i[f--],2);else 2<f&&"function"==typeof i[f-1]&&(l=i[--f]);for(;++a<f;)if((u=i[a])&&V[typeof u])for(var c=-1,p=V[typeof u]&&Fe(u),s=p?p.length:0;++c<s;)r=p[c],o[r]=l?l(o[r],u[r]):u[r];return o}function H(n){var t,e=[];if(!n||!V[typeof n])return e;for(t in n)me.call(n,t)&&e.push(t);return e}function J(n){return n&&typeof n=="object"&&!Te(n)&&me.call(n,"__wrapped__")?n:new Q(n)
-+}function Q(n,t){this.__chain__=!!t,this.__wrapped__=n}function X(n){function t(){if(r){var n=p(r);be.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return wt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return $e(t,n),t}function Z(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!wt(n))return n;var i=ce.call(n);if(!K[i])return n;var f=Ae[i];switch(i){case T:case F:return new f(+n);case W:case P:return new f(n);case z:return o=f(n.source,C.exec(n)),o.lastIndex=n.lastIndex,o
-+}if(i=Te(n),t){var c=!r;r||(r=a()),u||(u=a());for(var s=r.length;s--;)if(r[s]==n)return u[s];o=i?f(n.length):{}}else o=i?p(n):U({},n);return i&&(me.call(n,"index")&&(o.index=n.index),me.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(i?St:h)(n,function(n,i){o[i]=Z(n,t,e,r,u)}),c&&(l(r),l(u)),o):o}function nt(n){return wt(n)?ke(n):{}}function tt(n,t,e){if(typeof n!="function")return Ut;if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(De.funcNames&&(r=!n.name),r=r||!De.funcDecomp,!r)){var u=ge.call(n);
-+De.funcNames||(r=!O.test(u)),r||(r=E.test(u),$e(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=f?i:this;if(u){var h=p(u);be.apply(h,arguments)}return(o||c)&&(h||(h=p(arguments)),o&&be.apply(h,o),c&&h.length<a)?(r|=16,et([e,s?r:-4&r,h,null,i,a])):(h||(h=arguments),l&&(e=n[v]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),wt(h)?h:n):e.apply(n,h))
-+}var e=n[0],r=n[1],u=n[2],o=n[3],i=n[4],a=n[5],f=1&r,l=2&r,c=4&r,s=8&r,v=e;return $e(t,n),t}function rt(e,r){var u=-1,i=st(),a=e?e.length:0,f=a>=b&&i===n,l=[];if(f){var p=o(r);p?(i=t,r=p):f=false}for(;++u<a;)p=e[u],0>i(r,p)&&l.push(p);return f&&c(r),l}function ut(n,t,e,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r<u;){var i=n[r];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Te(i)||yt(i))){t||(i=ut(i,t,e));var a=-1,f=i.length,l=o.length;for(o.length+=f;++a<f;)o[l++]=i[a]}else e||o.push(i)}return o
-+}function ot(n,t,e,r,u,o){if(e){var i=e(n,t);if(typeof i!="undefined")return!!i}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&V[typeof n]||t&&V[typeof t]))return false;if(null==n||null==t)return n===t;var f=ce.call(n),c=ce.call(t);if(f==D&&(f=q),c==D&&(c=q),f!=c)return false;switch(f){case T:case F:return+n==+t;case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case z:case P:return n==oe(t)}if(c=f==$,!c){var p=me.call(n,"__wrapped__"),s=me.call(t,"__wrapped__");if(p||s)return ot(p?n.__wrapped__:n,s?t.__wrapped__:t,e,r,u,o);
-+if(f!=q)return false;if(f=n.constructor,p=t.constructor,f!=p&&!(dt(f)&&f instanceof f&&dt(p)&&p instanceof p)&&"constructor"in n&&"constructor"in t)return false}for(f=!u,u||(u=a()),o||(o=a()),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,i=true;if(u.push(n),o.push(t),c){if(p=n.length,v=t.length,(i=v==p)||r)for(;v--;)if(c=p,s=t[v],r)for(;c--&&!(i=ot(n[c],s,e,r,u,o)););else if(!(i=ot(n[v],s,e,r,u,o)))break}else g(t,function(t,a,f){return me.call(f,a)?(v++,i=me.call(n,a)&&ot(n[a],t,e,r,u,o)):void 0}),i&&!r&&g(n,function(n,t,e){return me.call(e,t)?i=-1<--v:void 0
-+});return u.pop(),o.pop(),f&&(l(u),l(o)),i}function it(n,t,e,r,u){(Te(t)?St:h)(t,function(t,o){var i,a,f=t,l=n[o];if(t&&((a=Te(t))||Pe(t))){for(f=r.length;f--;)if(i=r[f]==t){l=u[f];break}if(!i){var c;e&&(f=e(l,t),c=typeof f!="undefined")&&(l=f),c||(l=a?Te(l)?l:[]:Pe(l)?l:{}),r.push(t),u.push(l),c||it(l,t,e,r,u)}}else e&&(f=e(l,t),typeof f=="undefined"&&(f=t)),typeof f!="undefined"&&(l=f);n[o]=l})}function at(n,t){return n+he(Re()*(t-n+1))}function ft(e,r,u){var i=-1,f=st(),p=e?e.length:0,s=[],v=!r&&p>=b&&f===n,h=u||v?a():s;
-+for(v&&(h=o(h),f=t);++i<p;){var g=e[i],y=u?u(g,i,e):g;(r?!i||h[h.length-1]!==y:0>f(h,y))&&((u||v)&&h.push(y),s.push(g))}return v?(l(h.k),c(h)):u&&l(h),s}function lt(n){return function(t,e,r){var u={};e=J.createCallback(e,r,3),r=-1;var o=t?t.length:0;if(typeof o=="number")for(;++r<o;){var i=t[r];n(u,i,e(i,r,t),t)}else h(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function ct(n,t,e,r,u,o){var i=1&t,a=4&t,f=16&t,l=32&t;if(!(2&t||dt(n)))throw new ie;f&&!e.length&&(t&=-17,f=e=false),l&&!r.length&&(t&=-33,l=r=false);
-+var c=n&&n.__bindData__;return c&&true!==c?(c=p(c),c[2]&&(c[2]=p(c[2])),c[3]&&(c[3]=p(c[3])),!i||1&c[1]||(c[4]=u),!i&&1&c[1]&&(t|=8),!a||4&c[1]||(c[5]=o),f&&be.apply(c[2]||(c[2]=[]),e),l&&we.apply(c[3]||(c[3]=[]),r),c[1]|=t,ct.apply(null,c)):(1==t||17===t?X:et)([n,t,e,r,u,o])}function pt(n){return Be[n]}function st(){var t=(t=J.indexOf)===Wt?n:t;return t}function vt(n){return typeof n=="function"&&pe.test(n)}function ht(n){var t,e;return n&&ce.call(n)==q&&(t=n.constructor,!dt(t)||t instanceof t)?(g(n,function(n,t){e=t
-+}),typeof e=="undefined"||me.call(n,e)):false}function gt(n){return We[n]}function yt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==D||false}function mt(n,t,e){var r=Fe(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function bt(n){var t=[];return g(n,function(n,e){dt(n)&&t.push(e)}),t.sort()}function _t(n){for(var t=-1,e=Fe(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function dt(n){return typeof n=="function"}function wt(n){return!(!n||!V[typeof n])
-+}function jt(n){return typeof n=="number"||n&&typeof n=="object"&&ce.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&ce.call(n)==P||false}function xt(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;)u[t]=n[e[t]];return u}function Ct(n,t,e){var r=-1,u=st(),o=n?n.length:0,i=false;return e=(0>e?Ie(0,o+e):e)||0,Te(n)?i=-1<u(n,t,e):typeof o=="number"?i=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):h(n,function(n){return++r<e?void 0:!(i=n===t)}),i}function Ot(n,t,e){var r=true;t=J.createCallback(t,e,3),e=-1;
-+var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&(r=!!t(n[e],e,n)););else h(n,function(n,e,u){return r=!!t(n,e,u)});return r}function Nt(n,t,e){var r=[];t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}else h(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){t=J.createCallback(t,e,3),e=-1;var r=n?n.length:0;if(typeof r!="number"){var u;return h(n,function(n,e,r){return t(n,e,r)?(u=n,false):void 0}),u}for(;++e<r;){var o=n[e];
-+if(t(o,e,n))return o}}function St(n,t,e){var r=-1,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof u=="number")for(;++r<u&&false!==t(n[r],r,n););else h(n,t);return n}function Et(n,t,e){var r=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof r=="number")for(;r--&&false!==t(n[r],r,n););else{var u=Fe(n),r=u.length;h(n,function(n,e,o){return e=u?u[--r]:--r,t(o[e],e,o)})}return n}function Rt(n,t,e){var r=-1,u=n?n.length:0;if(t=J.createCallback(t,e,3),typeof u=="number")for(var o=Xt(u);++r<u;)o[r]=t(n[r],r,n);
-+else o=[],h(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function At(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a>o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Dt(n,t,e,r){if(!n)return e;var u=3>arguments.length;t=J.createCallback(t,r,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n);else h(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)
-+});return e}function $t(n,t,e,r){var u=3>arguments.length;return t=J.createCallback(t,r,4),Et(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Xt(typeof e=="number"?e:0);return St(n,function(n){var e=at(0,++t);r[t]=r[e],r[e]=n}),r}function Ft(n,t,e){var r;t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&!(r=t(n[e],e,n)););else h(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Bt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1;
-+for(t=J.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[0]:v;return p(n,0,Se(Ie(0,r),u))}function Wt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Ie(0,u+r):r||0}else if(r)return r=zt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=J.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Ie(0,t);return p(n,r)}function zt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?J.createCallback(e,r,1):Ut,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;
-+return u}function Pt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=J.createCallback(e,r,3)),ft(n,t,e)}function Kt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?At(Ve(n,"length")):0,r=Xt(0>e?0:e);++t<e;)r[t]=Ve(n,t);return r}function Lt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||Te(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?ct(n,17,p(arguments,2),null,t):ct(n,1,null,null,t)
-+}function Vt(n,t,e){function r(){c&&ve(c),i=c=p=v,(g||h!==t)&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null))}function u(){var e=t-(Ue()-f);0<e?c=_e(u,e):(i&&ve(i),e=p,i=c=p=v,e&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null)))}var o,i,a,f,l,c,p,s=0,h=false,g=true;if(!dt(n))throw new ie;if(t=Ie(0,t)||0,true===e)var y=true,g=false;else wt(e)&&(y=e.leading,h="maxWait"in e&&(Ie(t,e.maxWait)||0),g="trailing"in e?e.trailing:g);return function(){if(o=arguments,f=Ue(),l=this,p=g&&(c||!y),false===h)var e=y&&!c;else{i||y||(s=f);var v=h-(f-s),m=0>=v;
-+m?(i&&(i=ve(i)),s=f,a=n.apply(l,o)):i||(i=_e(r,v))}return m&&c?c=ve(c):c||t===h||(c=_e(u,t)),e&&(m=true,a=n.apply(l,o)),!m||c||i||(o=l=null),a}}function Ut(n){return n}function Gt(n,t,e){var r=true,u=t&&bt(t);t&&(e||u.length)||(null==e&&(e=t),o=Q,t=n,n=J,u=bt(t)),false===e?r=false:wt(e)&&"chain"in e&&(r=e.chain);var o=n,i=dt(o);St(u,function(e){var u=n[e]=t[e];i&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,i=[e];if(be.apply(i,arguments),i=u.apply(n,i),r||t){if(e===i&&wt(i))return this;
-+i=new o(i),i.__chain__=t}return i})})}function Ht(){}function Jt(n){return function(t){return t[n]}}function Qt(){return this.__wrapped__}e=e?Y.defaults(G.Object(),e,Y.pick(G,A)):G;var Xt=e.Array,Yt=e.Boolean,Zt=e.Date,ne=e.Function,te=e.Math,ee=e.Number,re=e.Object,ue=e.RegExp,oe=e.String,ie=e.TypeError,ae=[],fe=re.prototype,le=e._,ce=fe.toString,pe=ue("^"+oe(ce).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),se=te.ceil,ve=e.clearTimeout,he=te.floor,ge=ne.prototype.toString,ye=vt(ye=re.getPrototypeOf)&&ye,me=fe.hasOwnProperty,be=ae.push,_e=e.setTimeout,de=ae.splice,we=ae.unshift,je=function(){try{var n={},t=vt(t=re.defineProperty)&&t,e=t(n,n,n)&&t
-+}catch(r){}return e}(),ke=vt(ke=re.create)&&ke,xe=vt(xe=Xt.isArray)&&xe,Ce=e.isFinite,Oe=e.isNaN,Ne=vt(Ne=re.keys)&&Ne,Ie=te.max,Se=te.min,Ee=e.parseInt,Re=te.random,Ae={};Ae[$]=Xt,Ae[T]=Yt,Ae[F]=Zt,Ae[B]=ne,Ae[q]=re,Ae[W]=ee,Ae[z]=ue,Ae[P]=oe,Q.prototype=J.prototype;var De=J.support={};De.funcDecomp=!vt(e.a)&&E.test(s),De.funcNames=typeof ne.name=="string",J.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:J}},ke||(nt=function(){function n(){}return function(t){if(wt(t)){n.prototype=t;
-+var r=new n;n.prototype=null}return r||e.Object()}}());var $e=je?function(n,t){M.value=t,je(n,"__bindData__",M)}:Ht,Te=xe||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==$||false},Fe=Ne?function(n){return wt(n)?Ne(n):[]}:H,Be={"&":"&","<":"<",">":">",'"':""","'":"'"},We=_t(Be),qe=ue("("+Fe(We).join("|")+")","g"),ze=ue("["+Fe(Be).join("")+"]","g"),Pe=ye?function(n){if(!n||ce.call(n)!=q)return false;var t=n.valueOf,e=vt(t)&&(e=ye(t))&&ye(e);return e?n==e||ye(n)==e:ht(n)
-+}:ht,Ke=lt(function(n,t,e){me.call(n,e)?n[e]++:n[e]=1}),Le=lt(function(n,t,e){(me.call(n,e)?n[e]:n[e]=[]).push(t)}),Me=lt(function(n,t,e){n[e]=t}),Ve=Rt,Ue=vt(Ue=Zt.now)&&Ue||function(){return(new Zt).getTime()},Ge=8==Ee(d+"08")?Ee:function(n,t){return Ee(kt(n)?n.replace(I,""):n,t||0)};return J.after=function(n,t){if(!dt(t))throw new ie;return function(){return 1>--n?t.apply(this,arguments):void 0}},J.assign=U,J.at=function(n){for(var t=arguments,e=-1,r=ut(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Xt(t);++e<t;)u[e]=n[r[e]];
-+return u},J.bind=Mt,J.bindAll=function(n){for(var t=1<arguments.length?ut(arguments,true,false,1):bt(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=ct(n[u],1,null,null,n)}return n},J.bindKey=function(n,t){return 2<arguments.length?ct(t,19,p(arguments,2),null,n):ct(t,3,null,null,n)},J.chain=function(n){return n=new Q(n),n.__chain__=true,n},J.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},J.compose=function(){for(var n=arguments,t=n.length;t--;)if(!dt(n[t]))throw new ie;
-+return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},J.constant=function(n){return function(){return n}},J.countBy=Ke,J.create=function(n,t){var e=nt(n);return t?U(e,t):e},J.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e);if("object"!=r)return Jt(n);var u=Fe(n),o=u[0],i=n[o];return 1!=u.length||i!==i||wt(i)?function(t){for(var e=u.length,r=false;e--&&(r=ot(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],i===n&&(0!==i||1/i==1/n)
-+}},J.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,ct(n,4,null,null,null,t)},J.debounce=Vt,J.defaults=_,J.defer=function(n){if(!dt(n))throw new ie;var t=p(arguments,1);return _e(function(){n.apply(v,t)},1)},J.delay=function(n,t){if(!dt(n))throw new ie;var e=p(arguments,2);return _e(function(){n.apply(v,e)},t)},J.difference=function(n){return rt(n,ut(arguments,true,true,1))},J.filter=Nt,J.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Rt(n,e,r)),ut(n,t)
-+},J.forEach=St,J.forEachRight=Et,J.forIn=g,J.forInRight=function(n,t,e){var r=[];g(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},J.forOwn=h,J.forOwnRight=mt,J.functions=bt,J.groupBy=Le,J.indexBy=Me,J.initial=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return p(n,0,Se(Ie(0,u-r),u))},J.intersection=function(){for(var e=[],r=-1,u=arguments.length,i=a(),f=st(),p=f===n,s=a();++r<u;){var v=arguments[r];
-+(Te(v)||yt(v))&&(e.push(v),i.push(p&&v.length>=b&&o(r?e[r]:s)))}var p=e[0],h=-1,g=p?p.length:0,y=[];n:for(;++h<g;){var m=i[0],v=p[h];if(0>(m?t(m,v):f(s,v))){for(r=u,(m||s).push(v);--r;)if(m=i[r],0>(m?t(m,v):f(e[r],v)))continue n;y.push(v)}}for(;u--;)(m=i[u])&&c(m);return l(i),l(s),y},J.invert=_t,J.invoke=function(n,t){var e=p(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,i=Xt(typeof o=="number"?o:0);return St(n,function(n){i[++r]=(u?t:n[t]).apply(n,e)}),i},J.keys=Fe,J.map=Rt,J.mapValues=function(n,t,e){var r={};
-+return t=J.createCallback(t,e,3),h(n,function(n,e,u){r[e]=t(n,e,u)}),r},J.max=At,J.memoize=function(n,t){function e(){var r=e.cache,u=t?t.apply(this,arguments):m+arguments[0];return me.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!dt(n))throw new ie;return e.cache={},e},J.merge=function(n){var t=arguments,e=2;if(!wt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=p(arguments,1,e),u=-1,o=a(),i=a();++u<e;)it(n,t[u],r,o,i);
-+return l(o),l(i),n},J.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a<o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n)});return o},J.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];g(n,function(n,t){u.push(t)});for(var u=rt(u,ut(arguments,true,false,1)),o=-1,i=u.length;++o<i;){var a=u[o];r[a]=n[a]}}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)||(r[e]=n)
-+});return r},J.once=function(n){var t,e;if(!dt(n))throw new ie;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},J.pairs=function(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u},J.partial=function(n){return ct(n,16,p(arguments,1))},J.partialRight=function(n){return ct(n,32,null,p(arguments,1))},J.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ut(arguments,true,false,1),i=wt(n)?o.length:0;++u<i;){var a=o[u];a in n&&(r[a]=n[a])
-+}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},J.pluck=Ve,J.property=Jt,J.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,i=t[e];++o<u;)n[o]===i&&(de.call(n,o--,1),u--);return n},J.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Ie(0,se((t-n)/(e||1)));for(var u=Xt(t);++r<t;)u[r]=n,n+=e;return u},J.reject=function(n,t,e){return t=J.createCallback(t,e,3),Nt(n,function(n,e,r){return!t(n,e,r)
-+})},J.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=J.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),de.call(n,r--,1),u--);return o},J.rest=qt,J.shuffle=Tt,J.sortBy=function(n,t,e){var r=-1,o=Te(t),i=n?n.length:0,p=Xt(typeof i=="number"?i:0);for(o||(t=J.createCallback(t,e,3)),St(n,function(n,e,u){var i=p[++r]=f();o?i.m=Rt(t,function(t){return n[t]}):(i.m=a())[0]=t(n,e,u),i.n=r,i.o=n}),i=p.length,p.sort(u);i--;)n=p[i],p[i]=n.o,o||l(n.m),c(n);return p},J.tap=function(n,t){return t(n),n
-+},J.throttle=function(n,t,e){var r=true,u=true;if(!dt(n))throw new ie;return false===e?r=false:wt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),L.leading=r,L.maxWait=t,L.trailing=u,Vt(n,t,L)},J.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Xt(n);for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},J.toArray=function(n){return n&&typeof n.length=="number"?p(n):xt(n)},J.transform=function(n,t,e,r){var u=Te(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=J.createCallback(t,r,4),(u?St:h)(n,function(n,r,u){return t(e,n,r,u)
-+})),e},J.union=function(){return ft(ut(arguments,true,true))},J.uniq=Pt,J.values=xt,J.where=Nt,J.without=function(n){return rt(n,p(arguments,1))},J.wrap=function(n,t){return ct(t,16,[n])},J.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(Te(e)||yt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},J.zip=Kt,J.zipObject=Lt,J.collect=Rt,J.drop=qt,J.each=St,J.eachRight=Et,J.extend=U,J.methods=bt,J.object=Lt,J.select=Nt,J.tail=qt,J.unique=Pt,J.unzip=Kt,Gt(J),J.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Z(n,t,typeof e=="function"&&tt(e,r,1))
-+},J.cloneDeep=function(n,t,e){return Z(n,true,typeof t=="function"&&tt(t,e,1))},J.contains=Ct,J.escape=function(n){return null==n?"":oe(n).replace(ze,pt)},J.every=Ot,J.find=It,J.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=J.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},J.findKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),h(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.findLast=function(n,t,e){var r;return t=J.createCallback(t,e,3),Et(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0
-+}),r},J.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=J.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r;return-1},J.findLastKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),mt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.has=function(n,t){return n?me.call(n,t):false},J.identity=Ut,J.indexOf=Wt,J.isArguments=yt,J.isArray=Te,J.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&ce.call(n)==T||false},J.isDate=function(n){return n&&typeof n=="object"&&ce.call(n)==F||false
-+},J.isElement=function(n){return n&&1===n.nodeType||false},J.isEmpty=function(n){var t=true;if(!n)return t;var e=ce.call(n),r=n.length;return e==$||e==P||e==D||e==q&&typeof r=="number"&&dt(n.splice)?!r:(h(n,function(){return t=false}),t)},J.isEqual=function(n,t,e,r){return ot(n,t,typeof e=="function"&&tt(e,r,2))},J.isFinite=function(n){return Ce(n)&&!Oe(parseFloat(n))},J.isFunction=dt,J.isNaN=function(n){return jt(n)&&n!=+n},J.isNull=function(n){return null===n},J.isNumber=jt,J.isObject=wt,J.isPlainObject=Pe,J.isRegExp=function(n){return n&&typeof n=="object"&&ce.call(n)==z||false
-+},J.isString=kt,J.isUndefined=function(n){return typeof n=="undefined"},J.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Ie(0,r+e):Se(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},J.mixin=Gt,J.noConflict=function(){return e._=le,this},J.noop=Ht,J.now=Ue,J.parseInt=Ge,J.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Re(),Se(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):at(n,t)
-+},J.reduce=Dt,J.reduceRight=$t,J.result=function(n,t){if(n){var e=n[t];return dt(e)?n[t]():e}},J.runInContext=s,J.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Fe(n).length},J.some=Ft,J.sortedIndex=zt,J.template=function(n,t,e){var r=J.templateSettings;n=oe(n||""),e=_({},e,r);var u,o=_({},e.imports,r.imports),r=Fe(o),o=xt(o),a=0,f=e.interpolate||S,l="__p+='",f=ue((e.escape||S).source+"|"+f.source+"|"+(f===N?x:S).source+"|"+(e.evaluate||S).source+"|$","g");n.replace(f,function(t,e,r,o,f,c){return r||(r=o),l+=n.slice(a,c).replace(R,i),e&&(l+="'+__e("+e+")+'"),f&&(u=true,l+="';"+f+";\n__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),a=c+t.length,t
-+}),l+="';",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(w,""):l).replace(j,"$1").replace(k,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=ne(r,"return "+l).apply(v,o)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},J.unescape=function(n){return null==n?"":oe(n).replace(qe,gt)},J.uniqueId=function(n){var t=++y;return oe(null==n?"":n)+t
-+},J.all=Ot,J.any=Ft,J.detect=It,J.findWhere=It,J.foldl=Dt,J.foldr=$t,J.include=Ct,J.inject=Dt,Gt(function(){var n={};return h(J,function(t,e){J.prototype[e]||(n[e]=t)}),n}(),false),J.first=Bt,J.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:v;return p(n,Ie(0,u-r))},J.sample=function(n,t,e){return n&&typeof n.length!="number"&&(n=xt(n)),null==t||e?n?n[at(0,n.length-1)]:v:(n=Tt(n),n.length=Se(Ie(0,t),n.length),n)
-+},J.take=Bt,J.head=Bt,h(J,function(n,t){var e="sample"!==t;J.prototype[t]||(J.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new Q(o,u):o})}),J.VERSION="2.4.1",J.prototype.chain=function(){return this.__chain__=true,this},J.prototype.toString=function(){return oe(this.__wrapped__)},J.prototype.value=Qt,J.prototype.valueOf=Qt,St(["join","pop","shift"],function(n){var t=ae[n];J.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments);
-+return n?new Q(e,n):e}}),St(["push","reverse","sort","unshift"],function(n){var t=ae[n];J.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),St(["concat","slice","splice"],function(n){var t=ae[n];J.prototype[n]=function(){return new Q(t.apply(this.__wrapped__,arguments),this.__chain__)}}),J}var v,h=[],g=[],y=0,m=+new Date+"",b=75,_=40,d=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",w=/\b__p\+='';/g,j=/\b(__p\+=)''\+/g,k=/(__e\(.*?\)|\b__t\))\+'';/g,x=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,C=/\w*$/,O=/^\s*function[ \n\r\t]+\w/,N=/<%=([\s\S]+?)%>/g,I=RegExp("^["+d+"]*0+(?=.$)"),S=/($^)/,E=/\bthis\b/,R=/['\n\r\t\u2028\u2029\\]/g,A="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),D="[object Arguments]",$="[object Array]",T="[object Boolean]",F="[object Date]",B="[object Function]",W="[object Number]",q="[object Object]",z="[object RegExp]",P="[object String]",K={};
-+K[B]=false,K[D]=K[$]=K[T]=K[F]=K[W]=K[q]=K[z]=K[P]=true;var L={leading:false,maxWait:0,trailing:false},M={configurable:false,enumerable:false,value:null,writable:false},V={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},U={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},G=V[typeof window]&&window||this,H=V[typeof exports]&&exports&&!exports.nodeType&&exports,J=V[typeof module]&&module&&!module.nodeType&&module,Q=J&&J.exports===H&&H,X=V[typeof global]&&global;!X||X.global!==X&&X.window!==X||(G=X);
-+var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G._=Y, define(function(){return Y})):H&&J?Q?(J.exports=Y)._=Y:H._=Y:G._=Y}).call(this);
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.underscore.js
-@@ -0,0 +1,4979 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
-+ * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
-+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
-+ * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
-+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+ * Available under MIT license <http://lodash.com/license>
-+ */
-+;(function() {
-+
-+  /** Used as a safe reference for `undefined` in pre ES5 environments */
-+  var undefined;
-+
-+  /** Used to generate unique IDs */
-+  var idCounter = 0;
-+
-+  /** Used internally to indicate various things */
-+  var indicatorObject = {};
-+
-+  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
-+  var keyPrefix = +new Date + '';
-+
-+  /** Used to match "interpolate" template delimiters */
-+  var reInterpolate = /<%=([\s\S]+?)%>/g;
-+
-+  /** Used to ensure capturing order of template delimiters */
-+  var reNoMatch = /($^)/;
-+
-+  /** Used to match unescaped characters in compiled string literals */
-+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-+
-+  /** `Object#toString` result shortcuts */
-+  var argsClass = '[object Arguments]',
-+      arrayClass = '[object Array]',
-+      boolClass = '[object Boolean]',
-+      dateClass = '[object Date]',
-+      funcClass = '[object Function]',
-+      numberClass = '[object Number]',
-+      objectClass = '[object Object]',
-+      regexpClass = '[object RegExp]',
-+      stringClass = '[object String]';
-+
-+  /** Used to determine if values are of the language type Object */
-+  var objectTypes = {
-+    'boolean': false,
-+    'function': true,
-+    'object': true,
-+    'number': false,
-+    'string': false,
-+    'undefined': false
-+  };
-+
-+  /** Used to escape characters for inclusion in compiled string literals */
-+  var stringEscapes = {
-+    '\\': '\\',
-+    "'": "'",
-+    '\n': 'n',
-+    '\r': 'r',
-+    '\t': 't',
-+    '\u2028': 'u2028',
-+    '\u2029': 'u2029'
-+  };
-+
-+  /** Used as a reference to the global object */
-+  var root = (objectTypes[typeof window] && window) || this;
-+
-+  /** Detect free variable `exports` */
-+  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-+
-+  /** Detect free variable `module` */
-+  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-+
-+  /** Detect the popular CommonJS extension `module.exports` */
-+  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-+
-+  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
-+  var freeGlobal = objectTypes[typeof global] && global;
-+  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
-+    root = freeGlobal;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * The base implementation of `_.indexOf` without support for binary searches
-+   * or `fromIndex` constraints.
-+   *
-+   * @private
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {number} [fromIndex=0] The index to search from.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   */
-+  function baseIndexOf(array, value, fromIndex) {
-+    var index = (fromIndex || 0) - 1,
-+        length = array ? array.length : 0;
-+
-+    while (++index < length) {
-+      if (array[index] === value) {
-+        return index;
-+      }
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
-+   * them in ascending order.
-+   *
-+   * @private
-+   * @param {Object} a The object to compare to `b`.
-+   * @param {Object} b The object to compare to `a`.
-+   * @returns {number} Returns the sort order indicator of `1` or `-1`.
-+   */
-+  function compareAscending(a, b) {
-+    var ac = a.criteria,
-+        bc = b.criteria,
-+        index = -1,
-+        length = ac.length;
-+
-+    while (++index < length) {
-+      var value = ac[index],
-+          other = bc[index];
-+
-+      if (value !== other) {
-+        if (value > other || typeof value == 'undefined') {
-+          return 1;
-+        }
-+        if (value < other || typeof other == 'undefined') {
-+          return -1;
-+        }
-+      }
-+    }
-+    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-+    // that causes it, under certain circumstances, to return the same value for
-+    // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
-+    //
-+    // This also ensures a stable sort in V8 and other engines.
-+    // See http://code.google.com/p/v8/issues/detail?id=90
-+    return a.index - b.index;
-+  }
-+
-+  /**
-+   * Used by `template` to escape characters for inclusion in compiled
-+   * string literals.
-+   *
-+   * @private
-+   * @param {string} match The matched character to escape.
-+   * @returns {string} Returns the escaped character.
-+   */
-+  function escapeStringChar(match) {
-+    return '\\' + stringEscapes[match];
-+  }
-+
-+  /**
-+   * Slices the `collection` from the `start` index up to, but not including,
-+   * the `end` index.
-+   *
-+   * Note: This function is used instead of `Array#slice` to support node lists
-+   * in IE < 9 and to ensure dense arrays are returned.
-+   *
-+   * @private
-+   * @param {Array|Object|string} collection The collection to slice.
-+   * @param {number} start The start index.
-+   * @param {number} end The end index.
-+   * @returns {Array} Returns the new array.
-+   */
-+  function slice(array, start, end) {
-+    start || (start = 0);
-+    if (typeof end == 'undefined') {
-+      end = array ? array.length : 0;
-+    }
-+    var index = -1,
-+        length = end - start || 0,
-+        result = Array(length < 0 ? 0 : length);
-+
-+    while (++index < length) {
-+      result[index] = array[start + index];
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Used for `Array` method references.
-+   *
-+   * Normally `Array.prototype` would suffice, however, using an array literal
-+   * avoids issues in Narwhal.
-+   */
-+  var arrayRef = [];
-+
-+  /** Used for native method references */
-+  var objectProto = Object.prototype;
-+
-+  /** Used to restore the original `_` reference in `noConflict` */
-+  var oldDash = root._;
-+
-+  /** Used to resolve the internal [[Class]] of values */
-+  var toString = objectProto.toString;
-+
-+  /** Used to detect if a method is native */
-+  var reNative = RegExp('^' +
-+    String(toString)
-+      .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-+      .replace(/toString| for [^\]]+/g, '.*?') + '$'
-+  );
-+
-+  /** Native method shortcuts */
-+  var ceil = Math.ceil,
-+      floor = Math.floor,
-+      hasOwnProperty = objectProto.hasOwnProperty,
-+      push = arrayRef.push,
-+      propertyIsEnumerable = objectProto.propertyIsEnumerable;
-+
-+  /* Native method shortcuts for methods with the same name as other `lodash` methods */
-+  var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
-+      nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
-+      nativeIsFinite = root.isFinite,
-+      nativeIsNaN = root.isNaN,
-+      nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
-+      nativeMax = Math.max,
-+      nativeMin = Math.min,
-+      nativeRandom = Math.random;
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Creates a `lodash` object which wraps the given value to enable intuitive
-+   * method chaining.
-+   *
-+   * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
-+   * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
-+   * and `unshift`
-+   *
-+   * Chaining is supported in custom builds as long as the `value` method is
-+   * implicitly or explicitly included in the build.
-+   *
-+   * The chainable wrapper functions are:
-+   * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
-+   * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
-+   * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
-+   * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
-+   * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
-+   * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
-+   * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
-+   * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
-+   * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
-+   * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
-+   * and `zip`
-+   *
-+   * The non-chainable wrapper functions are:
-+   * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
-+   * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
-+   * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
-+   * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
-+   * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
-+   * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
-+   * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
-+   * `template`, `unescape`, `uniqueId`, and `value`
-+   *
-+   * The wrapper functions `first` and `last` return wrapped values when `n` is
-+   * provided, otherwise they return unwrapped values.
-+   *
-+   * Explicit chaining can be enabled by using the `_.chain` method.
-+   *
-+   * @name _
-+   * @constructor
-+   * @category Chaining
-+   * @param {*} value The value to wrap in a `lodash` instance.
-+   * @returns {Object} Returns a `lodash` instance.
-+   * @example
-+   *
-+   * var wrapped = _([1, 2, 3]);
-+   *
-+   * // returns an unwrapped value
-+   * wrapped.reduce(function(sum, num) {
-+   *   return sum + num;
-+   * });
-+   * // => 6
-+   *
-+   * // returns a wrapped value
-+   * var squares = wrapped.map(function(num) {
-+   *   return num * num;
-+   * });
-+   *
-+   * _.isArray(squares);
-+   * // => false
-+   *
-+   * _.isArray(squares.value());
-+   * // => true
-+   */
-+  function lodash(value) {
-+    return (value instanceof lodash)
-+      ? value
-+      : new lodashWrapper(value);
-+  }
-+
-+  /**
-+   * A fast path for creating `lodash` wrapper objects.
-+   *
-+   * @private
-+   * @param {*} value The value to wrap in a `lodash` instance.
-+   * @param {boolean} chainAll A flag to enable chaining for all methods
-+   * @returns {Object} Returns a `lodash` instance.
-+   */
-+  function lodashWrapper(value, chainAll) {
-+    this.__chain__ = !!chainAll;
-+    this.__wrapped__ = value;
-+  }
-+  // ensure `new lodashWrapper` is an instance of `lodash`
-+  lodashWrapper.prototype = lodash.prototype;
-+
-+  /**
-+   * An object used to flag environments features.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Object
-+   */
-+  var support = {};
-+
-+  (function() {
-+    var object = { '0': 1, 'length': 1 };
-+
-+    /**
-+     * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
-+     *
-+     * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
-+     * and `splice()` functions that fail to remove the last element, `value[0]`,
-+     * of array-like objects even though the `length` property is set to `0`.
-+     * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
-+     * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
-+     *
-+     * @memberOf _.support
-+     * @type boolean
-+     */
-+    support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-+  }(1));
-+
-+  /**
-+   * By default, the template delimiters used by Lo-Dash are similar to those in
-+   * embedded Ruby (ERB). Change the following template settings to use alternative
-+   * delimiters.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Object
-+   */
-+  lodash.templateSettings = {
-+
-+    /**
-+     * Used to detect `data` property values to be HTML-escaped.
-+     *
-+     * @memberOf _.templateSettings
-+     * @type RegExp
-+     */
-+    'escape': /<%-([\s\S]+?)%>/g,
-+
-+    /**
-+     * Used to detect code to be evaluated.
-+     *
-+     * @memberOf _.templateSettings
-+     * @type RegExp
-+     */
-+    'evaluate': /<%([\s\S]+?)%>/g,
-+
-+    /**
-+     * Used to detect `data` property values to inject.
-+     *
-+     * @memberOf _.templateSettings
-+     * @type RegExp
-+     */
-+    'interpolate': reInterpolate,
-+
-+    /**
-+     * Used to reference the data object in the template text.
-+     *
-+     * @memberOf _.templateSettings
-+     * @type string
-+     */
-+    'variable': ''
-+  };
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * The base implementation of `_.bind` that creates the bound function and
-+   * sets its meta data.
-+   *
-+   * @private
-+   * @param {Array} bindData The bind data array.
-+   * @returns {Function} Returns the new bound function.
-+   */
-+  function baseBind(bindData) {
-+    var func = bindData[0],
-+        partialArgs = bindData[2],
-+        thisArg = bindData[4];
-+
-+    function bound() {
-+      // `Function#bind` spec
-+      // http://es5.github.io/#x15.3.4.5
-+      if (partialArgs) {
-+        // avoid `arguments` object deoptimizations by using `slice` instead
-+        // of `Array.prototype.slice.call` and not assigning `arguments` to a
-+        // variable as a ternary expression
-+        var args = slice(partialArgs);
-+        push.apply(args, arguments);
-+      }
-+      // mimic the constructor's `return` behavior
-+      // http://es5.github.io/#x13.2.2
-+      if (this instanceof bound) {
-+        // ensure `new bound` is an instance of `func`
-+        var thisBinding = baseCreate(func.prototype),
-+            result = func.apply(thisBinding, args || arguments);
-+        return isObject(result) ? result : thisBinding;
-+      }
-+      return func.apply(thisArg, args || arguments);
-+    }
-+    return bound;
-+  }
-+
-+  /**
-+   * The base implementation of `_.create` without support for assigning
-+   * properties to the created object.
-+   *
-+   * @private
-+   * @param {Object} prototype The object to inherit from.
-+   * @returns {Object} Returns the new object.
-+   */
-+  function baseCreate(prototype, properties) {
-+    return isObject(prototype) ? nativeCreate(prototype) : {};
-+  }
-+  // fallback for browsers without `Object.create`
-+  if (!nativeCreate) {
-+    baseCreate = (function() {
-+      function Object() {}
-+      return function(prototype) {
-+        if (isObject(prototype)) {
-+          Object.prototype = prototype;
-+          var result = new Object;
-+          Object.prototype = null;
-+        }
-+        return result || root.Object();
-+      };
-+    }());
-+  }
-+
-+  /**
-+   * The base implementation of `_.createCallback` without support for creating
-+   * "_.pluck" or "_.where" style callbacks.
-+   *
-+   * @private
-+   * @param {*} [func=identity] The value to convert to a callback.
-+   * @param {*} [thisArg] The `this` binding of the created callback.
-+   * @param {number} [argCount] The number of arguments the callback accepts.
-+   * @returns {Function} Returns a callback function.
-+   */
-+  function baseCreateCallback(func, thisArg, argCount) {
-+    if (typeof func != 'function') {
-+      return identity;
-+    }
-+    // exit early for no `thisArg` or already bound by `Function#bind`
-+    if (typeof thisArg == 'undefined' || !('prototype' in func)) {
-+      return func;
-+    }
-+    switch (argCount) {
-+      case 1: return function(value) {
-+        return func.call(thisArg, value);
-+      };
-+      case 2: return function(a, b) {
-+        return func.call(thisArg, a, b);
-+      };
-+      case 3: return function(value, index, collection) {
-+        return func.call(thisArg, value, index, collection);
-+      };
-+      case 4: return function(accumulator, value, index, collection) {
-+        return func.call(thisArg, accumulator, value, index, collection);
-+      };
-+    }
-+    return bind(func, thisArg);
-+  }
-+
-+  /**
-+   * The base implementation of `createWrapper` that creates the wrapper and
-+   * sets its meta data.
-+   *
-+   * @private
-+   * @param {Array} bindData The bind data array.
-+   * @returns {Function} Returns the new function.
-+   */
-+  function baseCreateWrapper(bindData) {
-+    var func = bindData[0],
-+        bitmask = bindData[1],
-+        partialArgs = bindData[2],
-+        partialRightArgs = bindData[3],
-+        thisArg = bindData[4],
-+        arity = bindData[5];
-+
-+    var isBind = bitmask & 1,
-+        isBindKey = bitmask & 2,
-+        isCurry = bitmask & 4,
-+        isCurryBound = bitmask & 8,
-+        key = func;
-+
-+    function bound() {
-+      var thisBinding = isBind ? thisArg : this;
-+      if (partialArgs) {
-+        var args = slice(partialArgs);
-+        push.apply(args, arguments);
-+      }
-+      if (partialRightArgs || isCurry) {
-+        args || (args = slice(arguments));
-+        if (partialRightArgs) {
-+          push.apply(args, partialRightArgs);
-+        }
-+        if (isCurry && args.length < arity) {
-+          bitmask |= 16 & ~32;
-+          return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
-+        }
-+      }
-+      args || (args = arguments);
-+      if (isBindKey) {
-+        func = thisBinding[key];
-+      }
-+      if (this instanceof bound) {
-+        thisBinding = baseCreate(func.prototype);
-+        var result = func.apply(thisBinding, args);
-+        return isObject(result) ? result : thisBinding;
-+      }
-+      return func.apply(thisBinding, args);
-+    }
-+    return bound;
-+  }
-+
-+  /**
-+   * The base implementation of `_.difference` that accepts a single array
-+   * of values to exclude.
-+   *
-+   * @private
-+   * @param {Array} array The array to process.
-+   * @param {Array} [values] The array of values to exclude.
-+   * @returns {Array} Returns a new array of filtered values.
-+   */
-+  function baseDifference(array, values) {
-+    var index = -1,
-+        indexOf = getIndexOf(),
-+        length = array ? array.length : 0,
-+        result = [];
-+
-+    while (++index < length) {
-+      var value = array[index];
-+      if (indexOf(values, value) < 0) {
-+        result.push(value);
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * The base implementation of `_.flatten` without support for callback
-+   * shorthands or `thisArg` binding.
-+   *
-+   * @private
-+   * @param {Array} array The array to flatten.
-+   * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+   * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
-+   * @param {number} [fromIndex=0] The index to start from.
-+   * @returns {Array} Returns a new flattened array.
-+   */
-+  function baseFlatten(array, isShallow, isStrict, fromIndex) {
-+    var index = (fromIndex || 0) - 1,
-+        length = array ? array.length : 0,
-+        result = [];
-+
-+    while (++index < length) {
-+      var value = array[index];
-+
-+      if (value && typeof value == 'object' && typeof value.length == 'number'
-+          && (isArray(value) || isArguments(value))) {
-+        // recursively flatten arrays (susceptible to call stack limits)
-+        if (!isShallow) {
-+          value = baseFlatten(value, isShallow, isStrict);
-+        }
-+        var valIndex = -1,
-+            valLength = value.length,
-+            resIndex = result.length;
-+
-+        result.length += valLength;
-+        while (++valIndex < valLength) {
-+          result[resIndex++] = value[valIndex];
-+        }
-+      } else if (!isStrict) {
-+        result.push(value);
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * The base implementation of `_.isEqual`, without support for `thisArg` binding,
-+   * that allows partial "_.where" style comparisons.
-+   *
-+   * @private
-+   * @param {*} a The value to compare.
-+   * @param {*} b The other value to compare.
-+   * @param {Function} [callback] The function to customize comparing values.
-+   * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
-+   * @param {Array} [stackA=[]] Tracks traversed `a` objects.
-+   * @param {Array} [stackB=[]] Tracks traversed `b` objects.
-+   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+   */
-+  function baseIsEqual(a, b, stackA, stackB) {
-+    if (a === b) {
-+      return a !== 0 || (1 / a == 1 / b);
-+    }
-+    var type = typeof a,
-+        otherType = typeof b;
-+
-+    if (a === a &&
-+        !(a && objectTypes[type]) &&
-+        !(b && objectTypes[otherType])) {
-+      return false;
-+    }
-+    if (a == null || b == null) {
-+      return a === b;
-+    }
-+    var className = toString.call(a),
-+        otherClass = toString.call(b);
-+
-+    if (className != otherClass) {
-+      return false;
-+    }
-+    switch (className) {
-+      case boolClass:
-+      case dateClass:
-+        return +a == +b;
-+
-+      case numberClass:
-+        return a != +a
-+          ? b != +b
-+          : (a == 0 ? (1 / a == 1 / b) : a == +b);
-+
-+      case regexpClass:
-+      case stringClass:
-+        return a == String(b);
-+    }
-+    var isArr = className == arrayClass;
-+    if (!isArr) {
-+      var aWrapped = a instanceof lodash,
-+          bWrapped = b instanceof lodash;
-+
-+      if (aWrapped || bWrapped) {
-+        return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, stackA, stackB);
-+      }
-+      if (className != objectClass) {
-+        return false;
-+      }
-+      var ctorA = a.constructor,
-+          ctorB = b.constructor;
-+
-+      if (ctorA != ctorB &&
-+            !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
-+            ('constructor' in a && 'constructor' in b)
-+          ) {
-+        return false;
-+      }
-+    }
-+    stackA || (stackA = []);
-+    stackB || (stackB = []);
-+
-+    var length = stackA.length;
-+    while (length--) {
-+      if (stackA[length] == a) {
-+        return stackB[length] == b;
-+      }
-+    }
-+    var result = true,
-+        size = 0;
-+
-+    stackA.push(a);
-+    stackB.push(b);
-+
-+    if (isArr) {
-+      size = b.length;
-+      result = size == a.length;
-+
-+      if (result) {
-+        while (size--) {
-+          if (!(result = baseIsEqual(a[size], b[size], stackA, stackB))) {
-+            break;
-+          }
-+        }
-+      }
-+    }
-+    else {
-+      forIn(b, function(value, key, b) {
-+        if (hasOwnProperty.call(b, key)) {
-+          size++;
-+          return !(result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, stackA, stackB)) && indicatorObject;
-+        }
-+      });
-+
-+      if (result) {
-+        forIn(a, function(value, key, a) {
-+          if (hasOwnProperty.call(a, key)) {
-+            return !(result = --size > -1) && indicatorObject;
-+          }
-+        });
-+      }
-+    }
-+    stackA.pop();
-+    stackB.pop();
-+    return result;
-+  }
-+
-+  /**
-+   * The base implementation of `_.random` without argument juggling or support
-+   * for returning floating-point numbers.
-+   *
-+   * @private
-+   * @param {number} min The minimum possible value.
-+   * @param {number} max The maximum possible value.
-+   * @returns {number} Returns a random number.
-+   */
-+  function baseRandom(min, max) {
-+    return min + floor(nativeRandom() * (max - min + 1));
-+  }
-+
-+  /**
-+   * The base implementation of `_.uniq` without support for callback shorthands
-+   * or `thisArg` binding.
-+   *
-+   * @private
-+   * @param {Array} array The array to process.
-+   * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+   * @param {Function} [callback] The function called per iteration.
-+   * @returns {Array} Returns a duplicate-value-free array.
-+   */
-+  function baseUniq(array, isSorted, callback) {
-+    var index = -1,
-+        indexOf = getIndexOf(),
-+        length = array ? array.length : 0,
-+        result = [],
-+        seen = callback ? [] : result;
-+
-+    while (++index < length) {
-+      var value = array[index],
-+          computed = callback ? callback(value, index, array) : value;
-+
-+      if (isSorted
-+            ? !index || seen[seen.length - 1] !== computed
-+            : indexOf(seen, computed) < 0
-+          ) {
-+        if (callback) {
-+          seen.push(computed);
-+        }
-+        result.push(value);
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates a function that aggregates a collection, creating an object composed
-+   * of keys generated from the results of running each element of the collection
-+   * through a callback. The given `setter` function sets the keys and values
-+   * of the composed object.
-+   *
-+   * @private
-+   * @param {Function} setter The setter function.
-+   * @returns {Function} Returns the new aggregator function.
-+   */
-+  function createAggregator(setter) {
-+    return function(collection, callback, thisArg) {
-+      var result = {};
-+      callback = createCallback(callback, thisArg, 3);
-+
-+      var index = -1,
-+          length = collection ? collection.length : 0;
-+
-+      if (typeof length == 'number') {
-+        while (++index < length) {
-+          var value = collection[index];
-+          setter(result, value, callback(value, index, collection), collection);
-+        }
-+      } else {
-+        forOwn(collection, function(value, key, collection) {
-+          setter(result, value, callback(value, key, collection), collection);
-+        });
-+      }
-+      return result;
-+    };
-+  }
-+
-+  /**
-+   * Creates a function that, when called, either curries or invokes `func`
-+   * with an optional `this` binding and partially applied arguments.
-+   *
-+   * @private
-+   * @param {Function|string} func The function or method name to reference.
-+   * @param {number} bitmask The bitmask of method flags to compose.
-+   *  The bitmask may be composed of the following flags:
-+   *  1 - `_.bind`
-+   *  2 - `_.bindKey`
-+   *  4 - `_.curry`
-+   *  8 - `_.curry` (bound)
-+   *  16 - `_.partial`
-+   *  32 - `_.partialRight`
-+   * @param {Array} [partialArgs] An array of arguments to prepend to those
-+   *  provided to the new function.
-+   * @param {Array} [partialRightArgs] An array of arguments to append to those
-+   *  provided to the new function.
-+   * @param {*} [thisArg] The `this` binding of `func`.
-+   * @param {number} [arity] The arity of `func`.
-+   * @returns {Function} Returns the new function.
-+   */
-+  function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
-+    var isBind = bitmask & 1,
-+        isBindKey = bitmask & 2,
-+        isCurry = bitmask & 4,
-+        isCurryBound = bitmask & 8,
-+        isPartial = bitmask & 16,
-+        isPartialRight = bitmask & 32;
-+
-+    if (!isBindKey && !isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    if (isPartial && !partialArgs.length) {
-+      bitmask &= ~16;
-+      isPartial = partialArgs = false;
-+    }
-+    if (isPartialRight && !partialRightArgs.length) {
-+      bitmask &= ~32;
-+      isPartialRight = partialRightArgs = false;
-+    }
-+    // fast path for `_.bind`
-+    var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
-+    return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
-+  }
-+
-+  /**
-+   * Used by `escape` to convert characters to HTML entities.
-+   *
-+   * @private
-+   * @param {string} match The matched character to escape.
-+   * @returns {string} Returns the escaped character.
-+   */
-+  function escapeHtmlChar(match) {
-+    return htmlEscapes[match];
-+  }
-+
-+  /**
-+   * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
-+   * customized, this method returns the custom method, otherwise it returns
-+   * the `baseIndexOf` function.
-+   *
-+   * @private
-+   * @returns {Function} Returns the "indexOf" function.
-+   */
-+  function getIndexOf() {
-+    var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
-+    return result;
-+  }
-+
-+  /**
-+   * Checks if `value` is a native function.
-+   *
-+   * @private
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
-+   */
-+  function isNative(value) {
-+    return typeof value == 'function' && reNative.test(value);
-+  }
-+
-+  /**
-+   * Used by `unescape` to convert HTML entities to characters.
-+   *
-+   * @private
-+   * @param {string} match The matched character to unescape.
-+   * @returns {string} Returns the unescaped character.
-+   */
-+  function unescapeHtmlChar(match) {
-+    return htmlUnescapes[match];
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Checks if `value` is an `arguments` object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
-+   * @example
-+   *
-+   * (function() { return _.isArguments(arguments); })(1, 2, 3);
-+   * // => true
-+   *
-+   * _.isArguments([1, 2, 3]);
-+   * // => false
-+   */
-+  function isArguments(value) {
-+    return value && typeof value == 'object' && typeof value.length == 'number' &&
-+      toString.call(value) == argsClass || false;
-+  }
-+  // fallback for browsers that can't detect `arguments` objects by [[Class]]
-+  if (!isArguments(arguments)) {
-+    isArguments = function(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
-+    };
-+  }
-+
-+  /**
-+   * Checks if `value` is an array.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
-+   * @example
-+   *
-+   * (function() { return _.isArray(arguments); })();
-+   * // => false
-+   *
-+   * _.isArray([1, 2, 3]);
-+   * // => true
-+   */
-+  var isArray = nativeIsArray || function(value) {
-+    return value && typeof value == 'object' && typeof value.length == 'number' &&
-+      toString.call(value) == arrayClass || false;
-+  };
-+
-+  /**
-+   * A fallback implementation of `Object.keys` which produces an array of the
-+   * given object's own enumerable property names.
-+   *
-+   * @private
-+   * @type Function
-+   * @param {Object} object The object to inspect.
-+   * @returns {Array} Returns an array of property names.
-+   */
-+  var shimKeys = function(object) {
-+    var index, iterable = object, result = [];
-+    if (!iterable) return result;
-+    if (!(objectTypes[typeof object])) return result;
-+      for (index in iterable) {
-+        if (hasOwnProperty.call(iterable, index)) {
-+          result.push(index);
-+        }
-+      }
-+    return result
-+  };
-+
-+  /**
-+   * Creates an array composed of the own enumerable property names of an object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The object to inspect.
-+   * @returns {Array} Returns an array of property names.
-+   * @example
-+   *
-+   * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
-+   * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
-+   */
-+  var keys = !nativeKeys ? shimKeys : function(object) {
-+    if (!isObject(object)) {
-+      return [];
-+    }
-+    return nativeKeys(object);
-+  };
-+
-+  /**
-+   * Used to convert characters to HTML entities:
-+   *
-+   * Though the `>` character is escaped for symmetry, characters like `>` and `/`
-+   * don't require escaping in HTML and have no special meaning unless they're part
-+   * of a tag or an unquoted attribute value.
-+   * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
-+   */
-+  var htmlEscapes = {
-+    '&': '&',
-+    '<': '<',
-+    '>': '>',
-+    '"': '"',
-+    "'": '&#x27;'
-+  };
-+
-+  /** Used to convert HTML entities to characters */
-+  var htmlUnescapes = invert(htmlEscapes);
-+
-+  /** Used to match HTML entities and HTML characters */
-+  var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
-+      reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Assigns own enumerable properties of source object(s) to the destination
-+   * object. Subsequent sources will overwrite property assignments of previous
-+   * sources. If a callback is provided it will be executed to produce the
-+   * assigned values. The callback is bound to `thisArg` and invoked with two
-+   * arguments; (objectValue, sourceValue).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @alias extend
-+   * @category Objects
-+   * @param {Object} object The destination object.
-+   * @param {...Object} [source] The source objects.
-+   * @param {Function} [callback] The function to customize assigning values.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns the destination object.
-+   * @example
-+   *
-+   * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
-+   * // => { 'name': 'fred', 'employer': 'slate' }
-+   *
-+   * var defaults = _.partialRight(_.assign, function(a, b) {
-+   *   return typeof a == 'undefined' ? b : a;
-+   * });
-+   *
-+   * var object = { 'name': 'barney' };
-+   * defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+   * // => { 'name': 'barney', 'employer': 'slate' }
-+   */
-+  function assign(object) {
-+    if (!object) {
-+      return object;
-+    }
-+    for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
-+      var iterable = arguments[argsIndex];
-+      if (iterable) {
-+        for (var key in iterable) {
-+          object[key] = iterable[key];
-+        }
-+      }
-+    }
-+    return object;
-+  }
-+
-+  /**
-+   * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
-+   * be cloned, otherwise they will be assigned by reference. If a callback
-+   * is provided it will be executed to produce the cloned values. If the
-+   * callback returns `undefined` cloning will be handled by the method instead.
-+   * The callback is bound to `thisArg` and invoked with one argument; (value).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to clone.
-+   * @param {boolean} [isDeep=false] Specify a deep clone.
-+   * @param {Function} [callback] The function to customize cloning values.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the cloned value.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * var shallow = _.clone(characters);
-+   * shallow[0] === characters[0];
-+   * // => true
-+   *
-+   * var deep = _.clone(characters, true);
-+   * deep[0] === characters[0];
-+   * // => false
-+   *
-+   * _.mixin({
-+   *   'clone': _.partialRight(_.clone, function(value) {
-+   *     return _.isElement(value) ? value.cloneNode(false) : undefined;
-+   *   })
-+   * });
-+   *
-+   * var clone = _.clone(document.body);
-+   * clone.childNodes.length;
-+   * // => 0
-+   */
-+  function clone(value) {
-+    return isObject(value)
-+      ? (isArray(value) ? slice(value) : assign({}, value))
-+      : value;
-+  }
-+
-+  /**
-+   * Assigns own enumerable properties of source object(s) to the destination
-+   * object for all destination properties that resolve to `undefined`. Once a
-+   * property is set, additional defaults of the same property will be ignored.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Objects
-+   * @param {Object} object The destination object.
-+   * @param {...Object} [source] The source objects.
-+   * @param- {Object} [guard] Allows working with `_.reduce` without using its
-+   *  `key` and `object` arguments as sources.
-+   * @returns {Object} Returns the destination object.
-+   * @example
-+   *
-+   * var object = { 'name': 'barney' };
-+   * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+   * // => { 'name': 'barney', 'employer': 'slate' }
-+   */
-+  function defaults(object) {
-+    if (!object) {
-+      return object;
-+    }
-+    for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
-+      var iterable = arguments[argsIndex];
-+      if (iterable) {
-+        for (var key in iterable) {
-+          if (typeof object[key] == 'undefined') {
-+            object[key] = iterable[key];
-+          }
-+        }
-+      }
-+    }
-+    return object;
-+  }
-+
-+  /**
-+   * Iterates over own and inherited enumerable properties of an object,
-+   * executing the callback for each property. The callback is bound to `thisArg`
-+   * and invoked with three arguments; (value, key, object). Callbacks may exit
-+   * iteration early by explicitly returning `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Objects
-+   * @param {Object} object The object to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns `object`.
-+   * @example
-+   *
-+   * function Shape() {
-+   *   this.x = 0;
-+   *   this.y = 0;
-+   * }
-+   *
-+   * Shape.prototype.move = function(x, y) {
-+   *   this.x += x;
-+   *   this.y += y;
-+   * };
-+   *
-+   * _.forIn(new Shape, function(value, key) {
-+   *   console.log(key);
-+   * });
-+   * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
-+   */
-+  var forIn = function(collection, callback) {
-+    var index, iterable = collection, result = iterable;
-+    if (!iterable) return result;
-+    if (!objectTypes[typeof iterable]) return result;
-+      for (index in iterable) {
-+        if (callback(iterable[index], index, collection) === indicatorObject) return result;
-+      }
-+    return result
-+  };
-+
-+  /**
-+   * Iterates over own enumerable properties of an object, executing the callback
-+   * for each property. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, key, object). Callbacks may exit iteration early by
-+   * explicitly returning `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Objects
-+   * @param {Object} object The object to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns `object`.
-+   * @example
-+   *
-+   * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+   *   console.log(key);
-+   * });
-+   * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
-+   */
-+  var forOwn = function(collection, callback) {
-+    var index, iterable = collection, result = iterable;
-+    if (!iterable) return result;
-+    if (!objectTypes[typeof iterable]) return result;
-+      for (index in iterable) {
-+        if (hasOwnProperty.call(iterable, index)) {
-+          if (callback(iterable[index], index, collection) === indicatorObject) return result;
-+        }
-+      }
-+    return result
-+  };
-+
-+  /**
-+   * Creates a sorted array of property names of all enumerable properties,
-+   * own and inherited, of `object` that have function values.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias methods
-+   * @category Objects
-+   * @param {Object} object The object to inspect.
-+   * @returns {Array} Returns an array of property names that have function values.
-+   * @example
-+   *
-+   * _.functions(_);
-+   * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
-+   */
-+  function functions(object) {
-+    var result = [];
-+    forIn(object, function(value, key) {
-+      if (isFunction(value)) {
-+        result.push(key);
-+      }
-+    });
-+    return result.sort();
-+  }
-+
-+  /**
-+   * Checks if the specified property name exists as a direct property of `object`,
-+   * instead of an inherited property.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The object to inspect.
-+   * @param {string} key The name of the property to check.
-+   * @returns {boolean} Returns `true` if key is a direct property, else `false`.
-+   * @example
-+   *
-+   * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
-+   * // => true
-+   */
-+  function has(object, key) {
-+    return object ? hasOwnProperty.call(object, key) : false;
-+  }
-+
-+  /**
-+   * Creates an object composed of the inverted keys and values of the given object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The object to invert.
-+   * @returns {Object} Returns the created inverted object.
-+   * @example
-+   *
-+   * _.invert({ 'first': 'fred', 'second': 'barney' });
-+   * // => { 'fred': 'first', 'barney': 'second' }
-+   */
-+  function invert(object) {
-+    var index = -1,
-+        props = keys(object),
-+        length = props.length,
-+        result = {};
-+
-+    while (++index < length) {
-+      var key = props[index];
-+      result[object[key]] = key;
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Checks if `value` is a boolean value.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
-+   * @example
-+   *
-+   * _.isBoolean(null);
-+   * // => false
-+   */
-+  function isBoolean(value) {
-+    return value === true || value === false ||
-+      value && typeof value == 'object' && toString.call(value) == boolClass || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is a date.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
-+   * @example
-+   *
-+   * _.isDate(new Date);
-+   * // => true
-+   */
-+  function isDate(value) {
-+    return value && typeof value == 'object' && toString.call(value) == dateClass || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is a DOM element.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
-+   * @example
-+   *
-+   * _.isElement(document.body);
-+   * // => true
-+   */
-+  function isElement(value) {
-+    return value && value.nodeType === 1 || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
-+   * length of `0` and objects with no own enumerable properties are considered
-+   * "empty".
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Array|Object|string} value The value to inspect.
-+   * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
-+   * @example
-+   *
-+   * _.isEmpty([1, 2, 3]);
-+   * // => false
-+   *
-+   * _.isEmpty({});
-+   * // => true
-+   *
-+   * _.isEmpty('');
-+   * // => true
-+   */
-+  function isEmpty(value) {
-+    if (!value) {
-+      return true;
-+    }
-+    if (isArray(value) || isString(value)) {
-+      return !value.length;
-+    }
-+    for (var key in value) {
-+      if (hasOwnProperty.call(value, key)) {
-+        return false;
-+      }
-+    }
-+    return true;
-+  }
-+
-+  /**
-+   * Performs a deep comparison between two values to determine if they are
-+   * equivalent to each other. If a callback is provided it will be executed
-+   * to compare values. If the callback returns `undefined` comparisons will
-+   * be handled by the method instead. The callback is bound to `thisArg` and
-+   * invoked with two arguments; (a, b).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} a The value to compare.
-+   * @param {*} b The other value to compare.
-+   * @param {Function} [callback] The function to customize comparing values.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+   * @example
-+   *
-+   * var object = { 'name': 'fred' };
-+   * var copy = { 'name': 'fred' };
-+   *
-+   * object == copy;
-+   * // => false
-+   *
-+   * _.isEqual(object, copy);
-+   * // => true
-+   *
-+   * var words = ['hello', 'goodbye'];
-+   * var otherWords = ['hi', 'goodbye'];
-+   *
-+   * _.isEqual(words, otherWords, function(a, b) {
-+   *   var reGreet = /^(?:hello|hi)$/i,
-+   *       aGreet = _.isString(a) && reGreet.test(a),
-+   *       bGreet = _.isString(b) && reGreet.test(b);
-+   *
-+   *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
-+   * });
-+   * // => true
-+   */
-+  function isEqual(a, b) {
-+    return baseIsEqual(a, b);
-+  }
-+
-+  /**
-+   * Checks if `value` is, or can be coerced to, a finite number.
-+   *
-+   * Note: This is not the same as native `isFinite` which will return true for
-+   * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
-+   * @example
-+   *
-+   * _.isFinite(-101);
-+   * // => true
-+   *
-+   * _.isFinite('10');
-+   * // => true
-+   *
-+   * _.isFinite(true);
-+   * // => false
-+   *
-+   * _.isFinite('');
-+   * // => false
-+   *
-+   * _.isFinite(Infinity);
-+   * // => false
-+   */
-+  function isFinite(value) {
-+    return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
-+  }
-+
-+  /**
-+   * Checks if `value` is a function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
-+   * @example
-+   *
-+   * _.isFunction(_);
-+   * // => true
-+   */
-+  function isFunction(value) {
-+    return typeof value == 'function';
-+  }
-+  // fallback for older versions of Chrome and Safari
-+  if (isFunction(/x/)) {
-+    isFunction = function(value) {
-+      return typeof value == 'function' && toString.call(value) == funcClass;
-+    };
-+  }
-+
-+  /**
-+   * Checks if `value` is the language type of Object.
-+   * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
-+   * @example
-+   *
-+   * _.isObject({});
-+   * // => true
-+   *
-+   * _.isObject([1, 2, 3]);
-+   * // => true
-+   *
-+   * _.isObject(1);
-+   * // => false
-+   */
-+  function isObject(value) {
-+    // check if the value is the ECMAScript language type of Object
-+    // http://es5.github.io/#x8
-+    // and avoid a V8 bug
-+    // http://code.google.com/p/v8/issues/detail?id=2291
-+    return !!(value && objectTypes[typeof value]);
-+  }
-+
-+  /**
-+   * Checks if `value` is `NaN`.
-+   *
-+   * Note: This is not the same as native `isNaN` which will return `true` for
-+   * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
-+   * @example
-+   *
-+   * _.isNaN(NaN);
-+   * // => true
-+   *
-+   * _.isNaN(new Number(NaN));
-+   * // => true
-+   *
-+   * isNaN(undefined);
-+   * // => true
-+   *
-+   * _.isNaN(undefined);
-+   * // => false
-+   */
-+  function isNaN(value) {
-+    // `NaN` as a primitive is the only value that is not equal to itself
-+    // (perform the [[Class]] check first to avoid errors with some host objects in IE)
-+    return isNumber(value) && value != +value;
-+  }
-+
-+  /**
-+   * Checks if `value` is `null`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
-+   * @example
-+   *
-+   * _.isNull(null);
-+   * // => true
-+   *
-+   * _.isNull(undefined);
-+   * // => false
-+   */
-+  function isNull(value) {
-+    return value === null;
-+  }
-+
-+  /**
-+   * Checks if `value` is a number.
-+   *
-+   * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
-+   * @example
-+   *
-+   * _.isNumber(8.4 * 5);
-+   * // => true
-+   */
-+  function isNumber(value) {
-+    return typeof value == 'number' ||
-+      value && typeof value == 'object' && toString.call(value) == numberClass || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is a regular expression.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
-+   * @example
-+   *
-+   * _.isRegExp(/fred/);
-+   * // => true
-+   */
-+  function isRegExp(value) {
-+    return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is a string.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
-+   * @example
-+   *
-+   * _.isString('fred');
-+   * // => true
-+   */
-+  function isString(value) {
-+    return typeof value == 'string' ||
-+      value && typeof value == 'object' && toString.call(value) == stringClass || false;
-+  }
-+
-+  /**
-+   * Checks if `value` is `undefined`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
-+   * @example
-+   *
-+   * _.isUndefined(void 0);
-+   * // => true
-+   */
-+  function isUndefined(value) {
-+    return typeof value == 'undefined';
-+  }
-+
-+  /**
-+   * Creates a shallow clone of `object` excluding the specified properties.
-+   * Property names may be specified as individual arguments or as arrays of
-+   * property names. If a callback is provided it will be executed for each
-+   * property of `object` omitting the properties the callback returns truey
-+   * for. The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, key, object).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The source object.
-+   * @param {Function|...string|string[]} [callback] The properties to omit or the
-+   *  function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns an object without the omitted properties.
-+   * @example
-+   *
-+   * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
-+   * // => { 'name': 'fred' }
-+   *
-+   * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
-+   *   return typeof value == 'number';
-+   * });
-+   * // => { 'name': 'fred' }
-+   */
-+  function omit(object) {
-+    var props = [];
-+    forIn(object, function(value, key) {
-+      props.push(key);
-+    });
-+    props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-+
-+    var index = -1,
-+        length = props.length,
-+        result = {};
-+
-+    while (++index < length) {
-+      var key = props[index];
-+      result[key] = object[key];
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates a two dimensional array of an object's key-value pairs,
-+   * i.e. `[[key1, value1], [key2, value2]]`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The object to inspect.
-+   * @returns {Array} Returns new array of key-value pairs.
-+   * @example
-+   *
-+   * _.pairs({ 'barney': 36, 'fred': 40 });
-+   * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
-+   */
-+  function pairs(object) {
-+    var index = -1,
-+        props = keys(object),
-+        length = props.length,
-+        result = Array(length);
-+
-+    while (++index < length) {
-+      var key = props[index];
-+      result[index] = [key, object[key]];
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates a shallow clone of `object` composed of the specified properties.
-+   * Property names may be specified as individual arguments or as arrays of
-+   * property names. If a callback is provided it will be executed for each
-+   * property of `object` picking the properties the callback returns truey
-+   * for. The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, key, object).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The source object.
-+   * @param {Function|...string|string[]} [callback] The function called per
-+   *  iteration or property names to pick, specified as individual property
-+   *  names or arrays of property names.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns an object composed of the picked properties.
-+   * @example
-+   *
-+   * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
-+   * // => { 'name': 'fred' }
-+   *
-+   * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
-+   *   return key.charAt(0) != '_';
-+   * });
-+   * // => { 'name': 'fred' }
-+   */
-+  function pick(object) {
-+    var index = -1,
-+        props = baseFlatten(arguments, true, false, 1),
-+        length = props.length,
-+        result = {};
-+
-+    while (++index < length) {
-+      var key = props[index];
-+      if (key in object) {
-+        result[key] = object[key];
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an array composed of the own enumerable property values of `object`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Objects
-+   * @param {Object} object The object to inspect.
-+   * @returns {Array} Returns an array of property values.
-+   * @example
-+   *
-+   * _.values({ 'one': 1, 'two': 2, 'three': 3 });
-+   * // => [1, 2, 3] (property order is not guaranteed across environments)
-+   */
-+  function values(object) {
-+    var index = -1,
-+        props = keys(object),
-+        length = props.length,
-+        result = Array(length);
-+
-+    while (++index < length) {
-+      result[index] = object[props[index]];
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Checks if a given value is present in a collection using strict equality
-+   * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
-+   * offset from the end of the collection.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias include
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {*} target The value to check for.
-+   * @param {number} [fromIndex=0] The index to search from.
-+   * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
-+   * @example
-+   *
-+   * _.contains([1, 2, 3], 1);
-+   * // => true
-+   *
-+   * _.contains([1, 2, 3], 1, 2);
-+   * // => false
-+   *
-+   * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
-+   * // => true
-+   *
-+   * _.contains('pebbles', 'eb');
-+   * // => true
-+   */
-+  function contains(collection, target) {
-+    var indexOf = getIndexOf(),
-+        length = collection ? collection.length : 0,
-+        result = false;
-+    if (length && typeof length == 'number') {
-+      result = indexOf(collection, target) > -1;
-+    } else {
-+      forOwn(collection, function(value) {
-+        return (result = value === target) && indicatorObject;
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an object composed of keys generated from the results of running
-+   * each element of `collection` through the callback. The corresponding value
-+   * of each key is the number of times the key was returned by the callback.
-+   * The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns the composed aggregate object.
-+   * @example
-+   *
-+   * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
-+   * // => { '4': 1, '6': 2 }
-+   *
-+   * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+   * // => { '4': 1, '6': 2 }
-+   *
-+   * _.countBy(['one', 'two', 'three'], 'length');
-+   * // => { '3': 2, '5': 1 }
-+   */
-+  var countBy = createAggregator(function(result, value, key) {
-+    (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
-+  });
-+
-+  /**
-+   * Checks if the given callback returns truey value for **all** elements of
-+   * a collection. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias all
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {boolean} Returns `true` if all elements passed the callback check,
-+   *  else `false`.
-+   * @example
-+   *
-+   * _.every([true, 1, null, 'yes']);
-+   * // => false
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.every(characters, 'age');
-+   * // => true
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.every(characters, { 'age': 36 });
-+   * // => false
-+   */
-+  function every(collection, callback, thisArg) {
-+    var result = true;
-+    callback = createCallback(callback, thisArg, 3);
-+
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (typeof length == 'number') {
-+      while (++index < length) {
-+        if (!(result = !!callback(collection[index], index, collection))) {
-+          break;
-+        }
-+      }
-+    } else {
-+      forOwn(collection, function(value, index, collection) {
-+        return !(result = !!callback(value, index, collection)) && indicatorObject;
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Iterates over elements of a collection, returning an array of all elements
-+   * the callback returns truey for. The callback is bound to `thisArg` and
-+   * invoked with three arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias select
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a new array of elements that passed the callback check.
-+   * @example
-+   *
-+   * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+   * // => [2, 4, 6]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+   *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.filter(characters, 'blocked');
-+   * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.filter(characters, { 'age': 36 });
-+   * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+   */
-+  function filter(collection, callback, thisArg) {
-+    var result = [];
-+    callback = createCallback(callback, thisArg, 3);
-+
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (typeof length == 'number') {
-+      while (++index < length) {
-+        var value = collection[index];
-+        if (callback(value, index, collection)) {
-+          result.push(value);
-+        }
-+      }
-+    } else {
-+      forOwn(collection, function(value, index, collection) {
-+        if (callback(value, index, collection)) {
-+          result.push(value);
-+        }
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Iterates over elements of a collection, returning the first element that
-+   * the callback returns truey for. The callback is bound to `thisArg` and
-+   * invoked with three arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias detect, findWhere
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the found element, else `undefined`.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+   *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+   *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+   * ];
-+   *
-+   * _.find(characters, function(chr) {
-+   *   return chr.age < 40;
-+   * });
-+   * // => { 'name': 'barney', 'age': 36, 'blocked': false }
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.find(characters, { 'age': 1 });
-+   * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.find(characters, 'blocked');
-+   * // => { 'name': 'fred', 'age': 40, 'blocked': true }
-+   */
-+  function find(collection, callback, thisArg) {
-+    callback = createCallback(callback, thisArg, 3);
-+
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (typeof length == 'number') {
-+      while (++index < length) {
-+        var value = collection[index];
-+        if (callback(value, index, collection)) {
-+          return value;
-+        }
-+      }
-+    } else {
-+      var result;
-+      forOwn(collection, function(value, index, collection) {
-+        if (callback(value, index, collection)) {
-+          result = value;
-+          return indicatorObject;
-+        }
-+      });
-+      return result;
-+    }
-+  }
-+
-+  /**
-+   * Examines each element in a `collection`, returning the first that
-+   * has the given properties. When checking `properties`, this method
-+   * performs a deep comparison between values to determine if they are
-+   * equivalent to each other.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Object} properties The object of property values to filter by.
-+   * @returns {*} Returns the found element, else `undefined`.
-+   * @example
-+   *
-+   * var food = [
-+   *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
-+   *   { 'name': 'banana', 'organic': true,  'type': 'fruit' },
-+   *   { 'name': 'beet',   'organic': false, 'type': 'vegetable' }
-+   * ];
-+   *
-+   * _.findWhere(food, { 'type': 'vegetable' });
-+   * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
-+   */
-+  function findWhere(object, properties) {
-+    return where(object, properties, true);
-+  }
-+
-+  /**
-+   * Iterates over elements of a collection, executing the callback for each
-+   * element. The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, index|key, collection). Callbacks may exit iteration early by
-+   * explicitly returning `false`.
-+   *
-+   * Note: As with other "Collections" methods, objects with a `length` property
-+   * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
-+   * may be used for object iteration.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias each
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array|Object|string} Returns `collection`.
-+   * @example
-+   *
-+   * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
-+   * // => logs each number and returns '1,2,3'
-+   *
-+   * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
-+   * // => logs each number and returns the object (property order is not guaranteed across environments)
-+   */
-+  function forEach(collection, callback, thisArg) {
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+    if (typeof length == 'number') {
-+      while (++index < length) {
-+        if (callback(collection[index], index, collection) === indicatorObject) {
-+          break;
-+        }
-+      }
-+    } else {
-+      forOwn(collection, callback);
-+    }
-+  }
-+
-+  /**
-+   * This method is like `_.forEach` except that it iterates over elements
-+   * of a `collection` from right to left.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias eachRight
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array|Object|string} Returns `collection`.
-+   * @example
-+   *
-+   * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
-+   * // => logs each number from right to left and returns '3,2,1'
-+   */
-+  function forEachRight(collection, callback) {
-+    var length = collection ? collection.length : 0;
-+    if (typeof length == 'number') {
-+      while (length--) {
-+        if (callback(collection[length], length, collection) === false) {
-+          break;
-+        }
-+      }
-+    } else {
-+      var props = keys(collection);
-+      length = props.length;
-+      forOwn(collection, function(value, key, collection) {
-+        key = props ? props[--length] : --length;
-+        return callback(collection[key], key, collection) === false && indicatorObject;
-+      });
-+    }
-+  }
-+
-+  /**
-+   * Creates an object composed of keys generated from the results of running
-+   * each element of a collection through the callback. The corresponding value
-+   * of each key is an array of the elements responsible for generating the key.
-+   * The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns the composed aggregate object.
-+   * @example
-+   *
-+   * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
-+   * // => { '4': [4.2], '6': [6.1, 6.4] }
-+   *
-+   * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+   * // => { '4': [4.2], '6': [6.1, 6.4] }
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.groupBy(['one', 'two', 'three'], 'length');
-+   * // => { '3': ['one', 'two'], '5': ['three'] }
-+   */
-+  var groupBy = createAggregator(function(result, value, key) {
-+    (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
-+  });
-+
-+  /**
-+   * Creates an object composed of keys generated from the results of running
-+   * each element of the collection through the given callback. The corresponding
-+   * value of each key is the last element responsible for generating the key.
-+   * The callback is bound to `thisArg` and invoked with three arguments;
-+   * (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Object} Returns the composed aggregate object.
-+   * @example
-+   *
-+   * var keys = [
-+   *   { 'dir': 'left', 'code': 97 },
-+   *   { 'dir': 'right', 'code': 100 }
-+   * ];
-+   *
-+   * _.indexBy(keys, 'dir');
-+   * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
-+   *
-+   * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
-+   * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+   *
-+   * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
-+   * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+   */
-+  var indexBy = createAggregator(function(result, value, key) {
-+    result[key] = value;
-+  });
-+
-+  /**
-+   * Invokes the method named by `methodName` on each element in the `collection`
-+   * returning an array of the results of each invoked method. Additional arguments
-+   * will be provided to each invoked method. If `methodName` is a function it
-+   * will be invoked for, and `this` bound to, each element in the `collection`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|string} methodName The name of the method to invoke or
-+   *  the function invoked per iteration.
-+   * @param {...*} [arg] Arguments to invoke the method with.
-+   * @returns {Array} Returns a new array of the results of each invoked method.
-+   * @example
-+   *
-+   * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-+   * // => [[1, 5, 7], [1, 2, 3]]
-+   *
-+   * _.invoke([123, 456], String.prototype.split, '');
-+   * // => [['1', '2', '3'], ['4', '5', '6']]
-+   */
-+  function invoke(collection, methodName) {
-+    var args = slice(arguments, 2),
-+        index = -1,
-+        isFunc = typeof methodName == 'function',
-+        length = collection ? collection.length : 0,
-+        result = Array(typeof length == 'number' ? length : 0);
-+
-+    forEach(collection, function(value) {
-+      result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
-+    });
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an array of values by running each element in the collection
-+   * through the callback. The callback is bound to `thisArg` and invoked with
-+   * three arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias collect
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a new array of the results of each `callback` execution.
-+   * @example
-+   *
-+   * _.map([1, 2, 3], function(num) { return num * 3; });
-+   * // => [3, 6, 9]
-+   *
-+   * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
-+   * // => [3, 6, 9] (property order is not guaranteed across environments)
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.map(characters, 'name');
-+   * // => ['barney', 'fred']
-+   */
-+  function map(collection, callback, thisArg) {
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    callback = createCallback(callback, thisArg, 3);
-+    if (typeof length == 'number') {
-+      var result = Array(length);
-+      while (++index < length) {
-+        result[index] = callback(collection[index], index, collection);
-+      }
-+    } else {
-+      result = [];
-+      forOwn(collection, function(value, key, collection) {
-+        result[++index] = callback(value, key, collection);
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Retrieves the maximum value of a collection. If the collection is empty or
-+   * falsey `-Infinity` is returned. If a callback is provided it will be executed
-+   * for each value in the collection to generate the criterion by which the value
-+   * is ranked. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, index, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the maximum value.
-+   * @example
-+   *
-+   * _.max([4, 2, 8, 6]);
-+   * // => 8
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * _.max(characters, function(chr) { return chr.age; });
-+   * // => { 'name': 'fred', 'age': 40 };
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.max(characters, 'age');
-+   * // => { 'name': 'fred', 'age': 40 };
-+   */
-+  function max(collection, callback, thisArg) {
-+    var computed = -Infinity,
-+        result = computed;
-+
-+    // allows working with functions like `_.map` without using
-+    // their `index` argument as a callback
-+    if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+      callback = null;
-+    }
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (callback == null && typeof length == 'number') {
-+      while (++index < length) {
-+        var value = collection[index];
-+        if (value > result) {
-+          result = value;
-+        }
-+      }
-+    } else {
-+      callback = createCallback(callback, thisArg, 3);
-+
-+      forEach(collection, function(value, index, collection) {
-+        var current = callback(value, index, collection);
-+        if (current > computed) {
-+          computed = current;
-+          result = value;
-+        }
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Retrieves the minimum value of a collection. If the collection is empty or
-+   * falsey `Infinity` is returned. If a callback is provided it will be executed
-+   * for each value in the collection to generate the criterion by which the value
-+   * is ranked. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, index, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the minimum value.
-+   * @example
-+   *
-+   * _.min([4, 2, 8, 6]);
-+   * // => 2
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * _.min(characters, function(chr) { return chr.age; });
-+   * // => { 'name': 'barney', 'age': 36 };
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.min(characters, 'age');
-+   * // => { 'name': 'barney', 'age': 36 };
-+   */
-+  function min(collection, callback, thisArg) {
-+    var computed = Infinity,
-+        result = computed;
-+
-+    // allows working with functions like `_.map` without using
-+    // their `index` argument as a callback
-+    if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+      callback = null;
-+    }
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (callback == null && typeof length == 'number') {
-+      while (++index < length) {
-+        var value = collection[index];
-+        if (value < result) {
-+          result = value;
-+        }
-+      }
-+    } else {
-+      callback = createCallback(callback, thisArg, 3);
-+
-+      forEach(collection, function(value, index, collection) {
-+        var current = callback(value, index, collection);
-+        if (current < computed) {
-+          computed = current;
-+          result = value;
-+        }
-+      });
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Retrieves the value of a specified property from all elements in the collection.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {string} property The name of the property to pluck.
-+   * @returns {Array} Returns a new array of property values.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * _.pluck(characters, 'name');
-+   * // => ['barney', 'fred']
-+   */
-+  var pluck = map;
-+
-+  /**
-+   * Reduces a collection to a value which is the accumulated result of running
-+   * each element in the collection through the callback, where each successive
-+   * callback execution consumes the return value of the previous execution. If
-+   * `accumulator` is not provided the first element of the collection will be
-+   * used as the initial `accumulator` value. The callback is bound to `thisArg`
-+   * and invoked with four arguments; (accumulator, value, index|key, collection).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias foldl, inject
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [accumulator] Initial value of the accumulator.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the accumulated value.
-+   * @example
-+   *
-+   * var sum = _.reduce([1, 2, 3], function(sum, num) {
-+   *   return sum + num;
-+   * });
-+   * // => 6
-+   *
-+   * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+   *   result[key] = num * 3;
-+   *   return result;
-+   * }, {});
-+   * // => { 'a': 3, 'b': 6, 'c': 9 }
-+   */
-+  function reduce(collection, callback, accumulator, thisArg) {
-+    if (!collection) return accumulator;
-+    var noaccum = arguments.length < 3;
-+    callback = createCallback(callback, thisArg, 4);
-+
-+    var index = -1,
-+        length = collection.length;
-+
-+    if (typeof length == 'number') {
-+      if (noaccum) {
-+        accumulator = collection[++index];
-+      }
-+      while (++index < length) {
-+        accumulator = callback(accumulator, collection[index], index, collection);
-+      }
-+    } else {
-+      forOwn(collection, function(value, index, collection) {
-+        accumulator = noaccum
-+          ? (noaccum = false, value)
-+          : callback(accumulator, value, index, collection)
-+      });
-+    }
-+    return accumulator;
-+  }
-+
-+  /**
-+   * This method is like `_.reduce` except that it iterates over elements
-+   * of a `collection` from right to left.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias foldr
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function} [callback=identity] The function called per iteration.
-+   * @param {*} [accumulator] Initial value of the accumulator.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the accumulated value.
-+   * @example
-+   *
-+   * var list = [[0, 1], [2, 3], [4, 5]];
-+   * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-+   * // => [4, 5, 2, 3, 0, 1]
-+   */
-+  function reduceRight(collection, callback, accumulator, thisArg) {
-+    var noaccum = arguments.length < 3;
-+    callback = createCallback(callback, thisArg, 4);
-+    forEachRight(collection, function(value, index, collection) {
-+      accumulator = noaccum
-+        ? (noaccum = false, value)
-+        : callback(accumulator, value, index, collection);
-+    });
-+    return accumulator;
-+  }
-+
-+  /**
-+   * The opposite of `_.filter` this method returns the elements of a
-+   * collection that the callback does **not** return truey for.
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a new array of elements that failed the callback check.
-+   * @example
-+   *
-+   * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+   * // => [1, 3, 5]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+   *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.reject(characters, 'blocked');
-+   * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.reject(characters, { 'age': 36 });
-+   * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+   */
-+  function reject(collection, callback, thisArg) {
-+    callback = createCallback(callback, thisArg, 3);
-+    return filter(collection, function(value, index, collection) {
-+      return !callback(value, index, collection);
-+    });
-+  }
-+
-+  /**
-+   * Retrieves a random element or `n` random elements from a collection.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to sample.
-+   * @param {number} [n] The number of elements to sample.
-+   * @param- {Object} [guard] Allows working with functions like `_.map`
-+   *  without using their `index` arguments as `n`.
-+   * @returns {Array} Returns the random sample(s) of `collection`.
-+   * @example
-+   *
-+   * _.sample([1, 2, 3, 4]);
-+   * // => 2
-+   *
-+   * _.sample([1, 2, 3, 4], 2);
-+   * // => [3, 1]
-+   */
-+  function sample(collection, n, guard) {
-+    if (collection && typeof collection.length != 'number') {
-+      collection = values(collection);
-+    }
-+    if (n == null || guard) {
-+      return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
-+    }
-+    var result = shuffle(collection);
-+    result.length = nativeMin(nativeMax(0, n), result.length);
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an array of shuffled values, using a version of the Fisher-Yates
-+   * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to shuffle.
-+   * @returns {Array} Returns a new shuffled collection.
-+   * @example
-+   *
-+   * _.shuffle([1, 2, 3, 4, 5, 6]);
-+   * // => [4, 1, 6, 3, 5, 2]
-+   */
-+  function shuffle(collection) {
-+    var index = -1,
-+        length = collection ? collection.length : 0,
-+        result = Array(typeof length == 'number' ? length : 0);
-+
-+    forEach(collection, function(value) {
-+      var rand = baseRandom(0, ++index);
-+      result[index] = result[rand];
-+      result[rand] = value;
-+    });
-+    return result;
-+  }
-+
-+  /**
-+   * Gets the size of the `collection` by returning `collection.length` for arrays
-+   * and array-like objects or the number of own enumerable properties for objects.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to inspect.
-+   * @returns {number} Returns `collection.length` or number of own enumerable properties.
-+   * @example
-+   *
-+   * _.size([1, 2]);
-+   * // => 2
-+   *
-+   * _.size({ 'one': 1, 'two': 2, 'three': 3 });
-+   * // => 3
-+   *
-+   * _.size('pebbles');
-+   * // => 7
-+   */
-+  function size(collection) {
-+    var length = collection ? collection.length : 0;
-+    return typeof length == 'number' ? length : keys(collection).length;
-+  }
-+
-+  /**
-+   * Checks if the callback returns a truey value for **any** element of a
-+   * collection. The function returns as soon as it finds a passing value and
-+   * does not iterate over the entire collection. The callback is bound to
-+   * `thisArg` and invoked with three arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias any
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {boolean} Returns `true` if any element passed the callback check,
-+   *  else `false`.
-+   * @example
-+   *
-+   * _.some([null, 0, 'yes', false], Boolean);
-+   * // => true
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+   *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.some(characters, 'blocked');
-+   * // => true
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.some(characters, { 'age': 1 });
-+   * // => false
-+   */
-+  function some(collection, callback, thisArg) {
-+    var result;
-+    callback = createCallback(callback, thisArg, 3);
-+
-+    var index = -1,
-+        length = collection ? collection.length : 0;
-+
-+    if (typeof length == 'number') {
-+      while (++index < length) {
-+        if ((result = callback(collection[index], index, collection))) {
-+          break;
-+        }
-+      }
-+    } else {
-+      forOwn(collection, function(value, index, collection) {
-+        return (result = callback(value, index, collection)) && indicatorObject;
-+      });
-+    }
-+    return !!result;
-+  }
-+
-+  /**
-+   * Creates an array of elements, sorted in ascending order by the results of
-+   * running each element in a collection through the callback. This method
-+   * performs a stable sort, that is, it will preserve the original sort order
-+   * of equal elements. The callback is bound to `thisArg` and invoked with
-+   * three arguments; (value, index|key, collection).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an array of property names is provided for `callback` the collection
-+   * will be sorted by each property value.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Array|Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a new array of sorted elements.
-+   * @example
-+   *
-+   * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
-+   * // => [3, 1, 2]
-+   *
-+   * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
-+   * // => [3, 1, 2]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'age': 36 },
-+   *   { 'name': 'fred',    'age': 40 },
-+   *   { 'name': 'barney',  'age': 26 },
-+   *   { 'name': 'fred',    'age': 30 }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.map(_.sortBy(characters, 'age'), _.values);
-+   * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
-+   *
-+   * // sorting by multiple properties
-+   * _.map(_.sortBy(characters, ['name', 'age']), _.values);
-+   * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
-+   */
-+  function sortBy(collection, callback, thisArg) {
-+    var index = -1,
-+        length = collection ? collection.length : 0,
-+        result = Array(typeof length == 'number' ? length : 0);
-+
-+    callback = createCallback(callback, thisArg, 3);
-+    forEach(collection, function(value, key, collection) {
-+      result[++index] = {
-+        'criteria': [callback(value, key, collection)],
-+        'index': index,
-+        'value': value
-+      };
-+    });
-+
-+    length = result.length;
-+    result.sort(compareAscending);
-+    while (length--) {
-+      result[length] = result[length].value;
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Converts the `collection` to an array.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to convert.
-+   * @returns {Array} Returns the new converted array.
-+   * @example
-+   *
-+   * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-+   * // => [2, 3, 4]
-+   */
-+  function toArray(collection) {
-+    if (isArray(collection)) {
-+      return slice(collection);
-+    }
-+    if (collection && typeof collection.length == 'number') {
-+      return map(collection);
-+    }
-+    return values(collection);
-+  }
-+
-+  /**
-+   * Performs a deep comparison of each element in a `collection` to the given
-+   * `properties` object, returning an array of all elements that have equivalent
-+   * property values.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type Function
-+   * @category Collections
-+   * @param {Array|Object|string} collection The collection to iterate over.
-+   * @param {Object} props The object of property values to filter by.
-+   * @returns {Array} Returns a new array of elements that have the given properties.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
-+   *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+   * ];
-+   *
-+   * _.where(characters, { 'age': 36 });
-+   * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
-+   *
-+   * _.where(characters, { 'pets': ['dino'] });
-+   * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
-+   */
-+  function where(collection, properties, first) {
-+    return (first && isEmpty(properties))
-+      ? undefined
-+      : (first ? find : filter)(collection, properties);
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Creates an array with all falsey values removed. The values `false`, `null`,
-+   * `0`, `""`, `undefined`, and `NaN` are all falsey.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to compact.
-+   * @returns {Array} Returns a new array of filtered values.
-+   * @example
-+   *
-+   * _.compact([0, 1, false, 2, '', 3]);
-+   * // => [1, 2, 3]
-+   */
-+  function compact(array) {
-+    var index = -1,
-+        length = array ? array.length : 0,
-+        result = [];
-+
-+    while (++index < length) {
-+      var value = array[index];
-+      if (value) {
-+        result.push(value);
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an array excluding all values of the provided arrays using strict
-+   * equality for comparisons, i.e. `===`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to process.
-+   * @param {...Array} [values] The arrays of values to exclude.
-+   * @returns {Array} Returns a new array of filtered values.
-+   * @example
-+   *
-+   * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-+   * // => [1, 3, 4]
-+   */
-+  function difference(array) {
-+    return baseDifference(array, baseFlatten(arguments, true, true, 1));
-+  }
-+
-+  /**
-+   * Gets the first element or first `n` elements of an array. If a callback
-+   * is provided elements at the beginning of the array are returned as long
-+   * as the callback returns truey. The callback is bound to `thisArg` and
-+   * invoked with three arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias head, take
-+   * @category Arrays
-+   * @param {Array} array The array to query.
-+   * @param {Function|Object|number|string} [callback] The function called
-+   *  per element or the number of elements to return. If a property name or
-+   *  object is provided it will be used to create a "_.pluck" or "_.where"
-+   *  style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the first element(s) of `array`.
-+   * @example
-+   *
-+   * _.first([1, 2, 3]);
-+   * // => 1
-+   *
-+   * _.first([1, 2, 3], 2);
-+   * // => [1, 2]
-+   *
-+   * _.first([1, 2, 3], function(num) {
-+   *   return num < 3;
-+   * });
-+   * // => [1, 2]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+   *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
-+   *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.first(characters, 'blocked');
-+   * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
-+   * // => ['barney', 'fred']
-+   */
-+  function first(array, callback, thisArg) {
-+    var n = 0,
-+        length = array ? array.length : 0;
-+
-+    if (typeof callback != 'number' && callback != null) {
-+      var index = -1;
-+      callback = createCallback(callback, thisArg, 3);
-+      while (++index < length && callback(array[index], index, array)) {
-+        n++;
-+      }
-+    } else {
-+      n = callback;
-+      if (n == null || thisArg) {
-+        return array ? array[0] : undefined;
-+      }
-+    }
-+    return slice(array, 0, nativeMin(nativeMax(0, n), length));
-+  }
-+
-+  /**
-+   * Flattens a nested array (the nesting can be to any depth). If `isShallow`
-+   * is truey, the array will only be flattened a single level. If a callback
-+   * is provided each element of the array is passed through the callback before
-+   * flattening. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to flatten.
-+   * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a new flattened array.
-+   * @example
-+   *
-+   * _.flatten([1, [2], [3, [[4]]]]);
-+   * // => [1, 2, 3, 4];
-+   *
-+   * _.flatten([1, [2], [3, [[4]]]], true);
-+   * // => [1, 2, 3, [[4]]];
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
-+   *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.flatten(characters, 'pets');
-+   * // => ['hoppy', 'baby puss', 'dino']
-+   */
-+  function flatten(array, isShallow) {
-+    return baseFlatten(array, isShallow);
-+  }
-+
-+  /**
-+   * Gets the index at which the first occurrence of `value` is found using
-+   * strict equality for comparisons, i.e. `===`. If the array is already sorted
-+   * providing `true` for `fromIndex` will run a faster binary search.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {boolean|number} [fromIndex=0] The index to search from or `true`
-+   *  to perform a binary search on a sorted array.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   * @example
-+   *
-+   * _.indexOf([1, 2, 3, 1, 2, 3], 2);
-+   * // => 1
-+   *
-+   * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+   * // => 4
-+   *
-+   * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
-+   * // => 2
-+   */
-+  function indexOf(array, value, fromIndex) {
-+    if (typeof fromIndex == 'number') {
-+      var length = array ? array.length : 0;
-+      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
-+    } else if (fromIndex) {
-+      var index = sortedIndex(array, value);
-+      return array[index] === value ? index : -1;
-+    }
-+    return baseIndexOf(array, value, fromIndex);
-+  }
-+
-+  /**
-+   * Gets all but the last element or last `n` elements of an array. If a
-+   * callback is provided elements at the end of the array are excluded from
-+   * the result as long as the callback returns truey. The callback is bound
-+   * to `thisArg` and invoked with three arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to query.
-+   * @param {Function|Object|number|string} [callback=1] The function called
-+   *  per element or the number of elements to exclude. If a property name or
-+   *  object is provided it will be used to create a "_.pluck" or "_.where"
-+   *  style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a slice of `array`.
-+   * @example
-+   *
-+   * _.initial([1, 2, 3]);
-+   * // => [1, 2]
-+   *
-+   * _.initial([1, 2, 3], 2);
-+   * // => [1]
-+   *
-+   * _.initial([1, 2, 3], function(num) {
-+   *   return num > 1;
-+   * });
-+   * // => [1]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+   *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+   *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.initial(characters, 'blocked');
-+   * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
-+   * // => ['barney', 'fred']
-+   */
-+  function initial(array, callback, thisArg) {
-+    var n = 0,
-+        length = array ? array.length : 0;
-+
-+    if (typeof callback != 'number' && callback != null) {
-+      var index = length;
-+      callback = createCallback(callback, thisArg, 3);
-+      while (index-- && callback(array[index], index, array)) {
-+        n++;
-+      }
-+    } else {
-+      n = (callback == null || thisArg) ? 1 : callback || n;
-+    }
-+    return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
-+  }
-+
-+  /**
-+   * Creates an array of unique values present in all provided arrays using
-+   * strict equality for comparisons, i.e. `===`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {...Array} [array] The arrays to inspect.
-+   * @returns {Array} Returns an array of shared values.
-+   * @example
-+   *
-+   * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+   * // => [1, 2]
-+   */
-+  function intersection() {
-+    var args = [],
-+        argsIndex = -1,
-+        argsLength = arguments.length;
-+
-+    while (++argsIndex < argsLength) {
-+      var value = arguments[argsIndex];
-+       if (isArray(value) || isArguments(value)) {
-+         args.push(value);
-+       }
-+    }
-+    var array = args[0],
-+        index = -1,
-+        indexOf = getIndexOf(),
-+        length = array ? array.length : 0,
-+        result = [];
-+
-+    outer:
-+    while (++index < length) {
-+      value = array[index];
-+      if (indexOf(result, value) < 0) {
-+        var argsIndex = argsLength;
-+        while (--argsIndex) {
-+          if (indexOf(args[argsIndex], value) < 0) {
-+            continue outer;
-+          }
-+        }
-+        result.push(value);
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Gets the last element or last `n` elements of an array. If a callback is
-+   * provided elements at the end of the array are returned as long as the
-+   * callback returns truey. The callback is bound to `thisArg` and invoked
-+   * with three arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to query.
-+   * @param {Function|Object|number|string} [callback] The function called
-+   *  per element or the number of elements to return. If a property name or
-+   *  object is provided it will be used to create a "_.pluck" or "_.where"
-+   *  style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {*} Returns the last element(s) of `array`.
-+   * @example
-+   *
-+   * _.last([1, 2, 3]);
-+   * // => 3
-+   *
-+   * _.last([1, 2, 3], 2);
-+   * // => [2, 3]
-+   *
-+   * _.last([1, 2, 3], function(num) {
-+   *   return num > 1;
-+   * });
-+   * // => [2, 3]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+   *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+   *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.pluck(_.last(characters, 'blocked'), 'name');
-+   * // => ['fred', 'pebbles']
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.last(characters, { 'employer': 'na' });
-+   * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+   */
-+  function last(array, callback, thisArg) {
-+    var n = 0,
-+        length = array ? array.length : 0;
-+
-+    if (typeof callback != 'number' && callback != null) {
-+      var index = length;
-+      callback = createCallback(callback, thisArg, 3);
-+      while (index-- && callback(array[index], index, array)) {
-+        n++;
-+      }
-+    } else {
-+      n = callback;
-+      if (n == null || thisArg) {
-+        return array ? array[length - 1] : undefined;
-+      }
-+    }
-+    return slice(array, nativeMax(0, length - n));
-+  }
-+
-+  /**
-+   * Gets the index at which the last occurrence of `value` is found using strict
-+   * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
-+   * as the offset from the end of the collection.
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {number} [fromIndex=array.length-1] The index to search from.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   * @example
-+   *
-+   * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-+   * // => 4
-+   *
-+   * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+   * // => 1
-+   */
-+  function lastIndexOf(array, value, fromIndex) {
-+    var index = array ? array.length : 0;
-+    if (typeof fromIndex == 'number') {
-+      index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
-+    }
-+    while (index--) {
-+      if (array[index] === value) {
-+        return index;
-+      }
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * Creates an array of numbers (positive and/or negative) progressing from
-+   * `start` up to but not including `end`. If `start` is less than `stop` a
-+   * zero-length range is created unless a negative `step` is specified.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {number} [start=0] The start of the range.
-+   * @param {number} end The end of the range.
-+   * @param {number} [step=1] The value to increment or decrement by.
-+   * @returns {Array} Returns a new range array.
-+   * @example
-+   *
-+   * _.range(4);
-+   * // => [0, 1, 2, 3]
-+   *
-+   * _.range(1, 5);
-+   * // => [1, 2, 3, 4]
-+   *
-+   * _.range(0, 20, 5);
-+   * // => [0, 5, 10, 15]
-+   *
-+   * _.range(0, -4, -1);
-+   * // => [0, -1, -2, -3]
-+   *
-+   * _.range(1, 4, 0);
-+   * // => [1, 1, 1]
-+   *
-+   * _.range(0);
-+   * // => []
-+   */
-+  function range(start, end, step) {
-+    start = +start || 0;
-+    step =  (+step || 1);
-+
-+    if (end == null) {
-+      end = start;
-+      start = 0;
-+    }
-+    // use `Array(length)` so engines like Chakra and V8 avoid slower modes
-+    // http://youtu.be/XAqIpGU8ZZk#t=17m25s
-+    var index = -1,
-+        length = nativeMax(0, ceil((end - start) / step)),
-+        result = Array(length);
-+
-+    while (++index < length) {
-+      result[index] = start;
-+      start += step;
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * The opposite of `_.initial` this method gets all but the first element or
-+   * first `n` elements of an array. If a callback function is provided elements
-+   * at the beginning of the array are excluded from the result as long as the
-+   * callback returns truey. The callback is bound to `thisArg` and invoked
-+   * with three arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias drop, tail
-+   * @category Arrays
-+   * @param {Array} array The array to query.
-+   * @param {Function|Object|number|string} [callback=1] The function called
-+   *  per element or the number of elements to exclude. If a property name or
-+   *  object is provided it will be used to create a "_.pluck" or "_.where"
-+   *  style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a slice of `array`.
-+   * @example
-+   *
-+   * _.rest([1, 2, 3]);
-+   * // => [2, 3]
-+   *
-+   * _.rest([1, 2, 3], 2);
-+   * // => [3]
-+   *
-+   * _.rest([1, 2, 3], function(num) {
-+   *   return num < 3;
-+   * });
-+   * // => [3]
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+   *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
-+   *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
-+   * ];
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.pluck(_.rest(characters, 'blocked'), 'name');
-+   * // => ['fred', 'pebbles']
-+   *
-+   * // using "_.where" callback shorthand
-+   * _.rest(characters, { 'employer': 'slate' });
-+   * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+   */
-+  function rest(array, callback, thisArg) {
-+    if (typeof callback != 'number' && callback != null) {
-+      var n = 0,
-+          index = -1,
-+          length = array ? array.length : 0;
-+
-+      callback = createCallback(callback, thisArg, 3);
-+      while (++index < length && callback(array[index], index, array)) {
-+        n++;
-+      }
-+    } else {
-+      n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
-+    }
-+    return slice(array, n);
-+  }
-+
-+  /**
-+   * Uses a binary search to determine the smallest index at which a value
-+   * should be inserted into a given sorted array in order to maintain the sort
-+   * order of the array. If a callback is provided it will be executed for
-+   * `value` and each element of `array` to compute their sort ranking. The
-+   * callback is bound to `thisArg` and invoked with one argument; (value).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to inspect.
-+   * @param {*} value The value to evaluate.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {number} Returns the index at which `value` should be inserted
-+   *  into `array`.
-+   * @example
-+   *
-+   * _.sortedIndex([20, 30, 50], 40);
-+   * // => 2
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
-+   * // => 2
-+   *
-+   * var dict = {
-+   *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
-+   * };
-+   *
-+   * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+   *   return dict.wordToNumber[word];
-+   * });
-+   * // => 2
-+   *
-+   * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+   *   return this.wordToNumber[word];
-+   * }, dict);
-+   * // => 2
-+   */
-+  function sortedIndex(array, value, callback, thisArg) {
-+    var low = 0,
-+        high = array ? array.length : low;
-+
-+    // explicitly reference `identity` for better inlining in Firefox
-+    callback = callback ? createCallback(callback, thisArg, 1) : identity;
-+    value = callback(value);
-+
-+    while (low < high) {
-+      var mid = (low + high) >>> 1;
-+      (callback(array[mid]) < value)
-+        ? low = mid + 1
-+        : high = mid;
-+    }
-+    return low;
-+  }
-+
-+  /**
-+   * Creates an array of unique values, in order, of the provided arrays using
-+   * strict equality for comparisons, i.e. `===`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {...Array} [array] The arrays to inspect.
-+   * @returns {Array} Returns an array of combined values.
-+   * @example
-+   *
-+   * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+   * // => [1, 2, 3, 5, 4]
-+   */
-+  function union() {
-+    return baseUniq(baseFlatten(arguments, true, true));
-+  }
-+
-+  /**
-+   * Creates a duplicate-value-free version of an array using strict equality
-+   * for comparisons, i.e. `===`. If the array is sorted, providing
-+   * `true` for `isSorted` will use a faster algorithm. If a callback is provided
-+   * each element of `array` is passed through the callback before uniqueness
-+   * is computed. The callback is bound to `thisArg` and invoked with three
-+   * arguments; (value, index, array).
-+   *
-+   * If a property name is provided for `callback` the created "_.pluck" style
-+   * callback will return the property value of the given element.
-+   *
-+   * If an object is provided for `callback` the created "_.where" style callback
-+   * will return `true` for elements that have the properties of the given object,
-+   * else `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias unique
-+   * @category Arrays
-+   * @param {Array} array The array to process.
-+   * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+   * @param {Function|Object|string} [callback=identity] The function called
-+   *  per iteration. If a property name or object is provided it will be used
-+   *  to create a "_.pluck" or "_.where" style callback, respectively.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns a duplicate-value-free array.
-+   * @example
-+   *
-+   * _.uniq([1, 2, 1, 3, 1]);
-+   * // => [1, 2, 3]
-+   *
-+   * _.uniq([1, 1, 2, 2, 3], true);
-+   * // => [1, 2, 3]
-+   *
-+   * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
-+   * // => ['A', 'b', 'C']
-+   *
-+   * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
-+   * // => [1, 2.5, 3]
-+   *
-+   * // using "_.pluck" callback shorthand
-+   * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
-+   * // => [{ 'x': 1 }, { 'x': 2 }]
-+   */
-+  function uniq(array, isSorted, callback, thisArg) {
-+    // juggle arguments
-+    if (typeof isSorted != 'boolean' && isSorted != null) {
-+      thisArg = callback;
-+      callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
-+      isSorted = false;
-+    }
-+    if (callback != null) {
-+      callback = createCallback(callback, thisArg, 3);
-+    }
-+    return baseUniq(array, isSorted, callback);
-+  }
-+
-+  /**
-+   * Creates an array excluding all provided values using strict equality for
-+   * comparisons, i.e. `===`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Arrays
-+   * @param {Array} array The array to filter.
-+   * @param {...*} [value] The values to exclude.
-+   * @returns {Array} Returns a new array of filtered values.
-+   * @example
-+   *
-+   * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-+   * // => [2, 3, 4]
-+   */
-+  function without(array) {
-+    return baseDifference(array, slice(arguments, 1));
-+  }
-+
-+  /**
-+   * Creates an array of grouped elements, the first of which contains the first
-+   * elements of the given arrays, the second of which contains the second
-+   * elements of the given arrays, and so on.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias unzip
-+   * @category Arrays
-+   * @param {...Array} [array] Arrays to process.
-+   * @returns {Array} Returns a new array of grouped elements.
-+   * @example
-+   *
-+   * _.zip(['fred', 'barney'], [30, 40], [true, false]);
-+   * // => [['fred', 30, true], ['barney', 40, false]]
-+   */
-+  function zip() {
-+    var index = -1,
-+        length = max(pluck(arguments, 'length')),
-+        result = Array(length < 0 ? 0 : length);
-+
-+    while (++index < length) {
-+      result[index] = pluck(arguments, index);
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Creates an object composed from arrays of `keys` and `values`. Provide
-+   * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
-+   * or two arrays, one of `keys` and one of corresponding `values`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @alias object
-+   * @category Arrays
-+   * @param {Array} keys The array of keys.
-+   * @param {Array} [values=[]] The array of values.
-+   * @returns {Object} Returns an object composed of the given keys and
-+   *  corresponding values.
-+   * @example
-+   *
-+   * _.zipObject(['fred', 'barney'], [30, 40]);
-+   * // => { 'fred': 30, 'barney': 40 }
-+   */
-+  function zipObject(keys, values) {
-+    var index = -1,
-+        length = keys ? keys.length : 0,
-+        result = {};
-+
-+    if (!values && length && !isArray(keys[0])) {
-+      values = [];
-+    }
-+    while (++index < length) {
-+      var key = keys[index];
-+      if (values) {
-+        result[key] = values[index];
-+      } else if (key) {
-+        result[key[0]] = key[1];
-+      }
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Creates a function that executes `func`, with  the `this` binding and
-+   * arguments of the created function, only after being called `n` times.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {number} n The number of times the function must be called before
-+   *  `func` is executed.
-+   * @param {Function} func The function to restrict.
-+   * @returns {Function} Returns the new restricted function.
-+   * @example
-+   *
-+   * var saves = ['profile', 'settings'];
-+   *
-+   * var done = _.after(saves.length, function() {
-+   *   console.log('Done saving!');
-+   * });
-+   *
-+   * _.forEach(saves, function(type) {
-+   *   asyncSave({ 'type': type, 'complete': done });
-+   * });
-+   * // => logs 'Done saving!', after all saves have completed
-+   */
-+  function after(n, func) {
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    return function() {
-+      if (--n < 1) {
-+        return func.apply(this, arguments);
-+      }
-+    };
-+  }
-+
-+  /**
-+   * Creates a function that, when called, invokes `func` with the `this`
-+   * binding of `thisArg` and prepends any additional `bind` arguments to those
-+   * provided to the bound function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to bind.
-+   * @param {*} [thisArg] The `this` binding of `func`.
-+   * @param {...*} [arg] Arguments to be partially applied.
-+   * @returns {Function} Returns the new bound function.
-+   * @example
-+   *
-+   * var func = function(greeting) {
-+   *   return greeting + ' ' + this.name;
-+   * };
-+   *
-+   * func = _.bind(func, { 'name': 'fred' }, 'hi');
-+   * func();
-+   * // => 'hi fred'
-+   */
-+  function bind(func, thisArg) {
-+    return arguments.length > 2
-+      ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
-+      : createWrapper(func, 1, null, null, thisArg);
-+  }
-+
-+  /**
-+   * Binds methods of an object to the object itself, overwriting the existing
-+   * method. Method names may be specified as individual arguments or as arrays
-+   * of method names. If no method names are provided all the function properties
-+   * of `object` will be bound.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Object} object The object to bind and assign the bound methods to.
-+   * @param {...string} [methodName] The object method names to
-+   *  bind, specified as individual method names or arrays of method names.
-+   * @returns {Object} Returns `object`.
-+   * @example
-+   *
-+   * var view = {
-+   *   'label': 'docs',
-+   *   'onClick': function() { console.log('clicked ' + this.label); }
-+   * };
-+   *
-+   * _.bindAll(view);
-+   * jQuery('#docs').on('click', view.onClick);
-+   * // => logs 'clicked docs', when the button is clicked
-+   */
-+  function bindAll(object) {
-+    var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
-+        index = -1,
-+        length = funcs.length;
-+
-+    while (++index < length) {
-+      var key = funcs[index];
-+      object[key] = createWrapper(object[key], 1, null, null, object);
-+    }
-+    return object;
-+  }
-+
-+  /**
-+   * Creates a function that is the composition of the provided functions,
-+   * where each function consumes the return value of the function that follows.
-+   * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
-+   * Each function is executed with the `this` binding of the composed function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {...Function} [func] Functions to compose.
-+   * @returns {Function} Returns the new composed function.
-+   * @example
-+   *
-+   * var realNameMap = {
-+   *   'pebbles': 'penelope'
-+   * };
-+   *
-+   * var format = function(name) {
-+   *   name = realNameMap[name.toLowerCase()] || name;
-+   *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
-+   * };
-+   *
-+   * var greet = function(formatted) {
-+   *   return 'Hiya ' + formatted + '!';
-+   * };
-+   *
-+   * var welcome = _.compose(greet, format);
-+   * welcome('pebbles');
-+   * // => 'Hiya Penelope!'
-+   */
-+  function compose() {
-+    var funcs = arguments,
-+        length = funcs.length;
-+
-+    while (length--) {
-+      if (!isFunction(funcs[length])) {
-+        throw new TypeError;
-+      }
-+    }
-+    return function() {
-+      var args = arguments,
-+          length = funcs.length;
-+
-+      while (length--) {
-+        args = [funcs[length].apply(this, args)];
-+      }
-+      return args[0];
-+    };
-+  }
-+
-+  /**
-+   * Creates a function that will delay the execution of `func` until after
-+   * `wait` milliseconds have elapsed since the last time it was invoked.
-+   * Provide an options object to indicate that `func` should be invoked on
-+   * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
-+   * to the debounced function will return the result of the last `func` call.
-+   *
-+   * Note: If `leading` and `trailing` options are `true` `func` will be called
-+   * on the trailing edge of the timeout only if the the debounced function is
-+   * invoked more than once during the `wait` timeout.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to debounce.
-+   * @param {number} wait The number of milliseconds to delay.
-+   * @param {Object} [options] The options object.
-+   * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
-+   * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
-+   * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+   * @returns {Function} Returns the new debounced function.
-+   * @example
-+   *
-+   * // avoid costly calculations while the window size is in flux
-+   * var lazyLayout = _.debounce(calculateLayout, 150);
-+   * jQuery(window).on('resize', lazyLayout);
-+   *
-+   * // execute `sendMail` when the click event is fired, debouncing subsequent calls
-+   * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
-+   *   'leading': true,
-+   *   'trailing': false
-+   * });
-+   *
-+   * // ensure `batchLog` is executed once after 1 second of debounced calls
-+   * var source = new EventSource('/stream');
-+   * source.addEventListener('message', _.debounce(batchLog, 250, {
-+   *   'maxWait': 1000
-+   * }, false);
-+   */
-+  function debounce(func, wait, options) {
-+    var args,
-+        maxTimeoutId,
-+        result,
-+        stamp,
-+        thisArg,
-+        timeoutId,
-+        trailingCall,
-+        lastCalled = 0,
-+        maxWait = false,
-+        trailing = true;
-+
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    wait = nativeMax(0, wait) || 0;
-+    if (options === true) {
-+      var leading = true;
-+      trailing = false;
-+    } else if (isObject(options)) {
-+      leading = options.leading;
-+      maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
-+      trailing = 'trailing' in options ? options.trailing : trailing;
-+    }
-+    var delayed = function() {
-+      var remaining = wait - (now() - stamp);
-+      if (remaining <= 0) {
-+        if (maxTimeoutId) {
-+          clearTimeout(maxTimeoutId);
-+        }
-+        var isCalled = trailingCall;
-+        maxTimeoutId = timeoutId = trailingCall = undefined;
-+        if (isCalled) {
-+          lastCalled = now();
-+          result = func.apply(thisArg, args);
-+          if (!timeoutId && !maxTimeoutId) {
-+            args = thisArg = null;
-+          }
-+        }
-+      } else {
-+        timeoutId = setTimeout(delayed, remaining);
-+      }
-+    };
-+
-+    var maxDelayed = function() {
-+      if (timeoutId) {
-+        clearTimeout(timeoutId);
-+      }
-+      maxTimeoutId = timeoutId = trailingCall = undefined;
-+      if (trailing || (maxWait !== wait)) {
-+        lastCalled = now();
-+        result = func.apply(thisArg, args);
-+        if (!timeoutId && !maxTimeoutId) {
-+          args = thisArg = null;
-+        }
-+      }
-+    };
-+
-+    return function() {
-+      args = arguments;
-+      stamp = now();
-+      thisArg = this;
-+      trailingCall = trailing && (timeoutId || !leading);
-+
-+      if (maxWait === false) {
-+        var leadingCall = leading && !timeoutId;
-+      } else {
-+        if (!maxTimeoutId && !leading) {
-+          lastCalled = stamp;
-+        }
-+        var remaining = maxWait - (stamp - lastCalled),
-+            isCalled = remaining <= 0;
-+
-+        if (isCalled) {
-+          if (maxTimeoutId) {
-+            maxTimeoutId = clearTimeout(maxTimeoutId);
-+          }
-+          lastCalled = stamp;
-+          result = func.apply(thisArg, args);
-+        }
-+        else if (!maxTimeoutId) {
-+          maxTimeoutId = setTimeout(maxDelayed, remaining);
-+        }
-+      }
-+      if (isCalled && timeoutId) {
-+        timeoutId = clearTimeout(timeoutId);
-+      }
-+      else if (!timeoutId && wait !== maxWait) {
-+        timeoutId = setTimeout(delayed, wait);
-+      }
-+      if (leadingCall) {
-+        isCalled = true;
-+        result = func.apply(thisArg, args);
-+      }
-+      if (isCalled && !timeoutId && !maxTimeoutId) {
-+        args = thisArg = null;
-+      }
-+      return result;
-+    };
-+  }
-+
-+  /**
-+   * Defers executing the `func` function until the current call stack has cleared.
-+   * Additional arguments will be provided to `func` when it is invoked.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to defer.
-+   * @param {...*} [arg] Arguments to invoke the function with.
-+   * @returns {number} Returns the timer id.
-+   * @example
-+   *
-+   * _.defer(function(text) { console.log(text); }, 'deferred');
-+   * // logs 'deferred' after one or more milliseconds
-+   */
-+  function defer(func) {
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    var args = slice(arguments, 1);
-+    return setTimeout(function() { func.apply(undefined, args); }, 1);
-+  }
-+
-+  /**
-+   * Executes the `func` function after `wait` milliseconds. Additional arguments
-+   * will be provided to `func` when it is invoked.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to delay.
-+   * @param {number} wait The number of milliseconds to delay execution.
-+   * @param {...*} [arg] Arguments to invoke the function with.
-+   * @returns {number} Returns the timer id.
-+   * @example
-+   *
-+   * _.delay(function(text) { console.log(text); }, 1000, 'later');
-+   * // => logs 'later' after one second
-+   */
-+  function delay(func, wait) {
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    var args = slice(arguments, 2);
-+    return setTimeout(function() { func.apply(undefined, args); }, wait);
-+  }
-+
-+  /**
-+   * Creates a function that memoizes the result of `func`. If `resolver` is
-+   * provided it will be used to determine the cache key for storing the result
-+   * based on the arguments provided to the memoized function. By default, the
-+   * first argument provided to the memoized function is used as the cache key.
-+   * The `func` is executed with the `this` binding of the memoized function.
-+   * The result cache is exposed as the `cache` property on the memoized function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to have its output memoized.
-+   * @param {Function} [resolver] A function used to resolve the cache key.
-+   * @returns {Function} Returns the new memoizing function.
-+   * @example
-+   *
-+   * var fibonacci = _.memoize(function(n) {
-+   *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-+   * });
-+   *
-+   * fibonacci(9)
-+   * // => 34
-+   *
-+   * var data = {
-+   *   'fred': { 'name': 'fred', 'age': 40 },
-+   *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+   * };
-+   *
-+   * // modifying the result cache
-+   * var get = _.memoize(function(name) { return data[name]; }, _.identity);
-+   * get('pebbles');
-+   * // => { 'name': 'pebbles', 'age': 1 }
-+   *
-+   * get.cache.pebbles.name = 'penelope';
-+   * get('pebbles');
-+   * // => { 'name': 'penelope', 'age': 1 }
-+   */
-+  function memoize(func, resolver) {
-+    var cache = {};
-+    return function() {
-+      var key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-+      return hasOwnProperty.call(cache, key)
-+        ? cache[key]
-+        : (cache[key] = func.apply(this, arguments));
-+    };
-+  }
-+
-+  /**
-+   * Creates a function that is restricted to execute `func` once. Repeat calls to
-+   * the function will return the value of the first call. The `func` is executed
-+   * with the `this` binding of the created function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to restrict.
-+   * @returns {Function} Returns the new restricted function.
-+   * @example
-+   *
-+   * var initialize = _.once(createApplication);
-+   * initialize();
-+   * initialize();
-+   * // `initialize` executes `createApplication` once
-+   */
-+  function once(func) {
-+    var ran,
-+        result;
-+
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    return function() {
-+      if (ran) {
-+        return result;
-+      }
-+      ran = true;
-+      result = func.apply(this, arguments);
-+
-+      // clear the `func` variable so the function may be garbage collected
-+      func = null;
-+      return result;
-+    };
-+  }
-+
-+  /**
-+   * Creates a function that, when called, invokes `func` with any additional
-+   * `partial` arguments prepended to those provided to the new function. This
-+   * method is similar to `_.bind` except it does **not** alter the `this` binding.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to partially apply arguments to.
-+   * @param {...*} [arg] Arguments to be partially applied.
-+   * @returns {Function} Returns the new partially applied function.
-+   * @example
-+   *
-+   * var greet = function(greeting, name) { return greeting + ' ' + name; };
-+   * var hi = _.partial(greet, 'hi');
-+   * hi('fred');
-+   * // => 'hi fred'
-+   */
-+  function partial(func) {
-+    return createWrapper(func, 16, slice(arguments, 1));
-+  }
-+
-+  /**
-+   * Creates a function that, when executed, will only call the `func` function
-+   * at most once per every `wait` milliseconds. Provide an options object to
-+   * indicate that `func` should be invoked on the leading and/or trailing edge
-+   * of the `wait` timeout. Subsequent calls to the throttled function will
-+   * return the result of the last `func` call.
-+   *
-+   * Note: If `leading` and `trailing` options are `true` `func` will be called
-+   * on the trailing edge of the timeout only if the the throttled function is
-+   * invoked more than once during the `wait` timeout.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {Function} func The function to throttle.
-+   * @param {number} wait The number of milliseconds to throttle executions to.
-+   * @param {Object} [options] The options object.
-+   * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
-+   * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+   * @returns {Function} Returns the new throttled function.
-+   * @example
-+   *
-+   * // avoid excessively updating the position while scrolling
-+   * var throttled = _.throttle(updatePosition, 100);
-+   * jQuery(window).on('scroll', throttled);
-+   *
-+   * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
-+   * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
-+   *   'trailing': false
-+   * }));
-+   */
-+  function throttle(func, wait, options) {
-+    var leading = true,
-+        trailing = true;
-+
-+    if (!isFunction(func)) {
-+      throw new TypeError;
-+    }
-+    if (options === false) {
-+      leading = false;
-+    } else if (isObject(options)) {
-+      leading = 'leading' in options ? options.leading : leading;
-+      trailing = 'trailing' in options ? options.trailing : trailing;
-+    }
-+    options = {};
-+    options.leading = leading;
-+    options.maxWait = wait;
-+    options.trailing = trailing;
-+
-+    return debounce(func, wait, options);
-+  }
-+
-+  /**
-+   * Creates a function that provides `value` to the wrapper function as its
-+   * first argument. Additional arguments provided to the function are appended
-+   * to those provided to the wrapper function. The wrapper is executed with
-+   * the `this` binding of the created function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Functions
-+   * @param {*} value The value to wrap.
-+   * @param {Function} wrapper The wrapper function.
-+   * @returns {Function} Returns the new function.
-+   * @example
-+   *
-+   * var p = _.wrap(_.escape, function(func, text) {
-+   *   return '<p>' + func(text) + '</p>';
-+   * });
-+   *
-+   * p('Fred, Wilma, & Pebbles');
-+   * // => '<p>Fred, Wilma, & Pebbles</p>'
-+   */
-+  function wrap(value, wrapper) {
-+    return createWrapper(wrapper, 16, [value]);
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Produces a callback bound to an optional `thisArg`. If `func` is a property
-+   * name the created callback will return the property value for a given element.
-+   * If `func` is an object the created callback will return `true` for elements
-+   * that contain the equivalent object properties, otherwise it will return `false`.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {*} [func=identity] The value to convert to a callback.
-+   * @param {*} [thisArg] The `this` binding of the created callback.
-+   * @param {number} [argCount] The number of arguments the callback accepts.
-+   * @returns {Function} Returns a callback function.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * // wrap to create custom callback shorthands
-+   * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
-+   *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
-+   *   return !match ? func(callback, thisArg) : function(object) {
-+   *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
-+   *   };
-+   * });
-+   *
-+   * _.filter(characters, 'age__gt38');
-+   * // => [{ 'name': 'fred', 'age': 40 }]
-+   */
-+  function createCallback(func, thisArg, argCount) {
-+    var type = typeof func;
-+    if (func == null || type == 'function') {
-+      return baseCreateCallback(func, thisArg, argCount);
-+    }
-+    // handle "_.pluck" style callback shorthands
-+    if (type != 'object') {
-+      return property(func);
-+    }
-+    var props = keys(func);
-+    return function(object) {
-+      var length = props.length,
-+          result = false;
-+
-+      while (length--) {
-+        if (!(result = object[props[length]] === func[props[length]])) {
-+          break;
-+        }
-+      }
-+      return result;
-+    };
-+  }
-+
-+  /**
-+   * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
-+   * corresponding HTML entities.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {string} string The string to escape.
-+   * @returns {string} Returns the escaped string.
-+   * @example
-+   *
-+   * _.escape('Fred, Wilma, & Pebbles');
-+   * // => 'Fred, Wilma, & Pebbles'
-+   */
-+  function escape(string) {
-+    return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
-+  }
-+
-+  /**
-+   * This method returns the first argument provided to it.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {*} value Any value.
-+   * @returns {*} Returns `value`.
-+   * @example
-+   *
-+   * var object = { 'name': 'fred' };
-+   * _.identity(object) === object;
-+   * // => true
-+   */
-+  function identity(value) {
-+    return value;
-+  }
-+
-+  /**
-+   * Adds function properties of a source object to the destination object.
-+   * If `object` is a function methods will be added to its prototype as well.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {Function|Object} [object=lodash] object The destination object.
-+   * @param {Object} source The object of functions to add.
-+   * @param {Object} [options] The options object.
-+   * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
-+   * @example
-+   *
-+   * function capitalize(string) {
-+   *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
-+   * }
-+   *
-+   * _.mixin({ 'capitalize': capitalize });
-+   * _.capitalize('fred');
-+   * // => 'Fred'
-+   *
-+   * _('fred').capitalize().value();
-+   * // => 'Fred'
-+   *
-+   * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
-+   * _('fred').capitalize();
-+   * // => 'Fred'
-+   */
-+  function mixin(object) {
-+    forEach(functions(object), function(methodName) {
-+      var func = lodash[methodName] = object[methodName];
-+
-+      lodash.prototype[methodName] = function() {
-+        var args = [this.__wrapped__];
-+        push.apply(args, arguments);
-+
-+        var result = func.apply(lodash, args);
-+        return this.__chain__
-+          ? new lodashWrapper(result, true)
-+          : result;
-+      };
-+    });
-+  }
-+
-+  /**
-+   * Reverts the '_' variable to its previous value and returns a reference to
-+   * the `lodash` function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @returns {Function} Returns the `lodash` function.
-+   * @example
-+   *
-+   * var lodash = _.noConflict();
-+   */
-+  function noConflict() {
-+    root._ = oldDash;
-+    return this;
-+  }
-+
-+  /**
-+   * A no-operation function.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @example
-+   *
-+   * var object = { 'name': 'fred' };
-+   * _.noop(object) === undefined;
-+   * // => true
-+   */
-+  function noop() {
-+    // no operation performed
-+  }
-+
-+  /**
-+   * Gets the number of milliseconds that have elapsed since the Unix epoch
-+   * (1 January 1970 00:00:00 UTC).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @example
-+   *
-+   * var stamp = _.now();
-+   * _.defer(function() { console.log(_.now() - stamp); });
-+   * // => logs the number of milliseconds it took for the deferred function to be called
-+   */
-+  var now = isNative(now = Date.now) && now || function() {
-+    return new Date().getTime();
-+  };
-+
-+  /**
-+   * Creates a "_.pluck" style function, which returns the `key` value of a
-+   * given object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {string} key The name of the property to retrieve.
-+   * @returns {Function} Returns the new function.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'fred',   'age': 40 },
-+   *   { 'name': 'barney', 'age': 36 }
-+   * ];
-+   *
-+   * var getName = _.property('name');
-+   *
-+   * _.map(characters, getName);
-+   * // => ['barney', 'fred']
-+   *
-+   * _.sortBy(characters, getName);
-+   * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
-+   */
-+  function property(key) {
-+    return function(object) {
-+      return object[key];
-+    };
-+  }
-+
-+  /**
-+   * Produces a random number between `min` and `max` (inclusive). If only one
-+   * argument is provided a number between `0` and the given number will be
-+   * returned. If `floating` is truey or either `min` or `max` are floats a
-+   * floating-point number will be returned instead of an integer.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {number} [min=0] The minimum possible value.
-+   * @param {number} [max=1] The maximum possible value.
-+   * @param {boolean} [floating=false] Specify returning a floating-point number.
-+   * @returns {number} Returns a random number.
-+   * @example
-+   *
-+   * _.random(0, 5);
-+   * // => an integer between 0 and 5
-+   *
-+   * _.random(5);
-+   * // => also an integer between 0 and 5
-+   *
-+   * _.random(5, true);
-+   * // => a floating-point number between 0 and 5
-+   *
-+   * _.random(1.2, 5.2);
-+   * // => a floating-point number between 1.2 and 5.2
-+   */
-+  function random(min, max) {
-+    if (min == null && max == null) {
-+      max = 1;
-+    }
-+    min = +min || 0;
-+    if (max == null) {
-+      max = min;
-+      min = 0;
-+    } else {
-+      max = +max || 0;
-+    }
-+    return min + floor(nativeRandom() * (max - min + 1));
-+  }
-+
-+  /**
-+   * Resolves the value of property `key` on `object`. If `key` is a function
-+   * it will be invoked with the `this` binding of `object` and its result returned,
-+   * else the property value is returned. If `object` is falsey then `undefined`
-+   * is returned.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {Object} object The object to inspect.
-+   * @param {string} key The name of the property to resolve.
-+   * @returns {*} Returns the resolved value.
-+   * @example
-+   *
-+   * var object = {
-+   *   'cheese': 'crumpets',
-+   *   'stuff': function() {
-+   *     return 'nonsense';
-+   *   }
-+   * };
-+   *
-+   * _.result(object, 'cheese');
-+   * // => 'crumpets'
-+   *
-+   * _.result(object, 'stuff');
-+   * // => 'nonsense'
-+   */
-+  function result(object, key) {
-+    if (object) {
-+      var value = object[key];
-+      return isFunction(value) ? object[key]() : value;
-+    }
-+  }
-+
-+  /**
-+   * A micro-templating method that handles arbitrary delimiters, preserves
-+   * whitespace, and correctly escapes quotes within interpolated code.
-+   *
-+   * Note: In the development build, `_.template` utilizes sourceURLs for easier
-+   * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+   *
-+   * For more information on precompiling templates see:
-+   * http://lodash.com/custom-builds
-+   *
-+   * For more information on Chrome extension sandboxes see:
-+   * http://developer.chrome.com/stable/extensions/sandboxingEval.html
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {string} text The template text.
-+   * @param {Object} data The data object used to populate the text.
-+   * @param {Object} [options] The options object.
-+   * @param {RegExp} [options.escape] The "escape" delimiter.
-+   * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
-+   * @param {Object} [options.imports] An object to import into the template as local variables.
-+   * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
-+   * @param {string} [sourceURL] The sourceURL of the template's compiled source.
-+   * @param {string} [variable] The data object variable name.
-+   * @returns {Function|string} Returns a compiled function when no `data` object
-+   *  is given, else it returns the interpolated text.
-+   * @example
-+   *
-+   * // using the "interpolate" delimiter to create a compiled template
-+   * var compiled = _.template('hello <%= name %>');
-+   * compiled({ 'name': 'fred' });
-+   * // => 'hello fred'
-+   *
-+   * // using the "escape" delimiter to escape HTML in data property values
-+   * _.template('<b><%- value %></b>', { 'value': '<script>' });
-+   * // => '<b><script></b>'
-+   *
-+   * // using the "evaluate" delimiter to generate HTML
-+   * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
-+   * _.template(list, { 'people': ['fred', 'barney'] });
-+   * // => '<li>fred</li><li>barney</li>'
-+   *
-+   * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
-+   * _.template('hello ${ name }', { 'name': 'pebbles' });
-+   * // => 'hello pebbles'
-+   *
-+   * // using the internal `print` function in "evaluate" delimiters
-+   * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
-+   * // => 'hello barney!'
-+   *
-+   * // using a custom template delimiters
-+   * _.templateSettings = {
-+   *   'interpolate': /{{([\s\S]+?)}}/g
-+   * };
-+   *
-+   * _.template('hello {{ name }}!', { 'name': 'mustache' });
-+   * // => 'hello mustache!'
-+   *
-+   * // using the `imports` option to import jQuery
-+   * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
-+   * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
-+   * // => '<li>fred</li><li>barney</li>'
-+   *
-+   * // using the `sourceURL` option to specify a custom sourceURL for the template
-+   * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
-+   * compiled(data);
-+   * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
-+   *
-+   * // using the `variable` option to ensure a with-statement isn't used in the compiled template
-+   * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
-+   * compiled.source;
-+   * // => function(data) {
-+   *   var __t, __p = '', __e = _.escape;
-+   *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
-+   *   return __p;
-+   * }
-+   *
-+   * // using the `source` property to inline compiled templates for meaningful
-+   * // line numbers in error messages and a stack trace
-+   * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
-+   *   var JST = {\
-+   *     "main": ' + _.template(mainText).source + '\
-+   *   };\
-+   * ');
-+   */
-+  function template(text, data, options) {
-+    var _ = lodash,
-+        settings = _.templateSettings;
-+
-+    text = String(text || '');
-+    options = defaults({}, options, settings);
-+
-+    var index = 0,
-+        source = "__p += '",
-+        variable = options.variable;
-+
-+    var reDelimiters = RegExp(
-+      (options.escape || reNoMatch).source + '|' +
-+      (options.interpolate || reNoMatch).source + '|' +
-+      (options.evaluate || reNoMatch).source + '|$'
-+    , 'g');
-+
-+    text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {
-+      source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
-+      if (escapeValue) {
-+        source += "' +\n_.escape(" + escapeValue + ") +\n'";
-+      }
-+      if (evaluateValue) {
-+        source += "';\n" + evaluateValue + ";\n__p += '";
-+      }
-+      if (interpolateValue) {
-+        source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
-+      }
-+      index = offset + match.length;
-+      return match;
-+    });
-+
-+    source += "';\n";
-+    if (!variable) {
-+      variable = 'obj';
-+      source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n';
-+    }
-+    source = 'function(' + variable + ') {\n' +
-+      "var __t, __p = '', __j = Array.prototype.join;\n" +
-+      "function print() { __p += __j.call(arguments, '') }\n" +
-+      source +
-+      'return __p\n}';
-+
-+    try {
-+      var result = Function('_', 'return ' + source)(_);
-+    } catch(e) {
-+      e.source = source;
-+      throw e;
-+    }
-+    if (data) {
-+      return result(data);
-+    }
-+    result.source = source;
-+    return result;
-+  }
-+
-+  /**
-+   * Executes the callback `n` times, returning an array of the results
-+   * of each callback execution. The callback is bound to `thisArg` and invoked
-+   * with one argument; (index).
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {number} n The number of times to execute the callback.
-+   * @param {Function} callback The function called per iteration.
-+   * @param {*} [thisArg] The `this` binding of `callback`.
-+   * @returns {Array} Returns an array of the results of each `callback` execution.
-+   * @example
-+   *
-+   * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
-+   * // => [3, 6, 4]
-+   *
-+   * _.times(3, function(n) { mage.castSpell(n); });
-+   * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
-+   *
-+   * _.times(3, function(n) { this.cast(n); }, mage);
-+   * // => also calls `mage.castSpell(n)` three times
-+   */
-+  function times(n, callback, thisArg) {
-+    n = (n = +n) > -1 ? n : 0;
-+    var index = -1,
-+        result = Array(n);
-+
-+    callback = baseCreateCallback(callback, thisArg, 1);
-+    while (++index < n) {
-+      result[index] = callback(index);
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * The inverse of `_.escape` this method converts the HTML entities
-+   * `&`, `<`, `>`, `"`, and `'` in `string` to their
-+   * corresponding characters.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {string} string The string to unescape.
-+   * @returns {string} Returns the unescaped string.
-+   * @example
-+   *
-+   * _.unescape('Fred, Barney & Pebbles');
-+   * // => 'Fred, Barney & Pebbles'
-+   */
-+  function unescape(string) {
-+    return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
-+  }
-+
-+  /**
-+   * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {string} [prefix] The value to prefix the ID with.
-+   * @returns {string} Returns the unique ID.
-+   * @example
-+   *
-+   * _.uniqueId('contact_');
-+   * // => 'contact_104'
-+   *
-+   * _.uniqueId();
-+   * // => '105'
-+   */
-+  function uniqueId(prefix) {
-+    var id = ++idCounter + '';
-+    return prefix ? prefix + id : id;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Creates a `lodash` object that wraps the given value with explicit
-+   * method chaining enabled.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Chaining
-+   * @param {*} value The value to wrap.
-+   * @returns {Object} Returns the wrapper object.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney',  'age': 36 },
-+   *   { 'name': 'fred',    'age': 40 },
-+   *   { 'name': 'pebbles', 'age': 1 }
-+   * ];
-+   *
-+   * var youngest = _.chain(characters)
-+   *     .sortBy('age')
-+   *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
-+   *     .first()
-+   *     .value();
-+   * // => 'pebbles is 1'
-+   */
-+  function chain(value) {
-+    value = new lodashWrapper(value);
-+    value.__chain__ = true;
-+    return value;
-+  }
-+
-+  /**
-+   * Invokes `interceptor` with the `value` as the first argument and then
-+   * returns `value`. The purpose of this method is to "tap into" a method
-+   * chain in order to perform operations on intermediate results within
-+   * the chain.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Chaining
-+   * @param {*} value The value to provide to `interceptor`.
-+   * @param {Function} interceptor The function to invoke.
-+   * @returns {*} Returns `value`.
-+   * @example
-+   *
-+   * _([1, 2, 3, 4])
-+   *  .tap(function(array) { array.pop(); })
-+   *  .reverse()
-+   *  .value();
-+   * // => [3, 2, 1]
-+   */
-+  function tap(value, interceptor) {
-+    interceptor(value);
-+    return value;
-+  }
-+
-+  /**
-+   * Enables explicit method chaining on the wrapper object.
-+   *
-+   * @name chain
-+   * @memberOf _
-+   * @category Chaining
-+   * @returns {*} Returns the wrapper object.
-+   * @example
-+   *
-+   * var characters = [
-+   *   { 'name': 'barney', 'age': 36 },
-+   *   { 'name': 'fred',   'age': 40 }
-+   * ];
-+   *
-+   * // without explicit chaining
-+   * _(characters).first();
-+   * // => { 'name': 'barney', 'age': 36 }
-+   *
-+   * // with explicit chaining
-+   * _(characters).chain()
-+   *   .first()
-+   *   .pick('age')
-+   *   .value();
-+   * // => { 'age': 36 }
-+   */
-+  function wrapperChain() {
-+    this.__chain__ = true;
-+    return this;
-+  }
-+
-+  /**
-+   * Extracts the wrapped value.
-+   *
-+   * @name valueOf
-+   * @memberOf _
-+   * @alias value
-+   * @category Chaining
-+   * @returns {*} Returns the wrapped value.
-+   * @example
-+   *
-+   * _([1, 2, 3]).valueOf();
-+   * // => [1, 2, 3]
-+   */
-+  function wrapperValueOf() {
-+    return this.__wrapped__;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // add functions that return wrapped values when chaining
-+  lodash.after = after;
-+  lodash.bind = bind;
-+  lodash.bindAll = bindAll;
-+  lodash.chain = chain;
-+  lodash.compact = compact;
-+  lodash.compose = compose;
-+  lodash.countBy = countBy;
-+  lodash.debounce = debounce;
-+  lodash.defaults = defaults;
-+  lodash.defer = defer;
-+  lodash.delay = delay;
-+  lodash.difference = difference;
-+  lodash.filter = filter;
-+  lodash.flatten = flatten;
-+  lodash.forEach = forEach;
-+  lodash.functions = functions;
-+  lodash.groupBy = groupBy;
-+  lodash.indexBy = indexBy;
-+  lodash.initial = initial;
-+  lodash.intersection = intersection;
-+  lodash.invert = invert;
-+  lodash.invoke = invoke;
-+  lodash.keys = keys;
-+  lodash.map = map;
-+  lodash.max = max;
-+  lodash.memoize = memoize;
-+  lodash.min = min;
-+  lodash.omit = omit;
-+  lodash.once = once;
-+  lodash.pairs = pairs;
-+  lodash.partial = partial;
-+  lodash.pick = pick;
-+  lodash.pluck = pluck;
-+  lodash.range = range;
-+  lodash.reject = reject;
-+  lodash.rest = rest;
-+  lodash.shuffle = shuffle;
-+  lodash.sortBy = sortBy;
-+  lodash.tap = tap;
-+  lodash.throttle = throttle;
-+  lodash.times = times;
-+  lodash.toArray = toArray;
-+  lodash.union = union;
-+  lodash.uniq = uniq;
-+  lodash.values = values;
-+  lodash.where = where;
-+  lodash.without = without;
-+  lodash.wrap = wrap;
-+  lodash.zip = zip;
-+
-+  // add aliases
-+  lodash.collect = map;
-+  lodash.drop = rest;
-+  lodash.each = forEach;
-+  lodash.extend = assign;
-+  lodash.methods = functions;
-+  lodash.object = zipObject;
-+  lodash.select = filter;
-+  lodash.tail = rest;
-+  lodash.unique = uniq;
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // add functions that return unwrapped values when chaining
-+  lodash.clone = clone;
-+  lodash.contains = contains;
-+  lodash.escape = escape;
-+  lodash.every = every;
-+  lodash.find = find;
-+  lodash.has = has;
-+  lodash.identity = identity;
-+  lodash.indexOf = indexOf;
-+  lodash.isArguments = isArguments;
-+  lodash.isArray = isArray;
-+  lodash.isBoolean = isBoolean;
-+  lodash.isDate = isDate;
-+  lodash.isElement = isElement;
-+  lodash.isEmpty = isEmpty;
-+  lodash.isEqual = isEqual;
-+  lodash.isFinite = isFinite;
-+  lodash.isFunction = isFunction;
-+  lodash.isNaN = isNaN;
-+  lodash.isNull = isNull;
-+  lodash.isNumber = isNumber;
-+  lodash.isObject = isObject;
-+  lodash.isRegExp = isRegExp;
-+  lodash.isString = isString;
-+  lodash.isUndefined = isUndefined;
-+  lodash.lastIndexOf = lastIndexOf;
-+  lodash.mixin = mixin;
-+  lodash.noConflict = noConflict;
-+  lodash.random = random;
-+  lodash.reduce = reduce;
-+  lodash.reduceRight = reduceRight;
-+  lodash.result = result;
-+  lodash.size = size;
-+  lodash.some = some;
-+  lodash.sortedIndex = sortedIndex;
-+  lodash.template = template;
-+  lodash.unescape = unescape;
-+  lodash.uniqueId = uniqueId;
-+
-+  // add aliases
-+  lodash.all = every;
-+  lodash.any = some;
-+  lodash.detect = find;
-+  lodash.findWhere = findWhere;
-+  lodash.foldl = reduce;
-+  lodash.foldr = reduceRight;
-+  lodash.include = contains;
-+  lodash.inject = reduce;
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // add functions capable of returning wrapped and unwrapped values when chaining
-+  lodash.first = first;
-+  lodash.last = last;
-+  lodash.sample = sample;
-+
-+  // add aliases
-+  lodash.take = first;
-+  lodash.head = first;
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // add functions to `lodash.prototype`
-+  mixin(lodash);
-+
-+  /**
-+   * The semantic version number.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @type string
-+   */
-+  lodash.VERSION = '2.4.1';
-+
-+  // add "Chaining" functions to the wrapper
-+  lodash.prototype.chain = wrapperChain;
-+  lodash.prototype.value = wrapperValueOf;
-+
-+    // add `Array` mutator functions to the wrapper
-+    forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        var value = this.__wrapped__;
-+        func.apply(value, arguments);
-+
-+        // avoid array-like object bugs with `Array#shift` and `Array#splice`
-+        // in Firefox < 10 and IE < 9
-+        if (!support.spliceObjects && value.length === 0) {
-+          delete value[0];
-+        }
-+        return this;
-+      };
-+    });
-+
-+    // add `Array` accessor functions to the wrapper
-+    forEach(['concat', 'join', 'slice'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        var value = this.__wrapped__,
-+            result = func.apply(value, arguments);
-+
-+        if (this.__chain__) {
-+          result = new lodashWrapper(result);
-+          result.__chain__ = true;
-+        }
-+        return result;
-+      };
-+    });
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // some AMD build optimizers like r.js check for condition patterns like the following:
-+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
-+    // Expose Lo-Dash to the global object even when an AMD loader is present in
-+    // case Lo-Dash is loaded with a RequireJS shim config.
-+    // See http://requirejs.org/docs/api.html#config-shim
-+    root._ = lodash;
-+
-+    // define as an anonymous module so, through path mapping, it can be
-+    // referenced as the "underscore" module
-+    define(function() {
-+      return lodash;
-+    });
-+  }
-+  // check for `exports` after `define` in case a build optimizer adds an `exports` object
-+  else if (freeExports && freeModule) {
-+    // in Node.js or RingoJS
-+    if (moduleExports) {
-+      (freeModule.exports = lodash)._ = lodash;
-+    }
-+    // in Narwhal or Rhino -require
-+    else {
-+      freeExports._ = lodash;
-+    }
-+  }
-+  else {
-+    // in a browser or Rhino
-+    root._ = lodash;
-+  }
-+}.call(this));
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/dist/lodash.underscore.min.js
-@@ -0,0 +1,39 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
-+ * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
-+ */
-+;(function(){function n(n,r,t){t=(t||0)-1;for(var e=n?n.length:0;++t<e;)if(n[t]===r)return t;return-1}function r(n,r){for(var t=n.m,e=r.m,u=-1,o=t.length;++u<o;){var i=t[u],f=e[u];if(i!==f){if(i>f||typeof i=="undefined")return 1;if(i<f||typeof f=="undefined")return-1}}return n.n-r.n}function t(n){return"\\"+yr[n]}function e(n,r,t){r||(r=0),typeof t=="undefined"&&(t=n?n.length:0);var e=-1;t=t-r||0;for(var u=Array(0>t?0:t);++e<t;)u[e]=n[r+e];return u}function u(n){return n instanceof u?n:new o(n)}function o(n,r){this.__chain__=!!r,this.__wrapped__=n
-+}function i(n){function r(){if(u){var n=e(u);Rr.apply(n,arguments)}if(this instanceof r){var i=f(t.prototype),n=t.apply(i,n||arguments);return O(n)?n:i}return t.apply(o,n||arguments)}var t=n[0],u=n[2],o=n[4];return r}function f(n){return O(n)?Br(n):{}}function a(n,r,t){if(typeof n!="function")return Y;if(typeof r=="undefined"||!("prototype"in n))return n;switch(t){case 1:return function(t){return n.call(r,t)};case 2:return function(t,e){return n.call(r,t,e)};case 3:return function(t,e,u){return n.call(r,t,e,u)
-+};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return L(n,r)}function l(n){function r(){var n=p?a:this;if(o){var y=e(o);Rr.apply(y,arguments)}return(i||g)&&(y||(y=e(arguments)),i&&Rr.apply(y,i),g&&y.length<c)?(u|=16,l([t,h?u:-4&u,y,null,a,c])):(y||(y=arguments),s&&(t=n[v]),this instanceof r?(n=f(t.prototype),y=t.apply(n,y),O(y)?y:n):t.apply(n,y))}var t=n[0],u=n[1],o=n[2],i=n[3],a=n[4],c=n[5],p=1&u,s=2&u,g=4&u,h=8&u,v=t;return r}function c(n,r){for(var t=-1,e=m(),u=n?n.length:0,o=[];++t<u;){var i=n[t];
-+0>e(r,i)&&o.push(i)}return o}function p(n,r,t,e){e=(e||0)-1;for(var u=n?n.length:0,o=[];++e<u;){var i=n[e];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Cr(i)||b(i))){r||(i=p(i,r,t));var f=-1,a=i.length,l=o.length;for(o.length+=a;++f<a;)o[l++]=i[f]}else t||o.push(i)}return o}function s(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(n===n&&!(n&&vr[typeof n]||r&&vr[typeof r]))return false;if(null==n||null==r)return n===r;var o=Er.call(n),i=Er.call(r);if(o!=i)return false;switch(o){case lr:case cr:return+n==+r;
-+case pr:return n!=+n?r!=+r:0==n?1/n==1/r:n==+r;case gr:case hr:return n==r+""}if(i=o==ar,!i){var f=n instanceof u,a=r instanceof u;if(f||a)return s(f?n.__wrapped__:n,a?r.__wrapped__:r,t,e);if(o!=sr)return false;if(o=n.constructor,f=r.constructor,o!=f&&!(A(o)&&o instanceof o&&A(f)&&f instanceof f)&&"constructor"in n&&"constructor"in r)return false}for(t||(t=[]),e||(e=[]),o=t.length;o--;)if(t[o]==n)return e[o]==r;var l=true,c=0;if(t.push(n),e.push(r),i){if(c=r.length,l=c==n.length)for(;c--&&(l=s(n[c],r[c],t,e)););}else Kr(r,function(r,u,o){return Nr.call(o,u)?(c++,!(l=Nr.call(n,u)&&s(n[u],r,t,e))&&er):void 0
-+}),l&&Kr(n,function(n,r,t){return Nr.call(t,r)?!(l=-1<--c)&&er:void 0});return t.pop(),e.pop(),l}function g(n,r,t){for(var e=-1,u=m(),o=n?n.length:0,i=[],f=t?[]:i;++e<o;){var a=n[e],l=t?t(a,e,n):a;(r?!e||f[f.length-1]!==l:0>u(f,l))&&(t&&f.push(l),i.push(a))}return i}function h(n){return function(r,t,e){var u={};t=X(t,e,3),e=-1;var o=r?r.length:0;if(typeof o=="number")for(;++e<o;){var i=r[e];n(u,i,t(i,e,r),r)}else Lr(r,function(r,e,o){n(u,r,t(r,e,o),o)});return u}}function v(n,r,t,e,u,o){var f=16&r,a=32&r;
-+if(!(2&r||A(n)))throw new TypeError;return f&&!t.length&&(r&=-17,t=false),a&&!e.length&&(r&=-33,e=false),(1==r||17===r?i:l)([n,r,t,e,u,o])}function y(n){return Vr[n]}function m(){var r=(r=u.indexOf)===G?n:r;return r}function _(n){return typeof n=="function"&&Ar.test(n)}function d(n){return Gr[n]}function b(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Er.call(n)==fr||false}function w(n){if(!n)return n;for(var r=1,t=arguments.length;r<t;r++){var e=arguments[r];if(e)for(var u in e)n[u]=e[u]}return n
-+}function j(n){if(!n)return n;for(var r=1,t=arguments.length;r<t;r++){var e=arguments[r];if(e)for(var u in e)"undefined"==typeof n[u]&&(n[u]=e[u])}return n}function x(n){var r=[];return Kr(n,function(n,t){A(n)&&r.push(t)}),r.sort()}function T(n){for(var r=-1,t=Ur(n),e=t.length,u={};++r<e;){var o=t[r];u[n[o]]=o}return u}function E(n){if(!n)return true;if(Cr(n)||N(n))return!n.length;for(var r in n)if(Nr.call(n,r))return false;return true}function A(n){return typeof n=="function"}function O(n){return!(!n||!vr[typeof n])
-+}function S(n){return typeof n=="number"||n&&typeof n=="object"&&Er.call(n)==pr||false}function N(n){return typeof n=="string"||n&&typeof n=="object"&&Er.call(n)==hr||false}function R(n){for(var r=-1,t=Ur(n),e=t.length,u=Array(e);++r<e;)u[r]=n[t[r]];return u}function k(n,r){var t=m(),e=n?n.length:0,u=false;return e&&typeof e=="number"?u=-1<t(n,r):Lr(n,function(n){return(u=n===r)&&er}),u}function B(n,r,t){var e=true;r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u&&(e=!!r(n[t],t,n)););else Lr(n,function(n,t,u){return!(e=!!r(n,t,u))&&er
-+});return e}function F(n,r,t){var e=[];r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u;){var o=n[t];r(o,t,n)&&e.push(o)}else Lr(n,function(n,t,u){r(n,t,u)&&e.push(n)});return e}function q(n,r,t){r=X(r,t,3),t=-1;var e=n?n.length:0;if(typeof e!="number"){var u;return Lr(n,function(n,t,e){return r(n,t,e)?(u=n,er):void 0}),u}for(;++t<e;){var o=n[t];if(r(o,t,n))return o}}function D(n,r,t){var e=-1,u=n?n.length:0;if(r=r&&typeof t=="undefined"?r:a(r,t,3),typeof u=="number")for(;++e<u&&r(n[e],e,n)!==er;);else Lr(n,r)
-+}function I(n,r){var t=n?n.length:0;if(typeof t=="number")for(;t--&&false!==r(n[t],t,n););else{var e=Ur(n),t=e.length;Lr(n,function(n,u,o){return u=e?e[--t]:--t,false===r(o[u],u,o)&&er})}}function M(n,r,t){var e=-1,u=n?n.length:0;if(r=X(r,t,3),typeof u=="number")for(var o=Array(u);++e<u;)o[e]=r(n[e],e,n);else o=[],Lr(n,function(n,t,u){o[++e]=r(n,t,u)});return o}function $(n,r,t){var e=-1/0,u=e;typeof r!="function"&&t&&t[r]===n&&(r=null);var o=-1,i=n?n.length:0;if(null==r&&typeof i=="number")for(;++o<i;)t=n[o],t>u&&(u=t);
-+else r=X(r,t,3),D(n,function(n,t,o){t=r(n,t,o),t>e&&(e=t,u=n)});return u}function W(n,r,t,e){if(!n)return t;var u=3>arguments.length;r=X(r,e,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(t=n[++o]);++o<i;)t=r(t,n[o],o,n);else Lr(n,function(n,e,o){t=u?(u=false,n):r(t,n,e,o)});return t}function z(n,r,t,e){var u=3>arguments.length;return r=X(r,e,4),I(n,function(n,e,o){t=u?(u=false,n):r(t,n,e,o)}),t}function C(n){var r=-1,t=n?n.length:0,e=Array(typeof t=="number"?t:0);return D(n,function(n){var t;t=++r,t=0+Sr(Wr()*(t-0+1)),e[r]=e[t],e[t]=n
-+}),e}function P(n,r,t){var e;r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u&&!(e=r(n[t],t,n)););else Lr(n,function(n,t,u){return(e=r(n,t,u))&&er});return!!e}function U(n,r,t){return t&&E(r)?rr:(t?q:F)(n,r)}function V(n,r,t){var u=0,o=n?n.length:0;if(typeof r!="number"&&null!=r){var i=-1;for(r=X(r,t,3);++i<o&&r(n[i],i,n);)u++}else if(u=r,null==u||t)return n?n[0]:rr;return e(n,0,$r(Mr(0,u),o))}function G(r,t,e){if(typeof e=="number"){var u=r?r.length:0;e=0>e?Mr(0,u+e):e||0}else if(e)return e=J(r,t),r[e]===t?e:-1;
-+return n(r,t,e)}function H(n,r,t){if(typeof r!="number"&&null!=r){var u=0,o=-1,i=n?n.length:0;for(r=X(r,t,3);++o<i&&r(n[o],o,n);)u++}else u=null==r||t?1:Mr(0,r);return e(n,u)}function J(n,r,t,e){var u=0,o=n?n.length:u;for(t=t?X(t,e,1):Y,r=t(r);u<o;)e=u+o>>>1,t(n[e])<r?u=e+1:o=e;return u}function K(n,r,t,e){return typeof r!="boolean"&&null!=r&&(e=t,t=typeof r!="function"&&e&&e[r]===n?null:r,r=false),null!=t&&(t=X(t,e,3)),g(n,r,t)}function L(n,r){return 2<arguments.length?v(n,17,e(arguments,2),null,r):v(n,1,null,null,r)
-+}function Q(n,r,t){var e,u,o,i,f,a,l,c=0,p=false,s=true;if(!A(n))throw new TypeError;if(r=Mr(0,r)||0,true===t)var g=true,s=false;else O(t)&&(g=t.leading,p="maxWait"in t&&(Mr(r,t.maxWait)||0),s="trailing"in t?t.trailing:s);var h=function(){var t=r-(nt()-i);0<t?a=setTimeout(h,t):(u&&clearTimeout(u),t=l,u=a=l=rr,t&&(c=nt(),o=n.apply(f,e),a||u||(e=f=null)))},v=function(){a&&clearTimeout(a),u=a=l=rr,(s||p!==r)&&(c=nt(),o=n.apply(f,e),a||u||(e=f=null))};return function(){if(e=arguments,i=nt(),f=this,l=s&&(a||!g),false===p)var t=g&&!a;
-+else{u||g||(c=i);var y=p-(i-c),m=0>=y;m?(u&&(u=clearTimeout(u)),c=i,o=n.apply(f,e)):u||(u=setTimeout(v,y))}return m&&a?a=clearTimeout(a):a||r===p||(a=setTimeout(h,r)),t&&(m=true,o=n.apply(f,e)),!m||a||u||(e=f=null),o}}function X(n,r,t){var e=typeof n;if(null==n||"function"==e)return a(n,r,t);if("object"!=e)return nr(n);var u=Ur(n);return function(r){for(var t=u.length,e=false;t--&&(e=r[u[t]]===n[u[t]]););return e}}function Y(n){return n}function Z(n){D(x(n),function(r){var t=u[r]=n[r];u.prototype[r]=function(){var n=[this.__wrapped__];
-+return Rr.apply(n,arguments),n=t.apply(u,n),this.__chain__?new o(n,true):n}})}function nr(n){return function(r){return r[n]}}var rr,tr=0,er={},ur=+new Date+"",or=/($^)/,ir=/['\n\r\t\u2028\u2029\\]/g,fr="[object Arguments]",ar="[object Array]",lr="[object Boolean]",cr="[object Date]",pr="[object Number]",sr="[object Object]",gr="[object RegExp]",hr="[object String]",vr={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},yr={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},mr=vr[typeof window]&&window||this,_r=vr[typeof exports]&&exports&&!exports.nodeType&&exports,dr=vr[typeof module]&&module&&!module.nodeType&&module,br=dr&&dr.exports===_r&&_r,wr=vr[typeof global]&&global;
-+!wr||wr.global!==wr&&wr.window!==wr||(mr=wr);var jr=[],xr=Object.prototype,Tr=mr._,Er=xr.toString,Ar=RegExp("^"+(Er+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),Or=Math.ceil,Sr=Math.floor,Nr=xr.hasOwnProperty,Rr=jr.push,kr=xr.propertyIsEnumerable,Br=_(Br=Object.create)&&Br,Fr=_(Fr=Array.isArray)&&Fr,qr=mr.isFinite,Dr=mr.isNaN,Ir=_(Ir=Object.keys)&&Ir,Mr=Math.max,$r=Math.min,Wr=Math.random;o.prototype=u.prototype;var zr={};!function(){var n={0:1,length:1};zr.spliceObjects=(jr.splice.call(n,0,1),!n[0])
-+}(1),u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},Br||(f=function(){function n(){}return function(r){if(O(r)){n.prototype=r;var t=new n;n.prototype=null}return t||mr.Object()}}()),b(arguments)||(b=function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Nr.call(n,"callee")&&!kr.call(n,"callee")||false});var Cr=Fr||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Er.call(n)==ar||false},Pr=function(n){var r,t=[];
-+if(!n||!vr[typeof n])return t;for(r in n)Nr.call(n,r)&&t.push(r);return t},Ur=Ir?function(n){return O(n)?Ir(n):[]}:Pr,Vr={"&":"&","<":"<",">":">",'"':""","'":"&#x27;"},Gr=T(Vr),Hr=RegExp("("+Ur(Gr).join("|")+")","g"),Jr=RegExp("["+Ur(Vr).join("")+"]","g"),Kr=function(n,r){var t;if(!n||!vr[typeof n])return n;for(t in n)if(r(n[t],t,n)===er)break;return n},Lr=function(n,r){var t;if(!n||!vr[typeof n])return n;for(t in n)if(Nr.call(n,t)&&r(n[t],t,n)===er)break;return n};A(/x/)&&(A=function(n){return typeof n=="function"&&"[object Function]"==Er.call(n)
-+});var Qr=h(function(n,r,t){Nr.call(n,t)?n[t]++:n[t]=1}),Xr=h(function(n,r,t){(Nr.call(n,t)?n[t]:n[t]=[]).push(r)}),Yr=h(function(n,r,t){n[t]=r}),Zr=M,nt=_(nt=Date.now)&&nt||function(){return(new Date).getTime()};u.after=function(n,r){if(!A(r))throw new TypeError;return function(){return 1>--n?r.apply(this,arguments):void 0}},u.bind=L,u.bindAll=function(n){for(var r=1<arguments.length?p(arguments,true,false,1):x(n),t=-1,e=r.length;++t<e;){var u=r[t];n[u]=v(n[u],1,null,null,n)}return n},u.chain=function(n){return n=new o(n),n.__chain__=true,n
-+},u.compact=function(n){for(var r=-1,t=n?n.length:0,e=[];++r<t;){var u=n[r];u&&e.push(u)}return e},u.compose=function(){for(var n=arguments,r=n.length;r--;)if(!A(n[r]))throw new TypeError;return function(){for(var r=arguments,t=n.length;t--;)r=[n[t].apply(this,r)];return r[0]}},u.countBy=Qr,u.debounce=Q,u.defaults=j,u.defer=function(n){if(!A(n))throw new TypeError;var r=e(arguments,1);return setTimeout(function(){n.apply(rr,r)},1)},u.delay=function(n,r){if(!A(n))throw new TypeError;var t=e(arguments,2);
-+return setTimeout(function(){n.apply(rr,t)},r)},u.difference=function(n){return c(n,p(arguments,true,true,1))},u.filter=F,u.flatten=function(n,r){return p(n,r)},u.forEach=D,u.functions=x,u.groupBy=Xr,u.indexBy=Yr,u.initial=function(n,r,t){var u=0,o=n?n.length:0;if(typeof r!="number"&&null!=r){var i=o;for(r=X(r,t,3);i--&&r(n[i],i,n);)u++}else u=null==r||t?1:r||u;return e(n,0,$r(Mr(0,o-u),o))},u.intersection=function(){for(var n=[],r=-1,t=arguments.length;++r<t;){var e=arguments[r];(Cr(e)||b(e))&&n.push(e)
-+}var u=n[0],o=-1,i=m(),f=u?u.length:0,a=[];n:for(;++o<f;)if(e=u[o],0>i(a,e)){for(r=t;--r;)if(0>i(n[r],e))continue n;a.push(e)}return a},u.invert=T,u.invoke=function(n,r){var t=e(arguments,2),u=-1,o=typeof r=="function",i=n?n.length:0,f=Array(typeof i=="number"?i:0);return D(n,function(n){f[++u]=(o?r:n[r]).apply(n,t)}),f},u.keys=Ur,u.map=M,u.max=$,u.memoize=function(n,r){var t={};return function(){var e=r?r.apply(this,arguments):ur+arguments[0];return Nr.call(t,e)?t[e]:t[e]=n.apply(this,arguments)
-+}},u.min=function(n,r,t){var e=1/0,u=e;typeof r!="function"&&t&&t[r]===n&&(r=null);var o=-1,i=n?n.length:0;if(null==r&&typeof i=="number")for(;++o<i;)t=n[o],t<u&&(u=t);else r=X(r,t,3),D(n,function(n,t,o){t=r(n,t,o),t<e&&(e=t,u=n)});return u},u.omit=function(n){var r=[];Kr(n,function(n,t){r.push(t)});for(var r=c(r,p(arguments,true,false,1)),t=-1,e=r.length,u={};++t<e;){var o=r[t];u[o]=n[o]}return u},u.once=function(n){var r,t;if(!A(n))throw new TypeError;return function(){return r?t:(r=true,t=n.apply(this,arguments),n=null,t)
-+}},u.pairs=function(n){for(var r=-1,t=Ur(n),e=t.length,u=Array(e);++r<e;){var o=t[r];u[r]=[o,n[o]]}return u},u.partial=function(n){return v(n,16,e(arguments,1))},u.pick=function(n){for(var r=-1,t=p(arguments,true,false,1),e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u},u.pluck=Zr,u.range=function(n,r,t){n=+n||0,t=+t||1,null==r&&(r=n,n=0);var e=-1;r=Mr(0,Or((r-n)/t));for(var u=Array(r);++e<r;)u[e]=n,n+=t;return u},u.reject=function(n,r,t){return r=X(r,t,3),F(n,function(n,t,e){return!r(n,t,e)
-+})},u.rest=H,u.shuffle=C,u.sortBy=function(n,t,e){var u=-1,o=n?n.length:0,i=Array(typeof o=="number"?o:0);for(t=X(t,e,3),D(n,function(n,r,e){i[++u]={m:[t(n,r,e)],n:u,o:n}}),o=i.length,i.sort(r);o--;)i[o]=i[o].o;return i},u.tap=function(n,r){return r(n),n},u.throttle=function(n,r,t){var e=true,u=true;if(!A(n))throw new TypeError;return false===t?e=false:O(t)&&(e="leading"in t?t.leading:e,u="trailing"in t?t.trailing:u),t={},t.leading=e,t.maxWait=r,t.trailing=u,Q(n,r,t)},u.times=function(n,r,t){n=-1<(n=+n)?n:0;
-+var e=-1,u=Array(n);for(r=a(r,t,1);++e<n;)u[e]=r(e);return u},u.toArray=function(n){return Cr(n)?e(n):n&&typeof n.length=="number"?M(n):R(n)},u.union=function(){return g(p(arguments,true,true))},u.uniq=K,u.values=R,u.where=U,u.without=function(n){return c(n,e(arguments,1))},u.wrap=function(n,r){return v(r,16,[n])},u.zip=function(){for(var n=-1,r=$(Zr(arguments,"length")),t=Array(0>r?0:r);++n<r;)t[n]=Zr(arguments,n);return t},u.collect=M,u.drop=H,u.each=D,u.extend=w,u.methods=x,u.object=function(n,r){var t=-1,e=n?n.length:0,u={};
-+for(r||!e||Cr(n[0])||(r=[]);++t<e;){var o=n[t];r?u[o]=r[t]:o&&(u[o[0]]=o[1])}return u},u.select=F,u.tail=H,u.unique=K,u.clone=function(n){return O(n)?Cr(n)?e(n):w({},n):n},u.contains=k,u.escape=function(n){return null==n?"":(n+"").replace(Jr,y)},u.every=B,u.find=q,u.has=function(n,r){return n?Nr.call(n,r):false},u.identity=Y,u.indexOf=G,u.isArguments=b,u.isArray=Cr,u.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&Er.call(n)==lr||false},u.isDate=function(n){return n&&typeof n=="object"&&Er.call(n)==cr||false
-+},u.isElement=function(n){return n&&1===n.nodeType||false},u.isEmpty=E,u.isEqual=function(n,r){return s(n,r)},u.isFinite=function(n){return qr(n)&&!Dr(parseFloat(n))},u.isFunction=A,u.isNaN=function(n){return S(n)&&n!=+n},u.isNull=function(n){return null===n},u.isNumber=S,u.isObject=O,u.isRegExp=function(n){return n&&vr[typeof n]&&Er.call(n)==gr||false},u.isString=N,u.isUndefined=function(n){return typeof n=="undefined"},u.lastIndexOf=function(n,r,t){var e=n?n.length:0;for(typeof t=="number"&&(e=(0>t?Mr(0,e+t):$r(t,e-1))+1);e--;)if(n[e]===r)return e;
-+return-1},u.mixin=Z,u.noConflict=function(){return mr._=Tr,this},u.random=function(n,r){return null==n&&null==r&&(r=1),n=+n||0,null==r?(r=n,n=0):r=+r||0,n+Sr(Wr()*(r-n+1))},u.reduce=W,u.reduceRight=z,u.result=function(n,r){if(n){var t=n[r];return A(t)?n[r]():t}},u.size=function(n){var r=n?n.length:0;return typeof r=="number"?r:Ur(n).length},u.some=P,u.sortedIndex=J,u.template=function(n,r,e){var o=u,i=o.templateSettings;n=(n||"")+"",e=j({},e,i);var f=0,a="__p+='",i=e.variable;n.replace(RegExp((e.escape||or).source+"|"+(e.interpolate||or).source+"|"+(e.evaluate||or).source+"|$","g"),function(r,e,u,o,i){return a+=n.slice(f,i).replace(ir,t),e&&(a+="'+_.escape("+e+")+'"),o&&(a+="';"+o+";\n__p+='"),u&&(a+="'+((__t=("+u+"))==null?'':__t)+'"),f=i+r.length,r
-+}),a+="';",i||(i="obj",a="with("+i+"||{}){"+a+"}"),a="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}";try{var l=Function("_","return "+a)(o)}catch(c){throw c.source=a,c}return r?l(r):(l.source=a,l)},u.unescape=function(n){return null==n?"":(n+"").replace(Hr,d)},u.uniqueId=function(n){var r=++tr+"";return n?n+r:r},u.all=B,u.any=P,u.detect=q,u.findWhere=function(n,r){return U(n,r,true)},u.foldl=W,u.foldr=z,u.include=k,u.inject=W,u.first=V,u.last=function(n,r,t){var u=0,o=n?n.length:0;
-+if(typeof r!="number"&&null!=r){var i=o;for(r=X(r,t,3);i--&&r(n[i],i,n);)u++}else if(u=r,null==u||t)return n?n[o-1]:rr;return e(n,Mr(0,o-u))},u.sample=function(n,r,t){return n&&typeof n.length!="number"&&(n=R(n)),null==r||t?n?n[0+Sr(Wr()*(n.length-1-0+1))]:rr:(n=C(n),n.length=$r(Mr(0,r),n.length),n)},u.take=V,u.head=V,Z(u),u.VERSION="2.4.1",u.prototype.chain=function(){return this.__chain__=true,this},u.prototype.value=function(){return this.__wrapped__},D("pop push reverse shift sort splice unshift".split(" "),function(n){var r=jr[n];
-+u.prototype[n]=function(){var n=this.__wrapped__;return r.apply(n,arguments),zr.spliceObjects||0!==n.length||delete n[0],this}}),D(["concat","join","slice"],function(n){var r=jr[n];u.prototype[n]=function(){var n=r.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new o(n),n.__chain__=true),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(mr._=u, define(function(){return u})):_r&&dr?br?(dr.exports=u)._=u:_r._=u:mr._=u}).call(this);
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/lodash.js
-@@ -0,0 +1,7179 @@
-+/**
-+ * @license
-+ * Lo-Dash 2.4.1 <http://lodash.com/>
-+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
-+ * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
-+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+ * Available under MIT license <http://lodash.com/license>
-+ */
-+;(function() {
-+
-+  /** Used as a safe reference for `undefined` in pre ES5 environments */
-+  var undefined;
-+
-+  /** Used to pool arrays and objects used internally */
-+  var arrayPool = [],
-+      objectPool = [];
-+
-+  /** Used to generate unique IDs */
-+  var idCounter = 0;
-+
-+  /** Used internally to indicate various things */
-+  var indicatorObject = {};
-+
-+  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
-+  var keyPrefix = +new Date + '';
-+
-+  /** Used as the size when optimizations are enabled for large arrays */
-+  var largeArraySize = 75;
-+
-+  /** Used as the max size of the `arrayPool` and `objectPool` */
-+  var maxPoolSize = 40;
-+
-+  /** Used to detect and test whitespace */
-+  var whitespace = (
-+    // whitespace
-+    ' \t\x0B\f\xA0\ufeff' +
-+
-+    // line terminators
-+    '\n\r\u2028\u2029' +
-+
-+    // unicode category "Zs" space separators
-+    '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-+  );
-+
-+  /** Used to match empty string literals in compiled template source */
-+  var reEmptyStringLeading = /\b__p \+= '';/g,
-+      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
-+      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-+
-+  /**
-+   * Used to match ES6 template delimiters
-+   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
-+   */
-+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-+
-+  /** Used to match regexp flags from their coerced string values */
-+  var reFlags = /\w*$/;
-+
-+  /** Used to detected named functions */
-+  var reFuncName = /^\s*function[ \n\r\t]+\w/;
-+
-+  /** Used to match "interpolate" template delimiters */
-+  var reInterpolate = /<%=([\s\S]+?)%>/g;
-+
-+  /** Used to match leading whitespace and zeros to be removed */
-+  var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-+
-+  /** Used to ensure capturing order of template delimiters */
-+  var reNoMatch = /($^)/;
-+
-+  /** Used to detect functions containing a `this` reference */
-+  var reThis = /\bthis\b/;
-+
-+  /** Used to match unescaped characters in compiled string literals */
-+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-+
-+  /** Used to assign default `context` object properties */
-+  var contextProps = [
-+    'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
-+    'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
-+    'parseInt', 'setTimeout'
-+  ];
-+
-+  /** Used to fix the JScript [[DontEnum]] bug */
-+  var shadowedProps = [
-+    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
-+    'toLocaleString', 'toString', 'valueOf'
-+  ];
-+
-+  /** Used to make template sourceURLs easier to identify */
-+  var templateCounter = 0;
-+
-+  /** `Object#toString` result shortcuts */
-+  var argsClass = '[object Arguments]',
-+      arrayClass = '[object Array]',
-+      boolClass = '[object Boolean]',
-+      dateClass = '[object Date]',
-+      errorClass = '[object Error]',
-+      funcClass = '[object Function]',
-+      numberClass = '[object Number]',
-+      objectClass = '[object Object]',
-+      regexpClass = '[object RegExp]',
-+      stringClass = '[object String]';
-+
-+  /** Used to identify object classifications that `_.clone` supports */
-+  var cloneableClasses = {};
-+  cloneableClasses[funcClass] = false;
-+  cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
-+  cloneableClasses[boolClass] = cloneableClasses[dateClass] =
-+  cloneableClasses[numberClass] = cloneableClasses[objectClass] =
-+  cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-+
-+  /** Used as an internal `_.debounce` options object */
-+  var debounceOptions = {
-+    'leading': false,
-+    'maxWait': 0,
-+    'trailing': false
-+  };
-+
-+  /** Used as the property descriptor for `__bindData__` */
-+  var descriptor = {
-+    'configurable': false,
-+    'enumerable': false,
-+    'value': null,
-+    'writable': false
-+  };
-+
-+  /** Used as the data object for `iteratorTemplate` */
-+  var iteratorData = {
-+    'args': '',
-+    'array': null,
-+    'bottom': '',
-+    'firstArg': '',
-+    'init': '',
-+    'keys': null,
-+    'loop': '',
-+    'shadowedProps': null,
-+    'support': null,
-+    'top': '',
-+    'useHas': false
-+  };
-+
-+  /** Used to determine if values are of the language type Object */
-+  var objectTypes = {
-+    'boolean': false,
-+    'function': true,
-+    'object': true,
-+    'number': false,
-+    'string': false,
-+    'undefined': false
-+  };
-+
-+  /** Used to escape characters for inclusion in compiled string literals */
-+  var stringEscapes = {
-+    '\\': '\\',
-+    "'": "'",
-+    '\n': 'n',
-+    '\r': 'r',
-+    '\t': 't',
-+    '\u2028': 'u2028',
-+    '\u2029': 'u2029'
-+  };
-+
-+  /** Used as a reference to the global object */
-+  var root = (objectTypes[typeof window] && window) || this;
-+
-+  /** Detect free variable `exports` */
-+  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-+
-+  /** Detect free variable `module` */
-+  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-+
-+  /** Detect the popular CommonJS extension `module.exports` */
-+  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-+
-+  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
-+  var freeGlobal = objectTypes[typeof global] && global;
-+  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
-+    root = freeGlobal;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * The base implementation of `_.indexOf` without support for binary searches
-+   * or `fromIndex` constraints.
-+   *
-+   * @private
-+   * @param {Array} array The array to search.
-+   * @param {*} value The value to search for.
-+   * @param {number} [fromIndex=0] The index to search from.
-+   * @returns {number} Returns the index of the matched value or `-1`.
-+   */
-+  function baseIndexOf(array, value, fromIndex) {
-+    var index = (fromIndex || 0) - 1,
-+        length = array ? array.length : 0;
-+
-+    while (++index < length) {
-+      if (array[index] === value) {
-+        return index;
-+      }
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * An implementation of `_.contains` for cache objects that mimics the return
-+   * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
-+   *
-+   * @private
-+   * @param {Object} cache The cache object to inspect.
-+   * @param {*} value The value to search for.
-+   * @returns {number} Returns `0` if `value` is found, else `-1`.
-+   */
-+  function cacheIndexOf(cache, value) {
-+    var type = typeof value;
-+    cache = cache.cache;
-+
-+    if (type == 'boolean' || value == null) {
-+      return cache[value] ? 0 : -1;
-+    }
-+    if (type != 'number' && type != 'string') {
-+      type = 'object';
-+    }
-+    var key = type == 'number' ? value : keyPrefix + value;
-+    cache = (cache = cache[type]) && cache[key];
-+
-+    return type == 'object'
-+      ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
-+      : (cache ? 0 : -1);
-+  }
-+
-+  /**
-+   * Adds a given value to the corresponding cache object.
-+   *
-+   * @private
-+   * @param {*} value The value to add to the cache.
-+   */
-+  function cachePush(value) {
-+    var cache = this.cache,
-+        type = typeof value;
-+
-+    if (type == 'boolean' || value == null) {
-+      cache[value] = true;
-+    } else {
-+      if (type != 'number' && type != 'string') {
-+        type = 'object';
-+      }
-+      var key = type == 'number' ? value : keyPrefix + value,
-+          typeCache = cache[type] || (cache[type] = {});
-+
-+      if (type == 'object') {
-+        (typeCache[key] || (typeCache[key] = [])).push(value);
-+      } else {
-+        typeCache[key] = true;
-+      }
-+    }
-+  }
-+
-+  /**
-+   * Used by `_.max` and `_.min` as the default callback when a given
-+   * collection is a string value.
-+   *
-+   * @private
-+   * @param {string} value The character to inspect.
-+   * @returns {number} Returns the code unit of given character.
-+   */
-+  function charAtCallback(value) {
-+    return value.charCodeAt(0);
-+  }
-+
-+  /**
-+   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
-+   * them in ascending order.
-+   *
-+   * @private
-+   * @param {Object} a The object to compare to `b`.
-+   * @param {Object} b The object to compare to `a`.
-+   * @returns {number} Returns the sort order indicator of `1` or `-1`.
-+   */
-+  function compareAscending(a, b) {
-+    var ac = a.criteria,
-+        bc = b.criteria,
-+        index = -1,
-+        length = ac.length;
-+
-+    while (++index < length) {
-+      var value = ac[index],
-+          other = bc[index];
-+
-+      if (value !== other) {
-+        if (value > other || typeof value == 'undefined') {
-+          return 1;
-+        }
-+        if (value < other || typeof other == 'undefined') {
-+          return -1;
-+        }
-+      }
-+    }
-+    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-+    // that causes it, under certain circumstances, to return the same value for
-+    // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
-+    //
-+    // This also ensures a stable sort in V8 and other engines.
-+    // See http://code.google.com/p/v8/issues/detail?id=90
-+    return a.index - b.index;
-+  }
-+
-+  /**
-+   * Creates a cache object to optimize linear searches of large arrays.
-+   *
-+   * @private
-+   * @param {Array} [array=[]] The array to search.
-+   * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
-+   */
-+  function createCache(array) {
-+    var index = -1,
-+        length = array.length,
-+        first = array[0],
-+        mid = array[(length / 2) | 0],
-+        last = array[length - 1];
-+
-+    if (first && typeof first == 'object' &&
-+        mid && typeof mid == 'object' && last && typeof last == 'object') {
-+      return false;
-+    }
-+    var cache = getObject();
-+    cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-+
-+    var result = getObject();
-+    result.array = array;
-+    result.cache = cache;
-+    result.push = cachePush;
-+
-+    while (++index < length) {
-+      result.push(array[index]);
-+    }
-+    return result;
-+  }
-+
-+  /**
-+   * Used by `template` to escape characters for inclusion in compiled
-+   * string literals.
-+   *
-+   * @private
-+   * @param {string} match The matched character to escape.
-+   * @returns {string} Returns the escaped character.
-+   */
-+  function escapeStringChar(match) {
-+    return '\\' + stringEscapes[match];
-+  }
-+
-+  /**
-+   * Gets an array from the array pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Array} The array from the pool.
-+   */
-+  function getArray() {
-+    return arrayPool.pop() || [];
-+  }
-+
-+  /**
-+   * Gets an object from the object pool or creates a new one if the pool is empty.
-+   *
-+   * @private
-+   * @returns {Object} The object from the pool.
-+   */
-+  function getObject() {
-+    return objectPool.pop() || {
-+      'array': null,
-+      'cache': null,
-+      'criteria': null,
-+      'false': false,
-+      'index': 0,
-+      'null': false,
-+      'number': null,
-+      'object': null,
-+      'push': null,
-+      'string': null,
-+      'true': false,
-+      'undefined': false,
-+      'value': null
-+    };
-+  }
-+
-+  /**
-+   * Checks if `value` is a DOM node in IE < 9.
-+   *
-+   * @private
-+   * @param {*} value The value to check.
-+   * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
-+   */
-+  function isNode(value) {
-+    // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
-+    // methods that are `typeof` "string" and still can coerce nodes to strings
-+    return typeof value.toString != 'function' && typeof (value + '') == 'string';
-+  }
-+
-+  /**
-+   * Releases the given array back to the array pool.
-+   *
-+   * @private
-+   * @param {Array} [array] The array to release.
-+   */
-+  function releaseArray(array) {
-+    array.length = 0;
-+    if (arrayPool.length < maxPoolSize) {
-+      arrayPool.push(array);
-+    }
-+  }
-+
-+  /**
-+   * Releases the given object back to the object pool.
-+   *
-+   * @private
-+   * @param {Object} [object] The object to release.
-+   */
-+  function releaseObject(object) {
-+    var cache = object.cache;
-+    if (cache) {
-+      releaseObject(cache);
-+    }
-+    object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
-+    if (objectPool.length < maxPoolSize) {
-+      objectPool.push(object);
-+    }
-+  }
-+
-+  /**
-+   * Slices the `collection` from the `start` index up to, but not including,
-+   * the `end` index.
-+   *
-+   * Note: This function is used instead of `Array#slice` to support node lists
-+   * in IE < 9 and to ensure dense arrays are returned.
-+   *
-+   * @private
-+   * @param {Array|Object|string} collection The collection to slice.
-+   * @param {number} start The start index.
-+   * @param {number} end The end index.
-+   * @returns {Array} Returns the new array.
-+   */
-+  function slice(array, start, end) {
-+    start || (start = 0);
-+    if (typeof end == 'undefined') {
-+      end = array ? array.length : 0;
-+    }
-+    var index = -1,
-+        length = end - start || 0,
-+        result = Array(length < 0 ? 0 : length);
-+
-+    while (++index < length) {
-+      result[index] = array[start + index];
-+    }
-+    return result;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  /**
-+   * Create a new `lodash` function using the given context object.
-+   *
-+   * @static
-+   * @memberOf _
-+   * @category Utilities
-+   * @param {Object} [context=root] The context object.
-+   * @returns {Function} Returns the `lodash` function.
-+   */
-+  function runInContext(context) {
-+    // Avoid issues with some ES3 environments that attempt to use values, named
-+    // after built-in constructors like `Object`, for the creation of literals.
-+    // ES5 clears this up by stating that literals must use built-in constructors.
-+    // See http://es5.github.io/#x11.1.5.
-+    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-+
-+    /** Native constructor references */
-+    var Array = context.Array,
-+        Boolean = context.Boolean,
-+        Date = context.Date,
-+        Error = context.Error,
-+        Function = context.Function,
-+        Math = context.Math,
-+        Number = context.Number,
-+        Object = context.Object,
-+        RegExp = context.RegExp,
-+        String = context.String,
-+        TypeError = context.TypeError;
-+
-+    /**
-+     * Used for `Array` method references.
-+     *
-+     * Normally `Array.prototype` would suffice, however, using an array literal
-+     * avoids issues in Narwhal.
-+     */
-+    var arrayRef = [];
-+
-+    /** Used for native method references */
-+    var errorProto = Error.prototype,
-+        objectProto = Object.prototype,
-+        stringProto = String.prototype;
-+
-+    /** Used to restore the original `_` reference in `noConflict` */
-+    var oldDash = context._;
-+
-+    /** Used to resolve the internal [[Class]] of values */
-+    var toString = objectProto.toString;
-+
-+    /** Used to detect if a method is native */
-+    var reNative = RegExp('^' +
-+      String(toString)
-+        .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-+        .replace(/toString| for [^\]]+/g, '.*?') + '$'
-+    );
-+
-+    /** Native method shortcuts */
-+    var ceil = Math.ceil,
-+        clearTimeout = context.clearTimeout,
-+        floor = Math.floor,
-+        fnToString = Function.prototype.toString,
-+        getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
-+        hasOwnProperty = objectProto.hasOwnProperty,
-+        push = arrayRef.push,
-+        propertyIsEnumerable = objectProto.propertyIsEnumerable,
-+        setTimeout = context.setTimeout,
-+        splice = arrayRef.splice,
-+        unshift = arrayRef.unshift;
-+
-+    /** Used to set meta data on functions */
-+    var defineProperty = (function() {
-+      // IE 8 only accepts DOM elements
-+      try {
-+        var o = {},
-+            func = isNative(func = Object.defineProperty) && func,
-+            result = func(o, o, o) && func;
-+      } catch(e) { }
-+      return result;
-+    }());
-+
-+    /* Native method shortcuts for methods with the same name as other `lodash` methods */
-+    var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
-+        nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
-+        nativeIsFinite = context.isFinite,
-+        nativeIsNaN = context.isNaN,
-+        nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
-+        nativeMax = Math.max,
-+        nativeMin = Math.min,
-+        nativeParseInt = context.parseInt,
-+        nativeRandom = Math.random;
-+
-+    /** Used to lookup a built-in constructor by [[Class]] */
-+    var ctorByClass = {};
-+    ctorByClass[arrayClass] = Array;
-+    ctorByClass[boolClass] = Boolean;
-+    ctorByClass[dateClass] = Date;
-+    ctorByClass[funcClass] = Function;
-+    ctorByClass[objectClass] = Object;
-+    ctorByClass[numberClass] = Number;
-+    ctorByClass[regexpClass] = RegExp;
-+    ctorByClass[stringClass] = String;
-+
-+    /** Used to avoid iterating non-enumerable properties in IE < 9 */
-+    var nonEnumProps = {};
-+    nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
-+    nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
-+    nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
-+    nonEnumProps[objectClass] = { 'constructor': true };
-+
-+    (function() {
-+      var length = shadowedProps.length;
-+      while (length--) {
-+        var key = shadowedProps[length];
-+        for (var className in nonEnumProps) {
-+          if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
-+            nonEnumProps[className][key] = false;
-+          }
-+        }
-+      }
-+    }());
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object which wraps the given value to enable intuitive
-+     * method chaining.
-+     *
-+     * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
-+     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
-+     * and `unshift`
-+     *
-+     * Chaining is supported in custom builds as long as the `value` method is
-+     * implicitly or explicitly included in the build.
-+     *
-+     * The chainable wrapper functions are:
-+     * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
-+     * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
-+     * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
-+     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
-+     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
-+     * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
-+     * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
-+     * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
-+     * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
-+     * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
-+     * and `zip`
-+     *
-+     * The non-chainable wrapper functions are:
-+     * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
-+     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
-+     * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
-+     * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
-+     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
-+     * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
-+     * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
-+     * `template`, `unescape`, `uniqueId`, and `value`
-+     *
-+     * The wrapper functions `first` and `last` return wrapped values when `n` is
-+     * provided, otherwise they return unwrapped values.
-+     *
-+     * Explicit chaining can be enabled by using the `_.chain` method.
-+     *
-+     * @name _
-+     * @constructor
-+     * @category Chaining
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @returns {Object} Returns a `lodash` instance.
-+     * @example
-+     *
-+     * var wrapped = _([1, 2, 3]);
-+     *
-+     * // returns an unwrapped value
-+     * wrapped.reduce(function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * // returns a wrapped value
-+     * var squares = wrapped.map(function(num) {
-+     *   return num * num;
-+     * });
-+     *
-+     * _.isArray(squares);
-+     * // => false
-+     *
-+     * _.isArray(squares.value());
-+     * // => true
-+     */
-+    function lodash(value) {
-+      // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
-+      return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
-+       ? value
-+       : new lodashWrapper(value);
-+    }
-+
-+    /**
-+     * A fast path for creating `lodash` wrapper objects.
-+     *
-+     * @private
-+     * @param {*} value The value to wrap in a `lodash` instance.
-+     * @param {boolean} chainAll A flag to enable chaining for all methods
-+     * @returns {Object} Returns a `lodash` instance.
-+     */
-+    function lodashWrapper(value, chainAll) {
-+      this.__chain__ = !!chainAll;
-+      this.__wrapped__ = value;
-+    }
-+    // ensure `new lodashWrapper` is an instance of `lodash`
-+    lodashWrapper.prototype = lodash.prototype;
-+
-+    /**
-+     * An object used to flag environments features.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    var support = lodash.support = {};
-+
-+    (function() {
-+      var ctor = function() { this.x = 1; },
-+          object = { '0': 1, 'length': 1 },
-+          props = [];
-+
-+      ctor.prototype = { 'valueOf': 1, 'y': 1 };
-+      for (var key in new ctor) { props.push(key); }
-+      for (key in arguments) { }
-+
-+      /**
-+       * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.argsClass = toString.call(arguments) == argsClass;
-+
-+      /**
-+       * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
-+
-+      /**
-+       * Detect if `name` or `message` properties of `Error.prototype` are
-+       * enumerable by default. (IE < 9, Safari < 5.1)
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
-+
-+      /**
-+       * Detect if `prototype` properties are enumerable by default.
-+       *
-+       * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
-+       * (if the prototype or a property on the prototype has been set)
-+       * incorrectly sets a function's `prototype` property [[Enumerable]]
-+       * value to `true`.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
-+
-+      /**
-+       * Detect if functions can be decompiled by `Function#toString`
-+       * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-+
-+      /**
-+       * Detect if `Function#name` is supported (all but IE).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.funcNames = typeof Function.name == 'string';
-+
-+      /**
-+       * Detect if `arguments` object indexes are non-enumerable
-+       * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.nonEnumArgs = key != 0;
-+
-+      /**
-+       * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
-+       *
-+       * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
-+       * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.nonEnumShadows = !/valueOf/.test(props);
-+
-+      /**
-+       * Detect if own properties are iterated after inherited properties (all but IE < 9).
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.ownLast = props[0] != 'x';
-+
-+      /**
-+       * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
-+       *
-+       * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
-+       * and `splice()` functions that fail to remove the last element, `value[0]`,
-+       * of array-like objects even though the `length` property is set to `0`.
-+       * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
-+       * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-+
-+      /**
-+       * Detect lack of support for accessing string characters by index.
-+       *
-+       * IE < 8 can't access characters by index and IE 8 can only access
-+       * characters by index on string literals.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
-+
-+      /**
-+       * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
-+       * and that the JS engine errors when attempting to coerce an object to
-+       * a string without a `toString` function.
-+       *
-+       * @memberOf _.support
-+       * @type boolean
-+       */
-+      try {
-+        support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
-+      } catch(e) {
-+        support.nodeClass = true;
-+      }
-+    }(1));
-+
-+    /**
-+     * By default, the template delimiters used by Lo-Dash are similar to those in
-+     * embedded Ruby (ERB). Change the following template settings to use alternative
-+     * delimiters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Object
-+     */
-+    lodash.templateSettings = {
-+
-+      /**
-+       * Used to detect `data` property values to be HTML-escaped.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'escape': /<%-([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect code to be evaluated.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'evaluate': /<%([\s\S]+?)%>/g,
-+
-+      /**
-+       * Used to detect `data` property values to inject.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type RegExp
-+       */
-+      'interpolate': reInterpolate,
-+
-+      /**
-+       * Used to reference the data object in the template text.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type string
-+       */
-+      'variable': '',
-+
-+      /**
-+       * Used to import variables into the compiled template.
-+       *
-+       * @memberOf _.templateSettings
-+       * @type Object
-+       */
-+      'imports': {
-+
-+        /**
-+         * A reference to the `lodash` function.
-+         *
-+         * @memberOf _.templateSettings.imports
-+         * @type Function
-+         */
-+        '_': lodash
-+      }
-+    };
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The template used to create iterator functions.
-+     *
-+     * @private
-+     * @param {Object} data The data object used to populate the text.
-+     * @returns {string} Returns the interpolated text.
-+     */
-+    var iteratorTemplate = template(
-+      // the `iterable` may be reassigned by the `top` snippet
-+      'var index, iterable = <%= firstArg %>, ' +
-+      // assign the `result` variable an initial value
-+      'result = <%= init %>;\n' +
-+      // exit early if the first argument is falsey
-+      'if (!iterable) return result;\n' +
-+      // add code before the iteration branches
-+      '<%= top %>;' +
-+
-+      // array-like iteration:
-+      '<% if (array) { %>\n' +
-+      'var length = iterable.length; index = -1;\n' +
-+      'if (<%= array %>) {' +
-+
-+      // add support for accessing string characters by index if needed
-+      '  <% if (support.unindexedChars) { %>\n' +
-+      '  if (isString(iterable)) {\n' +
-+      "    iterable = iterable.split('')\n" +
-+      '  }' +
-+      '  <% } %>\n' +
-+
-+      // iterate over the array-like value
-+      '  while (++index < length) {\n' +
-+      '    <%= loop %>;\n' +
-+      '  }\n' +
-+      '}\n' +
-+      'else {' +
-+
-+      // object iteration:
-+      // add support for iterating over `arguments` objects if needed
-+      '  <% } else if (support.nonEnumArgs) { %>\n' +
-+      '  var length = iterable.length; index = -1;\n' +
-+      '  if (length && isArguments(iterable)) {\n' +
-+      '    while (++index < length) {\n' +
-+      "      index += '';\n" +
-+      '      <%= loop %>;\n' +
-+      '    }\n' +
-+      '  } else {' +
-+      '  <% } %>' +
-+
-+      // avoid iterating over `prototype` properties in older Firefox, Opera, and Safari
-+      '  <% if (support.enumPrototypes) { %>\n' +
-+      "  var skipProto = typeof iterable == 'function';\n" +
-+      '  <% } %>' +
-+
-+      // avoid iterating over `Error.prototype` properties in older IE and Safari
-+      '  <% if (support.enumErrorProps) { %>\n' +
-+      '  var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n' +
-+      '  <% } %>' +
-+
-+      // define conditions used in the loop
-+      '  <%' +
-+      '    var conditions = [];' +
-+      '    if (support.enumPrototypes) { conditions.push(\'!(skipProto && index == "prototype")\'); }' +
-+      '    if (support.enumErrorProps)  { conditions.push(\'!(skipErrorProps && (index == "message" || index == "name"))\'); }' +
-+      '  %>' +
-+
-+      // iterate own properties using `Object.keys`
-+      '  <% if (useHas && keys) { %>\n' +
-+      '  var ownIndex = -1,\n' +
-+      '      ownProps = objectTypes[typeof iterable] && keys(iterable),\n' +
-+      '      length = ownProps ? ownProps.length : 0;\n\n' +
-+      '  while (++ownIndex < length) {\n' +
-+      '    index = ownProps[ownIndex];\n<%' +
-+      "    if (conditions.length) { %>    if (<%= conditions.join(' && ') %>) {\n  <% } %>" +
-+      '    <%= loop %>;' +
-+      '    <% if (conditions.length) { %>\n    }<% } %>\n' +
-+      '  }' +
-+
-+      // else using a for-in loop
-+      '  <% } else { %>\n' +
-+      '  for (index in iterable) {\n<%' +
-+      '    if (useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); }' +
-+      "    if (conditions.length) { %>    if (<%= conditions.join(' && ') %>) {\n  <% } %>" +
-+      '    <%= loop %>;' +
-+      '    <% if (conditions.length) { %>\n    }<% } %>\n' +
-+      '  }' +
-+
-+      // Because IE < 9 can't set the `[[Enumerable]]` attribute of an
-+      // existing property and the `constructor` property of a prototype
-+      // defaults to non-enumerable, Lo-Dash skips the `constructor`
-+      // property when it infers it's iterating over a `prototype` object.
-+      '    <% if (support.nonEnumShadows) { %>\n\n' +
-+      '  if (iterable !== objectProto) {\n' +
-+      "    var ctor = iterable.constructor,\n" +
-+      '        isProto = iterable === (ctor && ctor.prototype),\n' +
-+      '        className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n' +
-+      '        nonEnum = nonEnumProps[className];\n' +
-+      '      <% for (k = 0; k < 7; k++) { %>\n' +
-+      "    index = '<%= shadowedProps[k] %>';\n" +
-+      '    if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))<%' +
-+      '        if (!useHas) { %> || (!nonEnum[index] && iterable[index] !== objectProto[index])<% }' +
-+      '      %>) {\n' +
-+      '      <%= loop %>;\n' +
-+      '    }' +
-+      '      <% } %>\n' +
-+      '  }' +
-+      '    <% } %>' +
-+      '  <% } %>' +
-+      '  <% if (array || support.nonEnumArgs) { %>\n}<% } %>\n' +
-+
-+      // add code to the bottom of the iteration function
-+      '<%= bottom %>;\n' +
-+      // finally, return the `result`
-+      'return result'
-+    );
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The base implementation of `_.bind` that creates the bound function and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new bound function.
-+     */
-+    function baseBind(bindData) {
-+      var func = bindData[0],
-+          partialArgs = bindData[2],
-+          thisArg = bindData[4];
-+
-+      function bound() {
-+        // `Function#bind` spec
-+        // http://es5.github.io/#x15.3.4.5
-+        if (partialArgs) {
-+          // avoid `arguments` object deoptimizations by using `slice` instead
-+          // of `Array.prototype.slice.call` and not assigning `arguments` to a
-+          // variable as a ternary expression
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        // mimic the constructor's `return` behavior
-+        // http://es5.github.io/#x13.2.2
-+        if (this instanceof bound) {
-+          // ensure `new bound` is an instance of `func`
-+          var thisBinding = baseCreate(func.prototype),
-+              result = func.apply(thisBinding, args || arguments);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisArg, args || arguments);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.clone` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates clones with source counterparts.
-+     * @returns {*} Returns the cloned value.
-+     */
-+    function baseClone(value, isDeep, callback, stackA, stackB) {
-+      if (callback) {
-+        var result = callback(value);
-+        if (typeof result != 'undefined') {
-+          return result;
-+        }
-+      }
-+      // inspect [[Class]]
-+      var isObj = isObject(value);
-+      if (isObj) {
-+        var className = toString.call(value);
-+        if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
-+          return value;
-+        }
-+        var ctor = ctorByClass[className];
-+        switch (className) {
-+          case boolClass:
-+          case dateClass:
-+            return new ctor(+value);
-+
-+          case numberClass:
-+          case stringClass:
-+            return new ctor(value);
-+
-+          case regexpClass:
-+            result = ctor(value.source, reFlags.exec(value));
-+            result.lastIndex = value.lastIndex;
-+            return result;
-+        }
-+      } else {
-+        return value;
-+      }
-+      var isArr = isArray(value);
-+      if (isDeep) {
-+        // check for circular references and return corresponding clone
-+        var initedStack = !stackA;
-+        stackA || (stackA = getArray());
-+        stackB || (stackB = getArray());
-+
-+        var length = stackA.length;
-+        while (length--) {
-+          if (stackA[length] == value) {
-+            return stackB[length];
-+          }
-+        }
-+        result = isArr ? ctor(value.length) : {};
-+      }
-+      else {
-+        result = isArr ? slice(value) : assign({}, value);
-+      }
-+      // add array properties assigned by `RegExp#exec`
-+      if (isArr) {
-+        if (hasOwnProperty.call(value, 'index')) {
-+          result.index = value.index;
-+        }
-+        if (hasOwnProperty.call(value, 'input')) {
-+          result.input = value.input;
-+        }
-+      }
-+      // exit for shallow clone
-+      if (!isDeep) {
-+        return result;
-+      }
-+      // add the source value to the stack of traversed objects
-+      // and associate it with its clone
-+      stackA.push(value);
-+      stackB.push(result);
-+
-+      // recursively populate clone (susceptible to call stack limits)
-+      (isArr ? baseEach : forOwn)(value, function(objValue, key) {
-+        result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
-+      });
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.create` without support for assigning
-+     * properties to the created object.
-+     *
-+     * @private
-+     * @param {Object} prototype The object to inherit from.
-+     * @returns {Object} Returns the new object.
-+     */
-+    function baseCreate(prototype, properties) {
-+      return isObject(prototype) ? nativeCreate(prototype) : {};
-+    }
-+    // fallback for browsers without `Object.create`
-+    if (!nativeCreate) {
-+      baseCreate = (function() {
-+        function Object() {}
-+        return function(prototype) {
-+          if (isObject(prototype)) {
-+            Object.prototype = prototype;
-+            var result = new Object;
-+            Object.prototype = null;
-+          }
-+          return result || context.Object();
-+        };
-+      }());
-+    }
-+
-+    /**
-+     * The base implementation of `_.createCallback` without support for creating
-+     * "_.pluck" or "_.where" style callbacks.
-+     *
-+     * @private
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     */
-+    function baseCreateCallback(func, thisArg, argCount) {
-+      if (typeof func != 'function') {
-+        return identity;
-+      }
-+      // exit early for no `thisArg` or already bound by `Function#bind`
-+      if (typeof thisArg == 'undefined' || !('prototype' in func)) {
-+        return func;
-+      }
-+      var bindData = func.__bindData__;
-+      if (typeof bindData == 'undefined') {
-+        if (support.funcNames) {
-+          bindData = !func.name;
-+        }
-+        bindData = bindData || !support.funcDecomp;
-+        if (!bindData) {
-+          var source = fnToString.call(func);
-+          if (!support.funcNames) {
-+            bindData = !reFuncName.test(source);
-+          }
-+          if (!bindData) {
-+            // checks if `func` references the `this` keyword and stores the result
-+            bindData = reThis.test(source);
-+            setBindData(func, bindData);
-+          }
-+        }
-+      }
-+      // exit early if there are no `this` references or `func` is bound
-+      if (bindData === false || (bindData !== true && bindData[1] & 1)) {
-+        return func;
-+      }
-+      switch (argCount) {
-+        case 1: return function(value) {
-+          return func.call(thisArg, value);
-+        };
-+        case 2: return function(a, b) {
-+          return func.call(thisArg, a, b);
-+        };
-+        case 3: return function(value, index, collection) {
-+          return func.call(thisArg, value, index, collection);
-+        };
-+        case 4: return function(accumulator, value, index, collection) {
-+          return func.call(thisArg, accumulator, value, index, collection);
-+        };
-+      }
-+      return bind(func, thisArg);
-+    }
-+
-+    /**
-+     * The base implementation of `createWrapper` that creates the wrapper and
-+     * sets its meta data.
-+     *
-+     * @private
-+     * @param {Array} bindData The bind data array.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function baseCreateWrapper(bindData) {
-+      var func = bindData[0],
-+          bitmask = bindData[1],
-+          partialArgs = bindData[2],
-+          partialRightArgs = bindData[3],
-+          thisArg = bindData[4],
-+          arity = bindData[5];
-+
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          key = func;
-+
-+      function bound() {
-+        var thisBinding = isBind ? thisArg : this;
-+        if (partialArgs) {
-+          var args = slice(partialArgs);
-+          push.apply(args, arguments);
-+        }
-+        if (partialRightArgs || isCurry) {
-+          args || (args = slice(arguments));
-+          if (partialRightArgs) {
-+            push.apply(args, partialRightArgs);
-+          }
-+          if (isCurry && args.length < arity) {
-+            bitmask |= 16 & ~32;
-+            return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
-+          }
-+        }
-+        args || (args = arguments);
-+        if (isBindKey) {
-+          func = thisBinding[key];
-+        }
-+        if (this instanceof bound) {
-+          thisBinding = baseCreate(func.prototype);
-+          var result = func.apply(thisBinding, args);
-+          return isObject(result) ? result : thisBinding;
-+        }
-+        return func.apply(thisBinding, args);
-+      }
-+      setBindData(bound, bindData);
-+      return bound;
-+    }
-+
-+    /**
-+     * The base implementation of `_.difference` that accepts a single array
-+     * of values to exclude.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {Array} [values] The array of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     */
-+    function baseDifference(array, values) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          isLarge = length >= largeArraySize && indexOf === baseIndexOf,
-+          result = [];
-+
-+      if (isLarge) {
-+        var cache = createCache(values);
-+        if (cache) {
-+          indexOf = cacheIndexOf;
-+          values = cache;
-+        } else {
-+          isLarge = false;
-+        }
-+      }
-+      while (++index < length) {
-+        var value = array[index];
-+        if (indexOf(values, value) < 0) {
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseObject(values);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.flatten` without support for callback
-+     * shorthands or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
-+     * @param {number} [fromIndex=0] The index to start from.
-+     * @returns {Array} Returns a new flattened array.
-+     */
-+    function baseFlatten(array, isShallow, isStrict, fromIndex) {
-+      var index = (fromIndex || 0) - 1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+
-+        if (value && typeof value == 'object' && typeof value.length == 'number'
-+            && (isArray(value) || isArguments(value))) {
-+          // recursively flatten arrays (susceptible to call stack limits)
-+          if (!isShallow) {
-+            value = baseFlatten(value, isShallow, isStrict);
-+          }
-+          var valIndex = -1,
-+              valLength = value.length,
-+              resIndex = result.length;
-+
-+          result.length += valLength;
-+          while (++valIndex < valLength) {
-+            result[resIndex++] = value[valIndex];
-+          }
-+        } else if (!isStrict) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.isEqual`, without support for `thisArg` binding,
-+     * that allows partial "_.where" style comparisons.
-+     *
-+     * @private
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
-+     * @param {Array} [stackA=[]] Tracks traversed `a` objects.
-+     * @param {Array} [stackB=[]] Tracks traversed `b` objects.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     */
-+    function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
-+      // used to indicate that when comparing objects, `a` has at least the properties of `b`
-+      if (callback) {
-+        var result = callback(a, b);
-+        if (typeof result != 'undefined') {
-+          return !!result;
-+        }
-+      }
-+      // exit early for identical values
-+      if (a === b) {
-+        // treat `+0` vs. `-0` as not equal
-+        return a !== 0 || (1 / a == 1 / b);
-+      }
-+      var type = typeof a,
-+          otherType = typeof b;
-+
-+      // exit early for unlike primitive values
-+      if (a === a &&
-+          !(a && objectTypes[type]) &&
-+          !(b && objectTypes[otherType])) {
-+        return false;
-+      }
-+      // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
-+      // http://es5.github.io/#x15.3.4.4
-+      if (a == null || b == null) {
-+        return a === b;
-+      }
-+      // compare [[Class]] names
-+      var className = toString.call(a),
-+          otherClass = toString.call(b);
-+
-+      if (className == argsClass) {
-+        className = objectClass;
-+      }
-+      if (otherClass == argsClass) {
-+        otherClass = objectClass;
-+      }
-+      if (className != otherClass) {
-+        return false;
-+      }
-+      switch (className) {
-+        case boolClass:
-+        case dateClass:
-+          // coerce dates and booleans to numbers, dates to milliseconds and booleans
-+          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
-+          return +a == +b;
-+
-+        case numberClass:
-+          // treat `NaN` vs. `NaN` as equal
-+          return (a != +a)
-+            ? b != +b
-+            // but treat `+0` vs. `-0` as not equal
-+            : (a == 0 ? (1 / a == 1 / b) : a == +b);
-+
-+        case regexpClass:
-+        case stringClass:
-+          // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
-+          // treat string primitives and their corresponding object instances as equal
-+          return a == String(b);
-+      }
-+      var isArr = className == arrayClass;
-+      if (!isArr) {
-+        // unwrap any `lodash` wrapped values
-+        var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
-+            bWrapped = hasOwnProperty.call(b, '__wrapped__');
-+
-+        if (aWrapped || bWrapped) {
-+          return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
-+        }
-+        // exit for functions and DOM nodes
-+        if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
-+          return false;
-+        }
-+        // in older versions of Opera, `arguments` objects have `Array` constructors
-+        var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
-+            ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
-+
-+        // non `Object` object instances with different constructors are not equal
-+        if (ctorA != ctorB &&
-+              !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
-+              ('constructor' in a && 'constructor' in b)
-+            ) {
-+          return false;
-+        }
-+      }
-+      // assume cyclic structures are equal
-+      // the algorithm for detecting cyclic structures is adapted from ES 5.1
-+      // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
-+      var initedStack = !stackA;
-+      stackA || (stackA = getArray());
-+      stackB || (stackB = getArray());
-+
-+      var length = stackA.length;
-+      while (length--) {
-+        if (stackA[length] == a) {
-+          return stackB[length] == b;
-+        }
-+      }
-+      var size = 0;
-+      result = true;
-+
-+      // add `a` and `b` to the stack of traversed objects
-+      stackA.push(a);
-+      stackB.push(b);
-+
-+      // recursively compare objects and arrays (susceptible to call stack limits)
-+      if (isArr) {
-+        // compare lengths to determine if a deep comparison is necessary
-+        length = a.length;
-+        size = b.length;
-+        result = size == length;
-+
-+        if (result || isWhere) {
-+          // deep compare the contents, ignoring non-numeric properties
-+          while (size--) {
-+            var index = length,
-+                value = b[size];
-+
-+            if (isWhere) {
-+              while (index--) {
-+                if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
-+                  break;
-+                }
-+              }
-+            } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
-+              break;
-+            }
-+          }
-+        }
-+      }
-+      else {
-+        // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
-+        // which, in this case, is more costly
-+        forIn(b, function(value, key, b) {
-+          if (hasOwnProperty.call(b, key)) {
-+            // count the number of properties.
-+            size++;
-+            // deep compare each property value.
-+            return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
-+          }
-+        });
-+
-+        if (result && !isWhere) {
-+          // ensure both objects have the same number of properties
-+          forIn(a, function(value, key, a) {
-+            if (hasOwnProperty.call(a, key)) {
-+              // `size` will be `-1` if `a` has more properties than `b`
-+              return (result = --size > -1);
-+            }
-+          });
-+        }
-+      }
-+      stackA.pop();
-+      stackB.pop();
-+
-+      if (initedStack) {
-+        releaseArray(stackA);
-+        releaseArray(stackB);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The base implementation of `_.merge` without argument juggling or support
-+     * for `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Object} object The destination object.
-+     * @param {Object} source The source object.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {Array} [stackA=[]] Tracks traversed source objects.
-+     * @param {Array} [stackB=[]] Associates values with source counterparts.
-+     */
-+    function baseMerge(object, source, callback, stackA, stackB) {
-+      (isArray(source) ? forEach : forOwn)(source, function(source, key) {
-+        var found,
-+            isArr,
-+            result = source,
-+            value = object[key];
-+
-+        if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
-+          // avoid merging previously merged cyclic sources
-+          var stackLength = stackA.length;
-+          while (stackLength--) {
-+            if ((found = stackA[stackLength] == source)) {
-+              value = stackB[stackLength];
-+              break;
-+            }
-+          }
-+          if (!found) {
-+            var isShallow;
-+            if (callback) {
-+              result = callback(value, source);
-+              if ((isShallow = typeof result != 'undefined')) {
-+                value = result;
-+              }
-+            }
-+            if (!isShallow) {
-+              value = isArr
-+                ? (isArray(value) ? value : [])
-+                : (isPlainObject(value) ? value : {});
-+            }
-+            // add `source` and associated `value` to the stack of traversed objects
-+            stackA.push(source);
-+            stackB.push(value);
-+
-+            // recursively merge objects and arrays (susceptible to call stack limits)
-+            if (!isShallow) {
-+              baseMerge(value, source, callback, stackA, stackB);
-+            }
-+          }
-+        }
-+        else {
-+          if (callback) {
-+            result = callback(value, source);
-+            if (typeof result == 'undefined') {
-+              result = source;
-+            }
-+          }
-+          if (typeof result != 'undefined') {
-+            value = result;
-+          }
-+        }
-+        object[key] = value;
-+      });
-+    }
-+
-+    /**
-+     * The base implementation of `_.random` without argument juggling or support
-+     * for returning floating-point numbers.
-+     *
-+     * @private
-+     * @param {number} min The minimum possible value.
-+     * @param {number} max The maximum possible value.
-+     * @returns {number} Returns a random number.
-+     */
-+    function baseRandom(min, max) {
-+      return min + floor(nativeRandom() * (max - min + 1));
-+    }
-+
-+    /**
-+     * The base implementation of `_.uniq` without support for callback shorthands
-+     * or `thisArg` binding.
-+     *
-+     * @private
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function} [callback] The function called per iteration.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     */
-+    function baseUniq(array, isSorted, callback) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
-+          seen = (callback || isLarge) ? getArray() : result;
-+
-+      if (isLarge) {
-+        var cache = createCache(seen);
-+        indexOf = cacheIndexOf;
-+        seen = cache;
-+      }
-+      while (++index < length) {
-+        var value = array[index],
-+            computed = callback ? callback(value, index, array) : value;
-+
-+        if (isSorted
-+              ? !index || seen[seen.length - 1] !== computed
-+              : indexOf(seen, computed) < 0
-+            ) {
-+          if (callback || isLarge) {
-+            seen.push(computed);
-+          }
-+          result.push(value);
-+        }
-+      }
-+      if (isLarge) {
-+        releaseArray(seen.array);
-+        releaseObject(seen);
-+      } else if (callback) {
-+        releaseArray(seen);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a function that aggregates a collection, creating an object composed
-+     * of keys generated from the results of running each element of the collection
-+     * through a callback. The given `setter` function sets the keys and values
-+     * of the composed object.
-+     *
-+     * @private
-+     * @param {Function} setter The setter function.
-+     * @returns {Function} Returns the new aggregator function.
-+     */
-+    function createAggregator(setter) {
-+      return function(collection, callback, thisArg) {
-+        var result = {};
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+
-+        if (isArray(collection)) {
-+          var index = -1,
-+              length = collection.length;
-+
-+          while (++index < length) {
-+            var value = collection[index];
-+            setter(result, value, callback(value, index, collection), collection);
-+          }
-+        } else {
-+          baseEach(collection, function(value, key, collection) {
-+            setter(result, value, callback(value, key, collection), collection);
-+          });
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, either curries or invokes `func`
-+     * with an optional `this` binding and partially applied arguments.
-+     *
-+     * @private
-+     * @param {Function|string} func The function or method name to reference.
-+     * @param {number} bitmask The bitmask of method flags to compose.
-+     *  The bitmask may be composed of the following flags:
-+     *  1 - `_.bind`
-+     *  2 - `_.bindKey`
-+     *  4 - `_.curry`
-+     *  8 - `_.curry` (bound)
-+     *  16 - `_.partial`
-+     *  32 - `_.partialRight`
-+     * @param {Array} [partialArgs] An array of arguments to prepend to those
-+     *  provided to the new function.
-+     * @param {Array} [partialRightArgs] An array of arguments to append to those
-+     *  provided to the new function.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {number} [arity] The arity of `func`.
-+     * @returns {Function} Returns the new function.
-+     */
-+    function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
-+      var isBind = bitmask & 1,
-+          isBindKey = bitmask & 2,
-+          isCurry = bitmask & 4,
-+          isCurryBound = bitmask & 8,
-+          isPartial = bitmask & 16,
-+          isPartialRight = bitmask & 32;
-+
-+      if (!isBindKey && !isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (isPartial && !partialArgs.length) {
-+        bitmask &= ~16;
-+        isPartial = partialArgs = false;
-+      }
-+      if (isPartialRight && !partialRightArgs.length) {
-+        bitmask &= ~32;
-+        isPartialRight = partialRightArgs = false;
-+      }
-+      var bindData = func && func.__bindData__;
-+      if (bindData && bindData !== true) {
-+        // clone `bindData`
-+        bindData = slice(bindData);
-+        if (bindData[2]) {
-+          bindData[2] = slice(bindData[2]);
-+        }
-+        if (bindData[3]) {
-+          bindData[3] = slice(bindData[3]);
-+        }
-+        // set `thisBinding` is not previously bound
-+        if (isBind && !(bindData[1] & 1)) {
-+          bindData[4] = thisArg;
-+        }
-+        // set if previously bound but not currently (subsequent curried functions)
-+        if (!isBind && bindData[1] & 1) {
-+          bitmask |= 8;
-+        }
-+        // set curried arity if not yet set
-+        if (isCurry && !(bindData[1] & 4)) {
-+          bindData[5] = arity;
-+        }
-+        // append partial left arguments
-+        if (isPartial) {
-+          push.apply(bindData[2] || (bindData[2] = []), partialArgs);
-+        }
-+        // append partial right arguments
-+        if (isPartialRight) {
-+          unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
-+        }
-+        // merge flags
-+        bindData[1] |= bitmask;
-+        return createWrapper.apply(null, bindData);
-+      }
-+      // fast path for `_.bind`
-+      var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
-+      return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
-+    }
-+
-+    /**
-+     * Creates compiled iteration functions.
-+     *
-+     * @private
-+     * @param {...Object} [options] The compile options object(s).
-+     * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
-+     * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
-+     * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
-+     * @param {string} [options.args] A comma separated string of iteration function arguments.
-+     * @param {string} [options.top] Code to execute before the iteration branches.
-+     * @param {string} [options.loop] Code to execute in the object loop.
-+     * @param {string} [options.bottom] Code to execute after the iteration branches.
-+     * @returns {Function} Returns the compiled function.
-+     */
-+    function createIterator() {
-+      // data properties
-+      iteratorData.shadowedProps = shadowedProps;
-+      iteratorData.support = support;
-+
-+      // iterator options
-+      iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
-+      iteratorData.init = 'iterable';
-+      iteratorData.useHas = true;
-+
-+      // merge options into a template data object
-+      for (var object, index = 0; object = arguments[index]; index++) {
-+        for (var key in object) {
-+          iteratorData[key] = object[key];
-+        }
-+      }
-+      var args = iteratorData.args;
-+      iteratorData.firstArg = /^[^,]+/.exec(args)[0];
-+
-+      // create the function factory
-+      var factory = Function(
-+          'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
-+          'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
-+          'objectTypes, nonEnumProps, stringClass, stringProto, toString',
-+        'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
-+      );
-+
-+      // return the compiled function
-+      return factory(
-+        baseCreateCallback, errorClass, errorProto, hasOwnProperty,
-+        indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
-+        objectTypes, nonEnumProps, stringClass, stringProto, toString
-+      );
-+    }
-+
-+    /**
-+     * Used by `escape` to convert characters to HTML entities.
-+     *
-+     * @private
-+     * @param {string} match The matched character to escape.
-+     * @returns {string} Returns the escaped character.
-+     */
-+    function escapeHtmlChar(match) {
-+      return htmlEscapes[match];
-+    }
-+
-+    /**
-+     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
-+     * customized, this method returns the custom method, otherwise it returns
-+     * the `baseIndexOf` function.
-+     *
-+     * @private
-+     * @returns {Function} Returns the "indexOf" function.
-+     */
-+    function getIndexOf() {
-+      var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a native function.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
-+     */
-+    function isNative(value) {
-+      return typeof value == 'function' && reNative.test(value);
-+    }
-+
-+    /**
-+     * Sets `this` binding data on a given function.
-+     *
-+     * @private
-+     * @param {Function} func The function to set data on.
-+     * @param {Array} value The data array to set.
-+     */
-+    var setBindData = !defineProperty ? noop : function(func, value) {
-+      descriptor.value = value;
-+      defineProperty(func, '__bindData__', descriptor);
-+    };
-+
-+    /**
-+     * A fallback implementation of `isPlainObject` which checks if a given value
-+     * is an object created by the `Object` constructor, assuming objects created
-+     * by the `Object` constructor have no inherited enumerable properties and that
-+     * there are no `Object.prototype` extensions.
-+     *
-+     * @private
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     */
-+    function shimIsPlainObject(value) {
-+      var ctor,
-+          result;
-+
-+      // avoid non Object objects, `arguments` objects, and DOM elements
-+      if (!(value && toString.call(value) == objectClass) ||
-+          (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
-+          (!support.argsClass && isArguments(value)) ||
-+          (!support.nodeClass && isNode(value))) {
-+        return false;
-+      }
-+      // IE < 9 iterates inherited properties before own properties. If the first
-+      // iterated property is an object's own property then there are no inherited
-+      // enumerable properties.
-+      if (support.ownLast) {
-+        forIn(value, function(value, key, object) {
-+          result = hasOwnProperty.call(object, key);
-+          return false;
-+        });
-+        return result !== false;
-+      }
-+      // In most environments an object's own properties are iterated before
-+      // its inherited properties. If the last iterated property is an object's
-+      // own property then there are no inherited enumerable properties.
-+      forIn(value, function(value, key) {
-+        result = key;
-+      });
-+      return typeof result == 'undefined' || hasOwnProperty.call(value, result);
-+    }
-+
-+    /**
-+     * Used by `unescape` to convert HTML entities to characters.
-+     *
-+     * @private
-+     * @param {string} match The matched character to unescape.
-+     * @returns {string} Returns the unescaped character.
-+     */
-+    function unescapeHtmlChar(match) {
-+      return htmlUnescapes[match];
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Checks if `value` is an `arguments` object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArguments(arguments); })(1, 2, 3);
-+     * // => true
-+     *
-+     * _.isArguments([1, 2, 3]);
-+     * // => false
-+     */
-+    function isArguments(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == argsClass || false;
-+    }
-+    // fallback for browsers that can't detect `arguments` objects by [[Class]]
-+    if (!support.argsClass) {
-+      isArguments = function(value) {
-+        return value && typeof value == 'object' && typeof value.length == 'number' &&
-+          hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
-+      };
-+    }
-+
-+    /**
-+     * Checks if `value` is an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
-+     * @example
-+     *
-+     * (function() { return _.isArray(arguments); })();
-+     * // => false
-+     *
-+     * _.isArray([1, 2, 3]);
-+     * // => true
-+     */
-+    var isArray = nativeIsArray || function(value) {
-+      return value && typeof value == 'object' && typeof value.length == 'number' &&
-+        toString.call(value) == arrayClass || false;
-+    };
-+
-+    /**
-+     * A fallback implementation of `Object.keys` which produces an array of the
-+     * given object's own enumerable property names.
-+     *
-+     * @private
-+     * @type Function
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     */
-+    var shimKeys = createIterator({
-+      'args': 'object',
-+      'init': '[]',
-+      'top': 'if (!(objectTypes[typeof object])) return result',
-+      'loop': 'result.push(index)'
-+    });
-+
-+    /**
-+     * Creates an array composed of the own enumerable property names of an object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names.
-+     * @example
-+     *
-+     * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
-+     */
-+    var keys = !nativeKeys ? shimKeys : function(object) {
-+      if (!isObject(object)) {
-+        return [];
-+      }
-+      if ((support.enumPrototypes && typeof object == 'function') ||
-+          (support.nonEnumArgs && object.length && isArguments(object))) {
-+        return shimKeys(object);
-+      }
-+      return nativeKeys(object);
-+    };
-+
-+    /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
-+    var eachIteratorOptions = {
-+      'args': 'collection, callback, thisArg',
-+      'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
-+      'array': "typeof length == 'number'",
-+      'keys': keys,
-+      'loop': 'if (callback(iterable[index], index, collection) === false) return result'
-+    };
-+
-+    /** Reusable iterator options for `assign` and `defaults` */
-+    var defaultsIteratorOptions = {
-+      'args': 'object, source, guard',
-+      'top':
-+        'var args = arguments,\n' +
-+        '    argsIndex = 0,\n' +
-+        "    argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
-+        'while (++argsIndex < argsLength) {\n' +
-+        '  iterable = args[argsIndex];\n' +
-+        '  if (iterable && objectTypes[typeof iterable]) {',
-+      'keys': keys,
-+      'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
-+      'bottom': '  }\n}'
-+    };
-+
-+    /** Reusable iterator options for `forIn` and `forOwn` */
-+    var forOwnIteratorOptions = {
-+      'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
-+      'array': false
-+    };
-+
-+    /**
-+     * Used to convert characters to HTML entities:
-+     *
-+     * Though the `>` character is escaped for symmetry, characters like `>` and `/`
-+     * don't require escaping in HTML and have no special meaning unless they're part
-+     * of a tag or an unquoted attribute value.
-+     * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
-+     */
-+    var htmlEscapes = {
-+      '&': '&',
-+      '<': '<',
-+      '>': '>',
-+      '"': '"',
-+      "'": '''
-+    };
-+
-+    /** Used to convert HTML entities to characters */
-+    var htmlUnescapes = invert(htmlEscapes);
-+
-+    /** Used to match HTML entities and HTML characters */
-+    var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
-+        reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-+
-+    /**
-+     * A function compiled to iterate `arguments` objects, arrays, objects, and
-+     * strings consistenly across environments, executing the callback for each
-+     * element in the collection. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index|key, collection). Callbacks may exit
-+     * iteration early by explicitly returning `false`.
-+     *
-+     * @private
-+     * @type Function
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     */
-+    var baseEach = createIterator(eachIteratorOptions);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object. Subsequent sources will overwrite property assignments of previous
-+     * sources. If a callback is provided it will be executed to produce the
-+     * assigned values. The callback is bound to `thisArg` and invoked with two
-+     * arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @alias extend
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize assigning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
-+     * // => { 'name': 'fred', 'employer': 'slate' }
-+     *
-+     * var defaults = _.partialRight(_.assign, function(a, b) {
-+     *   return typeof a == 'undefined' ? b : a;
-+     * });
-+     *
-+     * var object = { 'name': 'barney' };
-+     * defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var assign = createIterator(defaultsIteratorOptions, {
-+      'top':
-+        defaultsIteratorOptions.top.replace(';',
-+          ';\n' +
-+          "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
-+          '  var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
-+          "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
-+          '  callback = args[--argsLength];\n' +
-+          '}'
-+        ),
-+      'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
-+    });
-+
-+    /**
-+     * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
-+     * be cloned, otherwise they will be assigned by reference. If a callback
-+     * is provided it will be executed to produce the cloned values. If the
-+     * callback returns `undefined` cloning will be handled by the method instead.
-+     * The callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to clone.
-+     * @param {boolean} [isDeep=false] Specify a deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var shallow = _.clone(characters);
-+     * shallow[0] === characters[0];
-+     * // => true
-+     *
-+     * var deep = _.clone(characters, true);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * _.mixin({
-+     *   'clone': _.partialRight(_.clone, function(value) {
-+     *     return _.isElement(value) ? value.cloneNode(false) : undefined;
-+     *   })
-+     * });
-+     *
-+     * var clone = _.clone(document.body);
-+     * clone.childNodes.length;
-+     * // => 0
-+     */
-+    function clone(value, isDeep, callback, thisArg) {
-+      // allows working with "Collections" methods without using their `index`
-+      // and `collection` arguments for `isDeep` and `callback`
-+      if (typeof isDeep != 'boolean' && isDeep != null) {
-+        thisArg = callback;
-+        callback = isDeep;
-+        isDeep = false;
-+      }
-+      return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates a deep clone of `value`. If a callback is provided it will be
-+     * executed to produce the cloned values. If the callback returns `undefined`
-+     * cloning will be handled by the method instead. The callback is bound to
-+     * `thisArg` and invoked with one argument; (value).
-+     *
-+     * Note: This method is loosely based on the structured clone algorithm. Functions
-+     * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
-+     * objects created by constructors other than `Object` are cloned to plain `Object` objects.
-+     * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to deep clone.
-+     * @param {Function} [callback] The function to customize cloning values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the deep cloned value.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * var deep = _.cloneDeep(characters);
-+     * deep[0] === characters[0];
-+     * // => false
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'node': element
-+     * };
-+     *
-+     * var clone = _.cloneDeep(view, function(value) {
-+     *   return _.isElement(value) ? value.cloneNode(true) : undefined;
-+     * });
-+     *
-+     * clone.node == view.node;
-+     * // => false
-+     */
-+    function cloneDeep(value, callback, thisArg) {
-+      return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
-+    }
-+
-+    /**
-+     * Creates an object that inherits from the given `prototype` object. If a
-+     * `properties` object is provided its own enumerable properties are assigned
-+     * to the created object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} prototype The object to inherit from.
-+     * @param {Object} [properties] The properties to assign to the object.
-+     * @returns {Object} Returns the new object.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * function Circle() {
-+     *   Shape.call(this);
-+     * }
-+     *
-+     * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
-+     *
-+     * var circle = new Circle;
-+     * circle instanceof Circle;
-+     * // => true
-+     *
-+     * circle instanceof Shape;
-+     * // => true
-+     */
-+    function create(prototype, properties) {
-+      var result = baseCreate(prototype);
-+      return properties ? assign(result, properties) : result;
-+    }
-+
-+    /**
-+     * Assigns own enumerable properties of source object(s) to the destination
-+     * object for all destination properties that resolve to `undefined`. Once a
-+     * property is set, additional defaults of the same property will be ignored.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param- {Object} [guard] Allows working with `_.reduce` without using its
-+     *  `key` and `object` arguments as sources.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var object = { 'name': 'barney' };
-+     * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
-+     * // => { 'name': 'barney', 'employer': 'slate' }
-+     */
-+    var defaults = createIterator(defaultsIteratorOptions);
-+
-+    /**
-+     * This method is like `_.findIndex` except that it returns the key of the
-+     * first element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': false },
-+     *   'fred': {    'age': 40, 'blocked': true },
-+     *   'pebbles': { 'age': 1,  'blocked': false }
-+     * };
-+     *
-+     * _.findKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => 'barney' (property order is not guaranteed across environments)
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findKey(characters, { 'age': 1 });
-+     * // => 'pebbles'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findKey(characters, 'blocked');
-+     * // => 'fred'
-+     */
-+    function findKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwn(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * This method is like `_.findKey` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to search.
-+     * @param {Function|Object|string} [callback=identity] The function called per
-+     *  iteration. If a property name or object is provided it will be used to
-+     *  create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = {
-+     *   'barney': {  'age': 36, 'blocked': true },
-+     *   'fred': {    'age': 40, 'blocked': false },
-+     *   'pebbles': { 'age': 1,  'blocked': true }
-+     * };
-+     *
-+     * _.findLastKey(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => returns `pebbles`, assuming `_.findKey` returns `barney`
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastKey(characters, { 'age': 40 });
-+     * // => 'fred'
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastKey(characters, 'blocked');
-+     * // => 'pebbles'
-+     */
-+    function findLastKey(object, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forOwnRight(object, function(value, key, object) {
-+        if (callback(value, key, object)) {
-+          result = key;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over own and inherited enumerable properties of an object,
-+     * executing the callback for each property. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, key, object). Callbacks may exit
-+     * iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forIn(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
-+     */
-+    var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
-+      'useHas': false
-+    });
-+
-+    /**
-+     * This method is like `_.forIn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * Shape.prototype.move = function(x, y) {
-+     *   this.x += x;
-+     *   this.y += y;
-+     * };
-+     *
-+     * _.forInRight(new Shape, function(value, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
-+     */
-+    function forInRight(object, callback, thisArg) {
-+      var pairs = [];
-+
-+      forIn(object, function(value, key) {
-+        pairs.push(key, value);
-+      });
-+
-+      var length = pairs.length;
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(pairs[length--], pairs[length], object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Iterates over own enumerable properties of an object, executing the callback
-+     * for each property. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, key, object). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
-+     */
-+    var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
-+
-+    /**
-+     * This method is like `_.forOwn` except that it iterates over elements
-+     * of a `collection` in the opposite order.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
-+     *   console.log(key);
-+     * });
-+     * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
-+     */
-+    function forOwnRight(object, callback, thisArg) {
-+      var props = keys(object),
-+          length = props.length;
-+
-+      callback = baseCreateCallback(callback, thisArg, 3);
-+      while (length--) {
-+        var key = props[length];
-+        if (callback(object[key], key, object) === false) {
-+          break;
-+        }
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a sorted array of property names of all enumerable properties,
-+     * own and inherited, of `object` that have function values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias methods
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property names that have function values.
-+     * @example
-+     *
-+     * _.functions(_);
-+     * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
-+     */
-+    function functions(object) {
-+      var result = [];
-+      forIn(object, function(value, key) {
-+        if (isFunction(value)) {
-+          result.push(key);
-+        }
-+      });
-+      return result.sort();
-+    }
-+
-+    /**
-+     * Checks if the specified property name exists as a direct property of `object`,
-+     * instead of an inherited property.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to check.
-+     * @returns {boolean} Returns `true` if key is a direct property, else `false`.
-+     * @example
-+     *
-+     * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
-+     * // => true
-+     */
-+    function has(object, key) {
-+      return object ? hasOwnProperty.call(object, key) : false;
-+    }
-+
-+    /**
-+     * Creates an object composed of the inverted keys and values of the given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to invert.
-+     * @returns {Object} Returns the created inverted object.
-+     * @example
-+     *
-+     * _.invert({ 'first': 'fred', 'second': 'barney' });
-+     * // => { 'fred': 'first', 'barney': 'second' }
-+     */
-+    function invert(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = {};
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[object[key]] = key;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if `value` is a boolean value.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
-+     * @example
-+     *
-+     * _.isBoolean(null);
-+     * // => false
-+     */
-+    function isBoolean(value) {
-+      return value === true || value === false ||
-+        value && typeof value == 'object' && toString.call(value) == boolClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a date.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
-+     * @example
-+     *
-+     * _.isDate(new Date);
-+     * // => true
-+     */
-+    function isDate(value) {
-+      return value && typeof value == 'object' && toString.call(value) == dateClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a DOM element.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
-+     * @example
-+     *
-+     * _.isElement(document.body);
-+     * // => true
-+     */
-+    function isElement(value) {
-+      return value && value.nodeType === 1 || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
-+     * length of `0` and objects with no own enumerable properties are considered
-+     * "empty".
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object|string} value The value to inspect.
-+     * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
-+     * @example
-+     *
-+     * _.isEmpty([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isEmpty({});
-+     * // => true
-+     *
-+     * _.isEmpty('');
-+     * // => true
-+     */
-+    function isEmpty(value) {
-+      var result = true;
-+      if (!value) {
-+        return result;
-+      }
-+      var className = toString.call(value),
-+          length = value.length;
-+
-+      if ((className == arrayClass || className == stringClass ||
-+          (support.argsClass ? className == argsClass : isArguments(value))) ||
-+          (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
-+        return !length;
-+      }
-+      forOwn(value, function() {
-+        return (result = false);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Performs a deep comparison between two values to determine if they are
-+     * equivalent to each other. If a callback is provided it will be executed
-+     * to compare values. If the callback returns `undefined` comparisons will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (a, b).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} a The value to compare.
-+     * @param {*} b The other value to compare.
-+     * @param {Function} [callback] The function to customize comparing values.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var copy = { 'name': 'fred' };
-+     *
-+     * object == copy;
-+     * // => false
-+     *
-+     * _.isEqual(object, copy);
-+     * // => true
-+     *
-+     * var words = ['hello', 'goodbye'];
-+     * var otherWords = ['hi', 'goodbye'];
-+     *
-+     * _.isEqual(words, otherWords, function(a, b) {
-+     *   var reGreet = /^(?:hello|hi)$/i,
-+     *       aGreet = _.isString(a) && reGreet.test(a),
-+     *       bGreet = _.isString(b) && reGreet.test(b);
-+     *
-+     *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
-+     * });
-+     * // => true
-+     */
-+    function isEqual(a, b, callback, thisArg) {
-+      return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
-+    }
-+
-+    /**
-+     * Checks if `value` is, or can be coerced to, a finite number.
-+     *
-+     * Note: This is not the same as native `isFinite` which will return true for
-+     * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
-+     * @example
-+     *
-+     * _.isFinite(-101);
-+     * // => true
-+     *
-+     * _.isFinite('10');
-+     * // => true
-+     *
-+     * _.isFinite(true);
-+     * // => false
-+     *
-+     * _.isFinite('');
-+     * // => false
-+     *
-+     * _.isFinite(Infinity);
-+     * // => false
-+     */
-+    function isFinite(value) {
-+      return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
-+    }
-+
-+    /**
-+     * Checks if `value` is a function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
-+     * @example
-+     *
-+     * _.isFunction(_);
-+     * // => true
-+     */
-+    function isFunction(value) {
-+      return typeof value == 'function';
-+    }
-+    // fallback for older versions of Chrome and Safari
-+    if (isFunction(/x/)) {
-+      isFunction = function(value) {
-+        return typeof value == 'function' && toString.call(value) == funcClass;
-+      };
-+    }
-+
-+    /**
-+     * Checks if `value` is the language type of Object.
-+     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
-+     * @example
-+     *
-+     * _.isObject({});
-+     * // => true
-+     *
-+     * _.isObject([1, 2, 3]);
-+     * // => true
-+     *
-+     * _.isObject(1);
-+     * // => false
-+     */
-+    function isObject(value) {
-+      // check if the value is the ECMAScript language type of Object
-+      // http://es5.github.io/#x8
-+      // and avoid a V8 bug
-+      // http://code.google.com/p/v8/issues/detail?id=2291
-+      return !!(value && objectTypes[typeof value]);
-+    }
-+
-+    /**
-+     * Checks if `value` is `NaN`.
-+     *
-+     * Note: This is not the same as native `isNaN` which will return `true` for
-+     * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
-+     * @example
-+     *
-+     * _.isNaN(NaN);
-+     * // => true
-+     *
-+     * _.isNaN(new Number(NaN));
-+     * // => true
-+     *
-+     * isNaN(undefined);
-+     * // => true
-+     *
-+     * _.isNaN(undefined);
-+     * // => false
-+     */
-+    function isNaN(value) {
-+      // `NaN` as a primitive is the only value that is not equal to itself
-+      // (perform the [[Class]] check first to avoid errors with some host objects in IE)
-+      return isNumber(value) && value != +value;
-+    }
-+
-+    /**
-+     * Checks if `value` is `null`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
-+     * @example
-+     *
-+     * _.isNull(null);
-+     * // => true
-+     *
-+     * _.isNull(undefined);
-+     * // => false
-+     */
-+    function isNull(value) {
-+      return value === null;
-+    }
-+
-+    /**
-+     * Checks if `value` is a number.
-+     *
-+     * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
-+     * @example
-+     *
-+     * _.isNumber(8.4 * 5);
-+     * // => true
-+     */
-+    function isNumber(value) {
-+      return typeof value == 'number' ||
-+        value && typeof value == 'object' && toString.call(value) == numberClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is an object created by the `Object` constructor.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-+     * @example
-+     *
-+     * function Shape() {
-+     *   this.x = 0;
-+     *   this.y = 0;
-+     * }
-+     *
-+     * _.isPlainObject(new Shape);
-+     * // => false
-+     *
-+     * _.isPlainObject([1, 2, 3]);
-+     * // => false
-+     *
-+     * _.isPlainObject({ 'x': 0, 'y': 0 });
-+     * // => true
-+     */
-+    var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
-+      if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
-+        return false;
-+      }
-+      var valueOf = value.valueOf,
-+          objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-+
-+      return objProto
-+        ? (value == objProto || getPrototypeOf(value) == objProto)
-+        : shimIsPlainObject(value);
-+    };
-+
-+    /**
-+     * Checks if `value` is a regular expression.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
-+     * @example
-+     *
-+     * _.isRegExp(/fred/);
-+     * // => true
-+     */
-+    function isRegExp(value) {
-+      return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is a string.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
-+     * @example
-+     *
-+     * _.isString('fred');
-+     * // => true
-+     */
-+    function isString(value) {
-+      return typeof value == 'string' ||
-+        value && typeof value == 'object' && toString.call(value) == stringClass || false;
-+    }
-+
-+    /**
-+     * Checks if `value` is `undefined`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {*} value The value to check.
-+     * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
-+     * @example
-+     *
-+     * _.isUndefined(void 0);
-+     * // => true
-+     */
-+    function isUndefined(value) {
-+      return typeof value == 'undefined';
-+    }
-+
-+    /**
-+     * Creates an object with the same keys as `object` and values generated by
-+     * running each own enumerable property of `object` through the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new object with values of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     *
-+     * var characters = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.mapValues(characters, 'age');
-+     * // => { 'fred': 40, 'pebbles': 1 }
-+     */
-+    function mapValues(object, callback, thisArg) {
-+      var result = {};
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      forOwn(object, function(value, key, object) {
-+        result[key] = callback(value, key, object);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Recursively merges own enumerable properties of the source object(s), that
-+     * don't resolve to `undefined` into the destination object. Subsequent sources
-+     * will overwrite property assignments of previous sources. If a callback is
-+     * provided it will be executed to produce the merged values of the destination
-+     * and source properties. If the callback returns `undefined` merging will
-+     * be handled by the method instead. The callback is bound to `thisArg` and
-+     * invoked with two arguments; (objectValue, sourceValue).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The destination object.
-+     * @param {...Object} [source] The source objects.
-+     * @param {Function} [callback] The function to customize merging properties.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the destination object.
-+     * @example
-+     *
-+     * var names = {
-+     *   'characters': [
-+     *     { 'name': 'barney' },
-+     *     { 'name': 'fred' }
-+     *   ]
-+     * };
-+     *
-+     * var ages = {
-+     *   'characters': [
-+     *     { 'age': 36 },
-+     *     { 'age': 40 }
-+     *   ]
-+     * };
-+     *
-+     * _.merge(names, ages);
-+     * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
-+     *
-+     * var food = {
-+     *   'fruits': ['apple'],
-+     *   'vegetables': ['beet']
-+     * };
-+     *
-+     * var otherFood = {
-+     *   'fruits': ['banana'],
-+     *   'vegetables': ['carrot']
-+     * };
-+     *
-+     * _.merge(food, otherFood, function(a, b) {
-+     *   return _.isArray(a) ? a.concat(b) : undefined;
-+     * });
-+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
-+     */
-+    function merge(object) {
-+      var args = arguments,
-+          length = 2;
-+
-+      if (!isObject(object)) {
-+        return object;
-+      }
-+      // allows working with `_.reduce` and `_.reduceRight` without using
-+      // their `index` and `collection` arguments
-+      if (typeof args[2] != 'number') {
-+        length = args.length;
-+      }
-+      if (length > 3 && typeof args[length - 2] == 'function') {
-+        var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
-+      } else if (length > 2 && typeof args[length - 1] == 'function') {
-+        callback = args[--length];
-+      }
-+      var sources = slice(arguments, 1, length),
-+          index = -1,
-+          stackA = getArray(),
-+          stackB = getArray();
-+
-+      while (++index < length) {
-+        baseMerge(object, sources[index], callback, stackA, stackB);
-+      }
-+      releaseArray(stackA);
-+      releaseArray(stackB);
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` excluding the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` omitting the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The properties to omit or the
-+     *  function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object without the omitted properties.
-+     * @example
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
-+     *   return typeof value == 'number';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function omit(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var props = [];
-+        forIn(object, function(value, key) {
-+          props.push(key);
-+        });
-+        props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-+
-+        var index = -1,
-+            length = props.length;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          result[key] = object[key];
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (!callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a two dimensional array of an object's key-value pairs,
-+     * i.e. `[[key1, value1], [key2, value2]]`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns new array of key-value pairs.
-+     * @example
-+     *
-+     * _.pairs({ 'barney': 36, 'fred': 40 });
-+     * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
-+     */
-+    function pairs(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        var key = props[index];
-+        result[index] = [key, object[key]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates a shallow clone of `object` composed of the specified properties.
-+     * Property names may be specified as individual arguments or as arrays of
-+     * property names. If a callback is provided it will be executed for each
-+     * property of `object` picking the properties the callback returns truey
-+     * for. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, key, object).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The source object.
-+     * @param {Function|...string|string[]} [callback] The function called per
-+     *  iteration or property names to pick, specified as individual property
-+     *  names or arrays of property names.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns an object composed of the picked properties.
-+     * @example
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
-+     * // => { 'name': 'fred' }
-+     *
-+     * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
-+     *   return key.charAt(0) != '_';
-+     * });
-+     * // => { 'name': 'fred' }
-+     */
-+    function pick(object, callback, thisArg) {
-+      var result = {};
-+      if (typeof callback != 'function') {
-+        var index = -1,
-+            props = baseFlatten(arguments, true, false, 1),
-+            length = isObject(object) ? props.length : 0;
-+
-+        while (++index < length) {
-+          var key = props[index];
-+          if (key in object) {
-+            result[key] = object[key];
-+          }
-+        }
-+      } else {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        forIn(object, function(value, key, object) {
-+          if (callback(value, key, object)) {
-+            result[key] = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * An alternative to `_.reduce` this method transforms `object` to a new
-+     * `accumulator` object which is the result of running each of its own
-+     * enumerable properties through a callback, with each callback execution
-+     * potentially mutating the `accumulator` object. The callback is bound to
-+     * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
-+     * Callbacks may exit iteration early by explicitly returning `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Array|Object} object The object to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] The custom accumulator value.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
-+     *   num *= num;
-+     *   if (num % 2) {
-+     *     return result.push(num) < 3;
-+     *   }
-+     * });
-+     * // => [1, 9, 25]
-+     *
-+     * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     * });
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function transform(object, callback, accumulator, thisArg) {
-+      var isArr = isArray(object);
-+      if (accumulator == null) {
-+        if (isArr) {
-+          accumulator = [];
-+        } else {
-+          var ctor = object && object.constructor,
-+              proto = ctor && ctor.prototype;
-+
-+          accumulator = baseCreate(proto);
-+        }
-+      }
-+      if (callback) {
-+        callback = lodash.createCallback(callback, thisArg, 4);
-+        (isArr ? baseEach : forOwn)(object, function(value, index, object) {
-+          return callback(accumulator, value, index, object);
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * Creates an array composed of the own enumerable property values of `object`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Objects
-+     * @param {Object} object The object to inspect.
-+     * @returns {Array} Returns an array of property values.
-+     * @example
-+     *
-+     * _.values({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => [1, 2, 3] (property order is not guaranteed across environments)
-+     */
-+    function values(object) {
-+      var index = -1,
-+          props = keys(object),
-+          length = props.length,
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = object[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array of elements from the specified indexes, or keys, of the
-+     * `collection`. Indexes may be specified as individual arguments or as arrays
-+     * of indexes.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
-+     *   to retrieve, specified as individual indexes or arrays of indexes.
-+     * @returns {Array} Returns a new array of elements corresponding to the
-+     *  provided indexes.
-+     * @example
-+     *
-+     * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
-+     * // => ['a', 'c', 'e']
-+     *
-+     * _.at(['fred', 'barney', 'pebbles'], 0, 2);
-+     * // => ['fred', 'pebbles']
-+     */
-+    function at(collection) {
-+      var args = arguments,
-+          index = -1,
-+          props = baseFlatten(args, true, false, 1),
-+          length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
-+          result = Array(length);
-+
-+      if (support.unindexedChars && isString(collection)) {
-+        collection = collection.split('');
-+      }
-+      while(++index < length) {
-+        result[index] = collection[props[index]];
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Checks if a given value is present in a collection using strict equality
-+     * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
-+     * offset from the end of the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias include
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {*} target The value to check for.
-+     * @param {number} [fromIndex=0] The index to search from.
-+     * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
-+     * @example
-+     *
-+     * _.contains([1, 2, 3], 1);
-+     * // => true
-+     *
-+     * _.contains([1, 2, 3], 1, 2);
-+     * // => false
-+     *
-+     * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
-+     * // => true
-+     *
-+     * _.contains('pebbles', 'eb');
-+     * // => true
-+     */
-+    function contains(collection, target, fromIndex) {
-+      var index = -1,
-+          indexOf = getIndexOf(),
-+          length = collection ? collection.length : 0,
-+          result = false;
-+
-+      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
-+      if (isArray(collection)) {
-+        result = indexOf(collection, target, fromIndex) > -1;
-+      } else if (typeof length == 'number') {
-+        result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
-+      } else {
-+        baseEach(collection, function(value) {
-+          if (++index >= fromIndex) {
-+            return !(result = value === target);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of `collection` through the callback. The corresponding value
-+     * of each key is the number of times the key was returned by the callback.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': 1, '6': 2 }
-+     *
-+     * _.countBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': 2, '5': 1 }
-+     */
-+    var countBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
-+    });
-+
-+    /**
-+     * Checks if the given callback returns truey value for **all** elements of
-+     * a collection. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias all
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if all elements passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.every([true, 1, null, 'yes']);
-+     * // => false
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.every(characters, 'age');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.every(characters, { 'age': 36 });
-+     * // => false
-+     */
-+    function every(collection, callback, thisArg) {
-+      var result = true;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if (!(result = !!callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          return (result = !!callback(value, index, collection));
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning an array of all elements
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias select
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that passed the callback check.
-+     * @example
-+     *
-+     * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [2, 4, 6]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.filter(characters, 'blocked');
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.filter(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     */
-+    function filter(collection, callback, thisArg) {
-+      var result = [];
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result.push(value);
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, returning the first element that
-+     * the callback returns truey for. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias detect, findWhere
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.find(characters, function(chr) {
-+     *   return chr.age < 40;
-+     * });
-+     * // => { 'name': 'barney', 'age': 36, 'blocked': false }
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.find(characters, { 'age': 1 });
-+     * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.find(characters, 'blocked');
-+     * // => { 'name': 'fred', 'age': 40, 'blocked': true }
-+     */
-+    function find(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (callback(value, index, collection)) {
-+            return value;
-+          }
-+        }
-+      } else {
-+        var result;
-+        baseEach(collection, function(value, index, collection) {
-+          if (callback(value, index, collection)) {
-+            result = value;
-+            return false;
-+          }
-+        });
-+        return result;
-+      }
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the found element, else `undefined`.
-+     * @example
-+     *
-+     * _.findLast([1, 2, 3, 4], function(num) {
-+     *   return num % 2 == 1;
-+     * });
-+     * // => 3
-+     */
-+    function findLast(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      forEachRight(collection, function(value, index, collection) {
-+        if (callback(value, index, collection)) {
-+          result = value;
-+          return false;
-+        }
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Iterates over elements of a collection, executing the callback for each
-+     * element. The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection). Callbacks may exit iteration early by
-+     * explicitly returning `false`.
-+     *
-+     * Note: As with other "Collections" methods, objects with a `length` property
-+     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
-+     * may be used for object iteration.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias each
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
-+     * // => logs each number and returns '1,2,3'
-+     *
-+     * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
-+     * // => logs each number and returns the object (property order is not guaranteed across environments)
-+     */
-+    function forEach(collection, callback, thisArg) {
-+      if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if (callback(collection[index], index, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, callback, thisArg);
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * This method is like `_.forEach` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias eachRight
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array|Object|string} Returns `collection`.
-+     * @example
-+     *
-+     * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
-+     * // => logs each number from right to left and returns '3,2,1'
-+     */
-+    function forEachRight(collection, callback, thisArg) {
-+      var iterable = collection,
-+          length = collection ? collection.length : 0;
-+
-+      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
-+      if (isArray(collection)) {
-+        while (length--) {
-+          if (callback(collection[length], length, collection) === false) {
-+            break;
-+          }
-+        }
-+      } else {
-+        if (typeof length != 'number') {
-+          var props = keys(collection);
-+          length = props.length;
-+        } else if (support.unindexedChars && isString(collection)) {
-+          iterable = collection.split('');
-+        }
-+        baseEach(collection, function(value, key, collection) {
-+          key = props ? props[--length] : --length;
-+          return callback(iterable[key], key, collection);
-+        });
-+      }
-+      return collection;
-+    }
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of a collection through the callback. The corresponding value
-+     * of each key is an array of the elements responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
-+     * // => { '4': [4.2], '6': [6.1, 6.4] }
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.groupBy(['one', 'two', 'three'], 'length');
-+     * // => { '3': ['one', 'two'], '5': ['three'] }
-+     */
-+    var groupBy = createAggregator(function(result, value, key) {
-+      (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
-+    });
-+
-+    /**
-+     * Creates an object composed of keys generated from the results of running
-+     * each element of the collection through the given callback. The corresponding
-+     * value of each key is the last element responsible for generating the key.
-+     * The callback is bound to `thisArg` and invoked with three arguments;
-+     * (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Object} Returns the composed aggregate object.
-+     * @example
-+     *
-+     * var keys = [
-+     *   { 'dir': 'left', 'code': 97 },
-+     *   { 'dir': 'right', 'code': 100 }
-+     * ];
-+     *
-+     * _.indexBy(keys, 'dir');
-+     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     *
-+     * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
-+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-+     */
-+    var indexBy = createAggregator(function(result, value, key) {
-+      result[key] = value;
-+    });
-+
-+    /**
-+     * Invokes the method named by `methodName` on each element in the `collection`
-+     * returning an array of the results of each invoked method. Additional arguments
-+     * will be provided to each invoked method. If `methodName` is a function it
-+     * will be invoked for, and `this` bound to, each element in the `collection`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|string} methodName The name of the method to invoke or
-+     *  the function invoked per iteration.
-+     * @param {...*} [arg] Arguments to invoke the method with.
-+     * @returns {Array} Returns a new array of the results of each invoked method.
-+     * @example
-+     *
-+     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-+     * // => [[1, 5, 7], [1, 2, 3]]
-+     *
-+     * _.invoke([123, 456], String.prototype.split, '');
-+     * // => [['1', '2', '3'], ['4', '5', '6']]
-+     */
-+    function invoke(collection, methodName) {
-+      var args = slice(arguments, 2),
-+          index = -1,
-+          isFunc = typeof methodName == 'function',
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of values by running each element in the collection
-+     * through the callback. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias collect
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * _.map([1, 2, 3], function(num) { return num * 3; });
-+     * // => [3, 6, 9]
-+     *
-+     * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
-+     * // => [3, 6, 9] (property order is not guaranteed across environments)
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function map(collection, callback, thisArg) {
-+      var index = -1,
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      if (isArray(collection)) {
-+        while (++index < length) {
-+          result[index] = callback(collection[index], index, collection);
-+        }
-+      } else {
-+        baseEach(collection, function(value, key, collection) {
-+          result[++index] = callback(value, key, collection);
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the maximum value of a collection. If the collection is empty or
-+     * falsey `-Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the maximum value.
-+     * @example
-+     *
-+     * _.max([4, 2, 8, 6]);
-+     * // => 8
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.max(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'fred', 'age': 40 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.max(characters, 'age');
-+     * // => { 'name': 'fred', 'age': 40 };
-+     */
-+    function max(collection, callback, thisArg) {
-+      var computed = -Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value > result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        baseEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current > computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the minimum value of a collection. If the collection is empty or
-+     * falsey `Infinity` is returned. If a callback is provided it will be executed
-+     * for each value in the collection to generate the criterion by which the value
-+     * is ranked. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the minimum value.
-+     * @example
-+     *
-+     * _.min([4, 2, 8, 6]);
-+     * // => 2
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.min(characters, function(chr) { return chr.age; });
-+     * // => { 'name': 'barney', 'age': 36 };
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.min(characters, 'age');
-+     * // => { 'name': 'barney', 'age': 36 };
-+     */
-+    function min(collection, callback, thisArg) {
-+      var computed = Infinity,
-+          result = computed;
-+
-+      // allows working with functions like `_.map` without using
-+      // their `index` argument as a callback
-+      if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
-+        callback = null;
-+      }
-+      if (callback == null && isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          var value = collection[index];
-+          if (value < result) {
-+            result = value;
-+          }
-+        }
-+      } else {
-+        callback = (callback == null && isString(collection))
-+          ? charAtCallback
-+          : lodash.createCallback(callback, thisArg, 3);
-+
-+        baseEach(collection, function(value, index, collection) {
-+          var current = callback(value, index, collection);
-+          if (current < computed) {
-+            computed = current;
-+            result = value;
-+          }
-+        });
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Retrieves the value of a specified property from all elements in the collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {string} property The name of the property to pluck.
-+     * @returns {Array} Returns a new array of property values.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * _.pluck(characters, 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    var pluck = map;
-+
-+    /**
-+     * Reduces a collection to a value which is the accumulated result of running
-+     * each element in the collection through the callback, where each successive
-+     * callback execution consumes the return value of the previous execution. If
-+     * `accumulator` is not provided the first element of the collection will be
-+     * used as the initial `accumulator` value. The callback is bound to `thisArg`
-+     * and invoked with four arguments; (accumulator, value, index|key, collection).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldl, inject
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var sum = _.reduce([1, 2, 3], function(sum, num) {
-+     *   return sum + num;
-+     * });
-+     * // => 6
-+     *
-+     * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
-+     *   result[key] = num * 3;
-+     *   return result;
-+     * }, {});
-+     * // => { 'a': 3, 'b': 6, 'c': 9 }
-+     */
-+    function reduce(collection, callback, accumulator, thisArg) {
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        if (noaccum) {
-+          accumulator = collection[++index];
-+        }
-+        while (++index < length) {
-+          accumulator = callback(accumulator, collection[index], index, collection);
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          accumulator = noaccum
-+            ? (noaccum = false, value)
-+            : callback(accumulator, value, index, collection)
-+        });
-+      }
-+      return accumulator;
-+    }
-+
-+    /**
-+     * This method is like `_.reduce` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias foldr
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function} [callback=identity] The function called per iteration.
-+     * @param {*} [accumulator] Initial value of the accumulator.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the accumulated value.
-+     * @example
-+     *
-+     * var list = [[0, 1], [2, 3], [4, 5]];
-+     * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-+     * // => [4, 5, 2, 3, 0, 1]
-+     */
-+    function reduceRight(collection, callback, accumulator, thisArg) {
-+      var noaccum = arguments.length < 3;
-+      callback = lodash.createCallback(callback, thisArg, 4);
-+      forEachRight(collection, function(value, index, collection) {
-+        accumulator = noaccum
-+          ? (noaccum = false, value)
-+          : callback(accumulator, value, index, collection);
-+      });
-+      return accumulator;
-+    }
-+
-+    /**
-+     * The opposite of `_.filter` this method returns the elements of a
-+     * collection that the callback does **not** return truey for.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of elements that failed the callback check.
-+     * @example
-+     *
-+     * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-+     * // => [1, 3, 5]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.reject(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.reject(characters, { 'age': 36 });
-+     * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
-+     */
-+    function reject(collection, callback, thisArg) {
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      return filter(collection, function(value, index, collection) {
-+        return !callback(value, index, collection);
-+      });
-+    }
-+
-+    /**
-+     * Retrieves a random element or `n` random elements from a collection.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to sample.
-+     * @param {number} [n] The number of elements to sample.
-+     * @param- {Object} [guard] Allows working with functions like `_.map`
-+     *  without using their `index` arguments as `n`.
-+     * @returns {Array} Returns the random sample(s) of `collection`.
-+     * @example
-+     *
-+     * _.sample([1, 2, 3, 4]);
-+     * // => 2
-+     *
-+     * _.sample([1, 2, 3, 4], 2);
-+     * // => [3, 1]
-+     */
-+    function sample(collection, n, guard) {
-+      if (collection && typeof collection.length != 'number') {
-+        collection = values(collection);
-+      } else if (support.unindexedChars && isString(collection)) {
-+        collection = collection.split('');
-+      }
-+      if (n == null || guard) {
-+        return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
-+      }
-+      var result = shuffle(collection);
-+      result.length = nativeMin(nativeMax(0, n), result.length);
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array of shuffled values, using a version of the Fisher-Yates
-+     * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to shuffle.
-+     * @returns {Array} Returns a new shuffled collection.
-+     * @example
-+     *
-+     * _.shuffle([1, 2, 3, 4, 5, 6]);
-+     * // => [4, 1, 6, 3, 5, 2]
-+     */
-+    function shuffle(collection) {
-+      var index = -1,
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      forEach(collection, function(value) {
-+        var rand = baseRandom(0, ++index);
-+        result[index] = result[rand];
-+        result[rand] = value;
-+      });
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the size of the `collection` by returning `collection.length` for arrays
-+     * and array-like objects or the number of own enumerable properties for objects.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to inspect.
-+     * @returns {number} Returns `collection.length` or number of own enumerable properties.
-+     * @example
-+     *
-+     * _.size([1, 2]);
-+     * // => 2
-+     *
-+     * _.size({ 'one': 1, 'two': 2, 'three': 3 });
-+     * // => 3
-+     *
-+     * _.size('pebbles');
-+     * // => 7
-+     */
-+    function size(collection) {
-+      var length = collection ? collection.length : 0;
-+      return typeof length == 'number' ? length : keys(collection).length;
-+    }
-+
-+    /**
-+     * Checks if the callback returns a truey value for **any** element of a
-+     * collection. The function returns as soon as it finds a passing value and
-+     * does not iterate over the entire collection. The callback is bound to
-+     * `thisArg` and invoked with three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias any
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {boolean} Returns `true` if any element passed the callback check,
-+     *  else `false`.
-+     * @example
-+     *
-+     * _.some([null, 0, 'yes', false], Boolean);
-+     * // => true
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',   'age': 40, 'blocked': true }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.some(characters, 'blocked');
-+     * // => true
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.some(characters, { 'age': 1 });
-+     * // => false
-+     */
-+    function some(collection, callback, thisArg) {
-+      var result;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+
-+      if (isArray(collection)) {
-+        var index = -1,
-+            length = collection.length;
-+
-+        while (++index < length) {
-+          if ((result = callback(collection[index], index, collection))) {
-+            break;
-+          }
-+        }
-+      } else {
-+        baseEach(collection, function(value, index, collection) {
-+          return !(result = callback(value, index, collection));
-+        });
-+      }
-+      return !!result;
-+    }
-+
-+    /**
-+     * Creates an array of elements, sorted in ascending order by the results of
-+     * running each element in a collection through the callback. This method
-+     * performs a stable sort, that is, it will preserve the original sort order
-+     * of equal elements. The callback is bound to `thisArg` and invoked with
-+     * three arguments; (value, index|key, collection).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an array of property names is provided for `callback` the collection
-+     * will be sorted by each property value.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Array|Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of sorted elements.
-+     * @example
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
-+     * // => [3, 1, 2]
-+     *
-+     * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
-+     * // => [3, 1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'barney',  'age': 26 },
-+     *   { 'name': 'fred',    'age': 30 }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.map(_.sortBy(characters, 'age'), _.values);
-+     * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
-+     *
-+     * // sorting by multiple properties
-+     * _.map(_.sortBy(characters, ['name', 'age']), _.values);
-+     * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
-+     */
-+    function sortBy(collection, callback, thisArg) {
-+      var index = -1,
-+          isArr = isArray(callback),
-+          length = collection ? collection.length : 0,
-+          result = Array(typeof length == 'number' ? length : 0);
-+
-+      if (!isArr) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      forEach(collection, function(value, key, collection) {
-+        var object = result[++index] = getObject();
-+        if (isArr) {
-+          object.criteria = map(callback, function(key) { return value[key]; });
-+        } else {
-+          (object.criteria = getArray())[0] = callback(value, key, collection);
-+        }
-+        object.index = index;
-+        object.value = value;
-+      });
-+
-+      length = result.length;
-+      result.sort(compareAscending);
-+      while (length--) {
-+        var object = result[length];
-+        result[length] = object.value;
-+        if (!isArr) {
-+          releaseArray(object.criteria);
-+        }
-+        releaseObject(object);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Converts the `collection` to an array.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to convert.
-+     * @returns {Array} Returns the new converted array.
-+     * @example
-+     *
-+     * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-+     * // => [2, 3, 4]
-+     */
-+    function toArray(collection) {
-+      if (collection && typeof collection.length == 'number') {
-+        return (support.unindexedChars && isString(collection))
-+          ? collection.split('')
-+          : slice(collection);
-+      }
-+      return values(collection);
-+    }
-+
-+    /**
-+     * Performs a deep comparison of each element in a `collection` to the given
-+     * `properties` object, returning an array of all elements that have equivalent
-+     * property values.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type Function
-+     * @category Collections
-+     * @param {Array|Object|string} collection The collection to iterate over.
-+     * @param {Object} props The object of property values to filter by.
-+     * @returns {Array} Returns a new array of elements that have the given properties.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * _.where(characters, { 'age': 36 });
-+     * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
-+     *
-+     * _.where(characters, { 'pets': ['dino'] });
-+     * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
-+     */
-+    var where = filter;
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates an array with all falsey values removed. The values `false`, `null`,
-+     * `0`, `""`, `undefined`, and `NaN` are all falsey.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to compact.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.compact([0, 1, false, 2, '', 3]);
-+     * // => [1, 2, 3]
-+     */
-+    function compact(array) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      while (++index < length) {
-+        var value = array[index];
-+        if (value) {
-+          result.push(value);
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an array excluding all values of the provided arrays using strict
-+     * equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {...Array} [values] The arrays of values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-+     * // => [1, 3, 4]
-+     */
-+    function difference(array) {
-+      return baseDifference(array, baseFlatten(arguments, true, true, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.find` except that it returns the index of the first
-+     * element that passes the callback check, instead of the element itself.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': false },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': true },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
-+     * ];
-+     *
-+     * _.findIndex(characters, function(chr) {
-+     *   return chr.age < 20;
-+     * });
-+     * // => 2
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findIndex(characters, 'blocked');
-+     * // => 1
-+     */
-+    function findIndex(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0;
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        if (callback(array[index], index, array)) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * This method is like `_.findIndex` except that it iterates over elements
-+     * of a `collection` from right to left.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index of the found element, else `-1`.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36, 'blocked': true },
-+     *   { 'name': 'fred',    'age': 40, 'blocked': false },
-+     *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
-+     * ];
-+     *
-+     * _.findLastIndex(characters, function(chr) {
-+     *   return chr.age > 30;
-+     * });
-+     * // => 1
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.findLastIndex(characters, { 'age': 36 });
-+     * // => 0
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.findLastIndex(characters, 'blocked');
-+     * // => 2
-+     */
-+    function findLastIndex(array, callback, thisArg) {
-+      var length = array ? array.length : 0;
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (length--) {
-+        if (callback(array[length], length, array)) {
-+          return length;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Gets the first element or first `n` elements of an array. If a callback
-+     * is provided elements at the beginning of the array are returned as long
-+     * as the callback returns truey. The callback is bound to `thisArg` and
-+     * invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias head, take
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the first element(s) of `array`.
-+     * @example
-+     *
-+     * _.first([1, 2, 3]);
-+     * // => 1
-+     *
-+     * _.first([1, 2, 3], 2);
-+     * // => [1, 2]
-+     *
-+     * _.first([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [1, 2]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.first(characters, 'blocked');
-+     * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function first(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = -1;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[0] : undefined;
-+        }
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, n), length));
-+    }
-+
-+    /**
-+     * Flattens a nested array (the nesting can be to any depth). If `isShallow`
-+     * is truey, the array will only be flattened a single level. If a callback
-+     * is provided each element of the array is passed through the callback before
-+     * flattening. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to flatten.
-+     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new flattened array.
-+     * @example
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]]);
-+     * // => [1, 2, 3, 4];
-+     *
-+     * _.flatten([1, [2], [3, [[4]]]], true);
-+     * // => [1, 2, 3, [[4]]];
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
-+     *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.flatten(characters, 'pets');
-+     * // => ['hoppy', 'baby puss', 'dino']
-+     */
-+    function flatten(array, isShallow, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isShallow != 'boolean' && isShallow != null) {
-+        thisArg = callback;
-+        callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
-+        isShallow = false;
-+      }
-+      if (callback != null) {
-+        array = map(array, callback, thisArg);
-+      }
-+      return baseFlatten(array, isShallow);
-+    }
-+
-+    /**
-+     * Gets the index at which the first occurrence of `value` is found using
-+     * strict equality for comparisons, i.e. `===`. If the array is already sorted
-+     * providing `true` for `fromIndex` will run a faster binary search.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
-+     *  to perform a binary search on a sorted array.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 1
-+     *
-+     * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 4
-+     *
-+     * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
-+     * // => 2
-+     */
-+    function indexOf(array, value, fromIndex) {
-+      if (typeof fromIndex == 'number') {
-+        var length = array ? array.length : 0;
-+        fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
-+      } else if (fromIndex) {
-+        var index = sortedIndex(array, value);
-+        return array[index] === value ? index : -1;
-+      }
-+      return baseIndexOf(array, value, fromIndex);
-+    }
-+
-+    /**
-+     * Gets all but the last element or last `n` elements of an array. If a
-+     * callback is provided elements at the end of the array are excluded from
-+     * the result as long as the callback returns truey. The callback is bound
-+     * to `thisArg` and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.initial([1, 2, 3]);
-+     * // => [1, 2]
-+     *
-+     * _.initial([1, 2, 3], 2);
-+     * // => [1]
-+     *
-+     * _.initial([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [1]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.initial(characters, 'blocked');
-+     * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
-+     * // => ['barney', 'fred']
-+     */
-+    function initial(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : callback || n;
-+      }
-+      return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
-+    }
-+
-+    /**
-+     * Creates an array of unique values present in all provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of shared values.
-+     * @example
-+     *
-+     * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2]
-+     */
-+    function intersection() {
-+      var args = [],
-+          argsIndex = -1,
-+          argsLength = arguments.length,
-+          caches = getArray(),
-+          indexOf = getIndexOf(),
-+          trustIndexOf = indexOf === baseIndexOf,
-+          seen = getArray();
-+
-+      while (++argsIndex < argsLength) {
-+        var value = arguments[argsIndex];
-+        if (isArray(value) || isArguments(value)) {
-+          args.push(value);
-+          caches.push(trustIndexOf && value.length >= largeArraySize &&
-+            createCache(argsIndex ? args[argsIndex] : seen));
-+        }
-+      }
-+      var array = args[0],
-+          index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      outer:
-+      while (++index < length) {
-+        var cache = caches[0];
-+        value = array[index];
-+
-+        if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
-+          argsIndex = argsLength;
-+          (cache || seen).push(value);
-+          while (--argsIndex) {
-+            cache = caches[argsIndex];
-+            if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
-+              continue outer;
-+            }
-+          }
-+          result.push(value);
-+        }
-+      }
-+      while (argsLength--) {
-+        cache = caches[argsLength];
-+        if (cache) {
-+          releaseObject(cache);
-+        }
-+      }
-+      releaseArray(caches);
-+      releaseArray(seen);
-+      return result;
-+    }
-+
-+    /**
-+     * Gets the last element or last `n` elements of an array. If a callback is
-+     * provided elements at the end of the array are returned as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback] The function called
-+     *  per element or the number of elements to return. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {*} Returns the last element(s) of `array`.
-+     * @example
-+     *
-+     * _.last([1, 2, 3]);
-+     * // => 3
-+     *
-+     * _.last([1, 2, 3], 2);
-+     * // => [2, 3]
-+     *
-+     * _.last([1, 2, 3], function(num) {
-+     *   return num > 1;
-+     * });
-+     * // => [2, 3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.last(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.last(characters, { 'employer': 'na' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function last(array, callback, thisArg) {
-+      var n = 0,
-+          length = array ? array.length : 0;
-+
-+      if (typeof callback != 'number' && callback != null) {
-+        var index = length;
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (index-- && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = callback;
-+        if (n == null || thisArg) {
-+          return array ? array[length - 1] : undefined;
-+        }
-+      }
-+      return slice(array, nativeMax(0, length - n));
-+    }
-+
-+    /**
-+     * Gets the index at which the last occurrence of `value` is found using strict
-+     * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
-+     * as the offset from the end of the collection.
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to search.
-+     * @param {*} value The value to search for.
-+     * @param {number} [fromIndex=array.length-1] The index to search from.
-+     * @returns {number} Returns the index of the matched value or `-1`.
-+     * @example
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-+     * // => 4
-+     *
-+     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
-+     * // => 1
-+     */
-+    function lastIndexOf(array, value, fromIndex) {
-+      var index = array ? array.length : 0;
-+      if (typeof fromIndex == 'number') {
-+        index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
-+      }
-+      while (index--) {
-+        if (array[index] === value) {
-+          return index;
-+        }
-+      }
-+      return -1;
-+    }
-+
-+    /**
-+     * Removes all provided values from the given array using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {...*} [value] The values to remove.
-+     * @returns {Array} Returns `array`.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 1, 2, 3];
-+     * _.pull(array, 2, 3);
-+     * console.log(array);
-+     * // => [1, 1]
-+     */
-+    function pull(array) {
-+      var args = arguments,
-+          argsIndex = 0,
-+          argsLength = args.length,
-+          length = array ? array.length : 0;
-+
-+      while (++argsIndex < argsLength) {
-+        var index = -1,
-+            value = args[argsIndex];
-+        while (++index < length) {
-+          if (array[index] === value) {
-+            splice.call(array, index--, 1);
-+            length--;
-+          }
-+        }
-+      }
-+      return array;
-+    }
-+
-+    /**
-+     * Creates an array of numbers (positive and/or negative) progressing from
-+     * `start` up to but not including `end`. If `start` is less than `stop` a
-+     * zero-length range is created unless a negative `step` is specified.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {number} [start=0] The start of the range.
-+     * @param {number} end The end of the range.
-+     * @param {number} [step=1] The value to increment or decrement by.
-+     * @returns {Array} Returns a new range array.
-+     * @example
-+     *
-+     * _.range(4);
-+     * // => [0, 1, 2, 3]
-+     *
-+     * _.range(1, 5);
-+     * // => [1, 2, 3, 4]
-+     *
-+     * _.range(0, 20, 5);
-+     * // => [0, 5, 10, 15]
-+     *
-+     * _.range(0, -4, -1);
-+     * // => [0, -1, -2, -3]
-+     *
-+     * _.range(1, 4, 0);
-+     * // => [1, 1, 1]
-+     *
-+     * _.range(0);
-+     * // => []
-+     */
-+    function range(start, end, step) {
-+      start = +start || 0;
-+      step = typeof step == 'number' ? step : (+step || 1);
-+
-+      if (end == null) {
-+        end = start;
-+        start = 0;
-+      }
-+      // use `Array(length)` so engines like Chakra and V8 avoid slower modes
-+      // http://youtu.be/XAqIpGU8ZZk#t=17m25s
-+      var index = -1,
-+          length = nativeMax(0, ceil((end - start) / (step || 1))),
-+          result = Array(length);
-+
-+      while (++index < length) {
-+        result[index] = start;
-+        start += step;
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Removes all elements from an array that the callback returns truey for
-+     * and returns an array of removed elements. The callback is bound to `thisArg`
-+     * and invoked with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to modify.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a new array of removed elements.
-+     * @example
-+     *
-+     * var array = [1, 2, 3, 4, 5, 6];
-+     * var evens = _.remove(array, function(num) { return num % 2 == 0; });
-+     *
-+     * console.log(array);
-+     * // => [1, 3, 5]
-+     *
-+     * console.log(evens);
-+     * // => [2, 4, 6]
-+     */
-+    function remove(array, callback, thisArg) {
-+      var index = -1,
-+          length = array ? array.length : 0,
-+          result = [];
-+
-+      callback = lodash.createCallback(callback, thisArg, 3);
-+      while (++index < length) {
-+        var value = array[index];
-+        if (callback(value, index, array)) {
-+          result.push(value);
-+          splice.call(array, index--, 1);
-+          length--;
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The opposite of `_.initial` this method gets all but the first element or
-+     * first `n` elements of an array. If a callback function is provided elements
-+     * at the beginning of the array are excluded from the result as long as the
-+     * callback returns truey. The callback is bound to `thisArg` and invoked
-+     * with three arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias drop, tail
-+     * @category Arrays
-+     * @param {Array} array The array to query.
-+     * @param {Function|Object|number|string} [callback=1] The function called
-+     *  per element or the number of elements to exclude. If a property name or
-+     *  object is provided it will be used to create a "_.pluck" or "_.where"
-+     *  style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a slice of `array`.
-+     * @example
-+     *
-+     * _.rest([1, 2, 3]);
-+     * // => [2, 3]
-+     *
-+     * _.rest([1, 2, 3], 2);
-+     * // => [3]
-+     *
-+     * _.rest([1, 2, 3], function(num) {
-+     *   return num < 3;
-+     * });
-+     * // => [3]
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
-+     *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
-+     *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
-+     * ];
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.pluck(_.rest(characters, 'blocked'), 'name');
-+     * // => ['fred', 'pebbles']
-+     *
-+     * // using "_.where" callback shorthand
-+     * _.rest(characters, { 'employer': 'slate' });
-+     * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
-+     */
-+    function rest(array, callback, thisArg) {
-+      if (typeof callback != 'number' && callback != null) {
-+        var n = 0,
-+            index = -1,
-+            length = array ? array.length : 0;
-+
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+        while (++index < length && callback(array[index], index, array)) {
-+          n++;
-+        }
-+      } else {
-+        n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
-+      }
-+      return slice(array, n);
-+    }
-+
-+    /**
-+     * Uses a binary search to determine the smallest index at which a value
-+     * should be inserted into a given sorted array in order to maintain the sort
-+     * order of the array. If a callback is provided it will be executed for
-+     * `value` and each element of `array` to compute their sort ranking. The
-+     * callback is bound to `thisArg` and invoked with one argument; (value).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to inspect.
-+     * @param {*} value The value to evaluate.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {number} Returns the index at which `value` should be inserted
-+     *  into `array`.
-+     * @example
-+     *
-+     * _.sortedIndex([20, 30, 50], 40);
-+     * // => 2
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
-+     * // => 2
-+     *
-+     * var dict = {
-+     *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
-+     * };
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return dict.wordToNumber[word];
-+     * });
-+     * // => 2
-+     *
-+     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
-+     *   return this.wordToNumber[word];
-+     * }, dict);
-+     * // => 2
-+     */
-+    function sortedIndex(array, value, callback, thisArg) {
-+      var low = 0,
-+          high = array ? array.length : low;
-+
-+      // explicitly reference `identity` for better inlining in Firefox
-+      callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
-+      value = callback(value);
-+
-+      while (low < high) {
-+        var mid = (low + high) >>> 1;
-+        (callback(array[mid]) < value)
-+          ? low = mid + 1
-+          : high = mid;
-+      }
-+      return low;
-+    }
-+
-+    /**
-+     * Creates an array of unique values, in order, of the provided arrays using
-+     * strict equality for comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of combined values.
-+     * @example
-+     *
-+     * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
-+     * // => [1, 2, 3, 5, 4]
-+     */
-+    function union() {
-+      return baseUniq(baseFlatten(arguments, true, true));
-+    }
-+
-+    /**
-+     * Creates a duplicate-value-free version of an array using strict equality
-+     * for comparisons, i.e. `===`. If the array is sorted, providing
-+     * `true` for `isSorted` will use a faster algorithm. If a callback is provided
-+     * each element of `array` is passed through the callback before uniqueness
-+     * is computed. The callback is bound to `thisArg` and invoked with three
-+     * arguments; (value, index, array).
-+     *
-+     * If a property name is provided for `callback` the created "_.pluck" style
-+     * callback will return the property value of the given element.
-+     *
-+     * If an object is provided for `callback` the created "_.where" style callback
-+     * will return `true` for elements that have the properties of the given object,
-+     * else `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unique
-+     * @category Arrays
-+     * @param {Array} array The array to process.
-+     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
-+     * @param {Function|Object|string} [callback=identity] The function called
-+     *  per iteration. If a property name or object is provided it will be used
-+     *  to create a "_.pluck" or "_.where" style callback, respectively.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns a duplicate-value-free array.
-+     * @example
-+     *
-+     * _.uniq([1, 2, 1, 3, 1]);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq([1, 1, 2, 2, 3], true);
-+     * // => [1, 2, 3]
-+     *
-+     * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
-+     * // => ['A', 'b', 'C']
-+     *
-+     * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
-+     * // => [1, 2.5, 3]
-+     *
-+     * // using "_.pluck" callback shorthand
-+     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
-+     * // => [{ 'x': 1 }, { 'x': 2 }]
-+     */
-+    function uniq(array, isSorted, callback, thisArg) {
-+      // juggle arguments
-+      if (typeof isSorted != 'boolean' && isSorted != null) {
-+        thisArg = callback;
-+        callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
-+        isSorted = false;
-+      }
-+      if (callback != null) {
-+        callback = lodash.createCallback(callback, thisArg, 3);
-+      }
-+      return baseUniq(array, isSorted, callback);
-+    }
-+
-+    /**
-+     * Creates an array excluding all provided values using strict equality for
-+     * comparisons, i.e. `===`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {Array} array The array to filter.
-+     * @param {...*} [value] The values to exclude.
-+     * @returns {Array} Returns a new array of filtered values.
-+     * @example
-+     *
-+     * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-+     * // => [2, 3, 4]
-+     */
-+    function without(array) {
-+      return baseDifference(array, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates an array that is the symmetric difference of the provided arrays.
-+     * See http://en.wikipedia.org/wiki/Symmetric_difference.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Arrays
-+     * @param {...Array} [array] The arrays to inspect.
-+     * @returns {Array} Returns an array of values.
-+     * @example
-+     *
-+     * _.xor([1, 2, 3], [5, 2, 1, 4]);
-+     * // => [3, 5, 4]
-+     *
-+     * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
-+     * // => [1, 4, 5]
-+     */
-+    function xor() {
-+      var index = -1,
-+          length = arguments.length;
-+
-+      while (++index < length) {
-+        var array = arguments[index];
-+        if (isArray(array) || isArguments(array)) {
-+          var result = result
-+            ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
-+            : array;
-+        }
-+      }
-+      return result || [];
-+    }
-+
-+    /**
-+     * Creates an array of grouped elements, the first of which contains the first
-+     * elements of the given arrays, the second of which contains the second
-+     * elements of the given arrays, and so on.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias unzip
-+     * @category Arrays
-+     * @param {...Array} [array] Arrays to process.
-+     * @returns {Array} Returns a new array of grouped elements.
-+     * @example
-+     *
-+     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
-+     * // => [['fred', 30, true], ['barney', 40, false]]
-+     */
-+    function zip() {
-+      var array = arguments.length > 1 ? arguments : arguments[0],
-+          index = -1,
-+          length = array ? max(pluck(array, 'length')) : 0,
-+          result = Array(length < 0 ? 0 : length);
-+
-+      while (++index < length) {
-+        result[index] = pluck(array, index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * Creates an object composed from arrays of `keys` and `values`. Provide
-+     * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
-+     * or two arrays, one of `keys` and one of corresponding `values`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @alias object
-+     * @category Arrays
-+     * @param {Array} keys The array of keys.
-+     * @param {Array} [values=[]] The array of values.
-+     * @returns {Object} Returns an object composed of the given keys and
-+     *  corresponding values.
-+     * @example
-+     *
-+     * _.zipObject(['fred', 'barney'], [30, 40]);
-+     * // => { 'fred': 30, 'barney': 40 }
-+     */
-+    function zipObject(keys, values) {
-+      var index = -1,
-+          length = keys ? keys.length : 0,
-+          result = {};
-+
-+      if (!values && length && !isArray(keys[0])) {
-+        values = [];
-+      }
-+      while (++index < length) {
-+        var key = keys[index];
-+        if (values) {
-+          result[key] = values[index];
-+        } else if (key) {
-+          result[key[0]] = key[1];
-+        }
-+      }
-+      return result;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that executes `func`, with  the `this` binding and
-+     * arguments of the created function, only after being called `n` times.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {number} n The number of times the function must be called before
-+     *  `func` is executed.
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var saves = ['profile', 'settings'];
-+     *
-+     * var done = _.after(saves.length, function() {
-+     *   console.log('Done saving!');
-+     * });
-+     *
-+     * _.forEach(saves, function(type) {
-+     *   asyncSave({ 'type': type, 'complete': done });
-+     * });
-+     * // => logs 'Done saving!', after all saves have completed
-+     */
-+    function after(n, func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (--n < 1) {
-+          return func.apply(this, arguments);
-+        }
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with the `this`
-+     * binding of `thisArg` and prepends any additional `bind` arguments to those
-+     * provided to the bound function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to bind.
-+     * @param {*} [thisArg] The `this` binding of `func`.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var func = function(greeting) {
-+     *   return greeting + ' ' + this.name;
-+     * };
-+     *
-+     * func = _.bind(func, { 'name': 'fred' }, 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     */
-+    function bind(func, thisArg) {
-+      return arguments.length > 2
-+        ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
-+        : createWrapper(func, 1, null, null, thisArg);
-+    }
-+
-+    /**
-+     * Binds methods of an object to the object itself, overwriting the existing
-+     * method. Method names may be specified as individual arguments or as arrays
-+     * of method names. If no method names are provided all the function properties
-+     * of `object` will be bound.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object to bind and assign the bound methods to.
-+     * @param {...string} [methodName] The object method names to
-+     *  bind, specified as individual method names or arrays of method names.
-+     * @returns {Object} Returns `object`.
-+     * @example
-+     *
-+     * var view = {
-+     *   'label': 'docs',
-+     *   'onClick': function() { console.log('clicked ' + this.label); }
-+     * };
-+     *
-+     * _.bindAll(view);
-+     * jQuery('#docs').on('click', view.onClick);
-+     * // => logs 'clicked docs', when the button is clicked
-+     */
-+    function bindAll(object) {
-+      var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
-+          index = -1,
-+          length = funcs.length;
-+
-+      while (++index < length) {
-+        var key = funcs[index];
-+        object[key] = createWrapper(object[key], 1, null, null, object);
-+      }
-+      return object;
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes the method at `object[key]`
-+     * and prepends any additional `bindKey` arguments to those provided to the bound
-+     * function. This method differs from `_.bind` by allowing bound functions to
-+     * reference methods that will be redefined or don't yet exist.
-+     * See http://michaux.ca/articles/lazy-function-definition-pattern.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Object} object The object the method belongs to.
-+     * @param {string} key The key of the method.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new bound function.
-+     * @example
-+     *
-+     * var object = {
-+     *   'name': 'fred',
-+     *   'greet': function(greeting) {
-+     *     return greeting + ' ' + this.name;
-+     *   }
-+     * };
-+     *
-+     * var func = _.bindKey(object, 'greet', 'hi');
-+     * func();
-+     * // => 'hi fred'
-+     *
-+     * object.greet = function(greeting) {
-+     *   return greeting + 'ya ' + this.name + '!';
-+     * };
-+     *
-+     * func();
-+     * // => 'hiya fred!'
-+     */
-+    function bindKey(object, key) {
-+      return arguments.length > 2
-+        ? createWrapper(key, 19, slice(arguments, 2), null, object)
-+        : createWrapper(key, 3, null, null, object);
-+    }
-+
-+    /**
-+     * Creates a function that is the composition of the provided functions,
-+     * where each function consumes the return value of the function that follows.
-+     * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
-+     * Each function is executed with the `this` binding of the composed function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {...Function} [func] Functions to compose.
-+     * @returns {Function} Returns the new composed function.
-+     * @example
-+     *
-+     * var realNameMap = {
-+     *   'pebbles': 'penelope'
-+     * };
-+     *
-+     * var format = function(name) {
-+     *   name = realNameMap[name.toLowerCase()] || name;
-+     *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
-+     * };
-+     *
-+     * var greet = function(formatted) {
-+     *   return 'Hiya ' + formatted + '!';
-+     * };
-+     *
-+     * var welcome = _.compose(greet, format);
-+     * welcome('pebbles');
-+     * // => 'Hiya Penelope!'
-+     */
-+    function compose() {
-+      var funcs = arguments,
-+          length = funcs.length;
-+
-+      while (length--) {
-+        if (!isFunction(funcs[length])) {
-+          throw new TypeError;
-+        }
-+      }
-+      return function() {
-+        var args = arguments,
-+            length = funcs.length;
-+
-+        while (length--) {
-+          args = [funcs[length].apply(this, args)];
-+        }
-+        return args[0];
-+      };
-+    }
-+
-+    /**
-+     * Creates a function which accepts one or more arguments of `func` that when
-+     * invoked either executes `func` returning its result, if all `func` arguments
-+     * have been provided, or returns a function that accepts one or more of the
-+     * remaining `func` arguments, and so on. The arity of `func` can be specified
-+     * if `func.length` is not sufficient.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to curry.
-+     * @param {number} [arity=func.length] The arity of `func`.
-+     * @returns {Function} Returns the new curried function.
-+     * @example
-+     *
-+     * var curried = _.curry(function(a, b, c) {
-+     *   console.log(a + b + c);
-+     * });
-+     *
-+     * curried(1)(2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2)(3);
-+     * // => 6
-+     *
-+     * curried(1, 2, 3);
-+     * // => 6
-+     */
-+    function curry(func, arity) {
-+      arity = typeof arity == 'number' ? arity : (+arity || func.length);
-+      return createWrapper(func, 4, null, null, null, arity);
-+    }
-+
-+    /**
-+     * Creates a function that will delay the execution of `func` until after
-+     * `wait` milliseconds have elapsed since the last time it was invoked.
-+     * Provide an options object to indicate that `func` should be invoked on
-+     * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
-+     * to the debounced function will return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the debounced function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to debounce.
-+     * @param {number} wait The number of milliseconds to delay.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
-+     * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new debounced function.
-+     * @example
-+     *
-+     * // avoid costly calculations while the window size is in flux
-+     * var lazyLayout = _.debounce(calculateLayout, 150);
-+     * jQuery(window).on('resize', lazyLayout);
-+     *
-+     * // execute `sendMail` when the click event is fired, debouncing subsequent calls
-+     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
-+     *   'leading': true,
-+     *   'trailing': false
-+     * });
-+     *
-+     * // ensure `batchLog` is executed once after 1 second of debounced calls
-+     * var source = new EventSource('/stream');
-+     * source.addEventListener('message', _.debounce(batchLog, 250, {
-+     *   'maxWait': 1000
-+     * }, false);
-+     */
-+    function debounce(func, wait, options) {
-+      var args,
-+          maxTimeoutId,
-+          result,
-+          stamp,
-+          thisArg,
-+          timeoutId,
-+          trailingCall,
-+          lastCalled = 0,
-+          maxWait = false,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      wait = nativeMax(0, wait) || 0;
-+      if (options === true) {
-+        var leading = true;
-+        trailing = false;
-+      } else if (isObject(options)) {
-+        leading = options.leading;
-+        maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      var delayed = function() {
-+        var remaining = wait - (now() - stamp);
-+        if (remaining <= 0) {
-+          if (maxTimeoutId) {
-+            clearTimeout(maxTimeoutId);
-+          }
-+          var isCalled = trailingCall;
-+          maxTimeoutId = timeoutId = trailingCall = undefined;
-+          if (isCalled) {
-+            lastCalled = now();
-+            result = func.apply(thisArg, args);
-+            if (!timeoutId && !maxTimeoutId) {
-+              args = thisArg = null;
-+            }
-+          }
-+        } else {
-+          timeoutId = setTimeout(delayed, remaining);
-+        }
-+      };
-+
-+      var maxDelayed = function() {
-+        if (timeoutId) {
-+          clearTimeout(timeoutId);
-+        }
-+        maxTimeoutId = timeoutId = trailingCall = undefined;
-+        if (trailing || (maxWait !== wait)) {
-+          lastCalled = now();
-+          result = func.apply(thisArg, args);
-+          if (!timeoutId && !maxTimeoutId) {
-+            args = thisArg = null;
-+          }
-+        }
-+      };
-+
-+      return function() {
-+        args = arguments;
-+        stamp = now();
-+        thisArg = this;
-+        trailingCall = trailing && (timeoutId || !leading);
-+
-+        if (maxWait === false) {
-+          var leadingCall = leading && !timeoutId;
-+        } else {
-+          if (!maxTimeoutId && !leading) {
-+            lastCalled = stamp;
-+          }
-+          var remaining = maxWait - (stamp - lastCalled),
-+              isCalled = remaining <= 0;
-+
-+          if (isCalled) {
-+            if (maxTimeoutId) {
-+              maxTimeoutId = clearTimeout(maxTimeoutId);
-+            }
-+            lastCalled = stamp;
-+            result = func.apply(thisArg, args);
-+          }
-+          else if (!maxTimeoutId) {
-+            maxTimeoutId = setTimeout(maxDelayed, remaining);
-+          }
-+        }
-+        if (isCalled && timeoutId) {
-+          timeoutId = clearTimeout(timeoutId);
-+        }
-+        else if (!timeoutId && wait !== maxWait) {
-+          timeoutId = setTimeout(delayed, wait);
-+        }
-+        if (leadingCall) {
-+          isCalled = true;
-+          result = func.apply(thisArg, args);
-+        }
-+        if (isCalled && !timeoutId && !maxTimeoutId) {
-+          args = thisArg = null;
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Defers executing the `func` function until the current call stack has cleared.
-+     * Additional arguments will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to defer.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.defer(function(text) { console.log(text); }, 'deferred');
-+     * // logs 'deferred' after one or more milliseconds
-+     */
-+    function defer(func) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 1);
-+      return setTimeout(function() { func.apply(undefined, args); }, 1);
-+    }
-+
-+    /**
-+     * Executes the `func` function after `wait` milliseconds. Additional arguments
-+     * will be provided to `func` when it is invoked.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to delay.
-+     * @param {number} wait The number of milliseconds to delay execution.
-+     * @param {...*} [arg] Arguments to invoke the function with.
-+     * @returns {number} Returns the timer id.
-+     * @example
-+     *
-+     * _.delay(function(text) { console.log(text); }, 1000, 'later');
-+     * // => logs 'later' after one second
-+     */
-+    function delay(func, wait) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var args = slice(arguments, 2);
-+      return setTimeout(function() { func.apply(undefined, args); }, wait);
-+    }
-+
-+    /**
-+     * Creates a function that memoizes the result of `func`. If `resolver` is
-+     * provided it will be used to determine the cache key for storing the result
-+     * based on the arguments provided to the memoized function. By default, the
-+     * first argument provided to the memoized function is used as the cache key.
-+     * The `func` is executed with the `this` binding of the memoized function.
-+     * The result cache is exposed as the `cache` property on the memoized function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to have its output memoized.
-+     * @param {Function} [resolver] A function used to resolve the cache key.
-+     * @returns {Function} Returns the new memoizing function.
-+     * @example
-+     *
-+     * var fibonacci = _.memoize(function(n) {
-+     *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-+     * });
-+     *
-+     * fibonacci(9)
-+     * // => 34
-+     *
-+     * var data = {
-+     *   'fred': { 'name': 'fred', 'age': 40 },
-+     *   'pebbles': { 'name': 'pebbles', 'age': 1 }
-+     * };
-+     *
-+     * // modifying the result cache
-+     * var get = _.memoize(function(name) { return data[name]; }, _.identity);
-+     * get('pebbles');
-+     * // => { 'name': 'pebbles', 'age': 1 }
-+     *
-+     * get.cache.pebbles.name = 'penelope';
-+     * get('pebbles');
-+     * // => { 'name': 'penelope', 'age': 1 }
-+     */
-+    function memoize(func, resolver) {
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      var memoized = function() {
-+        var cache = memoized.cache,
-+            key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-+
-+        return hasOwnProperty.call(cache, key)
-+          ? cache[key]
-+          : (cache[key] = func.apply(this, arguments));
-+      }
-+      memoized.cache = {};
-+      return memoized;
-+    }
-+
-+    /**
-+     * Creates a function that is restricted to execute `func` once. Repeat calls to
-+     * the function will return the value of the first call. The `func` is executed
-+     * with the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to restrict.
-+     * @returns {Function} Returns the new restricted function.
-+     * @example
-+     *
-+     * var initialize = _.once(createApplication);
-+     * initialize();
-+     * initialize();
-+     * // `initialize` executes `createApplication` once
-+     */
-+    function once(func) {
-+      var ran,
-+          result;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      return function() {
-+        if (ran) {
-+          return result;
-+        }
-+        ran = true;
-+        result = func.apply(this, arguments);
-+
-+        // clear the `func` variable so the function may be garbage collected
-+        func = null;
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Creates a function that, when called, invokes `func` with any additional
-+     * `partial` arguments prepended to those provided to the new function. This
-+     * method is similar to `_.bind` except it does **not** alter the `this` binding.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var greet = function(greeting, name) { return greeting + ' ' + name; };
-+     * var hi = _.partial(greet, 'hi');
-+     * hi('fred');
-+     * // => 'hi fred'
-+     */
-+    function partial(func) {
-+      return createWrapper(func, 16, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * This method is like `_.partial` except that `partial` arguments are
-+     * appended to those provided to the new function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to partially apply arguments to.
-+     * @param {...*} [arg] Arguments to be partially applied.
-+     * @returns {Function} Returns the new partially applied function.
-+     * @example
-+     *
-+     * var defaultsDeep = _.partialRight(_.merge, _.defaults);
-+     *
-+     * var options = {
-+     *   'variable': 'data',
-+     *   'imports': { 'jq': $ }
-+     * };
-+     *
-+     * defaultsDeep(options, _.templateSettings);
-+     *
-+     * options.variable
-+     * // => 'data'
-+     *
-+     * options.imports
-+     * // => { '_': _, 'jq': $ }
-+     */
-+    function partialRight(func) {
-+      return createWrapper(func, 32, null, slice(arguments, 1));
-+    }
-+
-+    /**
-+     * Creates a function that, when executed, will only call the `func` function
-+     * at most once per every `wait` milliseconds. Provide an options object to
-+     * indicate that `func` should be invoked on the leading and/or trailing edge
-+     * of the `wait` timeout. Subsequent calls to the throttled function will
-+     * return the result of the last `func` call.
-+     *
-+     * Note: If `leading` and `trailing` options are `true` `func` will be called
-+     * on the trailing edge of the timeout only if the the throttled function is
-+     * invoked more than once during the `wait` timeout.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {Function} func The function to throttle.
-+     * @param {number} wait The number of milliseconds to throttle executions to.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
-+     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
-+     * @returns {Function} Returns the new throttled function.
-+     * @example
-+     *
-+     * // avoid excessively updating the position while scrolling
-+     * var throttled = _.throttle(updatePosition, 100);
-+     * jQuery(window).on('scroll', throttled);
-+     *
-+     * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
-+     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
-+     *   'trailing': false
-+     * }));
-+     */
-+    function throttle(func, wait, options) {
-+      var leading = true,
-+          trailing = true;
-+
-+      if (!isFunction(func)) {
-+        throw new TypeError;
-+      }
-+      if (options === false) {
-+        leading = false;
-+      } else if (isObject(options)) {
-+        leading = 'leading' in options ? options.leading : leading;
-+        trailing = 'trailing' in options ? options.trailing : trailing;
-+      }
-+      debounceOptions.leading = leading;
-+      debounceOptions.maxWait = wait;
-+      debounceOptions.trailing = trailing;
-+
-+      return debounce(func, wait, debounceOptions);
-+    }
-+
-+    /**
-+     * Creates a function that provides `value` to the wrapper function as its
-+     * first argument. Additional arguments provided to the function are appended
-+     * to those provided to the wrapper function. The wrapper is executed with
-+     * the `this` binding of the created function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Functions
-+     * @param {*} value The value to wrap.
-+     * @param {Function} wrapper The wrapper function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var p = _.wrap(_.escape, function(func, text) {
-+     *   return '<p>' + func(text) + '</p>';
-+     * });
-+     *
-+     * p('Fred, Wilma, & Pebbles');
-+     * // => '<p>Fred, Wilma, & Pebbles</p>'
-+     */
-+    function wrap(value, wrapper) {
-+      return createWrapper(wrapper, 16, [value]);
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a function that returns `value`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value The value to return from the new function.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * var getter = _.constant(object);
-+     * getter() === object;
-+     * // => true
-+     */
-+    function constant(value) {
-+      return function() {
-+        return value;
-+      };
-+    }
-+
-+    /**
-+     * Produces a callback bound to an optional `thisArg`. If `func` is a property
-+     * name the created callback will return the property value for a given element.
-+     * If `func` is an object the created callback will return `true` for elements
-+     * that contain the equivalent object properties, otherwise it will return `false`.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} [func=identity] The value to convert to a callback.
-+     * @param {*} [thisArg] The `this` binding of the created callback.
-+     * @param {number} [argCount] The number of arguments the callback accepts.
-+     * @returns {Function} Returns a callback function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // wrap to create custom callback shorthands
-+     * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
-+     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
-+     *   return !match ? func(callback, thisArg) : function(object) {
-+     *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
-+     *   };
-+     * });
-+     *
-+     * _.filter(characters, 'age__gt38');
-+     * // => [{ 'name': 'fred', 'age': 40 }]
-+     */
-+    function createCallback(func, thisArg, argCount) {
-+      var type = typeof func;
-+      if (func == null || type == 'function') {
-+        return baseCreateCallback(func, thisArg, argCount);
-+      }
-+      // handle "_.pluck" style callback shorthands
-+      if (type != 'object') {
-+        return property(func);
-+      }
-+      var props = keys(func),
-+          key = props[0],
-+          a = func[key];
-+
-+      // handle "_.where" style callback shorthands
-+      if (props.length == 1 && a === a && !isObject(a)) {
-+        // fast path the common case of providing an object with a single
-+        // property containing a primitive value
-+        return function(object) {
-+          var b = object[key];
-+          return a === b && (a !== 0 || (1 / a == 1 / b));
-+        };
-+      }
-+      return function(object) {
-+        var length = props.length,
-+            result = false;
-+
-+        while (length--) {
-+          if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
-+            break;
-+          }
-+        }
-+        return result;
-+      };
-+    }
-+
-+    /**
-+     * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding HTML entities.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to escape.
-+     * @returns {string} Returns the escaped string.
-+     * @example
-+     *
-+     * _.escape('Fred, Wilma, & Pebbles');
-+     * // => 'Fred, Wilma, & Pebbles'
-+     */
-+    function escape(string) {
-+      return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
-+    }
-+
-+    /**
-+     * This method returns the first argument provided to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {*} value Any value.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.identity(object) === object;
-+     * // => true
-+     */
-+    function identity(value) {
-+      return value;
-+    }
-+
-+    /**
-+     * Adds function properties of a source object to the destination object.
-+     * If `object` is a function methods will be added to its prototype as well.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Function|Object} [object=lodash] object The destination object.
-+     * @param {Object} source The object of functions to add.
-+     * @param {Object} [options] The options object.
-+     * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
-+     * @example
-+     *
-+     * function capitalize(string) {
-+     *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
-+     * }
-+     *
-+     * _.mixin({ 'capitalize': capitalize });
-+     * _.capitalize('fred');
-+     * // => 'Fred'
-+     *
-+     * _('fred').capitalize().value();
-+     * // => 'Fred'
-+     *
-+     * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
-+     * _('fred').capitalize();
-+     * // => 'Fred'
-+     */
-+    function mixin(object, source, options) {
-+      var chain = true,
-+          methodNames = source && functions(source);
-+
-+      if (!source || (!options && !methodNames.length)) {
-+        if (options == null) {
-+          options = source;
-+        }
-+        ctor = lodashWrapper;
-+        source = object;
-+        object = lodash;
-+        methodNames = functions(source);
-+      }
-+      if (options === false) {
-+        chain = false;
-+      } else if (isObject(options) && 'chain' in options) {
-+        chain = options.chain;
-+      }
-+      var ctor = object,
-+          isFunc = isFunction(ctor);
-+
-+      forEach(methodNames, function(methodName) {
-+        var func = object[methodName] = source[methodName];
-+        if (isFunc) {
-+          ctor.prototype[methodName] = function() {
-+            var chainAll = this.__chain__,
-+                value = this.__wrapped__,
-+                args = [value];
-+
-+            push.apply(args, arguments);
-+            var result = func.apply(object, args);
-+            if (chain || chainAll) {
-+              if (value === result && isObject(result)) {
-+                return this;
-+              }
-+              result = new ctor(result);
-+              result.__chain__ = chainAll;
-+            }
-+            return result;
-+          };
-+        }
-+      });
-+    }
-+
-+    /**
-+     * Reverts the '_' variable to its previous value and returns a reference to
-+     * the `lodash` function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @returns {Function} Returns the `lodash` function.
-+     * @example
-+     *
-+     * var lodash = _.noConflict();
-+     */
-+    function noConflict() {
-+      context._ = oldDash;
-+      return this;
-+    }
-+
-+    /**
-+     * A no-operation function.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var object = { 'name': 'fred' };
-+     * _.noop(object) === undefined;
-+     * // => true
-+     */
-+    function noop() {
-+      // no operation performed
-+    }
-+
-+    /**
-+     * Gets the number of milliseconds that have elapsed since the Unix epoch
-+     * (1 January 1970 00:00:00 UTC).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @example
-+     *
-+     * var stamp = _.now();
-+     * _.defer(function() { console.log(_.now() - stamp); });
-+     * // => logs the number of milliseconds it took for the deferred function to be called
-+     */
-+    var now = isNative(now = Date.now) && now || function() {
-+      return new Date().getTime();
-+    };
-+
-+    /**
-+     * Converts the given value into an integer of the specified radix.
-+     * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
-+     * `value` is a hexadecimal, in which case a `radix` of `16` is used.
-+     *
-+     * Note: This method avoids differences in native ES3 and ES5 `parseInt`
-+     * implementations. See http://es5.github.io/#E.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} value The value to parse.
-+     * @param {number} [radix] The radix used to interpret the value to parse.
-+     * @returns {number} Returns the new integer value.
-+     * @example
-+     *
-+     * _.parseInt('08');
-+     * // => 8
-+     */
-+    var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
-+      // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
-+      return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
-+    };
-+
-+    /**
-+     * Creates a "_.pluck" style function, which returns the `key` value of a
-+     * given object.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} key The name of the property to retrieve.
-+     * @returns {Function} Returns the new function.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'fred',   'age': 40 },
-+     *   { 'name': 'barney', 'age': 36 }
-+     * ];
-+     *
-+     * var getName = _.property('name');
-+     *
-+     * _.map(characters, getName);
-+     * // => ['barney', 'fred']
-+     *
-+     * _.sortBy(characters, getName);
-+     * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
-+     */
-+    function property(key) {
-+      return function(object) {
-+        return object[key];
-+      };
-+    }
-+
-+    /**
-+     * Produces a random number between `min` and `max` (inclusive). If only one
-+     * argument is provided a number between `0` and the given number will be
-+     * returned. If `floating` is truey or either `min` or `max` are floats a
-+     * floating-point number will be returned instead of an integer.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} [min=0] The minimum possible value.
-+     * @param {number} [max=1] The maximum possible value.
-+     * @param {boolean} [floating=false] Specify returning a floating-point number.
-+     * @returns {number} Returns a random number.
-+     * @example
-+     *
-+     * _.random(0, 5);
-+     * // => an integer between 0 and 5
-+     *
-+     * _.random(5);
-+     * // => also an integer between 0 and 5
-+     *
-+     * _.random(5, true);
-+     * // => a floating-point number between 0 and 5
-+     *
-+     * _.random(1.2, 5.2);
-+     * // => a floating-point number between 1.2 and 5.2
-+     */
-+    function random(min, max, floating) {
-+      var noMin = min == null,
-+          noMax = max == null;
-+
-+      if (floating == null) {
-+        if (typeof min == 'boolean' && noMax) {
-+          floating = min;
-+          min = 1;
-+        }
-+        else if (!noMax && typeof max == 'boolean') {
-+          floating = max;
-+          noMax = true;
-+        }
-+      }
-+      if (noMin && noMax) {
-+        max = 1;
-+      }
-+      min = +min || 0;
-+      if (noMax) {
-+        max = min;
-+        min = 0;
-+      } else {
-+        max = +max || 0;
-+      }
-+      if (floating || min % 1 || max % 1) {
-+        var rand = nativeRandom();
-+        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
-+      }
-+      return baseRandom(min, max);
-+    }
-+
-+    /**
-+     * Resolves the value of property `key` on `object`. If `key` is a function
-+     * it will be invoked with the `this` binding of `object` and its result returned,
-+     * else the property value is returned. If `object` is falsey then `undefined`
-+     * is returned.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {Object} object The object to inspect.
-+     * @param {string} key The name of the property to resolve.
-+     * @returns {*} Returns the resolved value.
-+     * @example
-+     *
-+     * var object = {
-+     *   'cheese': 'crumpets',
-+     *   'stuff': function() {
-+     *     return 'nonsense';
-+     *   }
-+     * };
-+     *
-+     * _.result(object, 'cheese');
-+     * // => 'crumpets'
-+     *
-+     * _.result(object, 'stuff');
-+     * // => 'nonsense'
-+     */
-+    function result(object, key) {
-+      if (object) {
-+        var value = object[key];
-+        return isFunction(value) ? object[key]() : value;
-+      }
-+    }
-+
-+    /**
-+     * A micro-templating method that handles arbitrary delimiters, preserves
-+     * whitespace, and correctly escapes quotes within interpolated code.
-+     *
-+     * Note: In the development build, `_.template` utilizes sourceURLs for easier
-+     * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+     *
-+     * For more information on precompiling templates see:
-+     * http://lodash.com/custom-builds
-+     *
-+     * For more information on Chrome extension sandboxes see:
-+     * http://developer.chrome.com/stable/extensions/sandboxingEval.html
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} text The template text.
-+     * @param {Object} data The data object used to populate the text.
-+     * @param {Object} [options] The options object.
-+     * @param {RegExp} [options.escape] The "escape" delimiter.
-+     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
-+     * @param {Object} [options.imports] An object to import into the template as local variables.
-+     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
-+     * @param {string} [sourceURL] The sourceURL of the template's compiled source.
-+     * @param {string} [variable] The data object variable name.
-+     * @returns {Function|string} Returns a compiled function when no `data` object
-+     *  is given, else it returns the interpolated text.
-+     * @example
-+     *
-+     * // using the "interpolate" delimiter to create a compiled template
-+     * var compiled = _.template('hello <%= name %>');
-+     * compiled({ 'name': 'fred' });
-+     * // => 'hello fred'
-+     *
-+     * // using the "escape" delimiter to escape HTML in data property values
-+     * _.template('<b><%- value %></b>', { 'value': '<script>' });
-+     * // => '<b><script></b>'
-+     *
-+     * // using the "evaluate" delimiter to generate HTML
-+     * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
-+     * _.template('hello ${ name }', { 'name': 'pebbles' });
-+     * // => 'hello pebbles'
-+     *
-+     * // using the internal `print` function in "evaluate" delimiters
-+     * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
-+     * // => 'hello barney!'
-+     *
-+     * // using a custom template delimiters
-+     * _.templateSettings = {
-+     *   'interpolate': /{{([\s\S]+?)}}/g
-+     * };
-+     *
-+     * _.template('hello {{ name }}!', { 'name': 'mustache' });
-+     * // => 'hello mustache!'
-+     *
-+     * // using the `imports` option to import jQuery
-+     * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
-+     * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
-+     * // => '<li>fred</li><li>barney</li>'
-+     *
-+     * // using the `sourceURL` option to specify a custom sourceURL for the template
-+     * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
-+     * compiled(data);
-+     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
-+     *
-+     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
-+     * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
-+     * compiled.source;
-+     * // => function(data) {
-+     *   var __t, __p = '', __e = _.escape;
-+     *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
-+     *   return __p;
-+     * }
-+     *
-+     * // using the `source` property to inline compiled templates for meaningful
-+     * // line numbers in error messages and a stack trace
-+     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
-+     *   var JST = {\
-+     *     "main": ' + _.template(mainText).source + '\
-+     *   };\
-+     * ');
-+     */
-+    function template(text, data, options) {
-+      // based on John Resig's `tmpl` implementation
-+      // http://ejohn.org/blog/javascript-micro-templating/
-+      // and Laura Doktorova's doT.js
-+      // https://github.com/olado/doT
-+      var settings = lodash.templateSettings;
-+      text = String(text || '');
-+
-+      // avoid missing dependencies when `iteratorTemplate` is not defined
-+      options = iteratorTemplate ? defaults({}, options, settings) : settings;
-+
-+      var imports = iteratorTemplate && defaults({}, options.imports, settings.imports),
-+          importsKeys = iteratorTemplate ? keys(imports) : ['_'],
-+          importsValues = iteratorTemplate ? values(imports) : [lodash];
-+
-+      var isEvaluating,
-+          index = 0,
-+          interpolate = options.interpolate || reNoMatch,
-+          source = "__p += '";
-+
-+      // compile the regexp to match each delimiter
-+      var reDelimiters = RegExp(
-+        (options.escape || reNoMatch).source + '|' +
-+        interpolate.source + '|' +
-+        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
-+        (options.evaluate || reNoMatch).source + '|$'
-+      , 'g');
-+
-+      text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
-+        interpolateValue || (interpolateValue = esTemplateValue);
-+
-+        // escape characters that cannot be included in string literals
-+        source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
-+
-+        // replace delimiters with snippets
-+        if (escapeValue) {
-+          source += "' +\n__e(" + escapeValue + ") +\n'";
-+        }
-+        if (evaluateValue) {
-+          isEvaluating = true;
-+          source += "';\n" + evaluateValue + ";\n__p += '";
-+        }
-+        if (interpolateValue) {
-+          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
-+        }
-+        index = offset + match.length;
-+
-+        // the JS engine embedded in Adobe products requires returning the `match`
-+        // string in order to produce the correct `offset` value
-+        return match;
-+      });
-+
-+      source += "';\n";
-+
-+      // if `variable` is not specified, wrap a with-statement around the generated
-+      // code to add the data object to the top of the scope chain
-+      var variable = options.variable,
-+          hasVariable = variable;
-+
-+      if (!hasVariable) {
-+        variable = 'obj';
-+        source = 'with (' + variable + ') {\n' + source + '\n}\n';
-+      }
-+      // cleanup code by stripping empty strings
-+      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
-+        .replace(reEmptyStringMiddle, '$1')
-+        .replace(reEmptyStringTrailing, '$1;');
-+
-+      // frame code as the function body
-+      source = 'function(' + variable + ') {\n' +
-+        (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
-+        "var __t, __p = '', __e = _.escape" +
-+        (isEvaluating
-+          ? ', __j = Array.prototype.join;\n' +
-+            "function print() { __p += __j.call(arguments, '') }\n"
-+          : ';\n'
-+        ) +
-+        source +
-+        'return __p\n}';
-+
-+      // Use a sourceURL for easier debugging.
-+      // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
-+      var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
-+
-+      try {
-+        var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
-+      } catch(e) {
-+        e.source = source;
-+        throw e;
-+      }
-+      if (data) {
-+        return result(data);
-+      }
-+      // provide the compiled function's source by its `toString` method, in
-+      // supported environments, or the `source` property as a convenience for
-+      // inlining compiled templates during the build process
-+      result.source = source;
-+      return result;
-+    }
-+
-+    /**
-+     * Executes the callback `n` times, returning an array of the results
-+     * of each callback execution. The callback is bound to `thisArg` and invoked
-+     * with one argument; (index).
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {number} n The number of times to execute the callback.
-+     * @param {Function} callback The function called per iteration.
-+     * @param {*} [thisArg] The `this` binding of `callback`.
-+     * @returns {Array} Returns an array of the results of each `callback` execution.
-+     * @example
-+     *
-+     * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
-+     * // => [3, 6, 4]
-+     *
-+     * _.times(3, function(n) { mage.castSpell(n); });
-+     * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
-+     *
-+     * _.times(3, function(n) { this.cast(n); }, mage);
-+     * // => also calls `mage.castSpell(n)` three times
-+     */
-+    function times(n, callback, thisArg) {
-+      n = (n = +n) > -1 ? n : 0;
-+      var index = -1,
-+          result = Array(n);
-+
-+      callback = baseCreateCallback(callback, thisArg, 1);
-+      while (++index < n) {
-+        result[index] = callback(index);
-+      }
-+      return result;
-+    }
-+
-+    /**
-+     * The inverse of `_.escape` this method converts the HTML entities
-+     * `&`, `<`, `>`, `"`, and `'` in `string` to their
-+     * corresponding characters.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} string The string to unescape.
-+     * @returns {string} Returns the unescaped string.
-+     * @example
-+     *
-+     * _.unescape('Fred, Barney & Pebbles');
-+     * // => 'Fred, Barney & Pebbles'
-+     */
-+    function unescape(string) {
-+      return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
-+    }
-+
-+    /**
-+     * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Utilities
-+     * @param {string} [prefix] The value to prefix the ID with.
-+     * @returns {string} Returns the unique ID.
-+     * @example
-+     *
-+     * _.uniqueId('contact_');
-+     * // => 'contact_104'
-+     *
-+     * _.uniqueId();
-+     * // => '105'
-+     */
-+    function uniqueId(prefix) {
-+      var id = ++idCounter;
-+      return String(prefix == null ? '' : prefix) + id;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * Creates a `lodash` object that wraps the given value with explicit
-+     * method chaining enabled.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to wrap.
-+     * @returns {Object} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney',  'age': 36 },
-+     *   { 'name': 'fred',    'age': 40 },
-+     *   { 'name': 'pebbles', 'age': 1 }
-+     * ];
-+     *
-+     * var youngest = _.chain(characters)
-+     *     .sortBy('age')
-+     *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
-+     *     .first()
-+     *     .value();
-+     * // => 'pebbles is 1'
-+     */
-+    function chain(value) {
-+      value = new lodashWrapper(value);
-+      value.__chain__ = true;
-+      return value;
-+    }
-+
-+    /**
-+     * Invokes `interceptor` with the `value` as the first argument and then
-+     * returns `value`. The purpose of this method is to "tap into" a method
-+     * chain in order to perform operations on intermediate results within
-+     * the chain.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @category Chaining
-+     * @param {*} value The value to provide to `interceptor`.
-+     * @param {Function} interceptor The function to invoke.
-+     * @returns {*} Returns `value`.
-+     * @example
-+     *
-+     * _([1, 2, 3, 4])
-+     *  .tap(function(array) { array.pop(); })
-+     *  .reverse()
-+     *  .value();
-+     * // => [3, 2, 1]
-+     */
-+    function tap(value, interceptor) {
-+      interceptor(value);
-+      return value;
-+    }
-+
-+    /**
-+     * Enables explicit method chaining on the wrapper object.
-+     *
-+     * @name chain
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {*} Returns the wrapper object.
-+     * @example
-+     *
-+     * var characters = [
-+     *   { 'name': 'barney', 'age': 36 },
-+     *   { 'name': 'fred',   'age': 40 }
-+     * ];
-+     *
-+     * // without explicit chaining
-+     * _(characters).first();
-+     * // => { 'name': 'barney', 'age': 36 }
-+     *
-+     * // with explicit chaining
-+     * _(characters).chain()
-+     *   .first()
-+     *   .pick('age')
-+     *   .value();
-+     * // => { 'age': 36 }
-+     */
-+    function wrapperChain() {
-+      this.__chain__ = true;
-+      return this;
-+    }
-+
-+    /**
-+     * Produces the `toString` result of the wrapped value.
-+     *
-+     * @name toString
-+     * @memberOf _
-+     * @category Chaining
-+     * @returns {string} Returns the string result.
-+     * @example
-+     *
-+     * _([1, 2, 3]).toString();
-+     * // => '1,2,3'
-+     */
-+    function wrapperToString() {
-+      return String(this.__wrapped__);
-+    }
-+
-+    /**
-+     * Extracts the wrapped value.
-+     *
-+     * @name valueOf
-+     * @memberOf _
-+     * @alias value
-+     * @category Chaining
-+     * @returns {*} Returns the wrapped value.
-+     * @example
-+     *
-+     * _([1, 2, 3]).valueOf();
-+     * // => [1, 2, 3]
-+     */
-+    function wrapperValueOf() {
-+      return this.__wrapped__;
-+    }
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return wrapped values when chaining
-+    lodash.after = after;
-+    lodash.assign = assign;
-+    lodash.at = at;
-+    lodash.bind = bind;
-+    lodash.bindAll = bindAll;
-+    lodash.bindKey = bindKey;
-+    lodash.chain = chain;
-+    lodash.compact = compact;
-+    lodash.compose = compose;
-+    lodash.constant = constant;
-+    lodash.countBy = countBy;
-+    lodash.create = create;
-+    lodash.createCallback = createCallback;
-+    lodash.curry = curry;
-+    lodash.debounce = debounce;
-+    lodash.defaults = defaults;
-+    lodash.defer = defer;
-+    lodash.delay = delay;
-+    lodash.difference = difference;
-+    lodash.filter = filter;
-+    lodash.flatten = flatten;
-+    lodash.forEach = forEach;
-+    lodash.forEachRight = forEachRight;
-+    lodash.forIn = forIn;
-+    lodash.forInRight = forInRight;
-+    lodash.forOwn = forOwn;
-+    lodash.forOwnRight = forOwnRight;
-+    lodash.functions = functions;
-+    lodash.groupBy = groupBy;
-+    lodash.indexBy = indexBy;
-+    lodash.initial = initial;
-+    lodash.intersection = intersection;
-+    lodash.invert = invert;
-+    lodash.invoke = invoke;
-+    lodash.keys = keys;
-+    lodash.map = map;
-+    lodash.mapValues = mapValues;
-+    lodash.max = max;
-+    lodash.memoize = memoize;
-+    lodash.merge = merge;
-+    lodash.min = min;
-+    lodash.omit = omit;
-+    lodash.once = once;
-+    lodash.pairs = pairs;
-+    lodash.partial = partial;
-+    lodash.partialRight = partialRight;
-+    lodash.pick = pick;
-+    lodash.pluck = pluck;
-+    lodash.property = property;
-+    lodash.pull = pull;
-+    lodash.range = range;
-+    lodash.reject = reject;
-+    lodash.remove = remove;
-+    lodash.rest = rest;
-+    lodash.shuffle = shuffle;
-+    lodash.sortBy = sortBy;
-+    lodash.tap = tap;
-+    lodash.throttle = throttle;
-+    lodash.times = times;
-+    lodash.toArray = toArray;
-+    lodash.transform = transform;
-+    lodash.union = union;
-+    lodash.uniq = uniq;
-+    lodash.values = values;
-+    lodash.where = where;
-+    lodash.without = without;
-+    lodash.wrap = wrap;
-+    lodash.xor = xor;
-+    lodash.zip = zip;
-+    lodash.zipObject = zipObject;
-+
-+    // add aliases
-+    lodash.collect = map;
-+    lodash.drop = rest;
-+    lodash.each = forEach;
-+    lodash.eachRight = forEachRight;
-+    lodash.extend = assign;
-+    lodash.methods = functions;
-+    lodash.object = zipObject;
-+    lodash.select = filter;
-+    lodash.tail = rest;
-+    lodash.unique = uniq;
-+    lodash.unzip = zip;
-+
-+    // add functions to `lodash.prototype`
-+    mixin(lodash);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions that return unwrapped values when chaining
-+    lodash.clone = clone;
-+    lodash.cloneDeep = cloneDeep;
-+    lodash.contains = contains;
-+    lodash.escape = escape;
-+    lodash.every = every;
-+    lodash.find = find;
-+    lodash.findIndex = findIndex;
-+    lodash.findKey = findKey;
-+    lodash.findLast = findLast;
-+    lodash.findLastIndex = findLastIndex;
-+    lodash.findLastKey = findLastKey;
-+    lodash.has = has;
-+    lodash.identity = identity;
-+    lodash.indexOf = indexOf;
-+    lodash.isArguments = isArguments;
-+    lodash.isArray = isArray;
-+    lodash.isBoolean = isBoolean;
-+    lodash.isDate = isDate;
-+    lodash.isElement = isElement;
-+    lodash.isEmpty = isEmpty;
-+    lodash.isEqual = isEqual;
-+    lodash.isFinite = isFinite;
-+    lodash.isFunction = isFunction;
-+    lodash.isNaN = isNaN;
-+    lodash.isNull = isNull;
-+    lodash.isNumber = isNumber;
-+    lodash.isObject = isObject;
-+    lodash.isPlainObject = isPlainObject;
-+    lodash.isRegExp = isRegExp;
-+    lodash.isString = isString;
-+    lodash.isUndefined = isUndefined;
-+    lodash.lastIndexOf = lastIndexOf;
-+    lodash.mixin = mixin;
-+    lodash.noConflict = noConflict;
-+    lodash.noop = noop;
-+    lodash.now = now;
-+    lodash.parseInt = parseInt;
-+    lodash.random = random;
-+    lodash.reduce = reduce;
-+    lodash.reduceRight = reduceRight;
-+    lodash.result = result;
-+    lodash.runInContext = runInContext;
-+    lodash.size = size;
-+    lodash.some = some;
-+    lodash.sortedIndex = sortedIndex;
-+    lodash.template = template;
-+    lodash.unescape = unescape;
-+    lodash.uniqueId = uniqueId;
-+
-+    // add aliases
-+    lodash.all = every;
-+    lodash.any = some;
-+    lodash.detect = find;
-+    lodash.findWhere = find;
-+    lodash.foldl = reduce;
-+    lodash.foldr = reduceRight;
-+    lodash.include = contains;
-+    lodash.inject = reduce;
-+
-+    mixin(function() {
-+      var source = {}
-+      forOwn(lodash, function(func, methodName) {
-+        if (!lodash.prototype[methodName]) {
-+          source[methodName] = func;
-+        }
-+      });
-+      return source;
-+    }(), false);
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    // add functions capable of returning wrapped and unwrapped values when chaining
-+    lodash.first = first;
-+    lodash.last = last;
-+    lodash.sample = sample;
-+
-+    // add aliases
-+    lodash.take = first;
-+    lodash.head = first;
-+
-+    forOwn(lodash, function(func, methodName) {
-+      var callbackable = methodName !== 'sample';
-+      if (!lodash.prototype[methodName]) {
-+        lodash.prototype[methodName]= function(n, guard) {
-+          var chainAll = this.__chain__,
-+              result = func(this.__wrapped__, n, guard);
-+
-+          return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
-+            ? result
-+            : new lodashWrapper(result, chainAll);
-+        };
-+      }
-+    });
-+
-+    /*--------------------------------------------------------------------------*/
-+
-+    /**
-+     * The semantic version number.
-+     *
-+     * @static
-+     * @memberOf _
-+     * @type string
-+     */
-+    lodash.VERSION = '2.4.1';
-+
-+    // add "Chaining" functions to the wrapper
-+    lodash.prototype.chain = wrapperChain;
-+    lodash.prototype.toString = wrapperToString;
-+    lodash.prototype.value = wrapperValueOf;
-+    lodash.prototype.valueOf = wrapperValueOf;
-+
-+    // add `Array` functions that return unwrapped values
-+    baseEach(['join', 'pop', 'shift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        var chainAll = this.__chain__,
-+            result = func.apply(this.__wrapped__, arguments);
-+
-+        return chainAll
-+          ? new lodashWrapper(result, chainAll)
-+          : result;
-+      };
-+    });
-+
-+    // add `Array` functions that return the existing wrapped value
-+    baseEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        func.apply(this.__wrapped__, arguments);
-+        return this;
-+      };
-+    });
-+
-+    // add `Array` functions that return new wrapped values
-+    baseEach(['concat', 'slice', 'splice'], function(methodName) {
-+      var func = arrayRef[methodName];
-+      lodash.prototype[methodName] = function() {
-+        return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
-+      };
-+    });
-+
-+    // avoid array-like object bugs with `Array#shift` and `Array#splice`
-+    // in IE < 9, Firefox < 10, Narwhal, and RingoJS
-+    if (!support.spliceObjects) {
-+      baseEach(['pop', 'shift', 'splice'], function(methodName) {
-+        var func = arrayRef[methodName],
-+            isSplice = methodName == 'splice';
-+
-+        lodash.prototype[methodName] = function() {
-+          var chainAll = this.__chain__,
-+              value = this.__wrapped__,
-+              result = func.apply(value, arguments);
-+
-+          if (value.length === 0) {
-+            delete value[0];
-+          }
-+          return (chainAll || isSplice)
-+            ? new lodashWrapper(result, chainAll)
-+            : result;
-+        };
-+      });
-+    }
-+
-+    // add pseudo private property to be used and removed during the build process
-+    lodash._baseEach = baseEach;
-+    lodash._iteratorTemplate = iteratorTemplate;
-+    lodash._shimKeys = shimKeys;
-+
-+    return lodash;
-+  }
-+
-+  /*--------------------------------------------------------------------------*/
-+
-+  // expose Lo-Dash
-+  var _ = runInContext();
-+
-+  // some AMD build optimizers like r.js check for condition patterns like the following:
-+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
-+    // Expose Lo-Dash to the global object even when an AMD loader is present in
-+    // case Lo-Dash is loaded with a RequireJS shim config.
-+    // See http://requirejs.org/docs/api.html#config-shim
-+    root._ = _;
-+
-+    // define as an anonymous module so, through path mapping, it can be
-+    // referenced as the "underscore" module
-+    define(function() {
-+      return _;
-+    });
-+  }
-+  // check for `exports` after `define` in case a build optimizer adds an `exports` object
-+  else if (freeExports && freeModule) {
-+    // in Node.js or RingoJS
-+    if (moduleExports) {
-+      (freeModule.exports = _)._ = _;
-+    }
-+    // in Narwhal or Rhino -require
-+    else {
-+      freeExports._ = _;
-+    }
-+  }
-+  else {
-+    // in a browser or Rhino
-+    root._ = _;
-+  }
-+}.call(this));
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/lodash/package.json
-@@ -0,0 +1,102 @@
-+{
-+  "name": "lodash",
-+  "version": "2.4.1",
-+  "description": "A utility library delivering consistency, customization, performance, & extras.",
-+  "homepage": "http://lodash.com/",
-+  "license": "MIT",
-+  "main": "dist/lodash.js",
-+  "keywords": [
-+    "amd",
-+    "browser",
-+    "client",
-+    "customize",
-+    "functional",
-+    "server",
-+    "util"
-+  ],
-+  "author": {
-+    "name": "John-David Dalton",
-+    "email": "john.david.dalton at gmail.com",
-+    "url": "http://allyoucanleet.com/"
-+  },
-+  "contributors": [
-+    {
-+      "name": "John-David Dalton",
-+      "email": "john.david.dalton at gmail.com",
-+      "url": "http://allyoucanleet.com/"
-+    },
-+    {
-+      "name": "Blaine Bublitz",
-+      "email": "blaine at iceddev.com",
-+      "url": "http://www.iceddev.com/"
-+    },
-+    {
-+      "name": "Kit Cambridge",
-+      "email": "github at kitcambridge.be",
-+      "url": "http://kitcambridge.be/"
-+    },
-+    {
-+      "name": "Mathias Bynens",
-+      "email": "mathias at qiwi.be",
-+      "url": "http://mathiasbynens.be/"
-+    }
-+  ],
-+  "bugs": {
-+    "url": "https://github.com/lodash/lodash/issues"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/lodash/lodash.git"
-+  },
-+  "engines": [
-+    "node",
-+    "rhino"
-+  ],
-+  "files": [
-+    "LICENSE.txt",
-+    "lodash.js",
-+    "dist/lodash.js",
-+    "dist/lodash.min.js",
-+    "dist/lodash.compat.js",
-+    "dist/lodash.compat.min.js",
-+    "dist/lodash.underscore.js",
-+    "dist/lodash.underscore.min.js"
-+  ],
-+  "jam": {
-+    "main": "dist/lodash.compat.js",
-+    "include": [
-+      "LICENSE.txt",
-+      "dist/lodash.js",
-+      "dist/lodash.min.js",
-+      "dist/lodash.compat.js",
-+      "dist/lodash.compat.min.js",
-+      "dist/lodash.underscore.js",
-+      "dist/lodash.underscore.min.js"
-+    ]
-+  },
-+  "volo": {
-+    "type": "directory",
-+    "ignore": [
-+      ".*",
-+      "*.custom.*",
-+      "*.min.*",
-+      "*.template.*",
-+      "*.map",
-+      "*.md",
-+      "lodash.js",
-+      "index.js",
-+      "bower.json",
-+      "component.json",
-+      "doc",
-+      "modularize",
-+      "node_modules",
-+      "perf",
-+      "test",
-+      "vendor"
-+    ]
-+  },
-+  "readme": "# Lo-Dash v2.4.1\nA utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features).\n\n## Download\n\nCheck out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds.\n\n* Modern builds perfect for newer browsers/environments:<br>\n[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) &\n[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js)\n\n* Compatibility builds for older environment support too:<br>\n[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) &\n[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js)\n\n* Underscore builds to use as a drop-in replacement:<br>\n[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) &\n[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js)\n\nCDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed.\n\nLove modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method.\n\n## Dive in\n\nThere’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).<br>\nCheck out <a href=\"http://devdocs.io/lodash/\">DevDocs</a> as a fast, organized, & searchable interface for our documentation.\n\nThe full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).<br>\nA list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap).\n\n## Features *not* in Underscore\n\n * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.)\n * [_(…)](http://lodash.com/docs#_) supports intuitive chaining\n * [_.at](http://lodash.com/docs#at) for cherry-picking collection values\n * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods\n * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects\n * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects\n * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions\n * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex`\n * [_.create](http://lodash.com/docs#create) for easier object inheritance\n * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins\n * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions\n * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control\n * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys\n * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early\n * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties\n * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties\n * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object`\n * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object\n * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions\n * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend)\n * [_.noop](http://lodash.com/docs#noop) for function placeholders\n * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative\n * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior\n * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays\n * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers\n * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking\n * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties\n * [_.support](http://lodash.com/docs#support) for flagging environment features\n * [_.template](http://lodash.com/docs#template) supports [*“imports”*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals)\n * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects\n * [_.where](http://lodash.com/docs#where) supports deep object comparisons\n * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union)\n * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values\n * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), &\n   [more](http://lodash.com/docs \"_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest\") accept callbacks\n * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), &\n   [more](http://lodash.com/docs \"_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where\") accept strings\n * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), &\n   [more](http://lodash.com/docs \"_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq\") support *“_.pluck”* & *“_.where”* shorthands\n * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), &\n   [more](http://lodash.com/docs \"_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight\") right-associative methods\n\n## Resources\n\n * Podcasts\n  - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/)\n\n * Posts\n  - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)\n  - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/)\n\n * Videos\n  - [Introduction](https://vimeo.com/44154599)\n  - [Origins](https://vimeo.com/44154600)\n  - [Optimizations & builds](https://vimeo.com/44154601)\n  - [Native method use](https://vimeo.com/48576012)\n  - [Testing](https://vimeo.com/45865290)\n  - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk)\n\n A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources).\n\n## Support\n\nTested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.<br>\nAutomated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash).\n\nSpecial thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.<br>\n[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ \"Sauce Labs: Selenium Testing & More\")\n\n## Installation & usage\n\nIn browsers:\n\n```html\n<script src=\"lodash.js\"></script>\n```\n\nUsing [`npm`](http://npmjs.org/):\n\n```bash\nnpm i --save lodash\n\n{sudo} npm i -g lodash\nnpm ln lodash\n```\n\nIn [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):\n\n```js\nvar _ = require('lodash');\n// or as Underscore\nvar _ = require('lodash/dist/lodash.underscore');\n```\n\n**Notes:**\n * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL\n * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it\n\nIn [Rhino](http://www.mozilla.org/rhino/):\n\n```js\nload('lodash.js');\n```\n\nIn an AMD loader:\n\n```js\nrequire({\n  'packages': [\n    { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }\n  ]\n},\n['lodash'], function(_) {\n  console.log(_.VERSION);\n});\n```\n\n## Author\n\n| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton \"Follow @jdalton on Twitter\") |\n|---|\n| [John-David Dalton](http://allyoucanleet.com/) |\n\n## Contributors\n\n| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz \"Follow @BlaineBublitz on Twitter\") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge \"Follow @kitcambridge on Twitter\") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias \"Follow @mathias on Twitter\") |\n|---|---|---|\n| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n",
-+  "readmeFilename": "README.md",
-+  "_id": "lodash at 2.4.1",
-+  "_from": "lodash@~2.4.1"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/.npmignore
-@@ -0,0 +1,5 @@
-+build/
-+test/
-+examples/
-+fs.js
-+zlib.js
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/LICENSE
-@@ -0,0 +1,27 @@
-+Copyright (c) Isaac Z. Schlueter ("Author")
-+All rights reserved.
-+
-+The BSD License
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+1. Redistributions of source code must retain the above copyright
-+   notice, this list of conditions and the following disclaimer.
-+
-+2. Redistributions in binary form must reproduce the above copyright
-+   notice, this list of conditions and the following disclaimer in the
-+   documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/README.md
-@@ -0,0 +1,15 @@
-+# readable-stream
-+
-+***Node-core streams for userland***
-+
-+[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true)](https://nodei.co/npm/readable-stream/)
-+[![NPM](https://nodei.co/npm-dl/readable-stream.png)](https://nodei.co/npm/readable-stream/)
-+
-+This package is a mirror of the Streams2 and Streams3 implementations in Node-core.
-+
-+If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core.
-+
-+**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.
-+
-+**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"`
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/duplex.js
-@@ -0,0 +1 @@
-+module.exports = require("./lib/_stream_duplex.js")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/lib/_stream_duplex.js
-@@ -0,0 +1,89 @@
-+// 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 = require('core-util-is');
-+util.inherits = require('inherits');
-+/*</replacement>*/
-+
-+var Readable = require('./_stream_readable');
-+var Writable = require('./_stream_writable');
-+
-+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);
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/lib/_stream_passthrough.js
-@@ -0,0 +1,46 @@
-+// 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 = require('./_stream_transform');
-+
-+/*<replacement>*/
-+var util = require('core-util-is');
-+util.inherits = require('inherits');
-+/*</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);
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/lib/_stream_readable.js
-@@ -0,0 +1,959 @@
-+// 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 = require('isarray');
-+/*</replacement>*/
-+
-+
-+/*<replacement>*/
-+var Buffer = require('buffer').Buffer;
-+/*</replacement>*/
-+
-+Readable.ReadableState = ReadableState;
-+
-+var EE = require('events').EventEmitter;
-+
-+/*<replacement>*/
-+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
-+  return emitter.listeners(type).length;
-+};
-+/*</replacement>*/
-+
-+var Stream = require('stream');
-+
-+/*<replacement>*/
-+var util = require('core-util-is');
-+util.inherits = require('inherits');
-+/*</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 = require('string_decoder/').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 = require('string_decoder/').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 (isNaN(n) || n === null) {
-+    // 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;
-+
-+  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) {
-+    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;
-+
-+  // 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);
-+
-+  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 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) {
-+    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);
-+    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 (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;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/lib/_stream_transform.js
-@@ -0,0 +1,210 @@
-+// 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 = require('./_stream_duplex');
-+
-+/*<replacement>*/
-+var util = require('core-util-is');
-+util.inherits = require('inherits');
-+/*</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);
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/lib/_stream_writable.js
-@@ -0,0 +1,387 @@
-+// 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 = require('buffer').Buffer;
-+/*</replacement>*/
-+
-+Writable.WritableState = WritableState;
-+
-+
-+/*<replacement>*/
-+var util = require('core-util-is');
-+util.inherits = require('inherits');
-+/*</replacement>*/
-+
-+
-+var Stream = require('stream');
-+
-+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 = require('./_stream_duplex');
-+
-+  // 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;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/core-util-is/README.md
-@@ -0,0 +1,3 @@
-+# core-util-is
-+
-+The `util.is*` functions introduced in Node v0.12.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/core-util-is/float.patch
-@@ -0,0 +1,604 @@
-+diff --git a/lib/util.js b/lib/util.js
-+index a03e874..9074e8e 100644
-+--- a/lib/util.js
-++++ b/lib/util.js
-+@@ -19,430 +19,6 @@
-+ // 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);
-+-  }
-+-
-+-  // 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)) {
-+-    // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
-+-    // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
-+-    if (value === 0 && 1 / value < 0)
-+-      return ctx.stylize('-0', 'number');
-+-    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) {
-+@@ -522,166 +98,10 @@ function isPrimitive(arg) {
-+ exports.isPrimitive = isPrimitive;
-+
-+ function isBuffer(arg) {
-+-  return arg instanceof Buffer;
-++  return Buffer.isBuffer(arg);
-+ }
-+ exports.isBuffer = isBuffer;
-+
-+ 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 = function(ctor, superCtor) {
-+-  ctor.super_ = superCtor;
-+-  ctor.prototype = Object.create(superCtor.prototype, {
-+-    constructor: {
-+-      value: ctor,
-+-      enumerable: false,
-+-      writable: true,
-+-      configurable: true
-+-    }
-+-  });
-+-};
-+-
-+-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);
-+-}
-+-
-+-
-+-// Deprecated old stuff.
-+-
-+-exports.p = exports.deprecate(function() {
-+-  for (var i = 0, len = arguments.length; i < len; ++i) {
-+-    console.error(exports.inspect(arguments[i]));
-+-  }
-+-}, 'util.p: Use console.error() instead');
-+-
-+-
-+-exports.exec = exports.deprecate(function() {
-+-  return require('child_process').exec.apply(this, arguments);
-+-}, 'util.exec is now called `child_process.exec`.');
-+-
-+-
-+-exports.print = exports.deprecate(function() {
-+-  for (var i = 0, len = arguments.length; i < len; ++i) {
-+-    process.stdout.write(String(arguments[i]));
-+-  }
-+-}, 'util.print: Use console.log instead');
-+-
-+-
-+-exports.puts = exports.deprecate(function() {
-+-  for (var i = 0, len = arguments.length; i < len; ++i) {
-+-    process.stdout.write(arguments[i] + '\n');
-+-  }
-+-}, 'util.puts: Use console.log instead');
-+-
-+-
-+-exports.debug = exports.deprecate(function(x) {
-+-  process.stderr.write('DEBUG: ' + x + '\n');
-+-}, 'util.debug: Use console.error instead');
-+-
-+-
-+-exports.error = exports.deprecate(function(x) {
-+-  for (var i = 0, len = arguments.length; i < len; ++i) {
-+-    process.stderr.write(arguments[i] + '\n');
-+-  }
-+-}, 'util.error: Use console.error instead');
-+-
-+-
-+-exports.pump = exports.deprecate(function(readStream, writeStream, callback) {
-+-  var callbackCalled = false;
-+-
-+-  function call(a, b, c) {
-+-    if (callback && !callbackCalled) {
-+-      callback(a, b, c);
-+-      callbackCalled = true;
-+-    }
-+-  }
-+-
-+-  readStream.addListener('data', function(chunk) {
-+-    if (writeStream.write(chunk) === false) readStream.pause();
-+-  });
-+-
-+-  writeStream.addListener('drain', function() {
-+-    readStream.resume();
-+-  });
-+-
-+-  readStream.addListener('end', function() {
-+-    writeStream.end();
-+-  });
-+-
-+-  readStream.addListener('close', function() {
-+-    call();
-+-  });
-+-
-+-  readStream.addListener('error', function(err) {
-+-    writeStream.end();
-+-    call(err);
-+-  });
-+-
-+-  writeStream.addListener('error', function(err) {
-+-    readStream.destroy();
-+-    call(err);
-+-  });
-+-}, 'util.pump(): Use readableStream.pipe() instead');
-+-
-+-
-+-var uv;
-+-exports._errnoException = function(err, syscall) {
-+-  if (isUndefined(uv)) uv = process.binding('uv');
-+-  var errname = uv.errname(err);
-+-  var e = new Error(syscall + ' ' + errname);
-+-  e.code = errname;
-+-  e.errno = errname;
-+-  e.syscall = syscall;
-+-  return e;
-+-};
-++}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/core-util-is/lib/util.js
-@@ -0,0 +1,107 @@
-+// 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(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;
-+
-+function isBuffer(arg) {
-+  return Buffer.isBuffer(arg);
-+}
-+exports.isBuffer = isBuffer;
-+
-+function objectToString(o) {
-+  return Object.prototype.toString.call(o);
-+}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/core-util-is/package.json
-@@ -0,0 +1,34 @@
-+{
-+  "name": "core-util-is",
-+  "version": "1.0.1",
-+  "description": "The `util.is*` functions introduced in Node v0.12.",
-+  "main": "lib/util.js",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/core-util-is"
-+  },
-+  "keywords": [
-+    "util",
-+    "isBuffer",
-+    "isArray",
-+    "isNumber",
-+    "isString",
-+    "isRegExp",
-+    "isThis",
-+    "isThat",
-+    "polyfill"
-+  ],
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": "MIT",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/core-util-is/issues"
-+  },
-+  "readme": "# core-util-is\n\nThe `util.is*` functions introduced in Node v0.12.\n",
-+  "readmeFilename": "README.md",
-+  "_id": "core-util-is at 1.0.1",
-+  "_from": "core-util-is@~1.0.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/core-util-is/util.js
-@@ -0,0 +1,106 @@
-+// 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(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]';
-+}
-+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;
-+
-+function isBuffer(arg) {
-+  return arg instanceof Buffer;
-+}
-+exports.isBuffer = isBuffer;
-+
-+function objectToString(o) {
-+  return Object.prototype.toString.call(o);
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/LICENSE
-@@ -0,0 +1,16 @@
-+The ISC License
-+
-+Copyright (c) Isaac Z. Schlueter
-+
-+Permission to use, copy, modify, and/or distribute this software for any
-+purpose with or without fee is hereby granted, provided that the above
-+copyright notice and this permission notice appear in all copies.
-+
-+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+PERFORMANCE OF THIS SOFTWARE.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/README.md
-@@ -0,0 +1,42 @@
-+Browser-friendly inheritance fully compatible with standard node.js
-+[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
-+
-+This package exports standard `inherits` from node.js `util` module in
-+node environment, but also provides alternative browser-friendly
-+implementation through [browser
-+field](https://gist.github.com/shtylman/4339901). Alternative
-+implementation is a literal copy of standard one located in standalone
-+module to avoid requiring of `util`. It also has a shim for old
-+browsers with no `Object.create` support.
-+
-+While keeping you sure you are using standard `inherits`
-+implementation in node.js environment, it allows bundlers such as
-+[browserify](https://github.com/substack/node-browserify) to not
-+include full `util` package to your client code if all you need is
-+just `inherits` function. It worth, because browser shim for `util`
-+package is large and `inherits` is often the single function you need
-+from it.
-+
-+It's recommended to use this package instead of
-+`require('util').inherits` for any code that has chances to be used
-+not only in node.js but in browser too.
-+
-+## usage
-+
-+```js
-+var inherits = require('inherits');
-+// then use exactly as the standard one
-+```
-+
-+## note on version ~1.0
-+
-+Version ~1.0 had completely different motivation and is not compatible
-+neither with 2.0 nor with standard node.js `inherits`.
-+
-+If you are using version ~1.0 and planning to switch to ~2.0, be
-+careful:
-+
-+* new version uses `super_` instead of `super` for referencing
-+  superclass
-+* new version overwrites current prototype while old one preserves any
-+  existing fields on it
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/inherits.js
-@@ -0,0 +1 @@
-+module.exports = require('util').inherits
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/inherits_browser.js
-@@ -0,0 +1,23 @@
-+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
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "inherits",
-+  "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
-+  "version": "2.0.1",
-+  "keywords": [
-+    "inheritance",
-+    "class",
-+    "klass",
-+    "oop",
-+    "object-oriented",
-+    "inherits",
-+    "browser",
-+    "browserify"
-+  ],
-+  "main": "./inherits.js",
-+  "browser": "./inherits_browser.js",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/inherits"
-+  },
-+  "license": "ISC",
-+  "scripts": {
-+    "test": "node test"
-+  },
-+  "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n  superclass\n* new version overwrites current prototype while old one preserves any\n  existing fields on it\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/inherits/issues"
-+  },
-+  "_id": "inherits at 2.0.1",
-+  "_from": "inherits@~2.0.1"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/inherits/test.js
-@@ -0,0 +1,25 @@
-+var inherits = require('./inherits.js')
-+var assert = require('assert')
-+
-+function test(c) {
-+  assert(c.constructor === Child)
-+  assert(c.constructor.super_ === Parent)
-+  assert(Object.getPrototypeOf(c) === Child.prototype)
-+  assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
-+  assert(c instanceof Child)
-+  assert(c instanceof Parent)
-+}
-+
-+function Child() {
-+  Parent.call(this)
-+  test(this)
-+}
-+
-+function Parent() {}
-+
-+inherits(Child, Parent)
-+
-+var c = new Child
-+test(c)
-+
-+console.log('ok')
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/isarray/README.md
-@@ -0,0 +1,54 @@
-+
-+# isarray
-+
-+`Array#isArray` for older browsers.
-+
-+## Usage
-+
-+```js
-+var isArray = require('isarray');
-+
-+console.log(isArray([])); // => true
-+console.log(isArray({})); // => false
-+```
-+
-+## Installation
-+
-+With [npm](http://npmjs.org) do
-+
-+```bash
-+$ npm install isarray
-+```
-+
-+Then bundle for the browser with
-+[browserify](https://github.com/substack/browserify).
-+
-+With [component](http://component.io) do
-+
-+```bash
-+$ component install juliangruber/isarray
-+```
-+
-+## License
-+
-+(MIT)
-+
-+Copyright (c) 2013 Julian Gruber <julian at juliangruber.com>
-+
-+Permission is hereby granted, free of charge, to any person obtaining a copy of
-+this software and associated documentation files (the "Software"), to deal in
-+the Software without restriction, including without limitation the rights to
-+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+of the Software, and to permit persons to whom the Software is furnished to do
-+so, subject to the following conditions:
-+
-+The above copyright notice and this permission notice shall be included in all
-+copies or substantial portions of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+SOFTWARE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/isarray/build/build.js
-@@ -0,0 +1,209 @@
-+
-+/**
-+ * Require the given path.
-+ *
-+ * @param {String} path
-+ * @return {Object} exports
-+ * @api public
-+ */
-+
-+function require(path, parent, orig) {
-+  var resolved = require.resolve(path);
-+
-+  // lookup failed
-+  if (null == resolved) {
-+    orig = orig || path;
-+    parent = parent || 'root';
-+    var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
-+    err.path = orig;
-+    err.parent = parent;
-+    err.require = true;
-+    throw err;
-+  }
-+
-+  var module = require.modules[resolved];
-+
-+  // perform real require()
-+  // by invoking the module's
-+  // registered function
-+  if (!module.exports) {
-+    module.exports = {};
-+    module.client = module.component = true;
-+    module.call(this, module.exports, require.relative(resolved), module);
-+  }
-+
-+  return module.exports;
-+}
-+
-+/**
-+ * Registered modules.
-+ */
-+
-+require.modules = {};
-+
-+/**
-+ * Registered aliases.
-+ */
-+
-+require.aliases = {};
-+
-+/**
-+ * Resolve `path`.
-+ *
-+ * Lookup:
-+ *
-+ *   - PATH/index.js
-+ *   - PATH.js
-+ *   - PATH
-+ *
-+ * @param {String} path
-+ * @return {String} path or null
-+ * @api private
-+ */
-+
-+require.resolve = function(path) {
-+  if (path.charAt(0) === '/') path = path.slice(1);
-+  var index = path + '/index.js';
-+
-+  var paths = [
-+    path,
-+    path + '.js',
-+    path + '.json',
-+    path + '/index.js',
-+    path + '/index.json'
-+  ];
-+
-+  for (var i = 0; i < paths.length; i++) {
-+    var path = paths[i];
-+    if (require.modules.hasOwnProperty(path)) return path;
-+  }
-+
-+  if (require.aliases.hasOwnProperty(index)) {
-+    return require.aliases[index];
-+  }
-+};
-+
-+/**
-+ * Normalize `path` relative to the current path.
-+ *
-+ * @param {String} curr
-+ * @param {String} path
-+ * @return {String}
-+ * @api private
-+ */
-+
-+require.normalize = function(curr, path) {
-+  var segs = [];
-+
-+  if ('.' != path.charAt(0)) return path;
-+
-+  curr = curr.split('/');
-+  path = path.split('/');
-+
-+  for (var i = 0; i < path.length; ++i) {
-+    if ('..' == path[i]) {
-+      curr.pop();
-+    } else if ('.' != path[i] && '' != path[i]) {
-+      segs.push(path[i]);
-+    }
-+  }
-+
-+  return curr.concat(segs).join('/');
-+};
-+
-+/**
-+ * Register module at `path` with callback `definition`.
-+ *
-+ * @param {String} path
-+ * @param {Function} definition
-+ * @api private
-+ */
-+
-+require.register = function(path, definition) {
-+  require.modules[path] = definition;
-+};
-+
-+/**
-+ * Alias a module definition.
-+ *
-+ * @param {String} from
-+ * @param {String} to
-+ * @api private
-+ */
-+
-+require.alias = function(from, to) {
-+  if (!require.modules.hasOwnProperty(from)) {
-+    throw new Error('Failed to alias "' + from + '", it does not exist');
-+  }
-+  require.aliases[to] = from;
-+};
-+
-+/**
-+ * Return a require function relative to the `parent` path.
-+ *
-+ * @param {String} parent
-+ * @return {Function}
-+ * @api private
-+ */
-+
-+require.relative = function(parent) {
-+  var p = require.normalize(parent, '..');
-+
-+  /**
-+   * lastIndexOf helper.
-+   */
-+
-+  function lastIndexOf(arr, obj) {
-+    var i = arr.length;
-+    while (i--) {
-+      if (arr[i] === obj) return i;
-+    }
-+    return -1;
-+  }
-+
-+  /**
-+   * The relative require() itself.
-+   */
-+
-+  function localRequire(path) {
-+    var resolved = localRequire.resolve(path);
-+    return require(resolved, parent, path);
-+  }
-+
-+  /**
-+   * Resolve relative to the parent.
-+   */
-+
-+  localRequire.resolve = function(path) {
-+    var c = path.charAt(0);
-+    if ('/' == c) return path.slice(1);
-+    if ('.' == c) return require.normalize(p, path);
-+
-+    // resolve deps by returning
-+    // the dep in the nearest "deps"
-+    // directory
-+    var segs = parent.split('/');
-+    var i = lastIndexOf(segs, 'deps') + 1;
-+    if (!i) i = 0;
-+    path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
-+    return path;
-+  };
-+
-+  /**
-+   * Check if module is defined at `path`.
-+   */
-+
-+  localRequire.exists = function(path) {
-+    return require.modules.hasOwnProperty(localRequire.resolve(path));
-+  };
-+
-+  return localRequire;
-+};
-+require.register("isarray/index.js", function(exports, require, module){
-+module.exports = Array.isArray || function (arr) {
-+  return Object.prototype.toString.call(arr) == '[object Array]';
-+};
-+
-+});
-+require.alias("isarray/index.js", "isarray/index.js");
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/isarray/component.json
-@@ -0,0 +1,19 @@
-+{
-+  "name" : "isarray",
-+  "description" : "Array#isArray for older browsers",
-+  "version" : "0.0.1",
-+  "repository" : "juliangruber/isarray",
-+  "homepage": "https://github.com/juliangruber/isarray",
-+  "main" : "index.js",
-+  "scripts" : [
-+    "index.js"
-+  ],
-+  "dependencies" : {},
-+  "keywords": ["browser","isarray","array"],
-+  "author": {
-+    "name": "Julian Gruber",
-+    "email": "mail at juliangruber.com",
-+    "url": "http://juliangruber.com"
-+  },
-+  "license": "MIT"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/isarray/index.js
-@@ -0,0 +1,3 @@
-+module.exports = Array.isArray || function (arr) {
-+  return Object.prototype.toString.call(arr) == '[object Array]';
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/isarray/package.json
-@@ -0,0 +1,40 @@
-+{
-+  "name": "isarray",
-+  "description": "Array#isArray for older browsers",
-+  "version": "0.0.1",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/juliangruber/isarray.git"
-+  },
-+  "homepage": "https://github.com/juliangruber/isarray",
-+  "main": "index.js",
-+  "scripts": {
-+    "test": "tap test/*.js"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "*"
-+  },
-+  "keywords": [
-+    "browser",
-+    "isarray",
-+    "array"
-+  ],
-+  "author": {
-+    "name": "Julian Gruber",
-+    "email": "mail at juliangruber.com",
-+    "url": "http://juliangruber.com"
-+  },
-+  "license": "MIT",
-+  "readme": "\n# isarray\n\n`Array#isArray` for older browsers.\n\n## Usage\n\n```js\nvar isArray = require('isarray');\n\nconsole.log(isArray([])); // => true\nconsole.log(isArray({})); // => false\n```\n\n## Installation\n\nWith [npm](http://npmjs.org) do\n\n```bash\n$ npm install isarray\n```\n\nThen bundle for the browser with\n[browserify](https://github.com/substack/browserify).\n\nWith [component](http://component.io) do\n\n```bash\n$ component install juliangruber/isarray\n```\n\n## License\n\n(MIT)\n\nCopyright (c) 2013 Julian Gruber <julian at juliangruber.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/juliangruber/isarray/issues"
-+  },
-+  "_id": "isarray at 0.0.1",
-+  "dist": {
-+    "shasum": "dc2d43f65e32bd485997e422c73ade69f488882f"
-+  },
-+  "_from": "isarray at 0.0.1",
-+  "_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/string_decoder/.npmignore
-@@ -0,0 +1,2 @@
-+build
-+test
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/string_decoder/LICENSE
-@@ -0,0 +1,20 @@
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/string_decoder/README.md
-@@ -0,0 +1,7 @@
-+**string_decoder.js** (`require('string_decoder')`) from Node.js core
-+
-+Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details.
-+
-+Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**
-+
-+The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/string_decoder/index.js
-@@ -0,0 +1,200 @@
-+// 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 = require('buffer').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);
-+  }
-+}
-+
-+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;
-+  }
-+
-+  this.charBuffer = new Buffer(6);
-+  this.charReceived = 0;
-+  this.charLength = 0;
-+};
-+
-+
-+StringDecoder.prototype.write = function(buffer) {
-+  var charStr = '';
-+  var offset = 0;
-+
-+  // 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 i = (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, offset, i);
-+    this.charReceived += (i - offset);
-+    offset = i;
-+
-+    if (this.charReceived < this.charLength) {
-+      // still not enough chars in this buffer? wait for more ...
-+      return '';
-+    }
-+
-+    // get the character that was split
-+    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
-+
-+    // 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 (i == buffer.length) return charStr;
-+
-+    // otherwise cut off the characters end from the beginning of this buffer
-+    buffer = buffer.slice(i, buffer.length);
-+    break;
-+  }
-+
-+  var lenIncomplete = this.detectIncompleteChar(buffer);
-+
-+  var end = buffer.length;
-+  if (this.charLength) {
-+    // buffer the incomplete character bytes we got
-+    buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end);
-+    this.charReceived = lenIncomplete;
-+    end -= lenIncomplete;
-+  }
-+
-+  charStr += buffer.toString(this.encoding, 0, end);
-+
-+  var end = charStr.length - 1;
-+  var charCode = charStr.charCodeAt(end);
-+  // 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);
-+    this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding);
-+    return charStr.substring(0, end);
-+  }
-+
-+  // or just emit the charStr
-+  return charStr;
-+};
-+
-+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;
-+    }
-+  }
-+
-+  return 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) {
-+  var incomplete = this.charReceived = buffer.length % 2;
-+  this.charLength = incomplete ? 2 : 0;
-+  return incomplete;
-+}
-+
-+function base64DetectIncompleteChar(buffer) {
-+  var incomplete = this.charReceived = buffer.length % 3;
-+  this.charLength = incomplete ? 3 : 0;
-+  return incomplete;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/node_modules/string_decoder/package.json
-@@ -0,0 +1,32 @@
-+{
-+  "name": "string_decoder",
-+  "version": "0.10.25-1",
-+  "description": "The string_decoder module from Node core",
-+  "main": "index.js",
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "~0.4.8"
-+  },
-+  "scripts": {
-+    "test": "tap test/simple/*.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/rvagg/string_decoder.git"
-+  },
-+  "homepage": "https://github.com/rvagg/string_decoder",
-+  "keywords": [
-+    "string",
-+    "decoder",
-+    "browser",
-+    "browserify"
-+  ],
-+  "license": "MIT",
-+  "readme": "**string_decoder.js** (`require('string_decoder')`) from Node.js core\n\nCopyright Joyent, Inc. and other Node contributors. See LICENCE file for details.\n\nVersion numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**\n\nThe *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/rvagg/string_decoder/issues"
-+  },
-+  "_id": "string_decoder at 0.10.25-1",
-+  "_from": "string_decoder@~0.10.x"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/package.json
-@@ -0,0 +1,43 @@
-+{
-+  "name": "readable-stream",
-+  "version": "1.0.27-1",
-+  "description": "Streams2, a user-land copy of the stream library from Node.js v0.10.x",
-+  "main": "readable.js",
-+  "dependencies": {
-+    "core-util-is": "~1.0.0",
-+    "isarray": "0.0.1",
-+    "string_decoder": "~0.10.x",
-+    "inherits": "~2.0.1"
-+  },
-+  "devDependencies": {
-+    "tap": "~0.2.6"
-+  },
-+  "scripts": {
-+    "test": "tap test/simple/*.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/readable-stream"
-+  },
-+  "keywords": [
-+    "readable",
-+    "stream",
-+    "pipe"
-+  ],
-+  "browser": {
-+    "util": false
-+  },
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": "MIT",
-+  "readme": "# readable-stream\n\n***Node-core streams for userland***\n\n[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true)](https://nodei.co/npm/readable-stream/)\n[![NPM](https://nodei.co/npm-dl/readable-stream.png)](https://nodei.co/npm/readable-stream/)\n\nThis package is a mirror of the Streams2 and Streams3 implementations in Node-core.\n\nIf you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *\"stream\"* module in Node-core.\n\n**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.\n\n**readable-stream** uses proper patch-level versioning so if you pin to `\"~1.0.0\"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `\"~1.1.0\"`\n\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/readable-stream/issues"
-+  },
-+  "_id": "readable-stream at 1.0.27-1",
-+  "_from": "readable-stream@~1.0.26"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/passthrough.js
-@@ -0,0 +1 @@
-+module.exports = require("./lib/_stream_passthrough.js")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/readable.js
-@@ -0,0 +1,6 @@
-+exports = module.exports = require('./lib/_stream_readable.js');
-+exports.Readable = exports;
-+exports.Writable = require('./lib/_stream_writable.js');
-+exports.Duplex = require('./lib/_stream_duplex.js');
-+exports.Transform = require('./lib/_stream_transform.js');
-+exports.PassThrough = require('./lib/_stream_passthrough.js');
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/transform.js
-@@ -0,0 +1 @@
-+module.exports = require("./lib/_stream_transform.js")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/readable-stream/writable.js
-@@ -0,0 +1 @@
-+module.exports = require("./lib/_stream_writable.js")
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/.npmignore
-@@ -0,0 +1,2 @@
-+node_modules
-+sandbox.js
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/.travis.yml
-@@ -0,0 +1,6 @@
-+language: node_js
-+node_js:
-+  - "0.8"
-+  - "0.10"
-+before_install:
-+  - npm install -g npm@~1.4.6
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/README.md
-@@ -0,0 +1,119 @@
-+# tar-stream
-+
-+tar-stream is a streaming tar parser and generator and nothing else. It is streams2 and operates purely using streams which means you can easily extract/parse tarballs without ever hitting the file system.
-+
-+	npm install tar-stream
-+
-+[![build status](https://secure.travis-ci.org/mafintosh/tar-stream.png)](http://travis-ci.org/mafintosh/tar-stream)
-+
-+# Usage
-+
-+tar-stream exposes two streams, [pack](https://github.com/mafintosh/tar-stream#packing) which creates tarballs and [extract](https://github.com/mafintosh/tar-stream#extracting) which extracts tarballs. To [modify an existing tarball](https://github.com/mafintosh/tar-stream#modifying-existing-tarballs) use both.
-+
-+## Packing
-+
-+To create a pack stream use `tar.pack()` and call `pack.entry(header, [callback])` to add tar entries.
-+
-+``` js
-+var tar = require('tar-stream');
-+var pack = tar.pack(); // p is a streams2 stream
-+
-+// add a file called my-test.txt with the content "Hello World!"
-+pack.entry({ name: 'my-test.txt' }, 'Hello World!');
-+
-+// add a file called my-stream-test.txt from a stream
-+var entry = pack.entry({ name: 'my-stream-test.txt' }, function(err) {
-+	// the stream was added
-+	// no more entries
-+	pack.finalize();
-+});
-+myStream.pipe(entry);
-+
-+// pipe the pack stream somewhere
-+pack.pipe(process.stdout);
-+```
-+
-+## Extracting
-+
-+To extract a stream use `tar.extract()` and listen for `extract.on('entry', header, stream, callback)`
-+
-+``` js
-+var extract = tar.extract();
-+
-+extract.on('entry', function(header, stream, callback) {
-+	// header is the tar header
-+	// stream is the content body (might be an empty stream)
-+	// call next when you are done with this entry
-+
-+	stream.resume(); // just auto drain the stream
-+	stream.on('end', function() {
-+		callback(); // ready for next entry
-+	});
-+});
-+
-+extract.on('finish', function() {
-+	// all entries read
-+});
-+
-+pack.pipe(extract);
-+```
-+
-+## Headers
-+
-+The header object using in `entry` should contain the following properties.
-+Most of these values can be found by stating a file.
-+
-+``` js
-+{
-+	name: 'path/to/this/entry.txt',
-+	size: 1314,        // entry size. defaults to 0
-+	mode: 0644,        // entry mode. defaults to to 0755 for dirs and 0644 otherwise
-+	mtime: new Date(), // last modified date for entry. defaults to now.
-+	type: 'file',      // type of entry. defaults to file. can be:
-+	                   // file | link | symlink | directory | block-device
-+	                   // character-device | fifo | contigious-file
-+	linkname: 'path',  // linked file name
-+	uid: 0,            // uid of entry owner. defaults to 0
-+	gid: 0,            // gid of entry owner. defaults to 0
-+	uname: 'maf',      // uname of entry owner. defaults to null
-+	gname: 'staff',    // gname of entry owner. defaults to null
-+	devmajor: 0,       // device major version. defaults to 0
-+	devminor: 0        // device minor version. defaults to 0
-+}
-+```
-+
-+## Modifying existing tarballs
-+
-+Using tar-stream it is easy to rewrite paths / change modes etc in an existing tarball.
-+
-+``` js
-+var extract = tar.extract();
-+var pack = tar.pack();
-+var path = require('path');
-+
-+extract.on('entry', function(header, stream, callback) {
-+	// let's prefix all names with 'tmp'
-+	header.name = path.join('tmp', header.name);
-+	// write the new entry to the pack stream
-+	stream.pipe(pack.entry(header, callback));
-+});
-+
-+extract.on('finish', function() {
-+	// all entries done - lets finalize it
-+	pack.finalize();
-+});
-+
-+// pipe the old tarball to the extractor
-+oldTarball.pipe(extract);
-+
-+// pipe the new tarball the another stream
-+pack.pipe(newTarball);
-+```
-+
-+## Performance
-+
-+[See tar-fs for a performance comparison with node-tar](https://github.com/mafintosh/tar-fs/blob/master/README.md#performance)
-+
-+# License
-+
-+MIT
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/extract.js
-@@ -0,0 +1,194 @@
-+var util = require('util');
-+var bl = require('bl');
-+var xtend = require('xtend');
-+var headers = require('./headers');
-+
-+var Writable = require('readable-stream').Writable;
-+var PassThrough = require('readable-stream').PassThrough;
-+
-+var noop = function() {};
-+
-+var overflow = function(size) {
-+	size &= 511;
-+	return size && 512 - size;
-+};
-+
-+var emptyStream = function() {
-+	var s = new PassThrough();
-+	s.end();
-+	return s;
-+};
-+
-+var mixinPax = function(header, pax) {
-+	if (pax.path) header.name = pax.path;
-+	if (pax.linkpath) header.linkname = pax.linkpath;
-+	return header;
-+};
-+
-+var Extract = function(opts) {
-+	if (!(this instanceof Extract)) return new Extract(opts);
-+	Writable.call(this, opts);
-+
-+	this._buffer = bl();
-+	this._missing = 0;
-+	this._onparse = noop;
-+	this._header = null;
-+	this._stream = null;
-+	this._overflow = null;
-+	this._cb = null;
-+	this._locked = false;
-+	this._destroyed = false;
-+	this._pax = null;
-+	this._paxGlobal = null;
-+
-+	var self = this;
-+	var b = self._buffer;
-+
-+	var oncontinue = function() {
-+		self._continue();
-+	};
-+
-+	var onunlock = function(err) {
-+		self._locked = false;
-+		if (err) return self.destroy(err);
-+		if (!self._stream) oncontinue();
-+	};
-+
-+	var onstreamend = function() {
-+		self._stream = null;
-+		var drain = overflow(self._header.size);
-+		if (drain) self._parse(drain, ondrain);
-+		else self._parse(512, onheader);
-+		if (!self._locked) oncontinue();
-+	};
-+
-+	var ondrain = function() {
-+		self._buffer.consume(overflow(self._header.size));
-+		self._parse(512, onheader);
-+		oncontinue();
-+	};
-+
-+	var onpaxglobalheader = function() {
-+		var size = self._header.size;
-+		self._paxGlobal = headers.decodePax(b.slice(0, size));
-+		b.consume(size);
-+		onstreamend();
-+	}
-+
-+	var onpaxheader = function() {
-+		var size = self._header.size;
-+		self._pax = headers.decodePax(b.slice(0, size));
-+		if (self._paxGlobal) self._pax = xtend(self._paxGlobal, self._pax);
-+		b.consume(size);
-+		onstreamend();
-+	};
-+
-+	var onheader = function() {
-+		var header
-+		try {
-+			header = self._header = headers.decode(b.slice(0, 512));
-+		} catch (err) {
-+			self.emit('error', err);
-+		}
-+		b.consume(512);
-+
-+		if (!header) {
-+			self._parse(512, onheader);
-+			oncontinue();
-+			return;
-+		}
-+		if (header.type === 'pax-global-header') {
-+			self._parse(header.size, onpaxglobalheader);
-+			oncontinue();
-+			return;
-+		}
-+		if (header.type === 'pax-header') {
-+			self._parse(header.size, onpaxheader);
-+			oncontinue();
-+			return;
-+		}
-+
-+		if (self._pax) {
-+			self._header = header = mixinPax(header, self._pax);
-+			self._pax = null;
-+		}
-+
-+		self._locked = true;
-+
-+		if (!header.size) {
-+			self._parse(512, onheader);
-+			self.emit('entry', header, emptyStream(), onunlock);
-+			return;
-+		}
-+
-+		self._stream = new PassThrough();
-+
-+		self.emit('entry', header, self._stream, onunlock);
-+		self._parse(header.size, onstreamend);
-+		oncontinue();
-+	};
-+
-+	this._parse(512, onheader);
-+};
-+
-+util.inherits(Extract, Writable);
-+
-+Extract.prototype.destroy = function(err) {
-+	if (this._destroyed) return;
-+	this._destroyed = true;
-+
-+	if (err) this.emit('error', err);
-+	this.emit('close');
-+	if (this._stream) this._stream.emit('close');
-+};
-+
-+Extract.prototype._parse = function(size, onparse) {
-+	if (this._destroyed) return;
-+	this._missing = size;
-+	this._onparse = onparse;
-+};
-+
-+Extract.prototype._continue = function(err) {
-+	if (this._destroyed) return;
-+	var cb = this._cb;
-+	this._cb = noop;
-+	if (this._overflow) this._write(this._overflow, undefined, cb);
-+	else cb();
-+};
-+
-+Extract.prototype._write = function(data, enc, cb) {
-+	if (this._destroyed) return;
-+
-+	var s = this._stream;
-+	var b = this._buffer;
-+	var missing = this._missing;
-+
-+	// we do not reach end-of-chunk now. just forward it
-+
-+	if (data.length < missing) {
-+		this._missing -= data.length;
-+		this._overflow = null;
-+		if (s) return s.write(data, cb);
-+		b.append(data);
-+		return cb();
-+	}
-+
-+	// end-of-chunk. the parser should call cb.
-+
-+	this._cb = cb;
-+	this._missing = 0;
-+
-+	var overflow = null;
-+	if (data.length > missing) {
-+		overflow = data.slice(missing);
-+		data = data.slice(0, missing);
-+	}
-+
-+	if (s) s.end(data);
-+	else b.append(data);
-+
-+	this._overflow = overflow;
-+	this._onparse();
-+};
-+
-+module.exports = Extract;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/headers.js
-@@ -0,0 +1,218 @@
-+var ZEROS = '0000000000000000000';
-+var ZERO_OFFSET = '0'.charCodeAt(0);
-+var USTAR = 'ustar\x0000';
-+
-+var clamp = function(index, len, defaultValue) {
-+	if (typeof index !== 'number') return defaultValue;
-+	index = ~~index;  // Coerce to integer.
-+	if (index >= len) return len;
-+	if (index >= 0) return index;
-+	index += len;
-+	if (index >= 0) return index;
-+	return 0;
-+};
-+
-+var toType = function(flag) {
-+	switch (flag) {
-+		case 0:
-+		return 'file';
-+		case 1:
-+		return 'link';
-+		case 2:
-+		return 'symlink';
-+		case 3:
-+		return 'character-device';
-+		case 4:
-+		return 'block-device';
-+		case 5:
-+		return 'directory';
-+		case 6:
-+		return 'fifo';
-+		case 7:
-+		return 'contiguous-file';
-+		case 72:
-+		return 'pax-header';
-+		case 55:
-+		return 'pax-global-header'
-+	}
-+
-+	return null;
-+};
-+
-+var toTypeflag = function(flag) {
-+	switch (flag) {
-+		case 'file':
-+		return 0;
-+		case 'link':
-+		return 1;
-+		case 'symlink':
-+		return 2;
-+		case 'character-device':
-+		return 3;
-+		case 'block-device':
-+		return 4;
-+		case 'directory':
-+		return 5;
-+		case 'fifo':
-+		return 6;
-+		case 'contiguous-file':
-+		return 7;
-+		case 'pax-header':
-+		return 72;
-+	}
-+
-+	return 0;
-+};
-+
-+var alloc = function(size) {
-+	var buf = new Buffer(size);
-+	buf.fill(0);
-+	return buf;
-+};
-+
-+var indexOf = function(block, num, offset, end) {
-+	for (; offset < end; offset++) {
-+		if (block[offset] === num) return offset;
-+	}
-+	return end;
-+};
-+
-+var cksum = function(block) {
-+	var sum = 8 * 32;
-+	for (var i = 0; i < 148; i++)   sum += block[i];
-+	for (var i = 156; i < 512; i++) sum += block[i];
-+	return sum;
-+};
-+
-+var encodeOct = function(val, n) {
-+	val = val.toString(8);
-+	return ZEROS.slice(0, n-val.length)+val+' ';
-+};
-+
-+var decodeOct = function(val, offset) {
-+	return parseInt(val.slice(offset, clamp(indexOf(val, 32, offset, val.length), val.length, val.length)).toString(), 8);
-+};
-+
-+var decodeStr = function(val, offset, length) {
-+	return val.slice(offset, indexOf(val, 0, offset, offset+length)).toString();
-+};
-+
-+var addLength = function(str) {
-+	var len = Buffer.byteLength(str);
-+	var digits = Math.floor(Math.log(len) / Math.log(10)) + 1;
-+	if (len + digits > Math.pow(10, digits)) digits++;
-+
-+	return (len+digits)+str;
-+};
-+
-+exports.encodePax = function(opts) { // TODO: encode more stuff in pax
-+	var result = '';
-+	if (opts.name) result += addLength(' path='+opts.name+'\n');
-+	if (opts.linkname) result += addLength(' linkpath='+opts.linkname+'\n');
-+	return new Buffer(result);
-+};
-+
-+exports.decodePax = function(buf) {
-+	var result = {};
-+
-+	while (buf.length) {
-+		var i = 0;
-+		for (; i < buf.length && buf[i] !== 32; i++);
-+		var len = parseInt(buf.slice(0, i).toString());
-+		if (!len) return result;
-+
-+		var b = buf.slice(i+1, len-1).toString();
-+		var keyIndex = b.indexOf('=');
-+		if (keyIndex === -1) return result;
-+		result[b.slice(0, keyIndex)] = b.slice(keyIndex+1);
-+
-+		buf = buf.slice(len);
-+	}
-+
-+	return result;
-+};
-+
-+exports.encode = function(opts) {
-+	var buf = alloc(512);
-+	var name = opts.name;
-+	var prefix = '';
-+
-+	if (opts.typeflag === 5 && name[name.length-1] !== '/') name += '/';
-+	if (Buffer.byteLength(name) !== name.length) return null; // utf-8
-+
-+	while (Buffer.byteLength(name) > 100) {
-+		var i = name.indexOf('/');
-+		if (i === -1) return null;
-+		prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i);
-+		name = name.slice(i+1);
-+	}
-+
-+	if (Buffer.byteLength(name) > 100 || Buffer.byteLength(prefix) > 155) return null;
-+	if (opts.linkname && Buffer.byteLength(opts.linkname) > 100) return null;
-+
-+	buf.write(name);
-+	buf.write(encodeOct(opts.mode & 07777, 6), 100);
-+	buf.write(encodeOct(opts.uid, 6), 108);
-+	buf.write(encodeOct(opts.gid, 6), 116);
-+	buf.write(encodeOct(opts.size, 11), 124);
-+	buf.write(encodeOct((opts.mtime.getTime() / 1000) | 0, 11), 136);
-+
-+	buf[156] = ZERO_OFFSET + toTypeflag(opts.type);
-+
-+	if (opts.linkname) buf.write(opts.linkname, 157);
-+
-+	buf.write(USTAR, 257);
-+	if (opts.uname) buf.write(opts.uname, 265);
-+	if (opts.gname) buf.write(opts.gname, 297);
-+	buf.write(encodeOct(opts.devmajor || 0, 6), 329);
-+	buf.write(encodeOct(opts.devminor || 0, 6), 337);
-+
-+	if (prefix) buf.write(prefix, 345);
-+
-+	buf.write(encodeOct(cksum(buf), 6), 148);
-+
-+	return buf;
-+};
-+
-+exports.decode = function(buf) {
-+	var typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET;
-+	var type = toType(typeflag);
-+
-+	var name = decodeStr(buf, 0, 100);
-+	var mode = decodeOct(buf, 100);
-+	var uid = decodeOct(buf, 108);
-+	var gid = decodeOct(buf, 116);
-+	var size = decodeOct(buf, 124);
-+	var mtime = decodeOct(buf, 136);
-+	var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100);
-+	var uname = decodeStr(buf, 265, 32);
-+	var gname = decodeStr(buf, 297, 32);
-+	var devmajor = decodeOct(buf, 329);
-+	var devminor = decodeOct(buf, 337);
-+
-+	if (buf[345]) name = decodeStr(buf, 345, 155)+'/'+name;
-+
-+	var c = cksum(buf)
-+
-+	//checksum is still initial value if header was null.
-+	if (c === 8*32) return null;
-+
-+	//valid checksum
-+	if (c !== decodeOct(buf, 148)) throw new Error('invalid header');
-+
-+	return {
-+		name: name,
-+		mode: mode,
-+		uid: uid,
-+		gid: gid,
-+		size: size,
-+		mtime: new Date(1000 * mtime),
-+		type: toType(typeflag),
-+		linkname: linkname,
-+		uname: uname,
-+		gname: gname,
-+		devmajor: devmajor,
-+		devminor: devminor
-+	};
-+};
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/index.js
-@@ -0,0 +1,2 @@
-+exports.extract = require('./extract');
-+exports.pack = require('./pack');
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/.jshintrc
-@@ -0,0 +1,59 @@
-+{
-+    "predef": [ ]
-+  , "bitwise": false
-+  , "camelcase": false
-+  , "curly": false
-+  , "eqeqeq": false
-+  , "forin": false
-+  , "immed": false
-+  , "latedef": false
-+  , "noarg": true
-+  , "noempty": true
-+  , "nonew": true
-+  , "plusplus": false
-+  , "quotmark": true
-+  , "regexp": false
-+  , "undef": true
-+  , "unused": true
-+  , "strict": false
-+  , "trailing": true
-+  , "maxlen": 120
-+  , "asi": true
-+  , "boss": true
-+  , "debug": true
-+  , "eqnull": true
-+  , "esnext": true
-+  , "evil": true
-+  , "expr": true
-+  , "funcscope": false
-+  , "globalstrict": false
-+  , "iterator": false
-+  , "lastsemic": true
-+  , "laxbreak": true
-+  , "laxcomma": true
-+  , "loopfunc": true
-+  , "multistr": false
-+  , "onecase": false
-+  , "proto": false
-+  , "regexdash": false
-+  , "scripturl": true
-+  , "smarttabs": false
-+  , "shadow": false
-+  , "sub": true
-+  , "supernew": false
-+  , "validthis": true
-+  , "browser": true
-+  , "couch": false
-+  , "devel": false
-+  , "dojo": false
-+  , "mootools": false
-+  , "node": true
-+  , "nonstandard": true
-+  , "prototypejs": false
-+  , "rhino": false
-+  , "worker": true
-+  , "wsh": false
-+  , "nomen": false
-+  , "onevar": false
-+  , "passfail": false
-+}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/.npmignore
-@@ -0,0 +1 @@
-+node_modules/
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/.travis.yml
-@@ -0,0 +1,11 @@
-+language: node_js
-+node_js:
-+  - 0.8
-+  - "0.10"
-+branches:
-+  only:
-+    - master
-+notifications:
-+  email:
-+    - rod at vagg.org
-+script: npm test
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/LICENSE
-@@ -0,0 +1,39 @@
-+Copyright 2013, Rod Vagg (the "Original Author")
-+All rights reserved.
-+
-+MIT +no-false-attribs License
-+
-+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.
-+
-+Distributions of all or part of the Software intended to be used
-+by the recipients as they would use the unmodified Software,
-+containing modifications that substantially alter, remove, or
-+disable functionality of the Software, outside of the documented
-+configuration mechanisms provided by the Software, shall be
-+modified such that the Original Author's bug reporting email
-+addresses and urls are either replaced with the contact information
-+of the parties responsible for the changes, or removed entirely.
-+
-+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.
-+
-+
-+Except where noted, this license applies to any and all software
-+programs and associated documentation files created by the
-+Original Author, when distributed with the Software.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/README.md
-@@ -0,0 +1,196 @@
-+# bl *(BufferList)*
-+
-+[![Build Status](https://secure.travis-ci.org/rvagg/bl.png)](http://travis-ci.org/rvagg/bl)
-+
-+**A Node.js Buffer list collector, reader and streamer thingy.**
-+
-+[![NPM](https://nodei.co/npm/bl.png?downloads=true)](https://nodei.co/npm/bl/)
-+[![NPM](https://nodei.co/npm-dl/bl.png?months=6)](https://nodei.co/npm/bl/)
-+
-+**bl** is a storage object for collections of Node Buffers, exposing them with the main Buffer readable API. Also works as a duplex stream so you can collect buffers from a stream that emits them and emit buffers to a stream that consumes them!
-+
-+The original buffers are kept intact and copies are only done as necessary. Any reads that require the use of a single original buffer will return a slice of that buffer only (which references the same memory as the original buffer). Reads that span buffers perform concatenation as required and return the results transparently.
-+
-+```js
-+const BufferList = require('bl')
-+
-+var bl = new BufferList()
-+bl.append(new Buffer('abcd'))
-+bl.append(new Buffer('efg'))
-+bl.append('hi')                     // bl will also accept & convert Strings
-+bl.append(new Buffer('j'))
-+bl.append(new Buffer([ 0x3, 0x4 ]))
-+
-+console.log(bl.length) // 12
-+
-+console.log(bl.slice(0, 10).toString('ascii')) // 'abcdefghij'
-+console.log(bl.slice(3, 10).toString('ascii')) // 'defghij'
-+console.log(bl.slice(3, 6).toString('ascii'))  // 'def'
-+console.log(bl.slice(3, 8).toString('ascii'))  // 'defgh'
-+console.log(bl.slice(5, 10).toString('ascii')) // 'fghij'
-+
-+// or just use toString!
-+console.log(bl.toString())               // 'abcdefghij\u0003\u0004'
-+console.log(bl.toString('ascii', 3, 8))  // 'defgh'
-+console.log(bl.toString('ascii', 5, 10)) // 'fghij'
-+
-+// other standard Buffer readables
-+console.log(bl.readUInt16BE(10)) // 0x0304
-+console.log(bl.readUInt16LE(10)) // 0x0403
-+```
-+
-+Give it a callback in the constructor and use it just like **[concat-stream](https://github.com/maxogden/node-concat-stream)**:
-+
-+```js
-+const bl = require('bl')
-+    , fs = require('fs')
-+
-+fs.createReadStream('README.md')
-+  .pipe(bl(function (err, data) { // note 'new' isn't strictly required
-+    // `data` is a complete Buffer object containing the full data
-+    console.log(data.toString())
-+  }))
-+```
-+
-+Note that when you use the *callback* method like this, the resulting `data` parameter is a concatenation of all `Buffer` objects in the list. If you want to avoid the overhead of this concatenation (in cases of extreme performance consciousness), then avoid the *callback* method and just listen to `'end'` instead, like a standard Stream.
-+
-+Or to fetch a URL using [hyperquest](https://github.com/substack/hyperquest) (should work with [request](http://github.com/mikeal/request) and even plain Node http too!):
-+```js
-+const hyperquest = require('hyperquest')
-+    , bl         = require('bl')
-+    , url        = 'https://raw.github.com/rvagg/bl/master/README.md'
-+
-+hyperquest(url).pipe(bl(function (err, data) {
-+  console.log(data.toString())
-+}))
-+```
-+
-+Or, use it as a readable stream to recompose a list of Buffers to an output source:
-+
-+```js
-+const BufferList = require('bl')
-+    , fs         = require('fs')
-+
-+var bl = new BufferList()
-+bl.append(new Buffer('abcd'))
-+bl.append(new Buffer('efg'))
-+bl.append(new Buffer('hi'))
-+bl.append(new Buffer('j'))
-+
-+bl.pipe(fs.createWriteStream('gibberish.txt'))
-+```
-+
-+## API
-+
-+  * <a href="#ctor"><code><b>new BufferList([ callback ])</b></code></a>
-+  * <a href="#length"><code>bl.<b>length</b></code></a>
-+  * <a href="#append"><code>bl.<b>append(buffer)</b></code></a>
-+  * <a href="#get"><code>bl.<b>get(index)</b></code></a>
-+  * <a href="#slice"><code>bl.<b>slice([ start[, end ] ])</b></code></a>
-+  * <a href="#copy"><code>bl.<b>copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])</b></code></a>
-+  * <a href="#duplicate"><code>bl.<b>duplicate()</b></code></a>
-+  * <a href="#consume"><code>bl.<b>consume(bytes)</b></code></a>
-+  * <a href="#toString"><code>bl.<b>toString([encoding, [ start, [ end ]]])</b></code></a>
-+  * <a href="#readXX"><code>bl.<b>readDoubleBE()</b></code>, <code>bl.<b>readDoubleLE()</b></code>, <code>bl.<b>readFloatBE()</b></code>, <code>bl.<b>readFloatLE()</b></code>, <code>bl.<b>readInt32BE()</b></code>, <code>bl.<b>readInt32LE()</b></code>, <code>bl.<b>readUInt32BE()</b></code>, <code>bl.<b>readUInt32LE()</b></code>, <code>bl.<b>readInt16BE()</b></code>, <code>bl.<b>readInt16LE()</b></code>, <code>bl.<b>readUInt16BE()</b></code>, <code>bl.<b>readUInt16LE()</b></code>, <code>bl.<b>readInt8()</b></code>, <code>bl.<b>readUInt8()</b></code></a>
-+  * <a href="#streams">Streams</a>
-+
-+--------------------------------------------------------
-+<a name="ctor"></a>
-+### new BufferList([ callback | buffer | buffer array ])
-+The constructor takes an optional callback, if supplied, the callback will be called with an error argument followed by a reference to the **bl** instance, when `bl.end()` is called (i.e. from a piped stream). This is a convenient method of collecting the entire contents of a stream, particularly when the stream is *chunky*, such as a network stream.
-+
-+Normally, no arguments are required for the constructor, but you can initialise the list by passing in a single `Buffer` object or an array of `Buffer` object.
-+
-+`new` is not strictly required, if you don't instantiate a new object, it will be done automatically for you so you can create a new instance simply with:
-+
-+```js
-+var bl = require('bl')
-+var myinstance = bl()
-+
-+// equivilant to:
-+
-+var BufferList = require('bl')
-+var myinstance = new BufferList()
-+```
-+
-+--------------------------------------------------------
-+<a name="length"></a>
-+### bl.length
-+Get the length of the list in bytes. This is the sum of the lengths of all of the buffers contained in the list, minus any initial offset for a semi-consumed buffer at the beginning. Should accurately represent the total number of bytes that can be read from the list.
-+
-+--------------------------------------------------------
-+<a name="append"></a>
-+### bl.append(buffer)
-+`append(buffer)` adds an additional buffer to the internal list.
-+
-+--------------------------------------------------------
-+<a name="get"></a>
-+### bl.get(index)
-+`get()` will return the byte at the specified index.
-+
-+--------------------------------------------------------
-+<a name="slice"></a>
-+### bl.slice([ start, [ end ] ])
-+`slice()` returns a new `Buffer` object containing the bytes within the range specified. Both `start` and `end` are optional and will default to the beginning and end of the list respectively.
-+
-+If the requested range spans a single internal buffer then a slice of that buffer will be returned which shares the original memory range of that Buffer. If the range spans multiple buffers then copy operations will likely occur to give you a uniform Buffer.
-+
-+--------------------------------------------------------
-+<a name="copy"></a>
-+### bl.copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])
-+`copy()` copies the content of the list in the `dest` buffer, starting from `destStart` and containing the bytes within the range specified with `srcStart` to `srcEnd`. `destStart`, `start` and `end` are optional and will default to the beginning of the `dest` buffer, and the beginning and end of the list respectively.
-+
-+--------------------------------------------------------
-+<a name="duplicate"></a>
-+### bl.duplicate()
-+`duplicate()` performs a **shallow-copy** of the list. The internal Buffers remains the same, so if you change the underlying Buffers, the change will be reflected in both the original and the duplicate. This method is needed if you want to call `consume()` or `pipe()` and still keep the original list.Example:
-+
-+```js
-+var bl = new BufferList()
-+
-+bl.append('hello')
-+bl.append(' world')
-+bl.append('\n')
-+
-+bl.duplicate().pipe(process.stdout, { end: false })
-+
-+console.log(bl.toString())
-+```
-+
-+--------------------------------------------------------
-+<a name="consume"></a>
-+### bl.consume(bytes)
-+`consume()` will shift bytes *off the start of the list*. The number of bytes consumed don't need to line up with the sizes of the internal Buffers—initial offsets will be calculated accordingly in order to give you a consistent view of the data.
-+
-+--------------------------------------------------------
-+<a name="toString"></a>
-+### bl.toString([encoding, [ start, [ end ]]])
-+`toString()` will return a string representation of the buffer. The optional `start` and `end` arguments are passed on to `slice()`, while the `encoding` is passed on to `toString()` of the resulting Buffer. See the [Buffer#toString()](http://nodejs.org/docs/latest/api/buffer.html#buffer_buf_tostring_encoding_start_end) documentation for more information.
-+
-+--------------------------------------------------------
-+<a name="readXX"></a>
-+### <code>bl.readDoubleBE()</code>, <code>bl.readDoubleLE()</code>, <code>bl.readFloatBE()</code>, <code>bl.readFloatLE()</code>, <code>bl.readInt32BE()</code>, <code>bl.readInt32LE()</code>, <code>bl.readUInt32BE()</code>, <code>bl.readUInt32LE()</code>, <code>bl.readInt16BE()</code>, <code>bl.readInt16LE()</code>, <code>bl.readUInt16BE()</code>, <code>bl.readUInt16LE()</code>, <code>bl.readInt8()</code>, <code>bl.readUInt8()</code>
-+
-+All of the standard byte-reading methods of the `Buffer` interface are implemented and will operate across internal Buffer boundaries transparently.
-+
-+See the <b><code>[Buffer](http://nodejs.org/docs/latest/api/buffer.html)</code></b> documentation for how these work.
-+
-+--------------------------------------------------------
-+<a name="streams"></a>
-+### Streams
-+**bl** is a Node **[Duplex Stream](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_duplex)**, so it can be read from and written to like a standard Node stream. You can also `pipe()` to and from a **bl** instance.
-+
-+--------------------------------------------------------
-+
-+## Contributors
-+
-+**bl** is brought to you by the following hackers:
-+
-+ * [Rod Vagg](https://github.com/rvagg)
-+ * [Matteo Collina](https://github.com/mcollina)
-+
-+=======
-+
-+## License
-+
-+**bl** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/bl.js
-@@ -0,0 +1,213 @@
-+var DuplexStream = require('readable-stream').Duplex
-+  , util         = require('util')
-+
-+function BufferList (callback) {
-+  if (!(this instanceof BufferList))
-+    return new BufferList(callback)
-+
-+  this._bufs  = []
-+  this.length = 0
-+
-+  if (typeof callback == 'function') {
-+    this._callback = callback
-+
-+    var piper = function (err) {
-+      if (this._callback) {
-+        this._callback(err)
-+        this._callback = null
-+      }
-+    }.bind(this)
-+
-+    this.on('pipe', function (src) {
-+      src.on('error', piper)
-+    })
-+    this.on('unpipe', function (src) {
-+      src.removeListener('error', piper)
-+    })
-+  }
-+  else if (Buffer.isBuffer(callback))
-+    this.append(callback)
-+  else if (Array.isArray(callback)) {
-+    callback.forEach(function (b) {
-+      Buffer.isBuffer(b) && this.append(b)
-+    }.bind(this))
-+  }
-+
-+  DuplexStream.call(this)
-+}
-+
-+util.inherits(BufferList, DuplexStream)
-+
-+BufferList.prototype._offset = function (offset) {
-+  var tot = 0, i = 0, _t
-+  for (; i < this._bufs.length; i++) {
-+    _t = tot + this._bufs[i].length
-+    if (offset < _t)
-+      return [ i, offset - tot ]
-+    tot = _t
-+  }
-+}
-+
-+BufferList.prototype.append = function (buf) {
-+  this._bufs.push(Buffer.isBuffer(buf) ? buf : new Buffer(buf))
-+  this.length += buf.length
-+  return this
-+}
-+
-+BufferList.prototype._write = function (buf, encoding, callback) {
-+  this.append(buf)
-+  if (callback)
-+    callback()
-+}
-+
-+BufferList.prototype._read = function (size) {
-+  if (!this.length)
-+    return this.push(null)
-+  size = Math.min(size, this.length)
-+  this.push(this.slice(0, size))
-+  this.consume(size)
-+}
-+
-+BufferList.prototype.end = function (chunk) {
-+  DuplexStream.prototype.end.call(this, chunk)
-+
-+  if (this._callback) {
-+    this._callback(null, this.slice())
-+    this._callback = null
-+  }
-+}
-+
-+BufferList.prototype.get = function (index) {
-+  return this.slice(index, index + 1)[0]
-+}
-+
-+BufferList.prototype.slice = function (start, end) {
-+  return this.copy(null, 0, start, end)
-+}
-+
-+BufferList.prototype.copy = function (dst, dstStart, srcStart, srcEnd) {
-+  if (typeof srcStart != 'number' || srcStart < 0)
-+    srcStart = 0
-+  if (typeof srcEnd != 'number' || srcEnd > this.length)
-+    srcEnd = this.length
-+  if (srcStart >= this.length)
-+    return dst || new Buffer(0)
-+  if (srcEnd <= 0)
-+    return dst || new Buffer(0)
-+
-+  var copy   = !!dst
-+    , off    = this._offset(srcStart)
-+    , len    = srcEnd - srcStart
-+    , bytes  = len
-+    , bufoff = (copy && dstStart) || 0
-+    , start  = off[1]
-+    , l
-+    , i
-+
-+  // copy/slice everything
-+  if (srcStart === 0 && srcEnd == this.length) {
-+    if (!copy) // slice, just return a full concat
-+      return Buffer.concat(this._bufs)
-+
-+    // copy, need to copy individual buffers
-+    for (i = 0; i < this._bufs.length; i++) {
-+      this._bufs[i].copy(dst, bufoff)
-+      bufoff += this._bufs[i].length
-+    }
-+
-+    return dst
-+  }
-+
-+  // easy, cheap case where it's a subset of one of the buffers
-+  if (bytes <= this._bufs[off[0]].length - start) {
-+    return copy
-+      ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes)
-+      : this._bufs[off[0]].slice(start, start + bytes)
-+  }
-+
-+  if (!copy) // a slice, we need something to copy in to
-+    dst = new Buffer(len)
-+
-+  for (i = off[0]; i < this._bufs.length; i++) {
-+    l = this._bufs[i].length - start
-+
-+    if (bytes > l) {
-+      this._bufs[i].copy(dst, bufoff, start)
-+    } else {
-+      this._bufs[i].copy(dst, bufoff, start, start + bytes)
-+      break
-+    }
-+
-+    bufoff += l
-+    bytes -= l
-+
-+    if (start)
-+      start = 0
-+  }
-+
-+  return dst
-+}
-+
-+BufferList.prototype.toString = function (encoding, start, end) {
-+  return this.slice(start, end).toString(encoding)
-+}
-+
-+BufferList.prototype.consume = function (bytes) {
-+  while (this._bufs.length) {
-+    if (bytes > this._bufs[0].length) {
-+      bytes -= this._bufs[0].length
-+      this.length -= this._bufs[0].length
-+      this._bufs.shift()
-+    } else {
-+      this._bufs[0] = this._bufs[0].slice(bytes)
-+      this.length -= bytes
-+      break
-+    }
-+  }
-+  return this
-+}
-+
-+BufferList.prototype.duplicate = function () {
-+  var i = 0
-+    , copy = new BufferList()
-+
-+  for (; i < this._bufs.length; i++)
-+    copy.append(this._bufs[i])
-+
-+  return copy
-+}
-+
-+BufferList.prototype.destroy = function () {
-+  this._bufs.length = 0;
-+  this.length = 0;
-+  this.push(null);
-+}
-+
-+;(function () {
-+  var methods = {
-+      'readDoubleBE' : 8
-+    , 'readDoubleLE' : 8
-+    , 'readFloatBE'  : 4
-+    , 'readFloatLE'  : 4
-+    , 'readInt32BE'  : 4
-+    , 'readInt32LE'  : 4
-+    , 'readUInt32BE' : 4
-+    , 'readUInt32LE' : 4
-+    , 'readInt16BE'  : 2
-+    , 'readInt16LE'  : 2
-+    , 'readUInt16BE' : 2
-+    , 'readUInt16LE' : 2
-+    , 'readInt8'     : 1
-+    , 'readUInt8'    : 1
-+  }
-+
-+  for (var m in methods) {
-+    (function (m) {
-+      BufferList.prototype[m] = function (offset) {
-+        return this.slice(offset, offset + methods[m])[m](0)
-+      }
-+    }(m))
-+  }
-+}())
-+
-+module.exports = BufferList
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/package.json
-@@ -0,0 +1,42 @@
-+{
-+  "name": "bl",
-+  "version": "0.8.2",
-+  "description": "Buffer List: collect buffers and access with a standard readable Buffer interface, streamable too!",
-+  "main": "bl.js",
-+  "scripts": {
-+    "test": "node test/test.js | faucet",
-+    "test-local": "brtapsauce-local test/basic-test.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/rvagg/bl.git"
-+  },
-+  "homepage": "https://github.com/rvagg/bl",
-+  "authors": [
-+    "Rod Vagg <rod at vagg.org> (https://github.com/rvagg)",
-+    "Matteo Collina <matteo.collina at gmail.com> (https://github.com/mcollina)"
-+  ],
-+  "keywords": [
-+    "buffer",
-+    "buffers",
-+    "stream",
-+    "awesomesauce"
-+  ],
-+  "license": "MIT",
-+  "dependencies": {
-+    "readable-stream": "~1.0.26"
-+  },
-+  "devDependencies": {
-+    "tape": "~2.12.3",
-+    "hash_file": "~0.1.1",
-+    "faucet": "~0.0.1",
-+    "brtapsauce": "~0.3.0"
-+  },
-+  "readme": "# bl *(BufferList)*\n\n[![Build Status](https://secure.travis-ci.org/rvagg/bl.png)](http://travis-ci.org/rvagg/bl)\n\n**A Node.js Buffer list collector, reader and streamer thingy.**\n\n[![NPM](https://nodei.co/npm/bl.png?downloads=true)](https://nodei.co/npm/bl/)\n[![NPM](https://nodei.co/npm-dl/bl.png?months=6)](https://nodei.co/npm/bl/)\n\n**bl** is a storage object for collections of Node Buffers, exposing them with the main Buffer readable API. Also works as a duplex stream so you can collect buffers from a stream that emits them and emit buffers to a stream that consumes them!\n\nThe original buffers are kept intact and copies are only done as necessary. Any reads that require the use of a single original buffer will return a slice of that buffer only (which references the same memory as the original buffer). Reads that span buffers perform concatenation as required and return the results transparently.\n\n```js\nconst BufferList = require('bl')\n\nvar bl = new BufferList()\nbl.append(new Buffer('abcd'))\nbl.append(new Buffer('efg'))\nbl.append('hi')                     // bl will also accept & convert Strings\nbl.append(new Buffer('j'))\nbl.append(new Buffer([ 0x3, 0x4 ]))\n\nconsole.log(bl.length) // 12\n\nconsole.log(bl.slice(0, 10).toString('ascii')) // 'abcdefghij'\nconsole.log(bl.slice(3, 10).toString('ascii')) // 'defghij'\nconsole.log(bl.slice(3, 6).toString('ascii'))  // 'def'\nconsole.log(bl.slice(3, 8).toString('ascii'))  // 'defgh'\nconsole.log(bl.slice(5, 10).toString('ascii')) // 'fghij'\n\n// or just use toString!\nconsole.log(bl.toString())               // 'abcdefghij\\u0003\\u0004'\nconsole.log(bl.toString('ascii', 3, 8))  // 'defgh'\nconsole.log(bl.toString('ascii', 5, 10)) // 'fghij'\n\n// other standard Buffer readables\nconsole.log(bl.readUInt16BE(10)) // 0x0304\nconsole.log(bl.readUInt16LE(10)) // 0x0403\n```\n\nGive it a callback in the constructor and use it just like **[concat-stream](https://github.com/maxogden/node-concat-stream)**:\n\n```js\nconst bl = require('bl')\n    , fs = require('fs')\n\nfs.createReadStream('README.md')\n  .pipe(bl(function (err, data) { // note 'new' isn't strictly required\n    // `data` is a complete Buffer object containing the full data\n    console.log(data.toString())\n  }))\n```\n\nNote that when you use the *callback* method like this, the resulting `data` parameter is a concatenation of all `Buffer` objects in the list. If you want to avoid the overhead of this concatenation (in cases of extreme performance consciousness), then avoid the *callback* method and just listen to `'end'` instead, like a standard Stream.\n\nOr to fetch a URL using [hyperquest](https://github.com/substack/hyperquest) (should work with [request](http://github.com/mikeal/request) and even plain Node http too!):\n```js\nconst hyperquest = require('hyperquest')\n    , bl         = require('bl')\n    , url        = 'https://raw.github.com/rvagg/bl/master/README.md'\n\nhyperquest(url).pipe(bl(function (err, data) {\n  console.log(data.toString())\n}))\n```\n\nOr, use it as a readable stream to recompose a list of Buffers to an output source:\n\n```js\nconst BufferList = require('bl')\n    , fs         = require('fs')\n\nvar bl = new BufferList()\nbl.append(new Buffer('abcd'))\nbl.append(new Buffer('efg'))\nbl.append(new Buffer('hi'))\nbl.append(new Buffer('j'))\n\nbl.pipe(fs.createWriteStream('gibberish.txt'))\n```\n\n## API\n\n  * <a href=\"#ctor\"><code><b>new BufferList([ callback ])</b></code></a>\n  * <a href=\"#length\"><code>bl.<b>length</b></code></a>\n  * <a href=\"#append\"><code>bl.<b>append(buffer)</b></code></a>\n  * <a href=\"#get\"><code>bl.<b>get(index)</b></code></a>\n  * <a href=\"#slice\"><code>bl.<b>slice([ start[, end ] ])</b></code></a>\n  * <a href=\"#copy\"><code>bl.<b>copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])</b></code></a>\n  * <a href=\"#duplicate\"><code>bl.<b>duplicate()</b></code></a>\n  * <a href=\"#consume\"><code>bl.<b>consume(bytes)</b></code></a>\n  * <a href=\"#toString\"><code>bl.<b>toString([encoding, [ start, [ end ]]])</b></code></a>\n  * <a href=\"#readXX\"><code>bl.<b>readDoubleBE()</b></code>, <code>bl.<b>readDoubleLE()</b></code>, <code>bl.<b>readFloatBE()</b></code>, <code>bl.<b>readFloatLE()</b></code>, <code>bl.<b>readInt32BE()</b></code>, <code>bl.<b>readInt32LE()</b></code>, <code>bl.<b>readUInt32BE()</b></code>, <code>bl.<b>readUInt32LE()</b></code>, <code>bl.<b>readInt16BE()</b></code>, <code>bl.<b>readInt16LE()</b></code>, <code>bl.<b>readUInt16BE()</b></code>, <code>bl.<b>readUInt16LE()</b></code>, <code>bl.<b>readInt8()</b></code>, <code>bl.<b>readUInt8()</b></code></a>\n  * <a href=\"#streams\">Streams</a>\n\n--------------------------------------------------------\n<a name=\"ctor\"></a>\n### new BufferList([ callback | buffer | buffer array ])\nThe constructor takes an optional callback, if supplied, the callback will be called with an error argument followed by a reference to the **bl** instance, when `bl.end()` is called (i.e. from a piped stream). This is a convenient method of collecting the entire contents of a stream, particularly when the stream is *chunky*, such as a network stream.\n\nNormally, no arguments are required for the constructor, but you can initialise the list by passing in a single `Buffer` object or an array of `Buffer` object.\n\n`new` is not strictly required, if you don't instantiate a new object, it will be done automatically for you so you can create a new instance simply with:\n\n```js\nvar bl = require('bl')\nvar myinstance = bl()\n\n// equivilant to:\n\nvar BufferList = require('bl')\nvar myinstance = new BufferList()\n```\n\n--------------------------------------------------------\n<a name=\"length\"></a>\n### bl.length\nGet the length of the list in bytes. This is the sum of the lengths of all of the buffers contained in the list, minus any initial offset for a semi-consumed buffer at the beginning. Should accurately represent the total number of bytes that can be read from the list.\n\n--------------------------------------------------------\n<a name=\"append\"></a>\n### bl.append(buffer)\n`append(buffer)` adds an additional buffer to the internal list.\n\n--------------------------------------------------------\n<a name=\"get\"></a>\n### bl.get(index)\n`get()` will return the byte at the specified index.\n\n--------------------------------------------------------\n<a name=\"slice\"></a>\n### bl.slice([ start, [ end ] ])\n`slice()` returns a new `Buffer` object containing the bytes within the range specified. Both `start` and `end` are optional and will default to the beginning and end of the list respectively.\n\nIf the requested range spans a single internal buffer then a slice of that buffer will be returned which shares the original memory range of that Buffer. If the range spans multiple buffers then copy operations will likely occur to give you a uniform Buffer.\n\n--------------------------------------------------------\n<a name=\"copy\"></a>\n### bl.copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])\n`copy()` copies the content of the list in the `dest` buffer, starting from `destStart` and containing the bytes within the range specified with `srcStart` to `srcEnd`. `destStart`, `start` and `end` are optional and will default to the beginning of the `dest` buffer, and the beginning and end of the list respectively.\n\n--------------------------------------------------------\n<a name=\"duplicate\"></a>\n### bl.duplicate()\n`duplicate()` performs a **shallow-copy** of the list. The internal Buffers remains the same, so if you change the underlying Buffers, the change will be reflected in both the original and the duplicate. This method is needed if you want to call `consume()` or `pipe()` and still keep the original list.Example:\n\n```js\nvar bl = new BufferList()\n\nbl.append('hello')\nbl.append(' world')\nbl.append('\\n')\n\nbl.duplicate().pipe(process.stdout, { end: false })\n\nconsole.log(bl.toString())\n```\n\n--------------------------------------------------------\n<a name=\"consume\"></a>\n### bl.consume(bytes)\n`consume()` will shift bytes *off the start of the list*. The number of bytes consumed don't need to line up with the sizes of the internal Buffers—initial offsets will be calculated accordingly in order to give you a consistent view of the data.\n\n--------------------------------------------------------\n<a name=\"toString\"></a>\n### bl.toString([encoding, [ start, [ end ]]])\n`toString()` will return a string representation of the buffer. The optional `start` and `end` arguments are passed on to `slice()`, while the `encoding` is passed on to `toString()` of the resulting Buffer. See the [Buffer#toString()](http://nodejs.org/docs/latest/api/buffer.html#buffer_buf_tostring_encoding_start_end) documentation for more information.\n\n--------------------------------------------------------\n<a name=\"readXX\"></a>\n### <code>bl.readDoubleBE()</code>, <code>bl.readDoubleLE()</code>, <code>bl.readFloatBE()</code>, <code>bl.readFloatLE()</code>, <code>bl.readInt32BE()</code>, <code>bl.readInt32LE()</code>, <code>bl.readUInt32BE()</code>, <code>bl.readUInt32LE()</code>, <code>bl.readInt16BE()</code>, <code>bl.readInt16LE()</code>, <code>bl.readUInt16BE()</code>, <code>bl.readUInt16LE()</code>, <code>bl.readInt8()</code>, <code>bl.readUInt8()</code>\n\nAll of the standard byte-reading methods of the `Buffer` interface are implemented and will operate across internal Buffer boundaries transparently.\n\nSee the <b><code>[Buffer](http://nodejs.org/docs/latest/api/buffer.html)</code></b> documentation for how these work.\n\n--------------------------------------------------------\n<a name=\"streams\"></a>\n### Streams\n**bl** is a Node **[Duplex Stream](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_duplex)**, so it can be read from and written to like a standard Node stream. You can also `pipe()` to and from a **bl** instance.\n\n--------------------------------------------------------\n\n## Contributors\n\n**bl** is brought to you by the following hackers:\n\n * [Rod Vagg](https://github.com/rvagg)\n * [Matteo Collina](https://github.com/mcollina)\n\n=======\n\n## License\n\n**bl** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/rvagg/bl/issues"
-+  },
-+  "_id": "bl at 0.8.2",
-+  "_from": "bl@~0.8.1"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/test/basic-test.js
-@@ -0,0 +1,524 @@
-+var tape       = require('tape')
-+  , crypto     = require('crypto')
-+  , fs         = require('fs')
-+  , hash       = require('hash_file')
-+  , BufferList = require('../')
-+
-+  , encodings  =
-+      ('hex utf8 utf-8 ascii binary base64'
-+          + (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')
-+
-+tape('single bytes from single buffer', function (t) {
-+  var bl = new BufferList()
-+  bl.append(new Buffer('abcd'))
-+
-+  t.equal(bl.length, 4)
-+
-+  t.equal(bl.get(0), 97)
-+  t.equal(bl.get(1), 98)
-+  t.equal(bl.get(2), 99)
-+  t.equal(bl.get(3), 100)
-+
-+  t.end()
-+})
-+
-+tape('single bytes from multiple buffers', function (t) {
-+  var bl = new BufferList()
-+  bl.append(new Buffer('abcd'))
-+  bl.append(new Buffer('efg'))
-+  bl.append(new Buffer('hi'))
-+  bl.append(new Buffer('j'))
-+
-+  t.equal(bl.length, 10)
-+
-+  t.equal(bl.get(0), 97)
-+  t.equal(bl.get(1), 98)
-+  t.equal(bl.get(2), 99)
-+  t.equal(bl.get(3), 100)
-+  t.equal(bl.get(4), 101)
-+  t.equal(bl.get(5), 102)
-+  t.equal(bl.get(6), 103)
-+  t.equal(bl.get(7), 104)
-+  t.equal(bl.get(8), 105)
-+  t.equal(bl.get(9), 106)
-+  t.end()
-+})
-+
-+tape('multi bytes from single buffer', function (t) {
-+  var bl = new BufferList()
-+  bl.append(new Buffer('abcd'))
-+
-+  t.equal(bl.length, 4)
-+
-+  t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')
-+  t.equal(bl.slice(0, 3).toString('ascii'), 'abc')
-+  t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')
-+
-+  t.end()
-+})
-+
-+tape('multiple bytes from multiple buffers', function (t) {
-+  var bl = new BufferList()
-+
-+  bl.append(new Buffer('abcd'))
-+  bl.append(new Buffer('efg'))
-+  bl.append(new Buffer('hi'))
-+  bl.append(new Buffer('j'))
-+
-+  t.equal(bl.length, 10)
-+
-+  t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
-+  t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
-+  t.equal(bl.slice(3, 6).toString('ascii'), 'def')
-+  t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
-+  t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
-+
-+  t.end()
-+})
-+
-+tape('consuming from multiple buffers', function (t) {
-+  var bl = new BufferList()
-+
-+  bl.append(new Buffer('abcd'))
-+  bl.append(new Buffer('efg'))
-+  bl.append(new Buffer('hi'))
-+  bl.append(new Buffer('j'))
-+
-+  t.equal(bl.length, 10)
-+
-+  t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
-+
-+  bl.consume(3)
-+  t.equal(bl.length, 7)
-+  t.equal(bl.slice(0, 7).toString('ascii'), 'defghij')
-+
-+  bl.consume(2)
-+  t.equal(bl.length, 5)
-+  t.equal(bl.slice(0, 5).toString('ascii'), 'fghij')
-+
-+  bl.consume(1)
-+  t.equal(bl.length, 4)
-+  t.equal(bl.slice(0, 4).toString('ascii'), 'ghij')
-+
-+  bl.consume(1)
-+  t.equal(bl.length, 3)
-+  t.equal(bl.slice(0, 3).toString('ascii'), 'hij')
-+
-+  bl.consume(2)
-+  t.equal(bl.length, 1)
-+  t.equal(bl.slice(0, 1).toString('ascii'), 'j')
-+
-+  t.end()
-+})
-+
-+tape('test readUInt8 / readInt8', function (t) {
-+  var buf1 = new Buffer(1)
-+    , buf2 = new Buffer(3)
-+    , buf3 = new Buffer(3)
-+    , bl  = new BufferList()
-+
-+  buf2[1] = 0x3
-+  buf2[2] = 0x4
-+  buf3[0] = 0x23
-+  buf3[1] = 0x42
-+
-+  bl.append(buf1)
-+  bl.append(buf2)
-+  bl.append(buf3)
-+
-+  t.equal(bl.readUInt8(2), 0x3)
-+  t.equal(bl.readInt8(2), 0x3)
-+  t.equal(bl.readUInt8(3), 0x4)
-+  t.equal(bl.readInt8(3), 0x4)
-+  t.equal(bl.readUInt8(4), 0x23)
-+  t.equal(bl.readInt8(4), 0x23)
-+  t.equal(bl.readUInt8(5), 0x42)
-+  t.equal(bl.readInt8(5), 0x42)
-+  t.end()
-+})
-+
-+tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) {
-+  var buf1 = new Buffer(1)
-+    , buf2 = new Buffer(3)
-+    , buf3 = new Buffer(3)
-+    , bl   = new BufferList()
-+
-+  buf2[1] = 0x3
-+  buf2[2] = 0x4
-+  buf3[0] = 0x23
-+  buf3[1] = 0x42
-+
-+  bl.append(buf1)
-+  bl.append(buf2)
-+  bl.append(buf3)
-+
-+  t.equal(bl.readUInt16BE(2), 0x0304)
-+  t.equal(bl.readUInt16LE(2), 0x0403)
-+  t.equal(bl.readInt16BE(2), 0x0304)
-+  t.equal(bl.readInt16LE(2), 0x0403)
-+  t.equal(bl.readUInt16BE(3), 0x0423)
-+  t.equal(bl.readUInt16LE(3), 0x2304)
-+  t.equal(bl.readInt16BE(3), 0x0423)
-+  t.equal(bl.readInt16LE(3), 0x2304)
-+  t.equal(bl.readUInt16BE(4), 0x2342)
-+  t.equal(bl.readUInt16LE(4), 0x4223)
-+  t.equal(bl.readInt16BE(4), 0x2342)
-+  t.equal(bl.readInt16LE(4), 0x4223)
-+  t.end()
-+})
-+
-+tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) {
-+  var buf1 = new Buffer(1)
-+    , buf2 = new Buffer(3)
-+    , buf3 = new Buffer(3)
-+    , bl   = new BufferList()
-+
-+  buf2[1] = 0x3
-+  buf2[2] = 0x4
-+  buf3[0] = 0x23
-+  buf3[1] = 0x42
-+
-+  bl.append(buf1)
-+  bl.append(buf2)
-+  bl.append(buf3)
-+
-+  t.equal(bl.readUInt32BE(2), 0x03042342)
-+  t.equal(bl.readUInt32LE(2), 0x42230403)
-+  t.equal(bl.readInt32BE(2), 0x03042342)
-+  t.equal(bl.readInt32LE(2), 0x42230403)
-+  t.end()
-+})
-+
-+tape('test readFloatLE / readFloatBE', function (t) {
-+  var buf1 = new Buffer(1)
-+    , buf2 = new Buffer(3)
-+    , buf3 = new Buffer(3)
-+    , bl   = new BufferList()
-+
-+  buf2[1] = 0x00
-+  buf2[2] = 0x00
-+  buf3[0] = 0x80
-+  buf3[1] = 0x3f
-+
-+  bl.append(buf1)
-+  bl.append(buf2)
-+  bl.append(buf3)
-+
-+  t.equal(bl.readFloatLE(2), 0x01)
-+  t.end()
-+})
-+
-+tape('test readDoubleLE / readDoubleBE', function (t) {
-+  var buf1 = new Buffer(1)
-+    , buf2 = new Buffer(3)
-+    , buf3 = new Buffer(10)
-+    , bl   = new BufferList()
-+
-+  buf2[1] = 0x55
-+  buf2[2] = 0x55
-+  buf3[0] = 0x55
-+  buf3[1] = 0x55
-+  buf3[2] = 0x55
-+  buf3[3] = 0x55
-+  buf3[4] = 0xd5
-+  buf3[5] = 0x3f
-+
-+  bl.append(buf1)
-+  bl.append(buf2)
-+  bl.append(buf3)
-+
-+  t.equal(bl.readDoubleLE(2), 0.3333333333333333)
-+  t.end()
-+})
-+
-+tape('test toString', function (t) {
-+  var bl = new BufferList()
-+
-+  bl.append(new Buffer('abcd'))
-+  bl.append(new Buffer('efg'))
-+  bl.append(new Buffer('hi'))
-+  bl.append(new Buffer('j'))
-+
-+  t.equal(bl.toString('ascii', 0, 10), 'abcdefghij')
-+  t.equal(bl.toString('ascii', 3, 10), 'defghij')
-+  t.equal(bl.toString('ascii', 3, 6), 'def')
-+  t.equal(bl.toString('ascii', 3, 8), 'defgh')
-+  t.equal(bl.toString('ascii', 5, 10), 'fghij')
-+
-+  t.end()
-+})
-+
-+tape('test toString encoding', function (t) {
-+  var bl = new BufferList()
-+    , b  = new Buffer('abcdefghij\xff\x00')
-+
-+  bl.append(new Buffer('abcd'))
-+  bl.append(new Buffer('efg'))
-+  bl.append(new Buffer('hi'))
-+  bl.append(new Buffer('j'))
-+  bl.append(new Buffer('\xff\x00'))
-+
-+  encodings.forEach(function (enc) {
-+      t.equal(bl.toString(enc), b.toString(enc), enc)
-+    })
-+
-+  t.end()
-+})
-+
-+!process.browser && tape('test stream', function (t) {
-+  var random = crypto.randomBytes(65534)
-+    , rndhash = hash(random, 'md5')
-+    , md5sum = crypto.createHash('md5')
-+    , bl     = new BufferList(function (err, buf) {
-+        t.ok(Buffer.isBuffer(buf))
-+        t.ok(err === null)
-+        t.equal(rndhash, hash(bl.slice(), 'md5'))
-+        t.equal(rndhash, hash(buf, 'md5'))
-+
-+        bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat'))
-+          .on('close', function () {
-+            var s = fs.createReadStream('/tmp/bl_test_rnd_out.dat')
-+            s.on('data', md5sum.update.bind(md5sum))
-+            s.on('end', function() {
-+              t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!')
-+              t.end()
-+            })
-+          })
-+
-+      })
-+
-+  fs.writeFileSync('/tmp/bl_test_rnd.dat', random)
-+  fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl)
-+})
-+
-+tape('instantiation with Buffer', function (t) {
-+  var buf  = crypto.randomBytes(1024)
-+    , buf2 = crypto.randomBytes(1024)
-+    , b    = BufferList(buf)
-+
-+  t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')
-+  b = BufferList([ buf, buf2 ])
-+  t.equal(b.slice().toString('hex'), Buffer.concat([ buf, buf2 ]).toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('test String appendage', function (t) {
-+  var bl = new BufferList()
-+    , b  = new Buffer('abcdefghij\xff\x00')
-+
-+  bl.append('abcd')
-+  bl.append('efg')
-+  bl.append('hi')
-+  bl.append('j')
-+  bl.append('\xff\x00')
-+
-+  encodings.forEach(function (enc) {
-+      t.equal(bl.toString(enc), b.toString(enc))
-+    })
-+
-+  t.end()
-+})
-+
-+tape('write nothing, should get empty buffer', function (t) {
-+  t.plan(3)
-+  BufferList(function (err, data) {
-+    t.notOk(err, 'no error')
-+    t.ok(Buffer.isBuffer(data), 'got a buffer')
-+    t.equal(0, data.length, 'got a zero-length buffer')
-+    t.end()
-+  }).end()
-+})
-+
-+tape('unicode string', function (t) {
-+  t.plan(2)
-+  var inp1 = '\u2600'
-+    , inp2 = '\u2603'
-+    , exp = inp1 + ' and ' + inp2
-+    , bl = BufferList()
-+  bl.write(inp1)
-+  bl.write(' and ')
-+  bl.write(inp2)
-+  t.equal(exp, bl.toString())
-+  t.equal(new Buffer(exp).toString('hex'), bl.toString('hex'))
-+})
-+
-+tape('should emit finish', function (t) {
-+  var source = BufferList()
-+    , dest = BufferList()
-+
-+  source.write('hello')
-+  source.pipe(dest)
-+
-+  dest.on('finish', function () {
-+    t.equal(dest.toString('utf8'), 'hello')
-+    t.end()
-+  })
-+})
-+
-+tape('basic copy', function (t) {
-+  var buf  = crypto.randomBytes(1024)
-+    , buf2 = new Buffer(1024)
-+    , b    = BufferList(buf)
-+
-+  b.copy(buf2)
-+  t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('copy after many appends', function (t) {
-+  var buf  = crypto.randomBytes(512)
-+    , buf2 = new Buffer(1024)
-+    , b    = BufferList(buf)
-+
-+  b.append(buf)
-+  b.copy(buf2)
-+  t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('copy at a precise position', function (t) {
-+  var buf  = crypto.randomBytes(1004)
-+    , buf2 = new Buffer(1024)
-+    , b    = BufferList(buf)
-+
-+  b.copy(buf2, 20)
-+  t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('copy starting from a precise location', function (t) {
-+  var buf  = crypto.randomBytes(10)
-+    , buf2 = new Buffer(5)
-+    , b    = BufferList(buf)
-+
-+  b.copy(buf2, 0, 5)
-+  t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('copy in an interval', function (t) {
-+  var rnd      = crypto.randomBytes(10)
-+    , b        = BufferList(rnd) // put the random bytes there
-+    , actual   = new Buffer(3)
-+    , expected = new Buffer(3)
-+
-+  rnd.copy(expected, 0, 5, 8)
-+  b.copy(actual, 0, 5, 8)
-+
-+  t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('copy an interval between two buffers', function (t) {
-+  var buf      = crypto.randomBytes(10)
-+    , buf2     = new Buffer(10)
-+    , b        = BufferList(buf)
-+
-+  b.append(buf)
-+  b.copy(buf2, 0, 5, 15)
-+
-+  t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')
-+  t.end()
-+})
-+
-+tape('duplicate', function (t) {
-+  t.plan(2)
-+
-+  var bl = new BufferList('abcdefghij\xff\x00')
-+    , dup = bl.duplicate()
-+
-+  t.equal(bl.prototype, dup.prototype)
-+  t.equal(bl.toString('hex'), dup.toString('hex'))
-+})
-+
-+tape('destroy no pipe', function (t) {
-+  t.plan(2)
-+
-+  var bl = new BufferList('alsdkfja;lsdkfja;lsdk')
-+  bl.destroy()
-+
-+  t.equal(bl._bufs.length, 0)
-+  t.equal(bl.length, 0)
-+})
-+
-+!process.browser && tape('destroy with pipe before read end', function (t) {
-+  t.plan(2)
-+
-+  var bl = new BufferList()
-+  fs.createReadStream(__dirname + '/sauce.js')
-+    .pipe(bl)
-+
-+  bl.destroy()
-+
-+  t.equal(bl._bufs.length, 0)
-+  t.equal(bl.length, 0)
-+
-+})
-+
-+!process.browser && tape('destroy with pipe before read end with race', function (t) {
-+  t.plan(2)
-+
-+  var bl = new BufferList()
-+  fs.createReadStream(__dirname + '/sauce.js')
-+    .pipe(bl)
-+
-+  setTimeout(function () {
-+    bl.destroy()
-+    setTimeout(function () {
-+      t.equal(bl._bufs.length, 0)
-+      t.equal(bl.length, 0)
-+    }, 500)
-+  }, 500)
-+})
-+
-+!process.browser && tape('destroy with pipe after read end', function (t) {
-+  t.plan(2)
-+
-+  var bl = new BufferList()
-+  fs.createReadStream(__dirname + '/sauce.js')
-+    .on('end', onEnd)
-+    .pipe(bl)
-+
-+  function onEnd () {
-+    bl.destroy()
-+
-+    t.equal(bl._bufs.length, 0)
-+    t.equal(bl.length, 0)
-+  }
-+})
-+
-+!process.browser && tape('destroy with pipe while writing to a destination', function (t) {
-+  t.plan(4)
-+
-+  var bl = new BufferList()
-+    , ds = new BufferList()
-+
-+  fs.createReadStream(__dirname + '/sauce.js')
-+    .on('end', onEnd)
-+    .pipe(bl)
-+
-+  function onEnd () {
-+    bl.pipe(ds)
-+
-+    setTimeout(function () {
-+      bl.destroy()
-+
-+      t.equals(bl._bufs.length, 0)
-+      t.equals(bl.length, 0)
-+
-+      ds.destroy()
-+
-+      t.equals(bl._bufs.length, 0)
-+      t.equals(bl.length, 0)
-+
-+    }, 100)
-+  }
-+})
-+
-+!process.browser && tape('handle error', function (t) {
-+  t.plan(2)
-+  fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {
-+    t.ok(err instanceof Error, 'has error')
-+    t.notOk(data, 'no data')
-+  }))
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/test/sauce.js
-@@ -0,0 +1,38 @@
-+#!/usr/bin/env node
-+
-+const user       = process.env.SAUCE_USER
-+    , key        = process.env.SAUCE_KEY
-+    , path       = require('path')
-+    , brtapsauce = require('brtapsauce')
-+    , testFile   = path.join(__dirname, 'basic-test.js')
-+
-+    , capabilities = [
-+          { browserName: 'chrome'            , platform: 'Windows XP', version: ''   }
-+        , { browserName: 'firefox'           , platform: 'Windows 8' , version: ''   }
-+        , { browserName: 'firefox'           , platform: 'Windows XP', version: '4'  }
-+        , { browserName: 'internet explorer' , platform: 'Windows 8' , version: '10' }
-+        , { browserName: 'internet explorer' , platform: 'Windows 7' , version: '9'  }
-+        , { browserName: 'internet explorer' , platform: 'Windows 7' , version: '8'  }
-+        , { browserName: 'internet explorer' , platform: 'Windows XP', version: '7'  }
-+        , { browserName: 'internet explorer' , platform: 'Windows XP', version: '6'  }
-+        , { browserName: 'safari'            , platform: 'Windows 7' , version: '5'  }
-+        , { browserName: 'safari'            , platform: 'OS X 10.8' , version: '6'  }
-+        , { browserName: 'opera'             , platform: 'Windows 7' , version: ''   }
-+        , { browserName: 'opera'             , platform: 'Windows 7' , version: '11' }
-+        , { browserName: 'ipad'              , platform: 'OS X 10.8' , version: '6'  }
-+        , { browserName: 'android'           , platform: 'Linux'     , version: '4.0', 'device-type': 'tablet' }
-+      ]
-+
-+if (!user)
-+  throw new Error('Must set a SAUCE_USER env var')
-+if (!key)
-+  throw new Error('Must set a SAUCE_KEY env var')
-+
-+brtapsauce({
-+    name         : 'Traversty'
-+  , user         : user
-+  , key          : key
-+  , brsrc        : testFile
-+  , capabilities : capabilities
-+  , options      : { timeout: 60 * 6 }
-+})
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/bl/test/test.js
-@@ -0,0 +1,9 @@
-+require('./basic-test')
-+
-+if (!process.env.SAUCE_KEY || !process.env.SAUCE_USER)
-+  return console.log('SAUCE_KEY and/or SAUCE_USER not set, not running sauce tests')
-+
-+if (!/v0\.10/.test(process.version))
-+  return console.log('Not Node v0.10.x, not running sauce tests')
-+
-+require('./sauce.js')
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/.npmignore
-@@ -0,0 +1 @@
-+node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/README.md
-@@ -0,0 +1,47 @@
-+# end-of-stream
-+
-+A node module that calls a callback when a readable/writable/duplex stream has completed or failed.
-+
-+	npm install end-of-stream
-+
-+## Usage
-+
-+Simply pass a stream and a callback to the `eos`.
-+Both legacy streams and streams2 are supported.
-+
-+``` js
-+var eos = require('end-of-stream');
-+
-+eos(readableStream, function(err) {
-+	if (err) return console.log('stream had an error or closed early');
-+	console.log('stream has ended');
-+});
-+
-+eos(writableStream, function(err) {
-+	if (err) return console.log('stream had an error or closed early');
-+	console.log('stream has finished');
-+});
-+
-+eos(duplexStream, function(err) {
-+	if (err) return console.log('stream had an error or closed early');
-+	console.log('stream has ended and finished');
-+});
-+
-+eos(duplexStream, {readable:false}, function(err) {
-+	if (err) return console.log('stream had an error or closed early');
-+	console.log('stream has ended but might still be writable');
-+});
-+
-+eos(duplexStream, {writable:false}, function(err) {
-+	if (err) return console.log('stream had an error or closed early');
-+	console.log('stream has ended but might still be readable');
-+});
-+
-+eos(readableStream, {error:false}, function(err) {
-+	// do not treat emit('error', err) as a end-of-stream
-+});
-+```
-+
-+## License
-+
-+MIT
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/index.js
-@@ -0,0 +1,61 @@
-+var once = require('once');
-+
-+var noop = function() {};
-+
-+var isRequest = function(stream) {
-+	return stream.setHeader && typeof stream.abort === 'function';
-+};
-+
-+var eos = function(stream, opts, callback) {
-+	if (typeof opts === 'function') return eos(stream, null, opts);
-+	if (!opts) opts = {};
-+
-+	callback = once(callback || noop);
-+
-+	var ws = stream._writableState;
-+	var rs = stream._readableState;
-+	var readable = opts.readable || (opts.readable !== false && stream.readable);
-+	var writable = opts.writable || (opts.writable !== false && stream.writable);
-+
-+	var onlegacyfinish = function() {
-+		if (!stream.writable) onfinish();
-+	};
-+
-+	var onfinish = function() {
-+		writable = false;
-+		if (!readable) callback();
-+	};
-+
-+	var onend = function() {
-+		readable = false;
-+		if (!writable) callback();
-+	};
-+
-+	var onclose = function() {
-+		if (readable && !(rs && rs.ended)) return callback(new Error('premature close'));
-+		if (writable && !(ws && ws.ended)) return callback(new Error('premature close'));
-+	};
-+
-+	var onrequest = function() {
-+		stream.req.on('finish', onfinish);
-+	};
-+
-+	if (isRequest(stream)) {
-+		stream.on('complete', onfinish);
-+		stream.on('abort', onclose);
-+		if (stream.req) onrequest();
-+		else stream.on('request', onrequest);
-+	} else if (writable && !ws) { // legacy streams
-+		stream.on('end', onlegacyfinish);
-+		stream.on('close', onlegacyfinish);
-+	}
-+
-+	stream.on('end', onend);
-+	stream.on('finish', onfinish);
-+	if (opts.error !== false) stream.on('error', callback);
-+	stream.on('close', onclose);
-+
-+	return stream;
-+};
-+
-+module.exports = eos;
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/node_modules/once/LICENSE
-@@ -0,0 +1,27 @@
-+Copyright (c) Isaac Z. Schlueter ("Author")
-+All rights reserved.
-+
-+The BSD License
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+1. Redistributions of source code must retain the above copyright
-+   notice, this list of conditions and the following disclaimer.
-+
-+2. Redistributions in binary form must reproduce the above copyright
-+   notice, this list of conditions and the following disclaimer in the
-+   documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/node_modules/once/README.md
-@@ -0,0 +1,51 @@
-+# once
-+
-+Only call a function once.
-+
-+## usage
-+
-+```javascript
-+var once = require('once')
-+
-+function load (file, cb) {
-+  cb = once(cb)
-+  loader.load('file')
-+  loader.once('load', cb)
-+  loader.once('error', cb)
-+}
-+```
-+
-+Or add to the Function.prototype in a responsible way:
-+
-+```javascript
-+// only has to be done once
-+require('once').proto()
-+
-+function load (file, cb) {
-+  cb = cb.once()
-+  loader.load('file')
-+  loader.once('load', cb)
-+  loader.once('error', cb)
-+}
-+```
-+
-+Ironically, the prototype feature makes this module twice as
-+complicated as necessary.
-+
-+To check whether you function has been called, use `fn.called`. Once the
-+function is called for the first time the return value of the original
-+function is saved in `fn.value` and subsequent calls will continue to
-+return this value.
-+
-+```javascript
-+var once = require('once')
-+
-+function load (cb) {
-+  cb = once(cb)
-+  var stream = createStream()
-+  stream.once('data', cb)
-+  stream.once('end', function () {
-+    if (!cb.called) cb(new Error('not found'))
-+  })
-+}
-+```
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/node_modules/once/once.js
-@@ -0,0 +1,20 @@
-+module.exports = once
-+
-+once.proto = once(function () {
-+  Object.defineProperty(Function.prototype, 'once', {
-+    value: function () {
-+      return once(this)
-+    },
-+    configurable: true
-+  })
-+})
-+
-+function once (fn) {
-+  var f = function () {
-+    if (f.called) return f.value
-+    f.called = true
-+    return f.value = fn.apply(this, arguments)
-+  }
-+  f.called = false
-+  return f
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/node_modules/once/package.json
-@@ -0,0 +1,39 @@
-+{
-+  "name": "once",
-+  "version": "1.3.0",
-+  "description": "Run a function exactly one time",
-+  "main": "once.js",
-+  "directories": {
-+    "test": "test"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tap": "~0.3.0"
-+  },
-+  "scripts": {
-+    "test": "tap test/*.js"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/isaacs/once"
-+  },
-+  "keywords": [
-+    "once",
-+    "function",
-+    "one",
-+    "single"
-+  ],
-+  "author": {
-+    "name": "Isaac Z. Schlueter",
-+    "email": "i at izs.me",
-+    "url": "http://blog.izs.me/"
-+  },
-+  "license": "BSD",
-+  "readme": "# once\n\nOnly call a function once.\n\n## usage\n\n```javascript\nvar once = require('once')\n\nfunction load (file, cb) {\n  cb = once(cb)\n  loader.load('file')\n  loader.once('load', cb)\n  loader.once('error', cb)\n}\n```\n\nOr add to the Function.prototype in a responsible way:\n\n```javascript\n// only has to be done once\nrequire('once').proto()\n\nfunction load (file, cb) {\n  cb = cb.once()\n  loader.load('file')\n  loader.once('load', cb)\n  loader.once('error', cb)\n}\n```\n\nIronically, the prototype feature makes this module twice as\ncomplicated as necessary.\n\nTo check whether you function has been called, use `fn.called`. Once the\nfunction is called for the first time the return value of the original\nfunction is saved in `fn.value` and subsequent calls will continue to\nreturn this value.\n\n```javascript\nvar once = require('once')\n\nfunction load (cb) {\n  cb = once(cb)\n  var stream = createStream()\n  stream.once('data', cb)\n  stream.once('end', function () {\n    if (!cb.called) cb(new Error('not found'))\n  })\n}\n```\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/isaacs/once/issues"
-+  },
-+  "_id": "once at 1.3.0",
-+  "_from": "once@~1.3.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/node_modules/once/test/once.js
-@@ -0,0 +1,20 @@
-+var test = require('tap').test
-+var once = require('../once.js')
-+
-+test('once', function (t) {
-+  var f = 0
-+  var foo = once(function (g) {
-+    t.equal(f, 0)
-+    f ++
-+    return f + g + this
-+  })
-+  t.notOk(foo.called)
-+  for (var i = 0; i < 1E3; i++) {
-+    t.same(f, i === 0 ? 0 : 1)
-+    var g = foo.call(1, 1)
-+    t.ok(foo.called)
-+    t.same(g, 3)
-+    t.same(f, 1)
-+  }
-+  t.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/package.json
-@@ -0,0 +1,38 @@
-+{
-+  "name": "end-of-stream",
-+  "version": "0.1.5",
-+  "description": "Call a callback when a readable/writable/duplex stream has completed or failed.",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/mafintosh/end-of-stream.git"
-+  },
-+  "dependencies": {
-+    "once": "~1.3.0"
-+  },
-+  "scripts": {
-+    "test": "node test.js"
-+  },
-+  "keywords": [
-+    "stream",
-+    "streams",
-+    "callback",
-+    "finish",
-+    "close",
-+    "end",
-+    "wait"
-+  ],
-+  "bugs": {
-+    "url": "https://github.com/mafintosh/end-of-stream/issues"
-+  },
-+  "homepage": "https://github.com/mafintosh/end-of-stream",
-+  "main": "index.js",
-+  "author": {
-+    "name": "Mathias Buus",
-+    "email": "mathiasbuus at gmail.com"
-+  },
-+  "license": "MIT",
-+  "readme": "# end-of-stream\n\nA node module that calls a callback when a readable/writable/duplex stream has completed or failed.\n\n\tnpm install end-of-stream\n\n## Usage\n\nSimply pass a stream and a callback to the `eos`.\nBoth legacy streams and streams2 are supported.\n\n``` js\nvar eos = require('end-of-stream');\n\neos(readableStream, function(err) {\n\tif (err) return console.log('stream had an error or closed early');\n\tconsole.log('stream has ended');\n});\n\neos(writableStream, function(err) {\n\tif (err) return console.log('stream had an error or closed early');\n\tconsole.log('stream has finished');\n});\n\neos(duplexStream, function(err) {\n\tif (err) return console.log('stream had an error or closed early');\n\tconsole.log('stream has ended and finished');\n});\n\neos(duplexStream, {readable:false}, function(err) {\n\tif (err) return console.log('stream had an error or closed early');\n\tconsole.log('stream has ended but might still be writable');\n});\n\neos(duplexStream, {writable:false}, function(err) {\n\tif (err) return console.log('stream had an error or closed early');\n\tconsole.log('stream has ended but might still be readable');\n});\n\neos(readableStream, {error:false}, function(err) {\n\t// do not treat emit('error', err) as a end-of-stream\n});\n```\n\n## License\n\nMIT",
-+  "readmeFilename": "README.md",
-+  "_id": "end-of-stream at 0.1.5",
-+  "_from": "end-of-stream@~0.1.3"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/end-of-stream/test.js
-@@ -0,0 +1,59 @@
-+var assert = require('assert');
-+var eos = require('./index');
-+
-+var expected = 6;
-+var fs = require('fs');
-+var net = require('net');
-+
-+var ws = fs.createWriteStream('/dev/null');
-+eos(ws, function(err) {
-+	expected--;
-+	assert(!!err);
-+	if (!expected) process.exit(0);
-+});
-+ws.close();
-+
-+var rs = fs.createReadStream('/dev/random');
-+eos(rs, function(err) {
-+	expected--;
-+	assert(!!err);
-+	if (!expected) process.exit(0);
-+});
-+rs.close();
-+
-+var rs = fs.createReadStream(__filename);
-+eos(rs, function(err) {
-+	expected--;
-+	assert(!err);
-+	if (!expected) process.exit(0);
-+});
-+rs.pipe(fs.createWriteStream('/dev/null'));
-+
-+var socket = net.connect(50000);
-+eos(socket, function(err) {
-+	expected--;
-+	assert(!!err);
-+	if (!expected) process.exit(0);
-+});
-+
-+
-+var server = net.createServer(function(socket) {
-+	eos(socket, function() {
-+		expected--;
-+		if (!expected) process.exit(0);
-+	});
-+	socket.destroy();
-+}).listen(30000, function() {
-+	var socket = net.connect(30000);
-+	eos(socket, function() {
-+		expected--;
-+		if (!expected) process.exit(0);
-+	});
-+});
-+
-+
-+
-+setTimeout(function() {
-+	assert(expected === 0);
-+	process.exit(0);
-+}, 1000);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/.jshintrc
-@@ -0,0 +1,30 @@
-+{
-+    "maxdepth": 4,
-+    "maxstatements": 200,
-+    "maxcomplexity": 12,
-+    "maxlen": 80,
-+    "maxparams": 5,
-+
-+    "curly": true,
-+    "eqeqeq": true,
-+    "immed": true,
-+    "latedef": false,
-+    "noarg": true,
-+    "noempty": true,
-+    "nonew": true,
-+    "undef": true,
-+    "unused": "vars",
-+    "trailing": true,
-+
-+    "quotmark": true,
-+    "expr": true,
-+    "asi": true,
-+
-+    "browser": false,
-+    "esnext": true,
-+    "devel": false,
-+    "node": false,
-+    "nonstandard": false,
-+
-+    "predef": ["require", "module", "__dirname", "__filename"]
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/.npmignore
-@@ -0,0 +1 @@
-+node_modules
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/LICENCE
-@@ -0,0 +1,19 @@
-+Copyright (c) 2012-2014 Raynos.
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/Makefile
-@@ -0,0 +1,4 @@
-+browser:
-+	node ./support/compile
-+
-+.PHONY: browser
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/README.md
-@@ -0,0 +1,28 @@
-+# xtend
-+
-+[![browser support][3]][4]
-+
-+Extend like a boss
-+
-+xtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes presedence.
-+
-+## Examples
-+
-+```js
-+var extend = require("xtend")
-+
-+// extend returns a new object. Does not mutate arguments
-+var combination = extend({
-+    a: "a"
-+}, {
-+    b: "b"
-+})
-+// { a: "a", b: "b" }
-+```
-+
-+
-+## MIT Licenced
-+
-+
-+  [3]: http://ci.testling.com/Raynos/xtend.png
-+  [4]: http://ci.testling.com/Raynos/xtend
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/index.js
-@@ -0,0 +1,17 @@
-+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
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/mutable.js
-@@ -0,0 +1,15 @@
-+module.exports = extend
-+
-+function extend(target) {
-+    for (var i = 1; i < arguments.length; i++) {
-+        var source = arguments[i]
-+
-+        for (var key in source) {
-+            if (source.hasOwnProperty(key)) {
-+                target[key] = source[key]
-+            }
-+        }
-+    }
-+
-+    return target
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/package.json
-@@ -0,0 +1,70 @@
-+{
-+  "name": "xtend",
-+  "version": "3.0.0",
-+  "description": "extend like a boss",
-+  "keywords": [
-+    "extend",
-+    "merge",
-+    "options",
-+    "opts",
-+    "object",
-+    "array"
-+  ],
-+  "author": {
-+    "name": "Raynos",
-+    "email": "raynos2 at gmail.com"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/Raynos/xtend.git"
-+  },
-+  "main": "index",
-+  "scripts": {
-+    "test": "node test"
-+  },
-+  "dependencies": {},
-+  "devDependencies": {
-+    "tape": "~1.1.0"
-+  },
-+  "homepage": "https://github.com/Raynos/xtend",
-+  "contributors": [
-+    {
-+      "name": "Jake Verbaten"
-+    },
-+    {
-+      "name": "Matt Esch"
-+    }
-+  ],
-+  "bugs": {
-+    "url": "https://github.com/Raynos/xtend/issues",
-+    "email": "raynos2 at gmail.com"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "http://github.com/raynos/xtend/raw/master/LICENSE"
-+    }
-+  ],
-+  "testling": {
-+    "files": "test.js",
-+    "browsers": [
-+      "ie/7..latest",
-+      "firefox/16..latest",
-+      "firefox/nightly",
-+      "chrome/22..latest",
-+      "chrome/canary",
-+      "opera/12..latest",
-+      "opera/next",
-+      "safari/5.1..latest",
-+      "ipad/6.0..latest",
-+      "iphone/6.0..latest"
-+    ]
-+  },
-+  "engines": {
-+    "node": ">=0.4"
-+  },
-+  "readme": "# xtend\n\n[![browser support][3]][4]\n\nExtend like a boss\n\nxtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes presedence.\n\n## Examples\n\n```js\nvar extend = require(\"xtend\")\n\n// extend returns a new object. Does not mutate arguments\nvar combination = extend({\n    a: \"a\"\n}, {\n    b: \"b\"\n})\n// { a: \"a\", b: \"b\" }\n```\n\n\n## MIT Licenced\n\n\n  [3]: http://ci.testling.com/Raynos/xtend.png\n  [4]: http://ci.testling.com/Raynos/xtend\n",
-+  "readmeFilename": "README.md",
-+  "_id": "xtend at 3.0.0",
-+  "_from": "xtend@~3.0.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/node_modules/xtend/test.js
-@@ -0,0 +1,63 @@
-+var test = require("tape")
-+var extend = require("./")
-+var mutableExtend = require("./mutable")
-+
-+test("merge", function(assert) {
-+    var a = { a: "foo" }
-+    var b = { b: "bar" }
-+
-+    assert.deepEqual(extend(a, b), { a: "foo", b: "bar" })
-+    assert.end()
-+})
-+
-+test("replace", function(assert) {
-+    var a = { a: "foo" }
-+    var b = { a: "bar" }
-+
-+    assert.deepEqual(extend(a, b), { a: "bar" })
-+    assert.end()
-+})
-+
-+test("undefined", function(assert) {
-+    var a = { a: undefined }
-+    var b = { b: "foo" }
-+
-+    assert.deepEqual(extend(a, b), { a: undefined, b: "foo" })
-+    assert.deepEqual(extend(b, a), { a: undefined, b: "foo" })
-+    assert.end()
-+})
-+
-+test("handle 0", function(assert) {
-+    var a = { a: "default" }
-+    var b = { a: 0 }
-+
-+    assert.deepEqual(extend(a, b), { a: 0 })
-+    assert.deepEqual(extend(b, a), { a: "default" })
-+    assert.end()
-+})
-+
-+test("is immutable", function (assert) {
-+    var record = {}
-+
-+    extend(record, { foo: "bar" })
-+    assert.equal(record.foo, undefined)
-+    assert.end()
-+})
-+
-+test("null as argument", function (assert) {
-+    var a = { foo: "bar" }
-+    var b = null
-+    var c = void 0
-+
-+    assert.deepEqual(extend(b, a, c), { foo: "bar" })
-+    assert.end()
-+})
-+
-+test("mutable", function (assert) {
-+    var a = { foo: "bar" }
-+
-+    mutableExtend(a, { bar: "baz" })
-+
-+    assert.equal(a.bar, "baz")
-+    assert.end()
-+})
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/pack.js
-@@ -0,0 +1,194 @@
-+var util = require('util');
-+var eos = require('end-of-stream');
-+var headers = require('./headers');
-+
-+var Readable = require('readable-stream').Readable;
-+var Writable = require('readable-stream').Writable;
-+var PassThrough = require('readable-stream').PassThrough;
-+
-+var END_OF_TAR = new Buffer(1024);
-+END_OF_TAR.fill(0);
-+
-+var noop = function() {};
-+
-+var overflow = function(self, size) {
-+	size &= 511;
-+	if (size) self.push(END_OF_TAR.slice(0, 512 - size));
-+};
-+
-+var Sink = function(to) {
-+	Writable.call(this);
-+	this.written = 0;
-+	this._to = to;
-+	this._destroyed = false;
-+};
-+
-+util.inherits(Sink, Writable);
-+
-+Sink.prototype._write = function(data, enc, cb) {
-+	this.written += data.length;
-+	if (this._to.push(data)) return cb();
-+	this._to._drain = cb;
-+};
-+
-+Sink.prototype.destroy = function() {
-+	if (this._destroyed) return;
-+	this._destroyed = true;
-+	this.emit('close');
-+};
-+
-+var Void = function() {
-+	Writable.call(this)
-+	this._destroyed = false;
-+};
-+
-+util.inherits(Void, Writable);
-+
-+Void.prototype._write = function(data, enc, cb) {
-+	cb(new Error('No body allowed for this entry'))
-+};
-+
-+Void.prototype.destroy = function() {
-+	if (this._destroyed) return;
-+	this._destroyed = true;
-+	this.emit('close')
-+}
-+
-+var Pack = function(opts) {
-+	if (!(this instanceof Pack)) return new Pack(opts);
-+	Readable.call(this, opts);
-+
-+	this._drain = noop;
-+	this._finalized = false;
-+	this._finalizing = false;
-+	this._destroyed = false;
-+	this._stream = null;
-+};
-+
-+util.inherits(Pack, Readable);
-+
-+Pack.prototype.entry = function(header, buffer, callback) {
-+	if (this._stream) throw new Error('already piping an entry');
-+	if (this._finalized || this._destroyed) return;
-+
-+	if (typeof buffer === 'function') {
-+		callback = buffer;
-+		buffer = null;
-+	}
-+
-+	if (!callback) callback = noop;
-+
-+	var self = this;
-+
-+	if (!header.size)  header.size = 0;
-+	if (!header.type)  header.type = 'file';
-+	if (!header.mode)  header.mode = header.type === 'directory' ? 0755 : 0644;
-+	if (!header.uid)   header.uid = 0;
-+	if (!header.gid)   header.gid = 0;
-+	if (!header.mtime) header.mtime = new Date();
-+
-+	if (typeof buffer === 'string') buffer = new Buffer(buffer);
-+	if (Buffer.isBuffer(buffer)) {
-+		header.size = buffer.length;
-+		this._encode(header);
-+		this.push(buffer);
-+		overflow(self, header.size);
-+		process.nextTick(callback);
-+		return new Void();
-+	}
-+	if (header.type !== 'file' && header.type !== 'contigious-file') {
-+		this._encode(header);
-+		process.nextTick(callback);
-+		return new Void();
-+	}
-+
-+	var sink = new Sink(this);
-+
-+	this._encode(header);
-+	this._stream = sink;
-+
-+	eos(sink, function(err) {
-+		self._stream = null;
-+
-+		if (err) { // stream was closed
-+			self.destroy();
-+			return callback(err);
-+		}
-+
-+		if (sink.written !== header.size) { // corrupting tar
-+			self.destroy();
-+			return callback(new Error('size mismatch'));
-+		}
-+
-+		overflow(self, header.size);
-+		if (self._finalizing) self.finalize();
-+		callback();
-+	});
-+
-+	return sink;
-+};
-+
-+Pack.prototype.finalize = function() {
-+	if (this._stream) {
-+		this._finalizing = true;
-+		return;
-+	}
-+
-+	if (this._finalized) return;
-+	this._finalized = true;
-+	this.push(END_OF_TAR);
-+	this.push(null);
-+};
-+
-+Pack.prototype.destroy = function(err) {
-+	if (this._destroyed) return;
-+	this._destroyed = true;
-+
-+	if (err) this.emit('error', err);
-+	this.emit('close');
-+	if (this._stream && this._stream.destroy) this._stream.destroy();
-+};
-+
-+Pack.prototype._encode = function(header) {
-+	var buf = headers.encode(header);
-+	if (buf) this.push(buf);
-+	else this._encodePax(header);
-+};
-+
-+Pack.prototype._encodePax = function(header) {
-+	var paxHeader = headers.encodePax({
-+		name: header.name,
-+		linkname: header.linkname
-+	});
-+
-+	var newHeader = {
-+		name: 'PaxHeader',
-+		mode: header.mode,
-+		uid: header.uid,
-+		gid: header.gid,
-+		size: paxHeader.length,
-+		mtime: header.mtime,
-+		type: 'pax-header',
-+		linkname: header.linkname && 'PaxHeader',
-+		uname: header.uname,
-+		gname: header.gname,
-+		devmajor: header.devmajor,
-+		devminor: header.devminor
-+	};
-+
-+	this.push(headers.encode(newHeader));
-+	this.push(paxHeader);
-+	overflow(this, paxHeader.length);
-+
-+	newHeader.size = header.size;
-+	newHeader.type = header.type;
-+	this.push(headers.encode(newHeader));
-+};
-+
-+Pack.prototype._read = function(n) {
-+	var drain = this._drain;
-+	this._drain = noop;
-+	drain();
-+};
-+
-+module.exports = Pack;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/package.json
-@@ -0,0 +1,58 @@
-+{
-+  "name": "tar-stream",
-+  "version": "0.4.4",
-+  "description": "tar-stream is a streaming tar parser and generator and nothing else. It is streams2 and operates purely using streams which means you can easily extract/parse tarballs without ever hitting the file system.",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com:mafintosh/tar-stream.git"
-+  },
-+  "author": {
-+    "name": "Mathias Buus",
-+    "email": "mathiasbuus at gmail.com"
-+  },
-+  "engines": {
-+    "node": ">= 0.8.0"
-+  },
-+  "dependencies": {
-+    "bl": "~0.8.1",
-+    "end-of-stream": "~0.1.3",
-+    "readable-stream": "~1.0.26-4",
-+    "xtend": "~3.0.0"
-+  },
-+  "devDependencies": {
-+    "tap": "~0.4.6",
-+    "concat-stream": "~1.2.1"
-+  },
-+  "scripts": {
-+    "test": "tap test/*.js"
-+  },
-+  "keywords": [
-+    "tar",
-+    "tarball",
-+    "parse",
-+    "parser",
-+    "generate",
-+    "generator",
-+    "stream",
-+    "stream2",
-+    "streams",
-+    "streams2",
-+    "streaming",
-+    "pack",
-+    "extract",
-+    "modify"
-+  ],
-+  "bugs": {
-+    "url": "https://github.com/mafintosh/tar-stream/issues"
-+  },
-+  "homepage": "https://github.com/mafintosh/tar-stream",
-+  "main": "index.js",
-+  "directories": {
-+    "test": "test"
-+  },
-+  "license": "MIT",
-+  "readme": "# tar-stream\n\ntar-stream is a streaming tar parser and generator and nothing else. It is streams2 and operates purely using streams which means you can easily extract/parse tarballs without ever hitting the file system.\n\n\tnpm install tar-stream\n\n[![build status](https://secure.travis-ci.org/mafintosh/tar-stream.png)](http://travis-ci.org/mafintosh/tar-stream)\n\n# Usage\n\ntar-stream exposes two streams, [pack](https://github.com/mafintosh/tar-stream#packing) which creates tarballs and [extract](https://github.com/mafintosh/tar-stream#extracting) which extracts tarballs. To [modify an existing tarball](https://github.com/mafintosh/tar-stream#modifying-existing-tarballs) use both.\n\n## Packing\n\nTo create a pack stream use `tar.pack()` and call `pack.entry(header, [callback])` to add tar entries.\n\n``` js\nvar tar = require('tar-stream');\nvar pack = tar.pack(); // p is a streams2 stream\n\n// add a file called my-test.txt with the content \"Hello World!\"\npack.entry({ name: 'my-test.txt' }, 'Hello World!');\n\n// add a file called my-stream-test.txt from a stream\nvar entry = pack.entry({ name: 'my-stream-test.txt' }, function(err) {\n\t// the stream was added\n\t// no more entries\n\tpack.finalize();\n});\nmyStream.pipe(entry);\n\n// pipe the pack stream somewhere\npack.pipe(process.stdout);\n```\n\n## Extracting\n\nTo extract a stream use `tar.extract()` and listen for `extract.on('entry', header, stream, callback)`\n\n``` js\nvar extract = tar.extract();\n\nextract.on('entry', function(header, stream, callback) {\n\t// header is the tar header\n\t// stream is the content body (might be an empty stream)\n\t// call next when you are done with this entry\n\n\tstream.resume(); // just auto drain the stream\n\tstream.on('end', function() {\n\t\tcallback(); // ready for next entry\n\t});\n});\n\nextract.on('finish', function() {\n\t// all entries read\n});\n\npack.pipe(extract);\n```\n\n## Headers\n\nThe header object using in `entry` should contain the following properties.\nMost of these values can be found by stating a file.\n\n``` js\n{\n\tname: 'path/to/this/entry.txt',\n\tsize: 1314,        // entry size. defaults to 0\n\tmode: 0644,        // entry mode. defaults to to 0755 for dirs and 0644 otherwise\n\tmtime: new Date(), // last modified date for entry. defaults to now.\n\ttype: 'file',      // type of entry. defaults to file. can be:\n\t                   // file | link | symlink | directory | block-device\n\t                   // character-device | fifo | contigious-file\n\tlinkname: 'path',  // linked file name\n\tuid: 0,            // uid of entry owner. defaults to 0\n\tgid: 0,            // gid of entry owner. defaults to 0\n\tuname: 'maf',      // uname of entry owner. defaults to null\n\tgname: 'staff',    // gname of entry owner. defaults to null\n\tdevmajor: 0,       // device major version. defaults to 0\n\tdevminor: 0        // device minor version. defaults to 0\n}\n```\n\n## Modifying existing tarballs\n\nUsing tar-stream it is easy to rewrite paths / change modes etc in an existing tarball.\n\n``` js\nvar extract = tar.extract();\nvar pack = tar.pack();\nvar path = require('path');\n\nextract.on('entry', function(header, stream, callback) {\n\t// let's prefix all names with 'tmp'\n\theader.name = path.join('tmp', header.name);\n\t// write the new entry to the pack stream\n\tstream.pipe(pack.entry(header, callback));\n});\n\nextract.on('finish', function() {\n\t// all entries done - lets finalize it\n\tpack.finalize();\n});\n\n// pipe the old tarball to the extractor\noldTarball.pipe(extract);\n\n// pipe the new tarball the another stream\npack.pipe(newTarball);\n```\n\n## Performance\n\n[See tar-fs for a performance comparison with node-tar](https://github.com/mafintosh/tar-fs/blob/master/README.md#performance)\n\n# License\n\nMIT\n",
-+  "readmeFilename": "README.md",
-+  "_id": "tar-stream at 0.4.4",
-+  "_from": "tar-stream@~0.4.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/test/extract.js
-@@ -0,0 +1,420 @@
-+var test = require('tap').test;
-+var tar = require('../index');
-+var fixtures = require('./fixtures');
-+var concat = require('concat-stream');
-+var fs = require('fs');
-+
-+var clamp = function(index, len, defaultValue) {
-+	if (typeof index !== 'number') return defaultValue;
-+	index = ~~index;  // Coerce to integer.
-+	if (index >= len) return len;
-+	if (index >= 0) return index;
-+	index += len;
-+	if (index >= 0) return index;
-+	return 0;
-+};
-+
-+test('one-file', function(t) {
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'test.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'hello world\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.ONE_FILE_TAR));
-+});
-+
-+test('chunked-one-file', function(t) {
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'test.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'hello world\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	var b = fs.readFileSync(fixtures.ONE_FILE_TAR);
-+
-+	for (var i = 0; i < b.length; i += 321) {
-+		extract.write(b.slice(i, clamp(i+321, b.length, b.length)));
-+	}
-+	extract.end();
-+});
-+
-+
-+test('multi-file', function(t) {
-+	t.plan(5);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	var onfile1 = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'file-1.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		extract.on('entry', onfile2);
-+		stream.pipe(concat(function(data) {
-+			t.same(data.toString(), 'i am file-1\n');
-+			callback();
-+		}));
-+	};
-+
-+	var onfile2 = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'file-2.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'i am file-2\n');
-+			callback();
-+		}));
-+	};
-+
-+	extract.once('entry', onfile1);
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.MULTI_FILE_TAR));
-+});
-+
-+test('chunked-multi-file', function(t) {
-+	t.plan(5);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	var onfile1 = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'file-1.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		extract.on('entry', onfile2);
-+		stream.pipe(concat(function(data) {
-+			t.same(data.toString(), 'i am file-1\n');
-+			callback();
-+		}));
-+	};
-+
-+	var onfile2 = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'file-2.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 12,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'i am file-2\n');
-+			callback();
-+		}));
-+	};
-+
-+	extract.once('entry', onfile1);
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	var b = fs.readFileSync(fixtures.MULTI_FILE_TAR);
-+	for (var i = 0; i < b.length; i += 321) {
-+		extract.write(b.slice(i, clamp(i+321, b.length, b.length)));
-+	}
-+	extract.end();
-+});
-+
-+test('types', function(t) {
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	var ondir = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'directory',
-+			mode: 0755,
-+			uid: 501,
-+			gid: 20,
-+			size: 0,
-+			mtime: new Date(1387580181000),
-+			type: 'directory',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+		stream.on('data', function() {
-+			t.ok(false);
-+		});
-+		extract.once('entry', onlink);
-+		callback();
-+	};
-+
-+	var onlink = function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'directory-link',
-+			mode: 0755,
-+			uid: 501,
-+			gid: 20,
-+			size: 0,
-+			mtime: new Date(1387580181000),
-+			type: 'symlink',
-+			linkname: 'directory',
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+		stream.on('data', function() {
-+			t.ok(false);
-+		});
-+		noEntries = true;
-+		callback();
-+	};
-+
-+	extract.once('entry', ondir);
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.TYPES_TAR));
-+});
-+
-+test('long-name', function(t) {
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'my/file/is/longer/than/100/characters/and/should/use/the/prefix/header/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/filename.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 16,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'hello long name\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.LONG_NAME_TAR));
-+});
-+
-+test('unicode-bsd', function(t) { // can unpack a bsdtar unicoded tarball
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'høllø.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 4,
-+			mtime: new Date(1387588646000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'hej\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.UNICODE_BSD_TAR));
-+});
-+
-+test('unicode', function(t) { // can unpack a bsdtar unicoded tarball
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+	var noEntries = false;
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.deepEqual(header, {
-+			name: 'høstål.txt',
-+			mode: 0644,
-+			uid: 501,
-+			gid: 20,
-+			size: 8,
-+			mtime: new Date(1387580181000),
-+			type: 'file',
-+			linkname: null,
-+			uname: 'maf',
-+			gname: 'staff',
-+			devmajor: 0,
-+			devminor: 0
-+		});
-+
-+		stream.pipe(concat(function(data) {
-+			noEntries = true;
-+			t.same(data.toString(), 'høllø\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(noEntries);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.UNICODE_TAR));
-+});
-+
-+test('name-is-100', function(t) {
-+	t.plan(3);
-+
-+	var extract = tar.extract();
-+
-+	extract.on('entry', function(header, stream, callback) {
-+		t.same(header.name.length, 100);
-+
-+		stream.pipe(concat(function(data) {
-+			t.same(data.toString(), 'hello\n');
-+			callback();
-+		}));
-+	});
-+
-+	extract.on('finish', function() {
-+		t.ok(true);
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.NAME_IS_100_TAR));
-+});
-+
-+test('invalid-file', function(t) {
-+	t.plan(1);
-+
-+	var extract = tar.extract();
-+
-+	extract.on('error', function(err) {
-+		t.ok(!!err);
-+		extract.destroy();
-+	});
-+
-+	extract.end(fs.readFileSync(fixtures.INVALID_TGZ));
-+});
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/test/fixtures/index.js
-@@ -0,0 +1,10 @@
-+var path = require('path');
-+
-+exports.ONE_FILE_TAR = path.join(__dirname, 'one-file.tar');
-+exports.MULTI_FILE_TAR = path.join(__dirname, 'multi-file.tar');
-+exports.TYPES_TAR = path.join(__dirname, 'types.tar');
-+exports.LONG_NAME_TAR = path.join(__dirname, 'long-name.tar');
-+exports.UNICODE_BSD_TAR = path.join(__dirname, 'unicode-bsd.tar');
-+exports.UNICODE_TAR = path.join(__dirname, 'unicode.tar');
-+exports.NAME_IS_100_TAR = path.join(__dirname, 'name-is-100.tar');
-+exports.INVALID_TGZ = path.join(__dirname, 'invalid.tgz');
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/tar-stream/test/pack.js
-@@ -0,0 +1,144 @@
-+var test = require('tap').test;
-+var tar = require('../index');
-+var fixtures = require('./fixtures');
-+var concat = require('concat-stream');
-+var fs = require('fs');
-+
-+test('one-file', function(t) {
-+	t.plan(2);
-+
-+	var pack = tar.pack();
-+
-+	pack.entry({
-+		name:'test.txt',
-+		mtime:new Date(1387580181000),
-+		mode:0644,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	}, 'hello world\n');
-+
-+	pack.finalize();
-+
-+	pack.pipe(concat(function(data) {
-+		t.same(data.length & 511, 0);
-+		t.deepEqual(data, fs.readFileSync(fixtures.ONE_FILE_TAR));
-+	}));
-+});
-+
-+test('multi-file', function(t) {
-+	t.plan(2);
-+
-+	var pack = tar.pack();
-+
-+	pack.entry({
-+		name:'file-1.txt',
-+		mtime:new Date(1387580181000),
-+		mode:0644,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	}, 'i am file-1\n');
-+
-+	pack.entry({
-+		name:'file-2.txt',
-+		mtime:new Date(1387580181000),
-+		mode:0644,
-+		size:12,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	}).end('i am file-2\n');
-+
-+	pack.finalize();
-+
-+	pack.pipe(concat(function(data) {
-+		t.same(data.length & 511, 0);
-+		t.deepEqual(data, fs.readFileSync(fixtures.MULTI_FILE_TAR));
-+	}));
-+});
-+
-+test('types', function(t) {
-+	t.plan(2);
-+	var pack = tar.pack();
-+
-+	pack.entry({
-+		name:'directory',
-+		mtime:new Date(1387580181000),
-+		type:'directory',
-+		mode:0755,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	});
-+
-+	pack.entry({
-+		name:'directory-link',
-+		mtime:new Date(1387580181000),
-+		type:'symlink',
-+		linkname: 'directory',
-+		mode:0755,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	});
-+
-+	pack.finalize();
-+
-+	pack.pipe(concat(function(data) {
-+		t.equal(data.length & 511, 0);
-+		t.deepEqual(data, fs.readFileSync(fixtures.TYPES_TAR));
-+	}));
-+
-+});
-+
-+test('long-name', function(t) {
-+	t.plan(2);
-+	var pack = tar.pack();
-+
-+	pack.entry({
-+		name:'my/file/is/longer/than/100/characters/and/should/use/the/prefix/header/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/filename.txt',
-+		mtime:new Date(1387580181000),
-+		type:'file',
-+		mode:0644,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	}, 'hello long name\n');
-+
-+	pack.finalize();
-+
-+	pack.pipe(concat(function(data) {
-+		t.equal(data.length & 511, 0);
-+		t.deepEqual(data, fs.readFileSync(fixtures.LONG_NAME_TAR));
-+	}));
-+});
-+
-+test('unicode', function(t) {
-+	t.plan(2);
-+	var pack = tar.pack();
-+
-+	pack.entry({
-+		name:'høstål.txt',
-+		mtime:new Date(1387580181000),
-+		type:'file',
-+		mode:0644,
-+		uname:'maf',
-+		gname:'staff',
-+		uid:501,
-+		gid:20
-+	}, 'høllø\n');
-+
-+	pack.finalize();
-+
-+	pack.pipe(concat(function(data) {
-+		t.equal(data.length & 511, 0);
-+		t.deepEqual(data, fs.readFileSync(fixtures.UNICODE_TAR));
-+	}));
-+});
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/LICENSE-MIT
-@@ -0,0 +1,22 @@
-+Copyright (c) 2014 Chris Talkington, 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.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/README.md
-@@ -0,0 +1,120 @@
-+# zip-stream v0.3.6 [![Build Status](https://travis-ci.org/ctalkington/node-zip-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-zip-stream)
-+
-+zip-stream is a streaming zip archive generator. It was built to be a successor to [zipstream](https://npmjs.org/package/zipstream). Dependencies are kept to a minimum through the use of many of node's built-in modules including the use of zlib module for compression.
-+
-+[![NPM](https://nodei.co/npm/zip-stream.png)](https://nodei.co/npm/zip-stream/)
-+
-+### Install
-+
-+```bash
-+npm install zip-stream --save
-+```
-+
-+You can also use `npm install https://github.com/ctalkington/node-zip-stream/archive/master.tar.gz` to test upcoming versions.
-+
-+### Usage
-+
-+This module is meant to be wrapped internally by other modules and therefore lacks any queue management. This means you have to wait until the previous entry has been fully consumed to add another. Nested callbacks should be used to add multiple entries. There are modules like [async](https://npmjs.org/package/async) that ease the so called "callback hell".
-+
-+If you want a module that handles entry queueing and much more, you should check out [archiver](https://npmjs.org/package/archiver) which uses this module internally.
-+
-+```js
-+var packer = require('zip-stream');
-+var archive = new packer(); // OR new packer(options)
-+
-+archive.on('error', function(err) {
-+  throw err;
-+});
-+
-+// pipe archive where you want it (ie fs, http, etc)
-+// listen to the destination's end, close, or finish event
-+
-+archive.entry('string contents', { name: 'string.txt' }, function(err, entry) {
-+  if (err) throw err;
-+  archive.entry(null, { name: 'directory/' }, function(err, entry) {
-+    if (err) throw err;
-+    archive.finalize();
-+  });
-+});
-+```
-+
-+### Instance API
-+
-+#### entry(input, data, callback(err, data))
-+
-+Appends an input source (text string, buffer, or stream) to the instance. When the instance has received, processed, and emitted the input, the callback is fired.
-+
-+#### finalize()
-+
-+Finalizes the instance. You should listen to the destination stream's `end`/`close`/`finish` event to know when all output has been safely consumed.
-+
-+### Instance Options
-+
-+#### comment `string`
-+
-+Sets the zip comment.
-+
-+#### forceUTC `boolean`
-+
-+If true, forces the entry date to UTC. Helps with testing across timezones.
-+
-+#### store `boolean`
-+
-+If true, all entry contents will be archived without compression by default.
-+
-+#### zlib `object`
-+
-+Passed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.
-+
-+### Entry Data
-+
-+#### name `string` `required`
-+
-+Sets the entry name including internal path.
-+
-+#### type `string`
-+
-+Sets the entry type. Defaults to `file` or `directory` if name ends with trailing slash.
-+
-+#### date `string|Date`
-+
-+Sets the entry date. This can be any valid date string or instance. Defaults to current time in locale.
-+
-+#### store `boolean`
-+
-+If true, entry contents will be archived without compression.
-+
-+#### comment `string`
-+
-+Sets the entry comment.
-+
-+#### mode `number`
-+
-+Sets the entry permissions. (experimental)
-+
-+## Debugging
-+
-+This library makes use of the [debug](https://npmjs.org/package/debug) module with a namespace of `zip-stream` which can be triggered by setting `DEBUG` in your environment like so:
-+
-+```shell
-+# unix
-+DEBUG=zip-stream:* node script
-+
-+# windows (powershell)
-+$env:DEBUG="zip-stream:*"
-+node script
-+
-+# windows (cmd)
-+SET DEBUG="zip-stream:*"
-+node script
-+```
-+
-+## Things of Interest
-+
-+- [Releases](https://github.com/ctalkington/node-zip-stream/releases)
-+- [Contributing](https://github.com/ctalkington/node-zip-stream/blob/master/CONTRIBUTING.md)
-+- [MIT License](https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT)
-+
-+## Credits
-+
-+Concept inspired by Antoine van Wel's [zipstream](https://npmjs.org/package/zipstream) module, which is no longer being updated.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/lib/headers.js
-@@ -0,0 +1,279 @@
-+/**
-+ * node-zip-stream
-+ *
-+ * Copyright (c) 2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var util = require('./util');
-+
-+var debug = util.debug('zip-stream:headers');
-+
-+var DEFAULT_FILE_MODE = 0100644; // 644 -rw-r--r-- = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-+var DEFAULT_DIR_MODE = 040755; // 755 drwxr-xr-x = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
-+var EXT_FILE_ATTR_DIR = 010173200020; // 755 drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D)
-+var EXT_FILE_ATTR_FILE = 020151000040; // 644 -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A) >>> 0
-+
-+// Unix file types
-+var S_IFIFO = 010000; // named pipe (fifo)
-+var S_IFCHR = 020000; // character special
-+var S_IFDIR = 040000; // directory
-+var S_IFBLK = 060000; // block special
-+var S_IFREG = 0100000; // regular
-+var S_IFLNK = 0120000; // symbolic link
-+var S_IFSOCK = 0140000; // socket
-+
-+var S_IRWXU = 0700; // RWX mask for owner
-+var S_IRUSR = 0400; // R for owner
-+var S_IWUSR = 0200; // W for owner
-+var S_IXUSR = 0100; // X for owner
-+
-+var S_IRWXG = 070; // RWX mask for group
-+var S_IRGRP = 040; // R for group
-+var S_IWGRP = 020; // W for group
-+var S_IXGRP = 010; // X for group
-+
-+var S_IRWXO = 07; // RWX mask for other
-+var S_IROTH = 04; // R for other
-+var S_IWOTH = 02; // W for other
-+var S_IXOTH = 01; // X for other
-+
-+var S_ISVTX = 01000; // save swapped text even after use
-+
-+// setuid/setgid/sticky bits
-+var S_ISUID = 04000; // set user id on execution
-+var S_ISGID = 02000; // set group id on execution
-+var S_ISTXT = 01000; // sticky bit
-+
-+// DOS file type flags
-+var S_DOS_A = 040; // Archive
-+var S_DOS_D = 020; // Directory
-+var S_DOS_V = 010; // Volume
-+var S_DOS_S = 04; // System
-+var S_DOS_H = 02; // Hidden
-+var S_DOS_R = 01; // Read Only
-+
-+function ZipHeader() {
-+  this.name = 'zipHeader';
-+  this.bufferSize = 0;
-+  this.fields = [];
-+}
-+
-+ZipHeader.prototype.toBuffer = function(data) {
-+  var self = this;
-+  var buf = new Buffer(self.bufferSize);
-+  var offset = 0;
-+  var val;
-+  var valLength;
-+  var fallback;
-+
-+  debug('%s:start', self.name);
-+
-+  data = self._normalize(data);
-+
-+  self.fields.forEach(function(field) {
-+    fallback = (field.type === 'string') ? '' : 0;
-+    val = data[field.name] || field.def || fallback;
-+    valLength = (field.lenField && data[field.lenField] > 0) ? data[field.lenField] : field.len;
-+
-+    if (typeof buf['write' + field.type] === 'function') {
-+      debug('%s:%s:%s:%d+%d', self.name, field.type, field.name, offset, field.len);
-+      buf['write' + field.type](val, offset);
-+    } else if (val.length > 0) {
-+      debug('%s:%s:%d+%d', self.name, field.name, offset, val.length);
-+      buf.write(val, offset);
-+    }
-+
-+    offset += valLength;
-+  });
-+
-+  debug('%s:finish:%d', self.name, offset);
-+
-+  return buf.slice(0, offset);
-+};
-+
-+ZipHeader.prototype.toObject = function(buf) {
-+  var self = this;
-+  var data = {};
-+  var offset = 0;
-+  var valLength;
-+
-+  self.fields.forEach(function(field) {
-+    valLength = (field.lenField && data[field.lenField] > 0) ? data[field.lenField] : field.len;
-+
-+    if (typeof buf['read' + field.type] === 'function') {
-+      data[field.name] = buf['read' + field.type](offset);
-+    } else if (valLength > 0) {
-+      data[field.name] = buf.toString(null, offset, valLength);
-+    } else {
-+      data[field.name] = null;
-+    }
-+
-+    offset += valLength;
-+  });
-+
-+  return data;
-+};
-+
-+ZipHeader.prototype._generateExternalAttributes = function(mode, type) {
-+  var isDir = type === 'directory';
-+
-+  var owner = (mode >> 6) & 07;
-+  var group = (mode >> 3) & 07;
-+  var other = mode & 07;
-+
-+  var attr = isDir ? S_IFDIR : S_IFREG;
-+  attr |= ((owner & 07) << 6) | ((group & 07) << 3) | (other & 07);
-+
-+  return (attr << 16) | (isDir ? S_DOS_D : S_DOS_A);
-+};
-+
-+ZipHeader.prototype._normalize = function(data) {
-+  // Don't always set mode as this is a experimental feature
-+  // if (!data.mode) {
-+  //   data.mode = DEFAULT_FILE_MODE;
-+  // }
-+
-+  data.filenameLength = 0;
-+  data.commentLength = 0;
-+  data.extraFieldLength = 0;
-+
-+  if (data.name) {
-+    if (Buffer.byteLength(data.name) !== data.name.length) {
-+      data.flags |= (1 << 11);
-+    }
-+
-+    data.filenameLength = Buffer.byteLength(data.name);
-+  }
-+
-+  if (data.comment) {
-+    if (Buffer.byteLength(data.comment) !== data.comment.length) {
-+      data.flags |= (1 << 11);
-+    }
-+
-+    data.commentLength = Buffer.byteLength(data.comment);
-+  }
-+
-+  if (data.extraField) {
-+    data.extraFieldLength = data.extraField.length;
-+  }
-+
-+  if (data.mode) {
-+    data.mode &= ~S_IFDIR;
-+
-+    if (data.type === 'file') {
-+      data.mode |= S_IFREG;
-+    }
-+
-+    data.externalFileAttributes &= ~data.externalFileAttributes;
-+    data.externalFileAttributes |= this._generateExternalAttributes(data.mode, data.type);
-+    data.externalFileAttributes >>>= 0;
-+  }
-+
-+  return data;
-+};
-+
-+function ZipHeaderFile() {
-+  ZipHeader.call(this);
-+
-+  this.name = 'file';
-+  this.bufferSize = 1024;
-+  this.fields = [
-+    {name: 'signature', len: 4, type: 'UInt32LE', def: 0x04034b50},
-+    {name: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20},
-+    {name: 'flags', len: 2, type: 'UInt16LE'},
-+    {name: 'compressionMethod', len: 2, type: 'UInt16LE'},
-+    {name: 'lastModifiedDate', len: 4, type: 'UInt32LE'},
-+    {name: 'crc32', len: 4, type: 'UInt32LE', def: 0},
-+    {name: 'compressedSize', len: 4, type: 'UInt32LE'},
-+    {name: 'uncompressedSize', len: 4, type: 'UInt32LE'},
-+    {name: 'filenameLength', len: 2, type: 'UInt16LE'},
-+    {name: 'extraFieldLength', len: 2, type: 'UInt16LE'},
-+    {name: 'name', len: 0, lenField: 'filenameLength', type: 'string'},
-+    {name: 'extraField', len: 0, lenField: 'extraFieldLength', type: 'string'}
-+  ];
-+}
-+inherits(ZipHeaderFile, ZipHeader);
-+
-+function ZipHeaderFileDescriptor() {
-+  ZipHeader.call(this);
-+
-+  this.name = 'fileDescriptor';
-+  this.bufferSize = 16;
-+  this.fields = [
-+    {name: 'signature', len: 4, type: 'UInt32LE', def: 0x08074b50},
-+    {name: 'crc32', len: 4, type: 'UInt32LE'},
-+    {name: 'compressedSize', len: 4, type: 'UInt32LE'},
-+    {name: 'uncompressedSize', len: 4, type: 'UInt32LE'}
-+  ];
-+}
-+inherits(ZipHeaderFileDescriptor, ZipHeader);
-+
-+function ZipHeaderCentralDirectory() {
-+  ZipHeader.call(this);
-+
-+  this.name = 'centralDirectory';
-+  this.bufferSize = 1024;
-+  this.fields = [
-+    {name: 'signature', len: 4, type: 'UInt32LE', def: 0x02014b50},
-+    {name: 'versionMadeBy', len: 2, type: 'UInt16LE', def: 20},
-+    {name: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20},
-+    {name: 'flags', len: 2, type: 'UInt16LE'},
-+    {name: 'compressionMethod', len: 2, type: 'UInt16LE'},
-+    {name: 'lastModifiedDate', len: 4, type: 'UInt32LE'},
-+    {name: 'crc32', len: 4, type: 'UInt32LE'},
-+    {name: 'compressedSize', len: 4, type: 'UInt32LE'},
-+    {name: 'uncompressedSize', len: 4, type: 'UInt32LE'},
-+    {name: 'filenameLength', len: 2, type: 'UInt16LE'},
-+    {name: 'extranameLength', len: 2, type: 'UInt16LE'},
-+    {name: 'commentLength', len: 2, type: 'UInt16LE'},
-+    {name: 'diskNumberStart', len: 2, type: 'UInt16LE'},
-+    {name: 'internalFileAttributes', len: 2, type: 'UInt16LE'},
-+    {name: 'externalFileAttributes', len: 4, type: 'UInt32LE'},
-+    {name: 'offset', len: 4, type: 'UInt32LE'},
-+    {name: 'name', len: 0, lenField: 'filenameLength', type: 'string'},
-+    {name: 'extraField', len: 0, lenField: 'extraFieldLength', type: 'string'},
-+    {name: 'comment', len: 0, lenField: 'commentLength', type: 'string'}
-+  ];
-+}
-+inherits(ZipHeaderCentralDirectory, ZipHeader);
-+
-+function ZipHeaderCentralFooter() {
-+  ZipHeader.call(this);
-+
-+  this.name = 'centralFooter';
-+  this.bufferSize = 512;
-+  this.fields = [
-+    {name: 'signature', len: 4, type: 'UInt32LE', def: 0x06054b50},
-+    {name: 'diskNumber', len: 2, type: 'UInt16LE'},
-+    {name: 'diskNumberStart', len: 2, type: 'UInt16LE'},
-+    {name: 'directoryRecordsDisk', len: 2, type: 'UInt16LE'},
-+    {name: 'directoryRecords', len: 2, type: 'UInt16LE'},
-+    {name: 'centralDirectorySize', len: 4, type: 'UInt32LE'},
-+    {name: 'centralDirectoryOffset', len: 4, type: 'UInt32LE'},
-+    {name: 'commentLength', len: 2, type: 'UInt16LE'},
-+    {name: 'comment', len: 0, lenField: 'commentLength', type: 'string'}
-+  ];
-+}
-+inherits(ZipHeaderCentralFooter, ZipHeader);
-+
-+var headers = {
-+  file: new ZipHeaderFile(),
-+  fileDescriptor: new ZipHeaderFileDescriptor(),
-+  centralDirectory: new ZipHeaderCentralDirectory(),
-+  centralFooter: new ZipHeaderCentralFooter()
-+};
-+
-+var encode = exports.encode = function(type, data) {
-+  if (!headers[type] || typeof headers[type].toBuffer !== 'function') {
-+    throw new Error('Unknown encode type');
-+  }
-+
-+  return headers[type].toBuffer(data);
-+};
-+
-+exports.file = ZipHeaderFile;
-+exports.fileDescriptor = ZipHeaderFileDescriptor;
-+exports.centralDirectory = ZipHeaderCentralDirectory;
-+exports.centralFooter = ZipHeaderCentralFooter;
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/lib/util/index.js
-@@ -0,0 +1,105 @@
-+/**
-+ * node-zip-stream
-+ *
-+ * Copyright (c) 2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT
-+ */
-+var fs = require('fs');
-+var path = require('path');
-+
-+var Stream = require('stream').Stream;
-+var PassThrough = require('readable-stream').PassThrough;
-+
-+var _ = require('lodash');
-+
-+var util = module.exports = {};
-+
-+util.debug = require('debug');
-+
-+util.convertDateTimeDos = function(input) {
-+  return new Date(
-+    ((input >> 25) & 0x7f) + 1980,
-+    ((input >> 21) & 0x0f) - 1,
-+    (input >> 16) & 0x1f,
-+    (input >> 11) & 0x1f,
-+    (input >> 5) & 0x3f,
-+    (input & 0x1f) << 1
-+  );
-+};
-+
-+util.dateify = function(dateish) {
-+  dateish = dateish || new Date();
-+
-+  if (dateish instanceof Date) {
-+    dateish = dateish;
-+  } else if (typeof dateish === 'string') {
-+    dateish = new Date(dateish);
-+  } else {
-+    dateish = new Date();
-+  }
-+
-+  return dateish;
-+};
-+
-+// this is slightly different from lodash version
-+util.defaults = function(object, source, guard) {
-+  var args = arguments;
-+  args[0] = args[0] || {};
-+
-+  return _.defaults.apply(_, args);
-+};
-+
-+util.dosDateTime = function(d, utc) {
-+  d = (d instanceof Date) ? d : util.dateify(d);
-+  utc = utc || false;
-+
-+  var year = utc ? d.getUTCFullYear() : d.getFullYear();
-+
-+  if (year < 1980) {
-+    return 2162688; // 1980-1-1 00:00:00
-+  } else if (year >= 2044) {
-+    return 2141175677; // 2043-12-31 23:59:58
-+  }
-+
-+  var val = {
-+    year: year,
-+    month: utc ? d.getUTCMonth() : d.getMonth(),
-+    date: utc ? d.getUTCDate() : d.getDate(),
-+    hours: utc ? d.getUTCHours() : d.getHours(),
-+    minutes: utc ? d.getUTCMinutes() : d.getMinutes(),
-+    seconds: utc ? d.getUTCSeconds() : d.getSeconds()
-+  };
-+
-+  return ((val.year-1980) << 25) | ((val.month+1) << 21) | (val.date << 16) |
-+    (val.hours << 11) | (val.minutes << 5) | (val.seconds / 2);
-+};
-+
-+util.isStream = function(source) {
-+  return source instanceof Stream;
-+};
-+
-+util.normalizeInputSource = function(source) {
-+  if (source === null) {
-+    return new Buffer(0);
-+  } else if (typeof source === 'string') {
-+    return new Buffer(source);
-+  } else if (util.isStream(source) && !source._readableState) {
-+    var normalized = new PassThrough();
-+    source.pipe(normalized);
-+
-+    return normalized;
-+  }
-+
-+  return source;
-+};
-+
-+util.sanitizePath = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return filepath.replace(/\\/g, '/').replace(/:/g, '').replace(/^\/+/, '');
-+};
-+
-+util.unixifyPath = function() {
-+  var filepath = path.join.apply(path, arguments);
-+  return filepath.replace(/\\/g, '/');
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/lib/zip-stream.js
-@@ -0,0 +1,307 @@
-+/**
-+ * node-zip-stream
-+ *
-+ * Copyright (c) 2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var Transform = require('readable-stream').Transform;
-+
-+var crc32 = require('buffer-crc32');
-+var ChecksumStream = require('crc32-stream');
-+var DeflateCRC32Stream = require('deflate-crc32-stream');
-+var headers = require('./headers');
-+var util = require('./util');
-+
-+var debug = util.debug('zip-stream:instance');
-+var debugEntry = util.debug('zip-stream:entry');
-+
-+var ZipStream = module.exports = function(options) {
-+  if (!(this instanceof ZipStream)) {
-+    return new ZipStream(options);
-+  }
-+
-+  debug('init');
-+
-+  options = this.options = util.defaults(options, {
-+    highWaterMark: 1024 * 1024,
-+    comment: '',
-+    forceUTC: false,
-+    store: false
-+  });
-+
-+  if (typeof options.zlib !== 'object') {
-+    options.zlib = {};
-+  }
-+
-+  if (typeof options.level === 'number' && options.level >= 0) {
-+    options.zlib.level = options.level;
-+    delete options.level;
-+  } else if (typeof options.zlib.level !== 'number') {
-+    options.zlib.level = 1;
-+  }
-+
-+  if (options.zlib.level === 0) {
-+    options.store = true;
-+  }
-+
-+  Transform.call(this, options);
-+
-+  this.offset = 0;
-+  this.entries = [];
-+
-+  this._finalize = false;
-+  this._finalized = false;
-+  this._processing = false;
-+
-+  this.once('end', function() {
-+    debug('stats:' + this.entries.length + 'e:' + this.offset + 'b');
-+    debug('end');
-+  });
-+};
-+
-+inherits(ZipStream, Transform);
-+
-+ZipStream.prototype._afterAppend = function(entry) {
-+  debugEntry('%s:finish', entry.name);
-+
-+  this.entries.push(entry);
-+  this._processing = false;
-+
-+  if (this._finalize) {
-+    this.finalize();
-+  }
-+};
-+
-+ZipStream.prototype._appendBuffer = function(source, data, callback) {
-+  var self = this;
-+
-+  data.offset = self.offset;
-+
-+  if (source.length === 0) {
-+    data.store = true;
-+    data.compressionMethod = 0;
-+  }
-+
-+  if (data.store) {
-+    data.uncompressedSize = source.length;
-+    data.compressedSize = data.uncompressedSize;
-+    data.crc32 = crc32.unsigned(source);
-+  } else {
-+    data.flags |= (1 << 3);
-+  }
-+
-+  self._writeHeader('file', data);
-+
-+  if (data.store) {
-+    self.write(source);
-+    self._afterAppend(data);
-+    callback(null, data);
-+  } else {
-+    var processStream = self._newProcessStream(data.store, function(err) {
-+      if (err) {
-+        return callback(err);
-+      }
-+
-+      data.crc32 = processStream.digest();
-+      data.uncompressedSize = processStream.size();
-+      data.compressedSize = processStream.compressedSize || data.uncompressedSize;
-+
-+      self._writeHeader('fileDescriptor', data);
-+      self._afterAppend(data);
-+      callback(null, data);
-+    });
-+
-+    processStream.end(source);
-+  }
-+};
-+
-+ZipStream.prototype._appendStream = function(source, data, callback) {
-+  var self = this;
-+
-+  data.flags |= (1 << 3);
-+  data.offset = self.offset;
-+
-+  self._writeHeader('file', data);
-+
-+  var processStream = self._newProcessStream(data.store, function(err) {
-+    if (err) {
-+      return callback(err);
-+    }
-+
-+    data.crc32 = processStream.digest();
-+    data.uncompressedSize = processStream.size();
-+    data.compressedSize = processStream.size(true);
-+
-+    self._writeHeader('fileDescriptor', data);
-+    self._afterAppend(data);
-+    callback(null, data);
-+  });
-+
-+  source.pipe(processStream);
-+};
-+
-+ZipStream.prototype._emitErrorCallback = function(err, data) {
-+  if (err) {
-+    this.emit('error', err);
-+  }
-+};
-+
-+ZipStream.prototype._newProcessStream = function(store, callback) {
-+  var process;
-+
-+  if (store) {
-+    process = new ChecksumStream();
-+  } else {
-+    process = new DeflateCRC32Stream(this.options.zlib);
-+  }
-+
-+  if (typeof callback === 'function') {
-+    process.once('error', callback);
-+    process.once('end', callback);
-+  }
-+
-+  process.pipe(this, { end: false });
-+
-+  return process;
-+};
-+
-+ZipStream.prototype._normalizeFileData = function(data) {
-+  data = util.defaults(data, {
-+    type: 'file',
-+    name: null,
-+    date: null,
-+    store: this.options.store,
-+    comment: ''
-+  });
-+
-+  var isDir = data.type === 'directory';
-+
-+  if (data.name) {
-+    data.name = util.sanitizePath(data.name);
-+
-+    if (data.name.slice(-1) === '/') {
-+      isDir = true;
-+      data.type = 'directory';
-+    } else if (isDir) {
-+      data.name += '/';
-+    }
-+  }
-+
-+  if (isDir) {
-+    data.store = true;
-+  }
-+
-+  if (typeof data.lastModifiedDate !== 'number') {
-+    data.lastModifiedDate = util.dosDateTime(data.date, this.options.forceUTC);
-+  }
-+
-+  data.flags = 0;
-+  data.compressionMethod = data.store ? 0 : 8;
-+  data.uncompressedSize = 0;
-+  data.compressedSize = 0;
-+
-+  return data;
-+};
-+
-+ZipStream.prototype._transform = function(chunk, encoding, callback) {
-+  callback(null, chunk);
-+};
-+
-+ZipStream.prototype._writeCentralDirectory = function() {
-+  var entries = this.entries;
-+  var comment = this.options.comment;
-+  var cdoffset = this.offset;
-+  var cdsize = 0;
-+
-+  var centralDirectoryBuffer;
-+  for (var i = 0; i < entries.length; i++) {
-+    var entry = entries[i];
-+
-+    centralDirectoryBuffer = this._writeHeader('centralDirectory', entry);
-+    cdsize += centralDirectoryBuffer.length;
-+  }
-+
-+  var centralDirectoryFooterData = {
-+    directoryRecordsDisk: entries.length,
-+    directoryRecords: entries.length,
-+    centralDirectorySize: cdsize,
-+    centralDirectoryOffset: cdoffset,
-+    comment: comment
-+  };
-+
-+  this._writeHeader('centralFooter', centralDirectoryFooterData);
-+};
-+
-+ZipStream.prototype._writeHeader = function(type, data) {
-+  var encoded = headers.encode(type, data);
-+  this.write(encoded);
-+
-+  return encoded;
-+};
-+
-+ZipStream.prototype.entry = function(source, data, callback) {
-+  if (typeof callback !== 'function') {
-+    callback = this._emitErrorCallback.bind(this);
-+  }
-+
-+  if (this._processing) {
-+    callback(new Error('already processing an entry'));
-+    return;
-+  }
-+
-+  if (this._finalize || this._finalized) {
-+    callback(new Error('entry after finalize()'));
-+    return;
-+  }
-+
-+  data = this._normalizeFileData(data);
-+  debugEntry('%s:start', data.name);
-+
-+  if (data.type !== 'file' && data.type !== 'directory') {
-+    callback(new Error(data.type + ' entries not currently supported'));
-+    return;
-+  }
-+
-+  if (typeof data.name !== 'string' || data.name.length === 0) {
-+    callback(new Error('entry name must be a non-empty string value'));
-+    return;
-+  }
-+
-+  this._processing = true;
-+  source = util.normalizeInputSource(source);
-+
-+  if (Buffer.isBuffer(source)) {
-+    debugEntry('%s:source:buffer', data.name);
-+    this._appendBuffer(source, data, callback);
-+  } else if (util.isStream(source)) {
-+    debugEntry('%s:source:stream', data.name);
-+    this._appendStream(source, data, callback);
-+  } else {
-+    this._processing = false;
-+    callback(new Error('input source must be valid Stream or Buffer instance'));
-+    return;
-+  }
-+};
-+
-+ZipStream.prototype.finalize = function() {
-+  if (this._processing) {
-+    this._finalize = true;
-+    return;
-+  }
-+
-+  debug('finalize');
-+  this._writeCentralDirectory();
-+  this._finalized = true;
-+  debug('finalized');
-+  this.end();
-+};
-+
-+ZipStream.prototype.write = function(chunk, cb) {
-+  if (chunk) {
-+    this.offset += chunk.length;
-+  }
-+
-+  return Transform.prototype.write.call(this, chunk, cb);
-+};
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/.npmignore
-@@ -0,0 +1,3 @@
-+npm-debug.log
-+node_modules/
-+tmp/
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/.travis.yml
-@@ -0,0 +1,4 @@
-+language: node_js
-+node_js:
-+  - "0.10"
-+  - "0.8"
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/CHANGELOG
-@@ -0,0 +1,18 @@
-+v0.2.0:
-+  date: 2014-05-03
-+  changes:
-+    - add size method to return raw size of data passed-through.
-+v0.1.2:
-+  date: 2014-04-18
-+  changes:
-+    - always use readable-stream for consistency.
-+    - use crc32.unsigned to get digest.
-+v0.1.1:
-+  date: 2014-03-30
-+  changes:
-+    - gracefully handle "no data" scenario.
-+    - trim down deps.
-+v0.1.0:
-+  date: 2014-03-30
-+  changes:
-+    - initial release.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/CONTRIBUTING.md
-@@ -0,0 +1,14 @@
-+## Contributing
-+
-+#### Code Style Guide
-+
-+* code should be indented with 2 spaces
-+* single quotes should be used where feasible
-+* commas should be followed by a single space (function params, etc)
-+* variable declaration should include `var`, [no multiple declarations](http://benalman.com/news/2012/05/multiple-var-statements-javascript/)
-+
-+#### Tests
-+
-+* tests should be added to the nodeunit configs in `test/`
-+* tests can be run with `npm test`
-+* see existing tests for guidance
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/LICENSE-MIT
-@@ -0,0 +1,22 @@
-+Copyright (c) 2014 Chris Talkington, 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.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/README.md
-@@ -0,0 +1,59 @@
-+# crc32-stream v0.2.0 [![Build Status](https://travis-ci.org/ctalkington/node-crc32-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-crc32-stream)
-+
-+crc32-stream is a streaming CRC32 checksumer. It uses [buffer-crc32](https://www.npmjs.org/package/buffer-crc32) behind the scenes to reliably handle binary data and fancy character sets. Data is passed through untouched.
-+
-+[![NPM](https://nodei.co/npm/crc32-stream.png)](https://nodei.co/npm/crc32-stream/)
-+
-+### Install
-+
-+```bash
-+npm install crc32-stream --save
-+```
-+
-+You can also use `npm install https://github.com/ctalkington/node-crc32-stream/archive/master.tar.gz` to test upcoming versions.
-+
-+### Usage
-+
-+```js
-+var CRC32Stream = require('crc32-stream');
-+
-+var source = fs.createReadStream('file.txt');
-+var checksum = new CRC32Stream();
-+
-+checksum.on('end', function(err) {
-+  // do something with checksum.digest() here
-+});
-+
-+// either pipe it
-+source.pipe(checksum);
-+
-+// or write it
-+checksum.write('string');
-+checksum.end();
-+```
-+
-+### Instance API
-+
-+Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) methods.
-+
-+#### digest()
-+
-+Returns the checksum digest in unsigned form.
-+
-+#### hex()
-+
-+Returns the hexadecimal representation of the checksum digest. (ie E81722F0)
-+
-+#### size()
-+
-+Returns the raw size/length of passed-through data.
-+
-+### Instance Options
-+
-+Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) options.
-+
-+## Things of Interest
-+
-+- [Changelog](https://github.com/ctalkington/node-crc32-stream/releases)
-+- [Contributing](https://github.com/ctalkington/node-crc32-stream/blob/master/CONTRIBUTING.md)
-+- [MIT License](https://github.com/ctalkington/node-crc32-stream/blob/master/LICENSE-MIT)
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/lib/crc32-stream.js
-@@ -0,0 +1,44 @@
-+/**
-+ * node-crc32-stream
-+ *
-+ * Copyright (c) 2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-crc32-stream/blob/master/LICENSE-MIT
-+ */
-+var inherits = require('util').inherits;
-+var Transform = require('readable-stream').Transform;
-+
-+var crc32 = require('buffer-crc32');
-+
-+function CRC32Stream(options) {
-+  Transform.call(this, options);
-+  this.checksum = new Buffer(4);
-+  this.checksum.writeInt32BE(0, 0);
-+
-+  this.rawSize = 0;
-+}
-+
-+inherits(CRC32Stream, Transform);
-+
-+CRC32Stream.prototype._transform = function(chunk, encoding, callback) {
-+  if (chunk) {
-+    this.checksum = crc32(chunk, this.checksum);
-+    this.rawSize += chunk.length;
-+  }
-+
-+  callback(null, chunk);
-+};
-+
-+CRC32Stream.prototype.digest = function() {
-+  return crc32.unsigned(0, this.checksum);
-+};
-+
-+CRC32Stream.prototype.hex = function() {
-+  return this.digest().toString(16).toUpperCase();
-+};
-+
-+CRC32Stream.prototype.size = function() {
-+  return this.rawSize;
-+};
-+
-+module.exports = CRC32Stream;
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/package.json
-@@ -0,0 +1,48 @@
-+{
-+  "name": "crc32-stream",
-+  "version": "0.2.0",
-+  "description": "a streaming CRC32 checksumer",
-+  "homepage": "https://github.com/ctalkington/node-crc32-stream",
-+  "author": {
-+    "name": "Chris Talkington",
-+    "url": "http://christalkington.com/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/ctalkington/node-crc32-stream.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/ctalkington/node-crc32-stream/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/ctalkington/node-crc32-stream/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/crc32-stream.js",
-+  "engines": {
-+    "node": ">= 0.8.0"
-+  },
-+  "scripts": {
-+    "test": "mocha --reporter dot"
-+  },
-+  "dependencies": {
-+    "readable-stream": "~1.0.24",
-+    "buffer-crc32": "~0.2.1"
-+  },
-+  "devDependencies": {
-+    "chai": "~1.8.1",
-+    "mocha": "~1.16.0"
-+  },
-+  "keywords": [
-+    "crc32-stream",
-+    "crc32",
-+    "stream",
-+    "checksum"
-+  ],
-+  "readme": "# crc32-stream v0.2.0 [![Build Status](https://travis-ci.org/ctalkington/node-crc32-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-crc32-stream)\r\n\r\ncrc32-stream is a streaming CRC32 checksumer. It uses [buffer-crc32](https://www.npmjs.org/package/buffer-crc32) behind the scenes to reliably handle binary data and fancy character sets. Data is passed through untouched.\r\n\r\n[![NPM](https://nodei.co/npm/crc32-stream.png)](https://nodei.co/npm/crc32-stream/)\r\n\r\n### Install\r\n\r\n```bash\r\nnpm install crc32-stream --save\r\n```\r\n\r\nYou can also use `npm install https://github.com/ctalkington/node-crc32-stream/archive/master.tar.gz` to test upcoming versions.\r\n\r\n### Usage\r\n\r\n```js\r\nvar CRC32Stream = require('crc32-stream');\r\n\r\nvar source = fs.createReadStream('file.txt');\r\nvar checksum = new CRC32Stream();\r\n\r\nchecksum.on('end', function(err) {\r\n  // do something with checksum.digest() here\r\n});\r\n\r\n// either pipe it\r\nsource.pipe(checksum);\r\n\r\n// or write it\r\nchecksum.write('string');\r\nchecksum.end();\r\n```\r\n\r\n### Instance API\r\n\r\nInherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) methods.\r\n\r\n#### digest()\r\n\r\nReturns the checksum digest in unsigned form.\r\n\r\n#### hex()\r\n\r\nReturns the hexadecimal representation of the checksum digest. (ie E81722F0)\r\n\r\n#### size()\r\n\r\nReturns the raw size/length of passed-through data.\r\n\r\n### Instance Options\r\n\r\nInherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) options.\r\n\r\n## Things of Interest\r\n\r\n- [Changelog](https://github.com/ctalkington/node-crc32-stream/releases)\r\n- [Contributing](https://github.com/ctalkington/node-crc32-stream/blob/master/CONTRIBUTING.md)\r\n- [MIT License](https://github.com/ctalkington/node-crc32-stream/blob/master/LICENSE-MIT)",
-+  "readmeFilename": "README.md",
-+  "_id": "crc32-stream at 0.2.0",
-+  "_from": "crc32-stream@~0.2.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/test/checksum.js
-@@ -0,0 +1,39 @@
-+/*global before,describe,it */
-+var assert = require('chai').assert;
-+
-+var helpers = require('./helpers');
-+var BinaryStream = helpers.BinaryStream;
-+var DeadEndStream = helpers.DeadEndStream;
-+
-+var CRC32Stream = require('../lib/crc32-stream.js');
-+
-+describe('CRC32Stream', function() {
-+  it('should checksum data while passing through data', function(done) {
-+    var binary = new BinaryStream(1024 * 16);
-+    var checksum = new CRC32Stream();
-+    var deadend = new DeadEndStream();
-+
-+    checksum.on('end', function() {
-+      assert.equal(checksum.digest(), 3893830384);
-+      assert.equal(checksum.hex(), 'E81722F0');
-+      assert.equal(checksum.size(), 16384);
-+      done();
-+    });
-+
-+    checksum.pipe(deadend);
-+    binary.pipe(checksum);
-+  });
-+
-+  it('should gracefully handle having no data chunks passed to it', function(done) {
-+    var checksum = new CRC32Stream();
-+    var deadend = new DeadEndStream();
-+
-+    checksum.on('end', function() {
-+      assert.equal(checksum.digest(), 0);
-+      done();
-+    });
-+
-+    checksum.pipe(deadend);
-+    checksum.end();
-+  });
-+});
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/crc32-stream/test/helpers/index.js
-@@ -0,0 +1,93 @@
-+var crypto = require('crypto');
-+var fs = require('fs');
-+var inherits = require('util').inherits;
-+
-+var Stream = require('stream').Stream;
-+var Readable = require('readable-stream').Readable;
-+var Writable = require('readable-stream').Writable;
-+
-+function adjustDateByOffset(d, offset) {
-+  d = (d instanceof Date) ? d : new Date();
-+
-+  if (offset >= 1) {
-+    d.setMinutes(d.getMinutes() - offset);
-+  } else {
-+    d.setMinutes(d.getMinutes() + Math.abs(offset));
-+  }
-+
-+  return d;
-+}
-+
-+module.exports.adjustDateByOffset = adjustDateByOffset;
-+
-+function binaryBuffer(n) {
-+  var buffer = new Buffer(n);
-+
-+  for (var i = 0; i < n; i++) {
-+    buffer.writeUInt8(i&255, i);
-+  }
-+
-+  return buffer;
-+}
-+
-+module.exports.binaryBuffer = binaryBuffer;
-+
-+function BinaryStream(size, options) {
-+  Readable.call(this, options);
-+
-+  var buf = new Buffer(size);
-+
-+  for (var i = 0; i < size; i++) {
-+    buf.writeUInt8(i&255, i);
-+  }
-+
-+  this.push(buf);
-+  this.push(null);
-+}
-+
-+inherits(BinaryStream, Readable);
-+
-+BinaryStream.prototype._read = function(size) {};
-+
-+module.exports.BinaryStream = BinaryStream;
-+
-+function DeadEndStream(options) {
-+  Writable.call(this, options);
-+}
-+
-+inherits(DeadEndStream, Writable);
-+
-+DeadEndStream.prototype._write = function(chuck, encoding, callback) {
-+  callback();
-+};
-+
-+module.exports.DeadEndStream = DeadEndStream;
-+
-+function fileBuffer(filepath) {
-+  return fs.readFileSync(filepath);
-+}
-+
-+module.exports.fileBuffer = fileBuffer;
-+
-+function WriteHashStream(path, options) {
-+  fs.WriteStream.call(this, path, options);
-+
-+  this.hash = crypto.createHash('sha1');
-+  this.digest = null;
-+
-+  this.on('close', function() {
-+    this.digest = this.hash.digest('hex');
-+  });
-+}
-+
-+inherits(WriteHashStream, fs.WriteStream);
-+
-+WriteHashStream.prototype.write = function(chunk) {
-+  if (chunk) {
-+    this.hash.update(chunk);
-+  }
-+
-+  return fs.WriteStream.prototype.write.call(this, chunk);
-+};
-+
-+module.exports.WriteHashStream = WriteHashStream;
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/.jshintrc
-@@ -0,0 +1,3 @@
-+{
-+  "laxbreak": true
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/.npmignore
-@@ -0,0 +1,6 @@
-+support
-+test
-+examples
-+example
-+*.sock
-+dist
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/History.md
-@@ -0,0 +1,126 @@
-+
-+1.0.2 / 2014-06-10
-+==================
-+
-+  * browser: update color palette (#113, @gscottolson)
-+  * common: make console logging function configurable (#108, @timoxley)
-+  * node: fix %o colors on old node <= 0.8.x
-+  * Makefile: find node path using shell/which (#109, @timoxley)
-+
-+1.0.1 / 2014-06-06
-+==================
-+
-+  * browser: use `removeItem()` to clear localStorage
-+  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
-+  * package: add "contributors" section
-+  * node: fix comment typo
-+  * README: list authors
-+
-+1.0.0 / 2014-06-04
-+==================
-+
-+  * make ms diff be global, not be scope
-+  * debug: ignore empty strings in enable()
-+  * node: make DEBUG_COLORS able to disable coloring
-+  * *: export the `colors` array
-+  * npmignore: don't publish the `dist` dir
-+  * Makefile: refactor to use browserify
-+  * package: add "browserify" as a dev dependency
-+  * Readme: add Web Inspector Colors section
-+  * node: reset terminal color for the debug content
-+  * node: map "%o" to `util.inspect()`
-+  * browser: map "%j" to `JSON.stringify()`
-+  * debug: add custom "formatters"
-+  * debug: use "ms" module for humanizing the diff
-+  * Readme: add "bash" syntax highlighting
-+  * browser: add Firebug color support
-+  * browser: add colors for WebKit browsers
-+  * node: apply log to `console`
-+  * rewrite: abstract common logic for Node & browsers
-+  * add .jshintrc file
-+
-+0.8.1 / 2014-04-14
-+==================
-+
-+  * package: re-add the "component" section
-+
-+0.8.0 / 2014-03-30
-+==================
-+
-+  * add `enable()` method for nodejs. Closes #27
-+  * change from stderr to stdout
-+  * remove unnecessary index.js file
-+
-+0.7.4 / 2013-11-13
-+==================
-+
-+  * remove "browserify" key from package.json (fixes something in browserify)
-+
-+0.7.3 / 2013-10-30
-+==================
-+
-+  * fix: catch localStorage security error when cookies are blocked (Chrome)
-+  * add debug(err) support. Closes #46
-+  * add .browser prop to package.json. Closes #42
-+
-+0.7.2 / 2013-02-06
-+==================
-+
-+  * fix package.json
-+  * fix: Mobile Safari (private mode) is broken with debug
-+  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-+
-+0.7.1 / 2013-02-05
-+==================
-+
-+  * add repository URL to package.json
-+  * add DEBUG_COLORED to force colored output
-+  * add browserify support
-+  * fix component. Closes #24
-+
-+0.7.0 / 2012-05-04
-+==================
-+
-+  * Added .component to package.json
-+  * Added debug.component.js build
-+
-+0.6.0 / 2012-03-16
-+==================
-+
-+  * Added support for "-" prefix in DEBUG [Vinay Pulim]
-+  * Added `.enabled` flag to the node version [TooTallNate]
-+
-+0.5.0 / 2012-02-02
-+==================
-+
-+  * Added: humanize diffs. Closes #8
-+  * Added `debug.disable()` to the CS variant
-+  * Removed padding. Closes #10
-+  * Fixed: persist client-side variant again. Closes #9
-+
-+0.4.0 / 2012-02-01
-+==================
-+
-+  * Added browser variant support for older browsers [TooTallNate]
-+  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
-+  * Added padding to diff (moved it to the right)
-+
-+0.3.0 / 2012-01-26
-+==================
-+
-+  * Added millisecond diff when isatty, otherwise UTC string
-+
-+0.2.0 / 2012-01-22
-+==================
-+
-+  * Added wildcard support
-+
-+0.1.0 / 2011-12-02
-+==================
-+
-+  * Added: remove colors unless stderr isatty [TooTallNate]
-+
-+0.0.1 / 2010-01-03
-+==================
-+
-+  * Initial release
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/Makefile
-@@ -0,0 +1,33 @@
-+
-+# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
-+THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-+THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
-+
-+# BIN directory
-+BIN := $(THIS_DIR)/node_modules/.bin
-+
-+# applications
-+NODE ?= $(shell which node)
-+NPM ?= $(NODE) $(shell which npm)
-+BROWSERIFY ?= $(NODE) $(BIN)/browserify
-+
-+all: dist/debug.js
-+
-+install: node_modules
-+
-+clean:
-+	@rm -rf node_modules dist
-+
-+dist:
-+	@mkdir -p $@
-+
-+dist/debug.js: node_modules browser.js debug.js dist
-+	@$(BROWSERIFY) \
-+		--standalone debug \
-+		. > $@
-+
-+node_modules: package.json
-+	@NODE_ENV= $(NPM) install
-+	@touch node_modules
-+
-+.PHONY: all install clean
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/Readme.md
-@@ -0,0 +1,153 @@
-+# debug
-+
-+  tiny node.js debugging utility modelled after node core's debugging technique.
-+
-+## Installation
-+
-+```bash
-+$ npm install debug
-+```
-+
-+## Usage
-+
-+ With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
-+
-+Example _app.js_:
-+
-+```js
-+var debug = require('debug')('http')
-+  , http = require('http')
-+  , name = 'My App';
-+
-+// fake app
-+
-+debug('booting %s', name);
-+
-+http.createServer(function(req, res){
-+  debug(req.method + ' ' + req.url);
-+  res.end('hello\n');
-+}).listen(3000, function(){
-+  debug('listening');
-+});
-+
-+// fake worker of some kind
-+
-+require('./worker');
-+```
-+
-+Example _worker.js_:
-+
-+```js
-+var debug = require('debug')('worker');
-+
-+setInterval(function(){
-+  debug('doing some work');
-+}, 1000);
-+```
-+
-+ The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
-+
-+  ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
-+
-+  ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
-+
-+## Millisecond diff
-+
-+  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
-+
-+  ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
-+
-+  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
-+
-+  ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
-+
-+## Conventions
-+
-+ If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
-+
-+## Wildcards
-+
-+  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
-+
-+  You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
-+
-+## Browser support
-+
-+  Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.
-+
-+```js
-+a = debug('worker:a');
-+b = debug('worker:b');
-+
-+setInterval(function(){
-+  a('doing some work');
-+}, 1000);
-+
-+setInterval(function(){
-+  b('doing some work');
-+}, 1200);
-+```
-+
-+#### Web Inspector Colors
-+
-+  Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
-+  option. These are WebKit web inspectors, and the Firebug plugin for Firefox.
-+  Colored output looks something like:
-+
-+  ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
-+
-+### stderr vs stdout
-+
-+You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
-+
-+Example _stderr.js_:
-+
-+```js
-+var debug = require('../');
-+var log = debug('app:log');
-+
-+// by default console.log is used
-+log('goes to stdout!');
-+
-+var error = debug('app:error');
-+// set this namespace to log via console.error
-+error.log = console.error.bind(console); // don't forget to bind to console!
-+error('goes to stderr');
-+log('still goes to stdout!');
-+
-+// set all output to go via console.warn
-+// overrides all per-namespace log settings
-+debug.log = console.warn.bind(console);
-+log('now goes to stderr via console.warn');
-+error('still goes to stderr, but via console.warn now');
-+```
-+
-+## Authors
-+
-+ - TJ Holowaychuk
-+ - Nathan Rajlich
-+
-+## License
-+
-+(The MIT License)
-+
-+Copyright (c) 2014 TJ Holowaychuk <tj at vision-media.ca>
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/browser.js
-@@ -0,0 +1,144 @@
-+
-+/**
-+ * This is the web browser implementation of `debug()`.
-+ *
-+ * Expose `debug()` as the module.
-+ */
-+
-+exports = module.exports = require('./debug');
-+exports.log = log;
-+exports.formatArgs = formatArgs;
-+exports.save = save;
-+exports.load = load;
-+exports.useColors = useColors;
-+
-+/**
-+ * Colors.
-+ */
-+
-+exports.colors = [
-+  'lightseagreen',
-+  'forestgreen',
-+  'goldenrod',
-+  'dodgerblue',
-+  'darkorchid',
-+  'crimson'
-+];
-+
-+/**
-+ * Currently only WebKit-based Web Inspectors and the Firebug
-+ * extension (*not* the built-in Firefox web inpector) 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)));
-+}
-+
-+/**
-+ * 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, ''].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,
-+  // where the `console.log` function doesn't have 'apply'
-+  return 'object' == typeof console
-+    && 'function' == typeof console.log
-+    && Function.prototype.apply.call(console.log, console, arguments);
-+}
-+
-+/**
-+ * Save `namespaces`.
-+ *
-+ * @param {String} namespaces
-+ * @api private
-+ */
-+
-+function save(namespaces) {
-+  try {
-+    if (null == namespaces) {
-+      localStorage.removeItem('debug');
-+    } else {
-+      localStorage.debug = namespaces;
-+    }
-+  } catch(e) {}
-+}
-+
-+/**
-+ * Load `namespaces`.
-+ *
-+ * @return {String} returns the previously persisted debug modes
-+ * @api private
-+ */
-+
-+function load() {
-+  var r;
-+  try {
-+    r = localStorage.debug;
-+  } catch(e) {}
-+  return r;
-+}
-+
-+/**
-+ * Enable namespaces listed in `localStorage.debug` initially.
-+ */
-+
-+exports.enable(load());
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/component.json
-@@ -0,0 +1,19 @@
-+{
-+  "name": "debug",
-+  "repo": "visionmedia/debug",
-+  "description": "small debugging utility",
-+  "version": "1.0.2",
-+  "keywords": [
-+    "debug",
-+    "log",
-+    "debugger"
-+  ],
-+  "main": "browser.js",
-+  "scripts": [
-+    "browser.js",
-+    "debug.js"
-+  ],
-+  "dependencies": {
-+    "guille/ms.js": "0.6.1"
-+  }
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/debug.js
-@@ -0,0 +1,197 @@
-+
-+/**
-+ * 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 = require('ms');
-+
-+/**
-+ * 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 = exports.log || enabled.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('*', '.*?');
-+    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;
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/node.js
-@@ -0,0 +1,129 @@
-+
-+/**
-+ * Module dependencies.
-+ */
-+
-+var tty = require('tty');
-+var util = require('util');
-+
-+/**
-+ * This is the Node.js implementation of `debug()`.
-+ *
-+ * Expose `debug()` as the module.
-+ */
-+
-+exports = module.exports = require('./debug');
-+exports.log = log;
-+exports.formatArgs = formatArgs;
-+exports.save = save;
-+exports.load = load;
-+exports.useColors = useColors;
-+
-+/**
-+ * Colors.
-+ */
-+
-+exports.colors = [6, 2, 3, 4, 5, 1];
-+
-+/**
-+ * Is stdout a TTY? Colored output is enabled when `true`.
-+ */
-+
-+function useColors() {
-+  var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
-+  if (0 === debugColors.length) {
-+    return tty.isatty(1);
-+  } else {
-+    return '0' !== debugColors
-+        && 'no' !== debugColors
-+        && 'false' !== debugColors
-+        && 'disabled' !== debugColors;
-+  }
-+}
-+
-+/**
-+ * Map %o to `util.inspect()`, since Node doesn't do that out of the box.
-+ */
-+
-+var inspect = (4 === util.inspect.length ?
-+  // node <= 0.8.x
-+  function (v, colors) {
-+    return util.inspect(v, void 0, void 0, colors);
-+  } :
-+  // node > 0.8.x
-+  function (v, colors) {
-+    return util.inspect(v, { colors: colors });
-+  }
-+);
-+
-+exports.formatters.o = function(v) {
-+  return inspect(v, this.useColors)
-+    .replace(/\s*\n\s*/g, ' ');
-+};
-+
-+/**
-+ * Adds ANSI color escape codes if enabled.
-+ *
-+ * @api public
-+ */
-+
-+function formatArgs() {
-+  var args = arguments;
-+  var useColors = this.useColors;
-+  var name = this.namespace;
-+
-+  if (useColors) {
-+    var c = this.color;
-+
-+    args[0] = '  \u001b[9' + c + 'm' + name + ' '
-+      + '\u001b[0m'
-+      + args[0] + '\u001b[3' + c + 'm'
-+      + ' +' + exports.humanize(this.diff) + '\u001b[0m';
-+  } else {
-+    args[0] = new Date().toUTCString()
-+      + ' ' + name + ' ' + args[0];
-+  }
-+  return args;
-+}
-+
-+/**
-+ * Invokes `console.log()` with the specified arguments.
-+ */
-+
-+function log() {
-+  return console.log.apply(console, arguments);
-+}
-+
-+/**
-+ * Save `namespaces`.
-+ *
-+ * @param {String} namespaces
-+ * @api private
-+ */
-+
-+function save(namespaces) {
-+  if (null == namespaces) {
-+    // If you set a process.env field to null or undefined, it gets cast to the
-+    // string 'null' or 'undefined'. Just delete instead.
-+    delete process.env.DEBUG;
-+  } else {
-+    process.env.DEBUG = namespaces;
-+  }
-+}
-+
-+/**
-+ * Load `namespaces`.
-+ *
-+ * @return {String} returns the previously persisted debug modes
-+ * @api private
-+ */
-+
-+function load() {
-+  return process.env.DEBUG;
-+}
-+
-+/**
-+ * Enable namespaces listed in `process.env.DEBUG` initially.
-+ */
-+
-+exports.enable(load());
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/node_modules/ms/.npmignore
-@@ -0,0 +1,5 @@
-+node_modules
-+test
-+History.md
-+Makefile
-+component.json
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/node_modules/ms/README.md
-@@ -0,0 +1,33 @@
-+# ms.js: miliseconds conversion utility
-+
-+```js
-+ms('1d')      // 86400000
-+ms('10h')     // 36000000
-+ms('2h')      // 7200000
-+ms('1m')      // 60000
-+ms('5s')      // 5000
-+ms('100')     // 100
-+```
-+
-+```js
-+ms(60000)             // "1m"
-+ms(2 * 60000)         // "2m"
-+ms(ms('10 hours'))    // "10h"
-+```
-+
-+```js
-+ms(60000, { long: true })             // "1 minute"
-+ms(2 * 60000, { long: true })         // "2 minutes"
-+ms(ms('10 hours', { long: true }))    // "10 hours"
-+```
-+
-+- Node/Browser compatible. Published as `ms` in NPM.
-+- If a number is supplied to `ms`, a string with a unit is returned.
-+- If a string that contains the number is supplied, it returns it as
-+a number (e.g: it returns `100` for `'100'`).
-+- If you pass a string with a number and a valid unit, the number of
-+equivalent ms is returned.
-+
-+## License
-+
-+MIT
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/node_modules/ms/index.js
-@@ -0,0 +1,111 @@
-+/**
-+ * 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) {
-+  var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|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 'y':
-+      return n * y;
-+    case 'days':
-+    case 'day':
-+    case 'd':
-+      return n * d;
-+    case 'hours':
-+    case 'hour':
-+    case 'h':
-+      return n * h;
-+    case 'minutes':
-+    case 'minute':
-+    case 'm':
-+      return n * m;
-+    case 'seconds':
-+    case 'second':
-+    case 's':
-+      return n * s;
-+    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';
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/node_modules/ms/package.json
-@@ -0,0 +1,27 @@
-+{
-+  "name": "ms",
-+  "version": "0.6.2",
-+  "description": "Tiny ms conversion utility",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/guille/ms.js.git"
-+  },
-+  "main": "./index",
-+  "devDependencies": {
-+    "mocha": "*",
-+    "expect.js": "*",
-+    "serve": "*"
-+  },
-+  "component": {
-+    "scripts": {
-+      "ms/index.js": "index.js"
-+    }
-+  },
-+  "readme": "# ms.js: miliseconds conversion utility\n\n```js\nms('1d')      // 86400000\nms('10h')     // 36000000\nms('2h')      // 7200000\nms('1m')      // 60000\nms('5s')      // 5000\nms('100')     // 100\n```\n\n```js\nms(60000)             // \"1m\"\nms(2 * 60000)         // \"2m\"\nms(ms('10 hours'))    // \"10h\"\n```\n\n```js\nms(60000, { long: true })             // \"1 minute\"\nms(2 * 60000, { long: true })         // \"2 minutes\"\nms(ms('10 hours', { long: true }))    // \"10 hours\"\n```\n\n- Node/Browser compatible. Published as `ms` in NPM.\n- If a number is supplied to `ms`, a string with a unit is returned.\n- If a string that contains the number is supplied, it returns it as\na number (e.g: it returns `100` for `'100'`).\n- If you pass a string with a number and a valid unit, the number of\nequivalent ms is returned.\n\n## License\n\nMIT",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/guille/ms.js/issues"
-+  },
-+  "_id": "ms at 0.6.2",
-+  "_from": "ms at 0.6.2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/debug/package.json
-@@ -0,0 +1,47 @@
-+{
-+  "name": "debug",
-+  "version": "1.0.2",
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/visionmedia/debug.git"
-+  },
-+  "description": "small debugging utility",
-+  "keywords": [
-+    "debug",
-+    "log",
-+    "debugger"
-+  ],
-+  "author": {
-+    "name": "TJ Holowaychuk",
-+    "email": "tj at vision-media.ca"
-+  },
-+  "contributors": [
-+    {
-+      "name": "Nathan Rajlich",
-+      "email": "nathan at tootallnate.net",
-+      "url": "http://n8.io"
-+    }
-+  ],
-+  "dependencies": {
-+    "ms": "0.6.2"
-+  },
-+  "devDependencies": {
-+    "browserify": "4.1.6",
-+    "mocha": "*"
-+  },
-+  "main": "./node.js",
-+  "browser": "./browser.js",
-+  "component": {
-+    "scripts": {
-+      "debug/index.js": "browser.js",
-+      "debug/debug.js": "debug.js"
-+    }
-+  },
-+  "readme": "# debug\n\n  tiny node.js debugging utility modelled after node core's debugging technique.\n\n## Installation\n\n```bash\n$ npm install debug\n```\n\n## Usage\n\n With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.\n\nExample _app.js_:\n\n```js\nvar debug = require('debug')('http')\n  , http = require('http')\n  , name = 'My App';\n\n// fake app\n\ndebug('booting %s', name);\n\nhttp.createServer(function(req, res){\n  debug(req.method + ' ' + req.url);\n  res.end('hello\\n');\n}).listen(3000, function(){\n  debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample _worker.js_:\n\n```js\nvar debug = require('debug')('worker');\n\nsetInterval(function(){\n  debug('doing some work');\n}, 1000);\n```\n\n The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:\n\n  ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)\n\n  ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)\n\n## Millisecond diff\n\n  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n  ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)\n\n  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:\n\n  ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)\n\n## Conventions\n\n If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\".\n\n## Wildcards\n\n  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\n  You can also exclude specific debuggers by prefixing them with a \"-\" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with \"connect:\".\n\n## Browser support\n\n  Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.\n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n  a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n  b('doing some work');\n}, 1200);\n```\n\n#### Web Inspector Colors\n\n  Colors are also enabled on \"Web Inspectors\" that understand the `%c` formatting\n  option. These are WebKit web inspectors, and the Firebug plugin for Firefox.\n  Colored output looks something like:\n\n  ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)\n\n### stderr vs stdout\n\nYou can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:\n\nExample _stderr.js_:\n\n```js\nvar debug = require('../');\nvar log = debug('app:log');\n\n// by default console.log is used\nlog('goes to stdout!');\n\nvar error = debug('app:error');\n// set this namespace to log via console.error\nerror.log = console.error.bind(console); // don't forget to bind to console!\nerror('goes to stderr');\nlog('still goes to stdout!');\n\n// set all output to go via console.warn\n// overrides all per-namespace log settings\ndebug.log = console.warn.bind(console);\nlog('now goes to stderr via console.warn');\nerror('still goes to stderr, but via console.warn now');\n```\n\n## Authors\n\n - TJ Holowaychuk\n - Nathan Rajlich\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2014 TJ Holowaychuk <tj at vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
-+  "readmeFilename": "Readme.md",
-+  "bugs": {
-+    "url": "https://github.com/visionmedia/debug/issues"
-+  },
-+  "_id": "debug at 1.0.2",
-+  "_from": "debug@~1.0.2"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/deflate-crc32-stream/LICENSE-MIT
-@@ -0,0 +1,22 @@
-+Copyright (c) 2014 Chris Talkington, 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.
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/deflate-crc32-stream/README.md
-@@ -0,0 +1,61 @@
-+# deflate-crc32-stream v0.1.0 [![Build Status](https://travis-ci.org/ctalkington/node-deflate-crc32-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-deflate-crc32-stream)
-+
-+deflate-crc32-stream is a streaming deflater with CRC32 checksumer. It uses [buffer-crc32](https://www.npmjs.org/package/buffer-crc32) behind the scenes to reliably handle binary data and fancy character sets. Data comes through compressed with [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw).
-+
-+[![NPM](https://nodei.co/npm/deflate-crc32-stream.png)](https://nodei.co/npm/deflate-crc32-stream/)
-+
-+### Install
-+
-+```bash
-+npm install deflate-crc32-stream --save
-+```
-+
-+You can also use `npm install https://github.com/ctalkington/node-deflate-crc32-stream/archive/master.tar.gz` to test upcoming versions.
-+
-+### Usage
-+
-+```js
-+var CRC32Stream = require('deflate-crc32-stream');
-+
-+var source = fs.createReadStream('file.txt');
-+var deflate = new DeflateCRC32Stream();
-+
-+deflate.on('end', function(err) {
-+  // do something with deflate.digest() here
-+});
-+
-+// either pipe it
-+source.pipe(deflate);
-+
-+// or write it
-+deflate.write('string');
-+deflate.end();
-+```
-+
-+### Instance API
-+
-+Inherits [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw) methods.
-+
-+#### digest()
-+
-+Returns the checksum digest in unsigned form.
-+
-+#### hex()
-+
-+Returns the hexadecimal representation of the checksum digest. (ie E81722F0)
-+
-+#### size(compressed)
-+
-+Returns the raw uncompressed size/length of passed-through data.
-+
-+If `compressed` is `true`, it returns compressed length instead.
-+
-+### Instance Options
-+
-+Inherits [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw) options.
-+
-+## Things of Interest
-+
-+- [Changelog](https://github.com/ctalkington/node-deflate-crc32-stream/releases)
-+- [Contributing](https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/CONTRIBUTING.md)
-+- [MIT License](https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/LICENSE-MIT)
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/deflate-crc32-stream/lib/deflate-crc32-stream.js
-@@ -0,0 +1,69 @@
-+/**
-+ * node-deflate-crc32-stream
-+ *
-+ * Copyright (c) 2014 Chris Talkington, contributors.
-+ * Licensed under the MIT license.
-+ * https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/LICENSE-MIT
-+ */
-+var zlib = require('zlib');
-+var inherits = require('util').inherits;
-+
-+var crc32 = require('buffer-crc32');
-+
-+function DeflateCRC32Stream(options) {
-+  zlib.DeflateRaw.call(this, options);
-+
-+  this.checksum = new Buffer(4);
-+  this.checksum.writeInt32BE(0, 0);
-+
-+  this.rawSize = 0;
-+  this.compressedSize = 0;
-+
-+  // BC v0.8
-+  if (typeof zlib.DeflateRaw.prototype.push !== 'function') {
-+    this.on('data', function(chunk) {
-+      if (chunk) {
-+        this.compressedSize += chunk.length;
-+      }
-+    });
-+  }
-+}
-+
-+inherits(DeflateCRC32Stream, zlib.DeflateRaw);
-+
-+DeflateCRC32Stream.prototype.push = function(chunk, encoding) {
-+  if (chunk) {
-+    this.compressedSize += chunk.length;
-+  }
-+
-+  return zlib.DeflateRaw.prototype.push.call(this, chunk, encoding);
-+};
-+
-+DeflateCRC32Stream.prototype.write = function(chunk, cb) {
-+  if (chunk) {
-+    this.checksum = crc32(chunk, this.checksum);
-+    this.rawSize += chunk.length;
-+  }
-+
-+  return zlib.DeflateRaw.prototype.write.call(this, chunk, cb);
-+};
-+
-+DeflateCRC32Stream.prototype.digest = function() {
-+  return crc32.unsigned(0, this.checksum);
-+};
-+
-+DeflateCRC32Stream.prototype.hex = function() {
-+  return this.digest().toString(16).toUpperCase();
-+};
-+
-+DeflateCRC32Stream.prototype.size = function(compressed) {
-+  compressed = compressed || false;
-+
-+  if (compressed) {
-+    return this.compressedSize;
-+  } else {
-+    return this.rawSize;
-+  }
-+};
-+
-+module.exports = DeflateCRC32Stream;
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/node_modules/deflate-crc32-stream/package.json
-@@ -0,0 +1,53 @@
-+{
-+  "name": "deflate-crc32-stream",
-+  "version": "0.1.1",
-+  "description": "a streaming deflater with CRC32 checksumer",
-+  "homepage": "https://github.com/ctalkington/node-deflate-crc32-stream",
-+  "author": {
-+    "name": "Chris Talkington",
-+    "url": "http://christalkington.com/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/ctalkington/node-deflate-crc32-stream.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/ctalkington/node-deflate-crc32-stream/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/deflate-crc32-stream.js",
-+  "files": [
-+    "lib",
-+    "LICENSE-MIT"
-+  ],
-+  "engines": {
-+    "node": ">= 0.8.0"
-+  },
-+  "scripts": {
-+    "test": "mocha --reporter dot"
-+  },
-+  "dependencies": {
-+    "buffer-crc32": "~0.2.1"
-+  },
-+  "devDependencies": {
-+    "chai": "~1.8.1",
-+    "mocha": "~1.16.0",
-+    "readable-stream": "~1.0.24"
-+  },
-+  "keywords": [
-+    "deflate",
-+    "crc32-stream",
-+    "crc32",
-+    "stream",
-+    "checksum"
-+  ],
-+  "readme": "# deflate-crc32-stream v0.1.0 [![Build Status](https://travis-ci.org/ctalkington/node-deflate-crc32-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-deflate-crc32-stream)\r\n\r\ndeflate-crc32-stream is a streaming deflater with CRC32 checksumer. It uses [buffer-crc32](https://www.npmjs.org/package/buffer-crc32) behind the scenes to reliably handle binary data and fancy character sets. Data comes through compressed with [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw).\r\n\r\n[![NPM](https://nodei.co/npm/deflate-crc32-stream.png)](https://nodei.co/npm/deflate-crc32-stream/)\r\n\r\n### Install\r\n\r\n```bash\r\nnpm install deflate-crc32-stream --save\r\n```\r\n\r\nYou can also use `npm install https://github.com/ctalkington/node-deflate-crc32-stream/archive/master.tar.gz` to test upcoming versions.\r\n\r\n### Usage\r\n\r\n```js\r\nvar CRC32Stream = require('deflate-crc32-stream');\r\n\r\nvar source = fs.createReadStream('file.txt');\r\nvar deflate = new DeflateCRC32Stream();\r\n\r\ndeflate.on('end', function(err) {\r\n  // do something with deflate.digest() here\r\n});\r\n\r\n// either pipe it\r\nsource.pipe(deflate);\r\n\r\n// or write it\r\ndeflate.write('string');\r\ndeflate.end();\r\n```\r\n\r\n### Instance API\r\n\r\nInherits [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw) methods.\r\n\r\n#### digest()\r\n\r\nReturns the checksum digest in unsigned form.\r\n\r\n#### hex()\r\n\r\nReturns the hexadecimal representation of the checksum digest. (ie E81722F0)\r\n\r\n#### size(compressed)\r\n\r\nReturns the raw uncompressed size/length of passed-through data.\r\n\r\nIf `compressed` is `true`, it returns compressed length instead.\r\n\r\n### Instance Options\r\n\r\nInherits [zlib.DeflateRaw](http://nodejs.org/api/zlib.html#zlib_class_zlib_deflateraw) options.\r\n\r\n## Things of Interest\r\n\r\n- [Changelog](https://github.com/ctalkington/node-deflate-crc32-stream/releases)\r\n- [Contributing](https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/CONTRIBUTING.md)\r\n- [MIT License](https://github.com/ctalkington/node-deflate-crc32-stream/blob/master/LICENSE-MIT)",
-+  "readmeFilename": "README.md",
-+  "_id": "deflate-crc32-stream at 0.1.1",
-+  "_from": "deflate-crc32-stream@~0.1.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/node_modules/zip-stream/package.json
-@@ -0,0 +1,58 @@
-+{
-+  "name": "zip-stream",
-+  "version": "0.3.6",
-+  "description": "a streaming zip archive generator.",
-+  "homepage": "https://github.com/ctalkington/node-zip-stream",
-+  "author": {
-+    "name": "Chris Talkington",
-+    "url": "http://christalkington.com/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/ctalkington/node-zip-stream.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/ctalkington/node-zip-stream/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/zip-stream.js",
-+  "files": [
-+    "lib",
-+    "LICENSE-MIT"
-+  ],
-+  "engines": {
-+    "node": ">= 0.8.0"
-+  },
-+  "scripts": {
-+    "test": "mocha --reporter dot"
-+  },
-+  "dependencies": {
-+    "buffer-crc32": "~0.2.1",
-+    "crc32-stream": "~0.2.0",
-+    "debug": "~1.0.2",
-+    "deflate-crc32-stream": "~0.1.0",
-+    "lodash": "~2.4.1",
-+    "readable-stream": "~1.0.26"
-+  },
-+  "devDependencies": {
-+    "chai": "~1.9.1",
-+    "mocha": "~1.18.2",
-+    "rimraf": "~2.2.8",
-+    "mkdirp": "~0.5.0"
-+  },
-+  "keywords": [
-+    "archive",
-+    "stream",
-+    "zip-stream",
-+    "zip"
-+  ],
-+  "readme": "# zip-stream v0.3.6 [![Build Status](https://travis-ci.org/ctalkington/node-zip-stream.svg?branch=master)](https://travis-ci.org/ctalkington/node-zip-stream)\r\n\r\nzip-stream is a streaming zip archive generator. It was built to be a successor to [zipstream](https://npmjs.org/package/zipstream). Dependencies are kept to a minimum through the use of many of node's built-in modules including the use of zlib module for compression.\r\n\r\n[![NPM](https://nodei.co/npm/zip-stream.png)](https://nodei.co/npm/zip-stream/)\r\n\r\n### Install\r\n\r\n```bash\r\nnpm install zip-stream --save\r\n```\r\n\r\nYou can also use `npm install https://github.com/ctalkington/node-zip-stream/archive/master.tar.gz` to test upcoming versions.\r\n\r\n### Usage\r\n\r\nThis module is meant to be wrapped internally by other modules and therefore lacks any queue management. This means you have to wait until the previous entry has been fully consumed to add another. Nested callbacks should be used to add multiple entries. There are modules like [async](https://npmjs.org/package/async) that ease the so called \"callback hell\".\r\n\r\nIf you want a module that handles entry queueing and much more, you should check out [archiver](https://npmjs.org/package/archiver) which uses this module internally.\r\n\r\n```js\r\nvar packer = require('zip-stream');\r\nvar archive = new packer(); // OR new packer(options)\r\n\r\narchive.on('error', function(err) {\r\n  throw err;\r\n});\r\n\r\n// pipe archive where you want it (ie fs, http, etc)\r\n// listen to the destination's end, close, or finish event\r\n\r\narchive.entry('string contents', { name: 'string.txt' }, function(err, entry) {\r\n  if (err) throw err;\r\n  archive.entry(null, { name: 'directory/' }, function(err, entry) {\r\n    if (err) throw err;\r\n    archive.finalize();\r\n  });\r\n});\r\n```\r\n\r\n### Instance API\r\n\r\n#### entry(input, data, callback(err, data))\r\n\r\nAppends an input source (text string, buffer, or stream) to the instance. When the instance has received, processed, and emitted the input, the callback is fired.\r\n\r\n#### finalize()\r\n\r\nFinalizes the instance. You should listen to the destination stream's `end`/`close`/`finish` event to know when all output has been safely consumed.\r\n\r\n### Instance Options\r\n\r\n#### comment `string`\r\n\r\nSets the zip comment.\r\n\r\n#### forceUTC `boolean`\r\n\r\nIf true, forces the entry date to UTC. Helps with testing across timezones.\r\n\r\n#### store `boolean`\r\n\r\nIf true, all entry contents will be archived without compression by default.\r\n\r\n#### zlib `object`\r\n\r\nPassed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.\r\n\r\n### Entry Data\r\n\r\n#### name `string` `required`\r\n\r\nSets the entry name including internal path.\r\n\r\n#### type `string`\r\n\r\nSets the entry type. Defaults to `file` or `directory` if name ends with trailing slash.\r\n\r\n#### date `string|Date`\r\n\r\nSets the entry date. This can be any valid date string or instance. Defaults to current time in locale.\r\n\r\n#### store `boolean`\r\n\r\nIf true, entry contents will be archived without compression.\r\n\r\n#### comment `string`\r\n\r\nSets the entry comment.\r\n\r\n#### mode `number`\r\n\r\nSets the entry permissions. (experimental)\r\n\r\n## Debugging\r\n\r\nThis library makes use of the [debug](https://npmjs.org/package/debug) module with a namespace of `zip-stream` which can be triggered by setting `DEBUG` in your environment like so:\r\n\r\n```shell\r\n# unix\r\nDEBUG=zip-stream:* node script\r\n\r\n# windows (powershell)\r\n$env:DEBUG=\"zip-stream:*\"\r\nnode script\r\n\r\n# windows (cmd)\r\nSET DEBUG=\"zip-stream:*\"\r\nnode script\r\n```\r\n\r\n## Things of Interest\r\n\r\n- [Releases](https://github.com/ctalkington/node-zip-stream/releases)\r\n- [Contributing](https://github.com/ctalkington/node-zip-stream/blob/master/CONTRIBUTING.md)\r\n- [MIT License](https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT)\r\n\r\n## Credits\r\n\r\nConcept inspired by Antoine van Wel's [zipstream](https://npmjs.org/package/zipstream) module, which is no longer being updated.",
-+  "readmeFilename": "README.md",
-+  "_id": "zip-stream at 0.3.6",
-+  "_from": "zip-stream@~0.3.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/archiver/package.json
-@@ -0,0 +1,62 @@
-+{
-+  "name": "archiver",
-+  "version": "0.10.1",
-+  "description": "a streaming interface for archive generation",
-+  "homepage": "https://github.com/ctalkington/node-archiver",
-+  "author": {
-+    "name": "Chris Talkington",
-+    "url": "http://christalkington.com/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "https://github.com/ctalkington/node-archiver.git"
-+  },
-+  "bugs": {
-+    "url": "https://github.com/ctalkington/node-archiver/issues"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT"
-+    }
-+  ],
-+  "main": "lib/archiver.js",
-+  "files": [
-+    "lib",
-+    "LICENSE-MIT"
-+  ],
-+  "engines": {
-+    "node": ">= 0.10.0"
-+  },
-+  "scripts": {
-+    "test": "mocha --reporter dot",
-+    "bench": "node benchmark/simple/pack-zip.js"
-+  },
-+  "dependencies": {
-+    "buffer-crc32": "~0.2.1",
-+    "readable-stream": "~1.0.26",
-+    "tar-stream": "~0.4.0",
-+    "zip-stream": "~0.3.0",
-+    "lazystream": "~0.1.0",
-+    "file-utils": "~0.2.0",
-+    "lodash": "~2.4.1"
-+  },
-+  "devDependencies": {
-+    "chai": "~1.9.1",
-+    "mocha": "~1.18.2",
-+    "rimraf": "~2.2.8",
-+    "mkdirp": "~0.5.0",
-+    "stream-bench": "~0.1.2"
-+  },
-+  "keywords": [
-+    "archive",
-+    "archiver",
-+    "stream",
-+    "zip",
-+    "tar"
-+  ],
-+  "readme": "# Archiver v0.10.1 [![Build Status](https://travis-ci.org/ctalkington/node-archiver.svg?branch=master)](https://travis-ci.org/ctalkington/node-archiver)\r\n\r\na streaming interface for archive generation\r\n\r\n[![NPM](https://nodei.co/npm/archiver.png)](https://nodei.co/npm/archiver/)\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install archiver --save\r\n```\r\n\r\nYou can also use `npm install https://github.com/ctalkington/node-archiver/archive/master.tar.gz` to test upcoming versions.\r\n\r\n## Archiver\r\n\r\n#### create(format, options)\r\n\r\nCreates an Archiver instance based on the format (zip, tar, etc) passed. Parameters can be passed directly to `Archiver` constructor for convenience.\r\n\r\n#### registerFormat(format, module)\r\n\r\nRegisters an archive format. Format modules are essentially transform streams with a few required methods. They will be further documented once a formal spec is in place.\r\n\r\n### Instance Methods\r\n\r\nInherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) methods.\r\n\r\n#### append(input, data)\r\n\r\nAppends an input source (text string, buffer, or stream) to the instance. When the instance has received, processed, and emitted the input, the `entry` event is fired.\r\n\r\nReplaced `#addFile` in v0.5.\r\n\r\n```js\r\narchive.append('string', { name:'string.txt' });\r\narchive.append(new Buffer('string'), { name:'buffer.txt' });\r\narchive.append(fs.createReadStream('mydir/file.txt'), { name:'stream.txt' });\r\narchive.append(null, { name:'dir/' });\r\n```\r\n\r\n#### bulk(mappings)\r\n\r\nAppends multiple entries from passed array of src-dest mappings. A lazystream wrapper is used to prevent issues with open file limits.\r\n\r\nGlobbing patterns are supported through use of the [file-utils](https://github.com/SBoudrias/file-utils) package. Please note that multiple src files to single dest file (ie concat) is not supported.\r\n\r\nThe `data` property can be set (per src-dest mapping) to define data for matched entries.\r\n\r\n```js\r\narchive.bulk([\r\n  { src: ['mydir/**'], data: { date: new Date() } },\r\n  { expand: true, cwd: 'mydir', src: ['**'], dest: 'newdir' }\r\n]);\r\n```\r\n\r\nFor more detail on this feature, please see [BULK.md](https://github.com/ctalkington/node-archiver/blob/master/BULK.md).\r\n\r\n#### file(filepath, data)\r\n\r\nAppends a file given its filepath using a lazystream wrapper to prevent issues with open file limits. When the instance has received, processed, and emitted the file, the `entry` event is fired.\r\n\r\n```js\r\narchive.file('mydir/file.txt', { name:'file.txt' });\r\n```\r\n\r\n#### finalize()\r\n\r\nFinalizes the instance. You should listen for the `end`/`close`/`finish` of the destination stream to properly detect completion.\r\n\r\n#### pointer()\r\n\r\nReturns the current byte length emitted by archiver. Use this in your end callback to log generated size.\r\n\r\n## Events\r\n\r\nInherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) events.\r\n\r\n#### entry\r\n\r\nFired when the input has been received, processed, and emitted. Passes entry data as first argument.\r\n\r\n## Zip\r\n\r\n### Options\r\n\r\n#### comment `string`\r\n\r\nSets the zip comment.\r\n\r\n#### forceUTC `boolean`\r\n\r\nIf true, forces the entry date to UTC. Helps with testing across timezones.\r\n\r\n#### store `boolean`\r\n\r\nIf true, all entry contents will be archived without compression by default.\r\n\r\n#### zlib `object`\r\n\r\nPassed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.\r\n\r\n### Entry Data\r\n\r\n#### name `string` `required`\r\n\r\nSets the entry name including internal path.\r\n\r\n#### date `string|Date`\r\n\r\nSets the entry date. This can be any valid date string or instance. Defaults to current time in locale.\r\n\r\n#### store `boolean`\r\n\r\nIf true, entry contents will be archived without compression.\r\n\r\n#### comment `string`\r\n\r\nSets the entry comment.\r\n\r\n#### mode `number`\r\n\r\nSets the entry permissions. Defaults to octal 0755 (directory) or 0644 (file).\r\n\r\n## Tar\r\n\r\n### Options\r\n\r\n#### gzip `boolean`\r\n\r\nCompresses the tar archive using gzip, default is false.\r\n\r\n#### gzipOptions `object`\r\n\r\nPassed to node's [zlib](http://nodejs.org/api/zlib.html#zlib_options) module to control compression. Options may vary by node version.\r\n\r\n### Entry Data\r\n\r\n#### name `string` `required`\r\n\r\nSets the entry name including internal path.\r\n\r\n#### date `string|Date`\r\n\r\nSets the entry date. This can be any valid date string or instance. Defaults to current time in locale.\r\n\r\n#### mode `number`\r\n\r\nSets the entry permissions. Defaults to octal 0755 (directory) or 0644 (file).\r\n\r\n## Libraries\r\n\r\nArchiver makes use of several libraries/modules to avoid duplication of efforts.\r\n\r\n- [zip-stream](https://npmjs.org/package/zip-stream)\r\n- [tar-stream](https://npmjs.org/package/tar-stream)\r\n\r\n## Things of Interest\r\n\r\n- [Examples](https://github.com/ctalkington/node-archiver/blob/master/examples)\r\n- [Changelog](https://github.com/ctalkington/node-archiver/releases)\r\n- [Contributing](https://github.com/ctalkington/node-archiver/blob/master/CONTRIBUTING.md)\r\n- [MIT License](https://github.com/ctalkington/node-archiver/blob/master/LICENSE-MIT)",
-+  "readmeFilename": "README.md",
-+  "_id": "archiver at 0.10.1",
-+  "_from": "archiver@~0.10.1"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/.npmignore
-@@ -0,0 +1 @@
-+config.js
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/History.md
-@@ -0,0 +1,97 @@
-+# Changelog
-+
-+## 0.9.0
-+* Add automatic retries to session authorisation.
-+* Deprecated session.authorise() in favour of supplying a token at creation.
-+
-+## 0.8.4
-+* Added some user functions to list of signed methods (maxkueng)
-+* Added some library functions to list of write methods (maxkueng)
-+
-+## 0.8.3
-+* Fix issue where undefined mbid in track object would cause scrobble
-+  to fail. (maxkueng)
-+* Fix issue where all undefined and null parameters would cause signatures
-+  to fail.
-+* Use http.request instead of deprecated http.createClient. (xhochy)
-+* lastfm-node now requires node v0.4.10 and above.
-+
-+## 0.8.1
-+* Automatically set album parameter from track details when available.
-+* Experimental REPL.
-+
-+## 0.8.0
-+
-+### Breaking changes
-+* Removed old handler options which were deprecated in 0.6.0.
-+
-+### New features
-+* Scrobble request which return error codes 11, 16 or 29 are automatically retried.
-+
-+## 0.7.0
-+
-+### Breaking changes
-+* The success event on `lastfm.request` now emits parsed JSON rather than raw text.
-+* `RecentTracksStream.isStreaming` has been removed in favour of `RecentTracksStream.isStreaming()`.
-+
-+## 0.6.3
-+
-+* Fixed bug where success/error handlers on lastfm.info and lastfm.update were being fired twice.
-+* Configurable user-agent string.
-+* LastFmUpdate can now accept any parameter. This will be passed through to Last.Fm. This allows artist/track info to be supplied without having to use the track object from RecentTrackStream.
-+
-+## 0.6.2
-+
-+Fixed path issue (regression)
-+
-+## 0.6.1
-+
-+* Reinstated LastFmSession.authorise() handler options which were accidentallly removed rather than deprecated. Thanks to Vytautas Jakutis for the spot.
-+* Fixed LastFmSession.authorise() documentation (Vytautas Jakutis)
-+
-+## 0.6.0
-+
-+### New features
-+
-+* Added request() method. Provides low-level support for entire Last.Fm API.
-+* Event handler options on RecentTrackStream, LastFmUpdate and LastFmInfo have been deprecated and replaced with more generic `handlers` option. These will be removed soon.
-+
-+## 0.5.1
-+
-+* More accurate error reporting from RecentTrackParser
-+* v0.4.x support
-+
-+## 0.5.0
-+
-+* Renamed lastfm.readRequest/writeRequest to read/write.
-+* Replace response reader with LastFmRequest.
-+
-+## 0.4.4
-+
-+* Handles response errors (timeouts, etc) when communicating with Last.fm
-+* Fixed bug where unexpected data in LastFmInfo would crash application.
-+
-+## 0.4.3
-+
-+* Fixed bug where RecentTrackStream was working with null tracks.
-+
-+## 0.4.2
-+
-+* Added session.isAuthorised()
-+
-+## 0.4.1
-+
-+* Added slightly more descriptive errors to RecentTracksParser.
-+
-+## 0.4.0
-+
-+### Breaking changes
-+
-+* `LastFmSession` is no longer responsible for sending update. Use `lastfm.update()`  instead.
-+
-+    lastfm.update("nowplaying", session, { track: track });
-+
-+### New Features
-+
-+* Access getInfo API calls through `lastfm.info()`. See README for example.
-+
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/LICENSE
-@@ -0,0 +1,19 @@
-+Copyright (c) 2011, James Scott and 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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/README.md
-@@ -0,0 +1,346 @@
-+# lastfm-node
-+
-+Read and write to users recent plays on Last.fm.
-+
-+## Installation
-+
-+    npm install lastfm
-+
-+## Usage
-+
-+    var LastFmNode = require('lastfm').LastFmNode;
-+  
-+    var lastfm = new LastFmNode({
-+      api_key: 'apikey',    // sign-up for a key at http://www.last.fm/api
-+      secret: 'secret',
-+      useragent: 'appname/vX.X MyApp' // optional. defaults to lastfm-node.
-+    });
-+
-+## Documentation
-+
-+### LastFmRequest
-+
-+    lastfm.request(method, options);
-+
-+Returns a `LastFmRequest` instance.
-+
-+Send request to Last.fm. Requests automatically include the API key and are signed and/or sent via POST as described in the Last.fm API documentation.
-+
-+Methods:
-+
-+Accepts any Last.fm API method name, eg "artist.getInfo". 
-+
-+Options:
-+
-+All options are passed through to Last.fm with the exception of the following.
-+
-+- *write*
-+
-+        Force request to act as a write method. Write methods are signed and sent via POST. Useful for new methods not yet recognised by lastfm-node.
-+
-+- *signed*
-+
-+        Force request to be signed. See Last.fm API docs for signature details. Useful for new methods not yet recognised by lastfm-node.
-+
-+- *handlers*
-+
-+        Default event handlers to attach to the request object on creation.
-+
-+Events:
-+
-+- *success(json)*
-+
-+        JSON response from Last.fm
-+
-+- *error(error)*
-+
-+        Ruh-roh. Either a error returned by Last.fm or a transmission error.
-+
-+### RecentTracksStream
-+
-+    lastfm.stream(username);
-+
-+Returns: a `RecentTracksStream` instance
-+
-+Methods:
-+
-+- *start()*
-+
-+        Start streaming recent track info.
-+
-+- *stop()*
-+
-+        Stop streaming recent track info.
-+
-+- *isStreaming()*
-+
-+        Boolean. True is nowplaying/recent track data is being actively fetched.
-+
-+- *on(event, listener)*
-+
-+        Adds a listener for the specified event.
-+
-+- *removeListener(event, listener)*
-+
-+        Removes the listener for the specified event.
-+
-+Options:
-+
-+- *autostart*
-+
-+        Start streaming automatically. Defaults to false.
-+
-+- *handlers*
-+
-+        Default event handlers to attach to the request object on creation.
-+
-+Events:
-+
-+- *lastPlayed(track)*
-+
-+        The user's last scrobbled track.
-+
-+- *nowPlaying(track)*
-+
-+        Track the user is currently listening to.
-+
-+- *scrobbled(track)*
-+        
-+        Now playing track has been scrobbled.
-+
-+- *stoppedPlaying(track)*
-+
-+        User stopped listening to current track.
-+
-+- *error(error)*
-+
-+        Ruh-roh.
-+
-+### LastFmSession
-+
-+    lastfm.session(options);
-+
-+Returns: a `LastFmSession` instance.
-+
-+If the user and session key are already known supply these in the options. Otherwise supply a token for authorisation. When a token is supplied the session will be authorised with Last.fm. If the user has not yet approved the token (desktop application flow) then authorisation will be automatically retried.
-+
-+See the last.fm API documentation for more info on Last.fm authorisation flow.
-+
-+Options:
-+
-+- *user*
-+
-+        User name, if known.
-+
-+- *key*
-+
-+        Session key, if known.
-+
-+- *token*
-+
-+        Token supplied by auth.getToken or web flow callback.
-+
-+- *retryInterval*
-+
-+        Time in milliseconds to leave between retries. Defaults to 10 seconds.
-+
-+- *handlers*
-+
-+        Default event handlers to attach to the session object on creation.
-+
-+
-+Public properties:
-+
-+- *user*
-+
-+        The username of the Last.fm user associated with the session.
-+
-+- *key*
-+
-+        The session key. Either passed in or generated using authorise().
-+
-+Methods:
-+
-+- *authorise(token, [options])*
-+
-+        Deprecated. Use lastfm.session({ token: token }) instead.
-+        Authorises user with Last.fm api. See last.fm documentation. Options argument has handlers property that has default event handlers to attach to the LastFmSession instance.
-+
-+- *on(event, handler)*
-+
-+        Adds a listener for the specified event.
-+
-+- *removeListener(event, handler)*
-+
-+        Removes the listener for the specified event.
-+
-+- *isAuthorised()*
-+
-+        Returns true if the session has been authorised or a key was specified in the constructor.
-+
-+- *cancel()*
-+
-+        Prevent any further authorisation retries. Only applies if token supplied.
-+
-+Events:
-+
-+- *success(session)*
-+
-+        Authorisation of session was successful.
-+        Note: Only emitted if a token was supplied in options. Username/key combinations supplied in options are assumed to be valid.
-+
-+- *authorised(session)*
-+
-+        Deprecated: Use success instead.
-+        Authorisation of session was successful.
-+
-+- *retrying(retry)*
-+
-+       Authorisation request was not successful but will be retried after a delay. Retry object contains the following properties:  
-+       `delay` - The time in milliseconds before the request will be retried.  
-+       `error` - The error code returned by the Last.fm API.  
-+       `message` - The error message returned by the Last.fm API.
-+
-+- *error(track, error)*
-+
-+        The authorisation was not successful and will not be retried.
-+
-+### LastFmUpdate
-+
-+    lastfm.update(method, session, options);
-+
-+Returns a `LastFmUpdate` instance. 
-+
-+Valid methods are 'nowplaying' and 'scrobble'.
-+
-+An authorised `LastFmSession` instance is required to make a successful update.
-+
-+If a scrobble request receives an 11 (service offline), 16 (temporarily unavailable) or 29 (rate limit exceeded) error code from Last.fm then the request is automatically retried until it is permanently rejected or accepted. The first retry attempt is made after 10 seconds with subsequent requests delayed by 30 seconds, 1 minute, 5 minutes, 15 minutes and then every 30 minutes.
-+
-+Options:
-+
-+Accepts all parameters used by track.updateNowPlaying and user.scrobble (see Last.Fm API) as well as:
-+
-+- *track*
-+    
-+        Track for nowplaying and scrobble requests. Uses same format as returned by `RecentTracksStream` events.
-+
-+- *timestamp*
-+
-+        Required for scrobble requests. Timestamp is in unix time (seconds since 01-01-1970 and is in UTC time).
-+
-+- *handlers*
-+
-+        Default event handlers to attach to the request object on creation.
-+
-+Events:
-+
-+- *success(track)*
-+
-+       Update request was successful. 
-+
-+- *retrying(retry)*
-+
-+       Scrobble request was not successful but will be retried after a delay. Retry object contains the following properties:  
-+       `delay` - The time in milliseconds before the request will be retried.  
-+       `error` - The error code returned by the Last.fm API.  
-+       `message` - The error message returned by the Last.fm API.
-+
-+- *error(track, error)*
-+
-+        Ruh-roh.
-+
-+### LastFmInfo
-+
-+    lastfm.info(itemtype, [options]);
-+
-+Returns: a `LastFmInfo` instance.
-+
-+Gets extended info about specified item.
-+
-+Public properties:
-+
-+- *itemtype*
-+
-+        Any Last.fm item with a getInfo method. eg user, track, artist, etc.
-+
-+Options:
-+
-+- *handlers*
-+
-+        Event handlers to attach to object at creation.
-+
-+- *various*
-+
-+       Params as specified in Last.fm API, eg user: "username"
-+
-+Special cases:
-+
-+When requesting track info the `track` param can be either the track name or a track object as returned by `RecentTracksStream`.
-+
-+
-+## Example
-+
-+    var LastFmNode = require('lastfm').LastFmNode;
-+    
-+    var lastfm = new LastFmNode({
-+      api_key: 'abc',
-+      secret: 'secret'
-+    });
-+
-+    var trackStream = lastfm.stream('username');
-+    
-+    trackStream.on('lastPlayed', function(track) {
-+      console.log('Last played: ' + track.name);
-+    });
-+    
-+    trackStream.on('nowPlaying', function(track) {
-+      console.log('Now playing: ' + track.name);
-+    });
-+
-+    trackStream.on('scrobbled', function(track) {
-+      console.log('Scrobbled: ' + track.name);
-+    });
-+
-+    trackStream.on('stoppedPlaying', function(track) {
-+      console.log('Stopped playing: ' + track.name);
-+    });
-+
-+    trackStream.on('error', function(error) {
-+      console.log('Error: '  + error.message);
-+    });
-+
-+    trackStream.start();
-+
-+    var session = lastfm.session({
-+       token: token,
-+       handlers: {
-+          success: function(session) {
-+             lastfm.update('nowplaying', session, { track: track } );
-+             lastfm.update('scrobble', session, { track: track, timestamp: 12345678 });
-+          }
-+       }
-+    });
-+
-+    var request = lastfm.request("artist.getInfo", {
-+        artist: "The Mae Shi",
-+        handlers: {
-+            success: function(data) {
-+                console.log("Success: " + data);
-+            },
-+            error: function(error) {
-+                console.log("Error: " + error.message);
-+            }
-+        }
-+    });
-+
-+## Influences
-+
-+Heavily drawn from technoweenie's twitter-node  
-+http://github.com/technoweenie/twitter-node
-+
-+## Contributors
-+
-+* Garret Wilkin (garrettwilkin) - http://geethink.com
-+* Uwe L. Korn (xhochy) - http://xhochy.com
-+* Max Kueng (maxkueng) - http://maxkueng.com
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/Roadmap.md
-@@ -0,0 +1,17 @@
-+# Roadmap
-+
-+## 0.7.0 (complete)
-+* Responses from lastfm.request are automatically converted to JSON.
-+
-+## 0.8.0
-+* Failed scrobbles are automatically retried when appropriate.
-+
-+## 0.9.0
-+* Caching support. Memory and reddis with other datastores to follow.
-+
-+## 1.0.0
-+* Finalise API.
-+* Tidy JSON responses.
-+
-+## 1.1.0
-+* Radio API/playlist support.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/config.example.js
-@@ -0,0 +1,4 @@
-+module.exports = {
-+    api_key: '',
-+    secret: ''
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lastfm-repl.js
-@@ -0,0 +1,44 @@
-+var LastFmNode = require('./lib/lastfm').LastFmNode,
-+    repl = require('repl'),
-+    config = require('./config'),
-+    _ = require('underscore');
-+
-+var echoHandler = function() {
-+    _(arguments).each(function(arg) {
-+        console.log(arg);
-+    });
-+};
-+
-+var errorHandler = function(error) {
-+    console.log('Error: ' + error.message);
-+};
-+
-+var quietHandler = function() { };
-+
-+var _echoHandlers = {
-+    error: errorHandler,
-+    success: echoHandler,
-+    lastPlayed: echoHandler,
-+    nowPlaying: echoHandler,
-+    scrobbled: echoHandler,
-+    stoppedPlaying: echoHandler
-+};
-+
-+var _quietHandlers = {
-+    error: errorHandler,
-+    success: quietHandler,
-+    lastPlayed: quietHandler,
-+    nowPlaying: quietHandler,
-+    scrobbled: quietHandler,
-+    stoppedPlaying: quietHandler
-+}
-+
-+var lastfm = new LastFmNode({
-+    api_key: config.api_key,
-+    secret: config.secret
-+});
-+
-+var context = repl.start().context;
-+context.lastfm = lastfm;
-+context._echoHandlers = _echoHandlers;
-+context._quietHandlers = _quietHandlers;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/index.js
-@@ -0,0 +1,35 @@
-+var RecentTracksStream = require("./recenttracks-stream"),
-+    LastFmSession = require("./lastfm-session"),
-+    LastFmUpdate = require("./lastfm-update"),
-+    LastFmInfo = require("./lastfm-info"),
-+    LastFmRequest = require("./lastfm-request");
-+
-+var LastFmNode = exports.LastFmNode = function(options) {
-+  options = options || {};
-+  this.url = "/2.0";
-+  this.host = "ws.audioscrobbler.com";
-+  this.format = "json";
-+  this.secret = options.secret;
-+  this.api_key = options.api_key;
-+  this.useragent = options.useragent || "lastfm-node";
-+};
-+
-+LastFmNode.prototype.request = function(method, params) {
-+  return new LastFmRequest(this, method, params);
-+};
-+
-+LastFmNode.prototype.stream = function(user, options) {
-+  return new RecentTracksStream(this, user, options);
-+};
-+
-+LastFmNode.prototype.session = function(user, key) {
-+  return new LastFmSession(this, user, key);
-+};
-+
-+LastFmNode.prototype.info = function(type, options) {
-+  return new LastFmInfo(this, type, options);
-+};
-+
-+LastFmNode.prototype.update = function(method, session, options) {
-+  return new LastFmUpdate(this, method, session, options);
-+};
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/lastfm-base.js
-@@ -0,0 +1,45 @@
-+var EventEmitter = require("events").EventEmitter
-+  , _ = require("underscore");
-+
-+var LastFmBase = function() {
-+  EventEmitter.call(this);
-+};
-+
-+LastFmBase.prototype = Object.create(EventEmitter.prototype);
-+
-+LastFmBase.prototype.registerHandlers = function(handlers) {
-+  if (typeof handlers !== "object") {
-+    return;
-+  }
-+  
-+  var that = this;
-+  _(handlers).each(function(value, key) {
-+    that.on(key, value);
-+  });
-+};
-+
-+var defaultBlacklist = ["error", "success", "handlers"];
-+LastFmBase.prototype.filterParameters = function(parameters, blacklist) {
-+  var filteredParams = {};
-+  _(parameters).each(function(value, key) {
-+    if (isBlackListed(key)) {
-+      return;
-+    }
-+    filteredParams[key] = value;
-+  });
-+  return filteredParams;
-+  
-+  function isBlackListed(name) {
-+    return _(defaultBlacklist).include(name) || _(blacklist).include(name);
-+  }
-+};
-+
-+LastFmBase.prototype.scheduleCallback = function(callback, delay) {
-+  return setTimeout(callback, delay);
-+};
-+
-+LastFmBase.prototype.cancelCallback = function(identifier) {
-+  clearTimeout(identifier);
-+};
-+
-+module.exports = LastFmBase;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/lastfm-info.js
-@@ -0,0 +1,43 @@
-+var LastFmBase = require("./lastfm-base");
-+
-+var LastFmInfo = function(lastfm, type, options) {
-+  var that = this;
-+  options = options || {};
-+  LastFmBase.call(this);
-+
-+  registerEventHandlers(options);
-+  requestInfo(type, options);
-+
-+  function registerEventHandlers(options) {
-+    that.registerHandlers(options.handlers);
-+  }
-+
-+  function requestInfo(type, options) {
-+    if (!type) {
-+      that.emit("error", new Error("Item type not specified"));
-+      return;
-+    }
-+
-+    var params = that.filterParameters(options)
-+      , method = type + ".getinfo"
-+      , request = lastfm.request(method, params);
-+    request.on("success", success);
-+    request.on("error", error);
-+  }
-+
-+  function success(response) {
-+    if (response[type]) {
-+      that.emit("success", response[type]);
-+      return;
-+    }
-+    that.emit("error", new Error("Unexpected error"));
-+  }
-+  
-+  function error(error) {
-+    that.emit("error", error);
-+  }
-+};
-+
-+LastFmInfo.prototype = Object.create(LastFmBase.prototype);
-+
-+module.exports = LastFmInfo;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/lastfm-request.js
-@@ -0,0 +1,144 @@
-+if (global.GENTLY_HIJACK) require = GENTLY_HIJACK.hijack(require);
-+
-+var http = require("http")
-+  , querystring = require('querystring')
-+  , _ = require("underscore")
-+  , crypto = require("crypto")
-+  , LastFmBase = require("./lastfm-base");
-+
-+var WRITE_METHODS = ["album.addtags", "album.removetag", "album.share",
-+        "artist.addtags", "artist.removetag", "artist.share", "artist.shout",
-+        "event.attend", "event.share", "event.shout",
-+        "library.addalbum", "library.addartist", "library.addtrack",
-+        "library.removealbum", "library.removeartist", "library.removetrack", "library.removescrobble",
-+        "playlist.addtrack", "playlist.create",
-+        "radio.tune",
-+        "track.addtags", "track.ban", "track.love", "track.removetag",
-+        "track.scrobble", "track.share", "track.unban", "track.unlove",
-+        "track.updatenowplaying",
-+        "user.shout"],
-+    SIGNED_METHODS = ["auth.getmobilesession", "auth.getsession", "auth.gettoken",
-+        "radio.getplaylist",
-+        "user.getrecentstations", "user.getrecommendedartists", "user.getrecommendedevents"];
-+
-+var LastFmRequest = module.exports = function(lastfm, method, params) {
-+  var that = this;
-+  LastFmBase.call(this);
-+  params = params || {};
-+
-+  that.registerHandlers(params.handlers);
-+
-+  sendRequest(lastfm.host, lastfm.url, params);
-+
-+  function sendRequest(host, url, params) {
-+    var httpVerb = isWriteRequest() ? "POST" : "GET"
-+    var requestParams = buildRequestParams(params);
-+    var data = querystring.stringify(requestParams);
-+    if (httpVerb == "GET") {
-+      url += "?" + data;
-+    }
-+    var options = {
-+        host: host,
-+        port: 80,
-+        path: url,
-+        method: httpVerb,
-+        headers: requestHeaders(httpVerb, host, data)
-+    };
-+    var req = http.request(options, chunkedResponse);
-+    req.on("error", function(error) {
-+        that.emit("error", error);
-+    });
-+    if (httpVerb == "POST") {
-+        req.write(data);
-+    }
-+    req.end()
-+  }
-+
-+  function buildRequestParams(params) {
-+    var requestParams = that.filterParameters(params, ["signed", "write"]);
-+    requestParams.method = method;
-+    requestParams.api_key = requestParams.api_key || lastfm.api_key;
-+    requestParams.format = requestParams.format || lastfm.format;
-+    if (params.track && typeof params.track === "object") {
-+      requestParams.artist = params.track.artist["#text"];
-+      requestParams.track = params.track.name;
-+      if (params.track.mbid) {
-+        requestParams.mbid = params.track.mbid;
-+      }
-+      if (params.track.album) {
-+        requestParams.album = requestParams.album || params.track.album["#text"];
-+      }
-+    }
-+    if (requiresSignature()) {
-+      requestParams.api_sig = createSignature(requestParams, lastfm.secret);
-+    }
-+    return requestParams;
-+  }
-+
-+  function requiresSignature() {
-+    return params.signed || isWriteRequest() || isSignedMethod(method);
-+  }
-+
-+  function isWriteRequest() {
-+    return params.write || isWriteMethod(method);
-+  }
-+
-+  function isSignedMethod(method) {
-+    return method && _(SIGNED_METHODS).include(method.toLowerCase());
-+  }
-+
-+  function isWriteMethod(method) {
-+    return method && _(WRITE_METHODS).include(method.toLowerCase());
-+  }
-+
-+  function requestHeaders(httpVerb, host, data) {
-+    var headers = {
-+      "User-Agent": lastfm.useragent
-+    };
-+
-+    if (httpVerb == "POST") {
-+      headers["Content-Length"] = data.length;
-+      headers["Content-Type"] = "application/x-www-form-urlencoded";
-+    }
-+
-+    return headers;
-+  }
-+
-+  function chunkedResponse(response) {
-+    var data = "";
-+    response.on("data", function(chunk) {
-+        data += chunk.toString("utf8");
-+    });
-+    response.on("end", function() {
-+      if (lastfm.format !== "json") {
-+        that.emit("success", data);
-+        return;
-+      }
-+      try {
-+        var json = JSON.parse(data);
-+        if (json.error) {
-+          that.emit("error", json);
-+          return;
-+        }
-+        that.emit("success", json);
-+      }
-+      catch(e) {
-+        that.emit("error", e)
-+      }
-+    });
-+  }
-+
-+  function createSignature(params, secret) {
-+    var sig = "";
-+    Object.keys(params).sort().forEach(function(key) {
-+      if (key != "format") {
-+        var value = typeof params[key] !== "undefined" && params[key] !== null ? params[key] : "";
-+        sig += key + value;
-+      }
-+    });
-+    sig += secret;
-+    return crypto.createHash("md5").update(sig, "utf8").digest("hex");
-+  }
-+};
-+
-+LastFmRequest.prototype = Object.create(LastFmBase.prototype);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/lastfm-session.js
-@@ -0,0 +1,113 @@
-+var LastFmBase = require("./lastfm-base");
-+
-+var LastFmSession = function(lastfm, options, key) {
-+  options = options || { };
-+  var that = this,
-+      retry = true;
-+
-+  LastFmBase.call(this);
-+  if (typeof options !== "object") {
-+    this.user = options || "";
-+    this.key = key || "";
-+  }
-+  else {
-+    this.user = options.user || "";
-+    this.key = options.key || "";
-+  }
-+
-+  if (options.token) {
-+    authorise(options.token, options);
-+  }
-+
-+  /**
-+   * @deprecated
-+   */
-+  this.authorise = function(token, options) {
-+    authorise(token, options);
-+  };
-+
-+  this.isAuthorised = function() {
-+    return isAuthorised();
-+  }
-+
-+  this.cancel = function() {
-+    retry = false;
-+  }
-+
-+  function authorise(token, options) {
-+    options = options || { };
-+
-+    registerEventHandlers(options);
-+
-+    validateToken(token, options);
-+  }
-+
-+  function registerEventHandlers(options) {
-+    that.registerHandlers(options.handlers);
-+  }
-+
-+  function validateToken(token, options) {
-+    options = options || { };
-+    if (!token) {
-+      that.emit("error", new Error("No token supplied"));
-+      return;
-+    }
-+
-+    var params = { token: token },
-+        request = lastfm.request("auth.getsession", params);
-+
-+    request.on("success", authoriseSession);
-+
-+    request.on("error", function handleError(error) {
-+      if (shouldBeRetried(error)) {
-+        if (!retry) {
-+          return;
-+        }
-+        var delay = options.retryInterval || 10000;
-+        that.emit("retrying", {
-+          error: error.error,
-+          message: error.message,
-+          delay: delay
-+        });
-+        that.scheduleCallback(function() {
-+          validateToken(token, options);
-+        }, delay);
-+        return;
-+      }
-+      bubbleError(error);
-+    });
-+  }
-+
-+  function shouldBeRetried(error) {
-+    return error.error == 14 ||
-+        error.error == 16 ||
-+        error.error == 11;
-+  }
-+
-+  function isAuthorised() {
-+    return that.key !== '';
-+  }
-+
-+  function authoriseSession(result) {
-+    if (!result.session) {
-+      that.emit("error", new Error("Unexpected error"));
-+      return;
-+    }
-+    setSessionDetails(result.session);
-+    that.emit("authorised", that);
-+    that.emit("success", that);
-+  }
-+
-+  function setSessionDetails(session) {
-+    that.user = session.name;
-+    that.key = session.key;
-+  }
-+
-+  function bubbleError(error) {
-+    that.emit("error", error);
-+  }
-+};
-+
-+LastFmSession.prototype = Object.create(LastFmBase.prototype);
-+
-+module.exports = LastFmSession;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/lastfm-update.js
-@@ -0,0 +1,104 @@
-+var _ = require("underscore")
-+  , LastFmBase = require("./lastfm-base")
-+  , retryOnErrors = [
-+      11,                 // Service offline
-+      16,                 // Temporarily unavailable
-+      29                  // Rate limit exceeded
-+    ]
-+  , retrySchedule = [
-+      10 * 1000,          // 10 seconds
-+      30 * 1000,          // 30 seconds
-+      60 * 1000,          // 1 minute
-+      5 * 60 * 1000,      // 5 minutes
-+      15 * 60 * 1000,     // 15 minutes
-+      30 * 60 * 1000      // 30 minutes
-+    ];
-+
-+var LastFmUpdate = function(lastfm, method, session, options) {
-+  var that = this;
-+  options = options || { };
-+  LastFmBase.call(this);
-+
-+  registerEventHandlers(options);
-+    
-+  if (!session.isAuthorised()) {
-+    this.emit("error", {
-+      error: 4,
-+      message: "Authentication failed"
-+    });
-+    return;
-+  }
-+  if (method !== "scrobble" && method !== "nowplaying") {
-+    return;
-+  }
-+  update(method, options); 
-+
-+  function registerEventHandlers(options) {
-+    that.registerHandlers(options.handlers);
-+  }
-+  
-+  function update(method, options) {
-+    if (method == "scrobble" && !options.timestamp) {
-+      that.emit("error", {
-+        error: 6,
-+        message: "Invalid parameters - Timestamp is required for scrobbling"
-+      });
-+      return;
-+    }
-+
-+    var retryCount = 0
-+      , params = buildRequestParams(options)
-+      , requestMethod = method == "scrobble" ? "track.scrobble" : "track.updateNowPlaying";
-+    makeRequest();
-+
-+    function makeRequest() {
-+      var request = lastfm.request(requestMethod, params);
-+      request.on("error", errorCallback);
-+      request.on("success", successCallback);
-+    }
-+
-+    function successCallback(response) {
-+      if (response) {
-+        that.emit("success", options.track);
-+      }
-+    }
-+
-+    function errorCallback(error) {
-+      if (shouldBeRetried(error)) {
-+        var delay = delayFor(retryCount++)
-+          , retry = {
-+              error: error.error,
-+              message: error.message,
-+              delay: delay
-+            };
-+        that.emit("retrying", retry);
-+        that.scheduleCallback(makeRequest, delay);
-+        return;
-+      }
-+      bubbleError(error);
-+    }
-+
-+    function shouldBeRetried(error) {
-+      return method == "scrobble" && _(retryOnErrors).include(error.error)
-+    }
-+  }
-+
-+  function bubbleError(error) {
-+    that.emit("error", error);
-+  }
-+
-+  function buildRequestParams(params) {
-+    var requestParams = that.filterParameters(params);
-+    requestParams.sk = session.key;
-+    return requestParams;
-+  }
-+
-+  function delayFor(retryCount) {
-+    var index = Math.min(retryCount, retrySchedule.length - 1);
-+    return retrySchedule[index];
-+  }
-+}
-+
-+LastFmUpdate.prototype = Object.create(LastFmBase.prototype);
-+
-+module.exports = LastFmUpdate;
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/lib/lastfm/recenttracks-stream.js
-@@ -0,0 +1,111 @@
-+var LastFmBase = require("./lastfm-base");
-+
-+var RecentTracksStream = module.exports = function(lastfm, user, options) {
-+  var that = this;
-+  LastFmBase.call(this);
-+  options = options || {};
-+
-+  var rate = 10
-+    , isStreaming = false
-+    , timeout
-+    , lastPlay = null
-+    , nowPlaying = null;
-+
-+  registerEventHandlers(options);
-+
-+  if (options.autostart) {
-+    start();
-+  }
-+
-+  this.start = function() {
-+    start();
-+  }
-+
-+  this.stop = function() {
-+    stop();
-+  }
-+
-+  this.isStreaming = function() {
-+    return isStreaming;
-+  }
-+
-+  function registerEventHandlers(options) {
-+    that.registerHandlers(options.handlers);
-+  }
-+
-+  function start() {
-+    isStreaming = true;
-+    check();
-+
-+    function check() {
-+      var request = lastfm.request("user.getrecenttracks", {
-+        user: user,
-+        limit: 1
-+      });
-+      request.on("success", handleSuccess);
-+      request.on("error", bubbleError);
-+      if (isStreaming) {
-+        timeout = that.scheduleCallback(check, rate * 1000);
-+      }
-+    }
-+
-+    function handleSuccess(data) {
-+      if (!data || !data.recenttracks || !data.recenttracks.track) {
-+        that.emit("error", new Error("Unexpected response"));
-+        return;
-+      }
-+
-+      var tracks = data.recenttracks.track;
-+      if (tracks instanceof Array) {
-+        processNowPlaying(tracks[0]);
-+        processLastPlay(tracks[1]);
-+        return;
-+      }
-+
-+      var track = tracks;
-+      if (track["@attr"] && track["@attr"]["nowplaying"]) {
-+        processNowPlaying(track);
-+        return;
-+      }
-+    
-+      processLastPlay(track);
-+      if (nowPlaying) {
-+        that.emit("stoppedPlaying", nowPlaying);
-+        nowPlaying = null;
-+      }
-+    }
-+
-+    function bubbleError(error) {
-+      that.emit("error", error);
-+    }
-+  }
-+
-+  function processNowPlaying(track) {
-+    var sameTrack = (nowPlaying && nowPlaying.name == track.name);
-+    if (!sameTrack) {
-+      nowPlaying = track;
-+      that.emit("nowPlaying", track);
-+    }
-+  }
-+
-+  function processLastPlay(track) {
-+    if (!lastPlay) {
-+      lastPlay = track;
-+      that.emit("lastPlayed", track);
-+      return;
-+    }
-+
-+    var sameTrack = (lastPlay.name == track.name);
-+    if (!sameTrack) {
-+      lastPlay = track;
-+      that.emit("scrobbled", track);
-+    }
-+  }
-+
-+  function stop() {
-+    that.cancelCallback(timeout);
-+    isStreaming = false;
-+  }
-+};
-+
-+RecentTracksStream.prototype = Object.create(LastFmBase.prototype);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/node_modules/underscore/LICENSE
-@@ -0,0 +1,23 @@
-+Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative
-+Reporters & Editors
-+
-+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.
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/node_modules/underscore/README.md
-@@ -0,0 +1,22 @@
-+                       __
-+                      /\ \                                                         __
-+     __  __    ___    \_\ \     __   _ __   ____    ___    ___   _ __    __       /\_\    ____
-+    /\ \/\ \ /' _ `\  /'_  \  /'__`\/\  __\/ ,__\  / ___\ / __`\/\  __\/'__`\     \/\ \  /',__\
-+    \ \ \_\ \/\ \/\ \/\ \ \ \/\  __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\  __/  __  \ \ \/\__, `\
-+     \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
-+      \/___/  \/_/\/_/\/__,_ /\/____/ \/_/ \/___/  \/____/\/___/  \/_/ \/____/\/_//\ \_\ \/___/
-+                                                                                  \ \____/
-+                                                                                   \/___/
-+
-+Underscore.js is a utility-belt library for JavaScript that provides
-+support for the usual functional suspects (each, map, reduce, filter...)
-+without extending any core JavaScript objects.
-+
-+For Docs, License, Tests, and pre-packed downloads, see:
-+http://underscorejs.org
-+
-+Underscore is an open-sourced component of DocumentCloud:
-+https://github.com/documentcloud
-+
-+Many thanks to our contributors:
-+https://github.com/jashkenas/underscore/contributors
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/node_modules/underscore/package.json
-@@ -0,0 +1,50 @@
-+{
-+  "name": "underscore",
-+  "description": "JavaScript's functional programming helper library.",
-+  "homepage": "http://underscorejs.org",
-+  "keywords": [
-+    "util",
-+    "functional",
-+    "server",
-+    "client",
-+    "browser"
-+  ],
-+  "author": {
-+    "name": "Jeremy Ashkenas",
-+    "email": "jeremy at documentcloud.org"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git://github.com/jashkenas/underscore.git"
-+  },
-+  "main": "underscore.js",
-+  "version": "1.6.0",
-+  "devDependencies": {
-+    "docco": "0.6.x",
-+    "phantomjs": "1.9.0-1",
-+    "uglify-js": "2.4.x"
-+  },
-+  "scripts": {
-+    "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true",
-+    "build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/    .*/\" -m --source-map underscore-min.map -o underscore-min.js",
-+    "doc": "docco underscore.js"
-+  },
-+  "licenses": [
-+    {
-+      "type": "MIT",
-+      "url": "https://raw.github.com/jashkenas/underscore/master/LICENSE"
-+    }
-+  ],
-+  "files": [
-+    "underscore.js",
-+    "underscore-min.js",
-+    "LICENSE"
-+  ],
-+  "readme": "                       __\n                      /\\ \\                                                         __\n     __  __    ___    \\_\\ \\     __   _ __   ____    ___    ___   _ __    __       /\\_\\    ____\n    /\\ \\/\\ \\ /' _ `\\  /'_  \\  /'__`\\/\\  __\\/ ,__\\  / ___\\ / __`\\/\\  __\\/'__`\\     \\/\\ \\  /',__\\\n    \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\  __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\  __/  __  \\ \\ \\/\\__, `\\\n     \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n      \\/___/  \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/  \\/____/\\/___/  \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/\n                                                                                  \\ \\____/\n                                                                                   \\/___/\n\nUnderscore.js is a utility-belt library for JavaScript that provides\nsupport for the usual functional suspects (each, map, reduce, filter...)\nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://underscorejs.org\n\nUnderscore is an open-sourced component of DocumentCloud:\nhttps://github.com/documentcloud\n\nMany thanks to our contributors:\nhttps://github.com/jashkenas/underscore/contributors\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/jashkenas/underscore/issues"
-+  },
-+  "_id": "underscore at 1.6.0",
-+  "_from": "underscore@"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/node_modules/underscore/underscore-min.js
-@@ -0,0 +1,6 @@
-+//     Underscore.js 1.6.0
-+//     http://underscorejs.org
-+//     (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+//     Underscore may be freely distributed under the MIT license.
-+(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?void(this._wrapped=n):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.6.0";var A=j.each=j.forEach=function(n,t,e){if(null==n)return n;if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return;return n};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var O="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},j.find=j.detect=function(n,t,r){var e;return k(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var k=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:k(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,j.property(t))},j.where=function(n,t){return j.filter(n,j.matches(t))},j.findWhere=function(n,t){return j.find(n,j.matches(t))},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);var e=-1/0,u=-1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;o>u&&(e=n,u=o)}),e},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);var e=1/0,u=1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;u>o&&(e=n,u=o)}),e},j.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=j.random(r++),e[r-1]=e[t],e[t]=n}),e},j.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=j.values(n)),n[j.random(n.length-1)]):j.shuffle(n).slice(0,Math.max(0,t))};var E=function(n){return null==n?j.identity:j.isFunction(n)?n:j.property(n)};j.sortBy=function(n,t,r){return t=E(t),j.pluck(j.map(n,function(n,e,u){return{value:n,index:e,criteria:t.call(r,n,e,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=E(r),A(t,function(i,a){var o=r.call(e,i,a,t);n(u,o,i)}),u}};j.groupBy=F(function(n,t,r){j.has(n,t)?n[t].push(r):n[t]=[r]}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=E(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])<u?i=o+1:a=o}return i},j.toArray=function(n){return n?j.isArray(n)?o.call(n):n.length===+n.length?j.map(n,j.identity):j.values(n):[]},j.size=function(n){return null==n?0:n.length===+n.length?n.length:j.keys(n).length},j.first=j.head=j.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:0>t?[]:o.call(n,0,t)},j.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},j.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},j.rest=j.tail=j.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},j.compact=function(n){return j.filter(n,j.identity)};var M=function(n,t,r){return t&&j.every(n,j.isArray)?c.apply(r,n):(A(n,function(n){j.isArray(n)||j.isArguments(n)?t?a.apply(r,n):M(n,t,r):r.push(n)}),r)};j.flatten=function(n,t){return M(n,t,[])},j.without=function(n){return j.difference(n,o.call(arguments,1))},j.partition=function(n,t){var r=[],e=[];return A(n,function(n){(t(n)?r:e).push(n)}),[r,e]},j.uniq=j.unique=function(n,t,r,e){j.isFunction(t)&&(e=r,r=t,t=!1);var u=r?j.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:j.contains(a,r))||(a.push(r),i.push(n[e]))}),i},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=function(n){var t=o.call(arguments,1);return j.filter(j.uniq(n),function(n){return j.every(t,function(t){return j.contains(t,n)})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===j&&(e[u]=arguments[r++]);for(;r<arguments.length;)e.push(arguments[r++]);return n.apply(this,e)}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:j.now(),a=null,i=n.apply(e,u),e=u=null};return function(){var l=j.now();o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u),e=u=null):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o,c=function(){var l=j.now()-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u),i=u=null))};return function(){i=this,u=arguments,a=j.now();var l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u),i=u=null),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return j.partial(t,n)},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=function(n){if(!j.isObject(n))return[];if(w)return w(n);var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o)&&"constructor"in n&&"constructor"in t)return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.constant=function(n){return function(){return n}},j.property=function(n){return function(t){return t[n]}},j.matches=function(n){return function(t){if(t===n)return!0;for(var r in n)if(n[r]!==t[r])return!1;return!0}},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},j.now=Date.now||function(){return(new Date).getTime()};var T={escape:{"&":"&","<":"<",">":">",'"':""","'":"&#x27;"}};T.unescape=j.invert(T.escape);var I={escape:new RegExp("["+j.keys(T.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(T.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(I[n],function(t){return T[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),"function"==typeof define&&define.amd&&define("underscore",[],function(){return j})}).call(this);
-+//# sourceMappingURL=underscore-min.map
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/node_modules/underscore/underscore.js
-@@ -0,0 +1,1343 @@
-+//     Underscore.js 1.6.0
-+//     http://underscorejs.org
-+//     (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-+//     Underscore may be freely distributed under the MIT license.
-+
-+(function() {
-+
-+  // Baseline setup
-+  // --------------
-+
-+  // Establish the root object, `window` in the browser, or `exports` on the server.
-+  var root = this;
-+
-+  // Save the previous value of the `_` variable.
-+  var previousUnderscore = root._;
-+
-+  // Establish the object that gets returned to break out of a loop iteration.
-+  var breaker = {};
-+
-+  // Save bytes in the minified (but not gzipped) version:
-+  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
-+
-+  // Create quick reference variables for speed access to core prototypes.
-+  var
-+    push             = ArrayProto.push,
-+    slice            = ArrayProto.slice,
-+    concat           = ArrayProto.concat,
-+    toString         = ObjProto.toString,
-+    hasOwnProperty   = ObjProto.hasOwnProperty;
-+
-+  // All **ECMAScript 5** native function implementations that we hope to use
-+  // are declared here.
-+  var
-+    nativeForEach      = ArrayProto.forEach,
-+    nativeMap          = ArrayProto.map,
-+    nativeReduce       = ArrayProto.reduce,
-+    nativeReduceRight  = ArrayProto.reduceRight,
-+    nativeFilter       = ArrayProto.filter,
-+    nativeEvery        = ArrayProto.every,
-+    nativeSome         = ArrayProto.some,
-+    nativeIndexOf      = ArrayProto.indexOf,
-+    nativeLastIndexOf  = ArrayProto.lastIndexOf,
-+    nativeIsArray      = Array.isArray,
-+    nativeKeys         = Object.keys,
-+    nativeBind         = FuncProto.bind;
-+
-+  // Create a safe reference to the Underscore object for use below.
-+  var _ = function(obj) {
-+    if (obj instanceof _) return obj;
-+    if (!(this instanceof _)) return new _(obj);
-+    this._wrapped = obj;
-+  };
-+
-+  // Export the Underscore object for **Node.js**, with
-+  // backwards-compatibility for the old `require()` API. If we're in
-+  // the browser, add `_` as a global object via a string identifier,
-+  // for Closure Compiler "advanced" mode.
-+  if (typeof exports !== 'undefined') {
-+    if (typeof module !== 'undefined' && module.exports) {
-+      exports = module.exports = _;
-+    }
-+    exports._ = _;
-+  } else {
-+    root._ = _;
-+  }
-+
-+  // Current version.
-+  _.VERSION = '1.6.0';
-+
-+  // Collection Functions
-+  // --------------------
-+
-+  // The cornerstone, an `each` implementation, aka `forEach`.
-+  // Handles objects with the built-in `forEach`, arrays, and raw objects.
-+  // Delegates to **ECMAScript 5**'s native `forEach` if available.
-+  var each = _.each = _.forEach = function(obj, iterator, context) {
-+    if (obj == null) return obj;
-+    if (nativeForEach && obj.forEach === nativeForEach) {
-+      obj.forEach(iterator, context);
-+    } else if (obj.length === +obj.length) {
-+      for (var i = 0, length = obj.length; i < length; i++) {
-+        if (iterator.call(context, obj[i], i, obj) === breaker) return;
-+      }
-+    } else {
-+      var keys = _.keys(obj);
-+      for (var i = 0, length = keys.length; i < length; i++) {
-+        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
-+      }
-+    }
-+    return obj;
-+  };
-+
-+  // Return the results of applying the iterator to each element.
-+  // Delegates to **ECMAScript 5**'s native `map` if available.
-+  _.map = _.collect = function(obj, iterator, context) {
-+    var results = [];
-+    if (obj == null) return results;
-+    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
-+    each(obj, function(value, index, list) {
-+      results.push(iterator.call(context, value, index, list));
-+    });
-+    return results;
-+  };
-+
-+  var reduceError = 'Reduce of empty array with no initial value';
-+
-+  // **Reduce** builds up a single result from a list of values, aka `inject`,
-+  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
-+  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
-+    var initial = arguments.length > 2;
-+    if (obj == null) obj = [];
-+    if (nativeReduce && obj.reduce === nativeReduce) {
-+      if (context) iterator = _.bind(iterator, context);
-+      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
-+    }
-+    each(obj, function(value, index, list) {
-+      if (!initial) {
-+        memo = value;
-+        initial = true;
-+      } else {
-+        memo = iterator.call(context, memo, value, index, list);
-+      }
-+    });
-+    if (!initial) throw new TypeError(reduceError);
-+    return memo;
-+  };
-+
-+  // The right-associative version of reduce, also known as `foldr`.
-+  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
-+  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
-+    var initial = arguments.length > 2;
-+    if (obj == null) obj = [];
-+    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
-+      if (context) iterator = _.bind(iterator, context);
-+      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
-+    }
-+    var length = obj.length;
-+    if (length !== +length) {
-+      var keys = _.keys(obj);
-+      length = keys.length;
-+    }
-+    each(obj, function(value, index, list) {
-+      index = keys ? keys[--length] : --length;
-+      if (!initial) {
-+        memo = obj[index];
-+        initial = true;
-+      } else {
-+        memo = iterator.call(context, memo, obj[index], index, list);
-+      }
-+    });
-+    if (!initial) throw new TypeError(reduceError);
-+    return memo;
-+  };
-+
-+  // Return the first value which passes a truth test. Aliased as `detect`.
-+  _.find = _.detect = function(obj, predicate, context) {
-+    var result;
-+    any(obj, function(value, index, list) {
-+      if (predicate.call(context, value, index, list)) {
-+        result = value;
-+        return true;
-+      }
-+    });
-+    return result;
-+  };
-+
-+  // Return all the elements that pass a truth test.
-+  // Delegates to **ECMAScript 5**'s native `filter` if available.
-+  // Aliased as `select`.
-+  _.filter = _.select = function(obj, predicate, context) {
-+    var results = [];
-+    if (obj == null) return results;
-+    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
-+    each(obj, function(value, index, list) {
-+      if (predicate.call(context, value, index, list)) results.push(value);
-+    });
-+    return results;
-+  };
-+
-+  // Return all the elements for which a truth test fails.
-+  _.reject = function(obj, predicate, context) {
-+    return _.filter(obj, function(value, index, list) {
-+      return !predicate.call(context, value, index, list);
-+    }, context);
-+  };
-+
-+  // Determine whether all of the elements match a truth test.
-+  // Delegates to **ECMAScript 5**'s native `every` if available.
-+  // Aliased as `all`.
-+  _.every = _.all = function(obj, predicate, context) {
-+    predicate || (predicate = _.identity);
-+    var result = true;
-+    if (obj == null) return result;
-+    if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
-+    each(obj, function(value, index, list) {
-+      if (!(result = result && predicate.call(context, value, index, list))) return breaker;
-+    });
-+    return !!result;
-+  };
-+
-+  // Determine if at least one element in the object matches a truth test.
-+  // Delegates to **ECMAScript 5**'s native `some` if available.
-+  // Aliased as `any`.
-+  var any = _.some = _.any = function(obj, predicate, context) {
-+    predicate || (predicate = _.identity);
-+    var result = false;
-+    if (obj == null) return result;
-+    if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
-+    each(obj, function(value, index, list) {
-+      if (result || (result = predicate.call(context, value, index, list))) return breaker;
-+    });
-+    return !!result;
-+  };
-+
-+  // Determine if the array or object contains a given value (using `===`).
-+  // Aliased as `include`.
-+  _.contains = _.include = function(obj, target) {
-+    if (obj == null) return false;
-+    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
-+    return any(obj, function(value) {
-+      return value === target;
-+    });
-+  };
-+
-+  // Invoke a method (with arguments) on every item in a collection.
-+  _.invoke = function(obj, method) {
-+    var args = slice.call(arguments, 2);
-+    var isFunc = _.isFunction(method);
-+    return _.map(obj, function(value) {
-+      return (isFunc ? method : value[method]).apply(value, args);
-+    });
-+  };
-+
-+  // Convenience version of a common use case of `map`: fetching a property.
-+  _.pluck = function(obj, key) {
-+    return _.map(obj, _.property(key));
-+  };
-+
-+  // Convenience version of a common use case of `filter`: selecting only objects
-+  // containing specific `key:value` pairs.
-+  _.where = function(obj, attrs) {
-+    return _.filter(obj, _.matches(attrs));
-+  };
-+
-+  // Convenience version of a common use case of `find`: getting the first object
-+  // containing specific `key:value` pairs.
-+  _.findWhere = function(obj, attrs) {
-+    return _.find(obj, _.matches(attrs));
-+  };
-+
-+  // Return the maximum element or (element-based computation).
-+  // Can't optimize arrays of integers longer than 65,535 elements.
-+  // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
-+  _.max = function(obj, iterator, context) {
-+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
-+      return Math.max.apply(Math, obj);
-+    }
-+    var result = -Infinity, lastComputed = -Infinity;
-+    each(obj, function(value, index, list) {
-+      var computed = iterator ? iterator.call(context, value, index, list) : value;
-+      if (computed > lastComputed) {
-+        result = value;
-+        lastComputed = computed;
-+      }
-+    });
-+    return result;
-+  };
-+
-+  // Return the minimum element (or element-based computation).
-+  _.min = function(obj, iterator, context) {
-+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
-+      return Math.min.apply(Math, obj);
-+    }
-+    var result = Infinity, lastComputed = Infinity;
-+    each(obj, function(value, index, list) {
-+      var computed = iterator ? iterator.call(context, value, index, list) : value;
-+      if (computed < lastComputed) {
-+        result = value;
-+        lastComputed = computed;
-+      }
-+    });
-+    return result;
-+  };
-+
-+  // Shuffle an array, using the modern version of the
-+  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
-+  _.shuffle = function(obj) {
-+    var rand;
-+    var index = 0;
-+    var shuffled = [];
-+    each(obj, function(value) {
-+      rand = _.random(index++);
-+      shuffled[index - 1] = shuffled[rand];
-+      shuffled[rand] = value;
-+    });
-+    return shuffled;
-+  };
-+
-+  // Sample **n** random values from a collection.
-+  // If **n** is not specified, returns a single random element.
-+  // The internal `guard` argument allows it to work with `map`.
-+  _.sample = function(obj, n, guard) {
-+    if (n == null || guard) {
-+      if (obj.length !== +obj.length) obj = _.values(obj);
-+      return obj[_.random(obj.length - 1)];
-+    }
-+    return _.shuffle(obj).slice(0, Math.max(0, n));
-+  };
-+
-+  // An internal function to generate lookup iterators.
-+  var lookupIterator = function(value) {
-+    if (value == null) return _.identity;
-+    if (_.isFunction(value)) return value;
-+    return _.property(value);
-+  };
-+
-+  // Sort the object's values by a criterion produced by an iterator.
-+  _.sortBy = function(obj, iterator, context) {
-+    iterator = lookupIterator(iterator);
-+    return _.pluck(_.map(obj, function(value, index, list) {
-+      return {
-+        value: value,
-+        index: index,
-+        criteria: iterator.call(context, value, index, list)
-+      };
-+    }).sort(function(left, right) {
-+      var a = left.criteria;
-+      var b = right.criteria;
-+      if (a !== b) {
-+        if (a > b || a === void 0) return 1;
-+        if (a < b || b === void 0) return -1;
-+      }
-+      return left.index - right.index;
-+    }), 'value');
-+  };
-+
-+  // An internal function used for aggregate "group by" operations.
-+  var group = function(behavior) {
-+    return function(obj, iterator, context) {
-+      var result = {};
-+      iterator = lookupIterator(iterator);
-+      each(obj, function(value, index) {
-+        var key = iterator.call(context, value, index, obj);
-+        behavior(result, key, value);
-+      });
-+      return result;
-+    };
-+  };
-+
-+  // Groups the object's values by a criterion. Pass either a string attribute
-+  // to group by, or a function that returns the criterion.
-+  _.groupBy = group(function(result, key, value) {
-+    _.has(result, key) ? result[key].push(value) : result[key] = [value];
-+  });
-+
-+  // Indexes the object's values by a criterion, similar to `groupBy`, but for
-+  // when you know that your index values will be unique.
-+  _.indexBy = group(function(result, key, value) {
-+    result[key] = value;
-+  });
-+
-+  // Counts instances of an object that group by a certain criterion. Pass
-+  // either a string attribute to count by, or a function that returns the
-+  // criterion.
-+  _.countBy = group(function(result, key) {
-+    _.has(result, key) ? result[key]++ : result[key] = 1;
-+  });
-+
-+  // Use a comparator function to figure out the smallest index at which
-+  // an object should be inserted so as to maintain order. Uses binary search.
-+  _.sortedIndex = function(array, obj, iterator, context) {
-+    iterator = lookupIterator(iterator);
-+    var value = iterator.call(context, obj);
-+    var low = 0, high = array.length;
-+    while (low < high) {
-+      var mid = (low + high) >>> 1;
-+      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
-+    }
-+    return low;
-+  };
-+
-+  // Safely create a real, live array from anything iterable.
-+  _.toArray = function(obj) {
-+    if (!obj) return [];
-+    if (_.isArray(obj)) return slice.call(obj);
-+    if (obj.length === +obj.length) return _.map(obj, _.identity);
-+    return _.values(obj);
-+  };
-+
-+  // Return the number of elements in an object.
-+  _.size = function(obj) {
-+    if (obj == null) return 0;
-+    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
-+  };
-+
-+  // Array Functions
-+  // ---------------
-+
-+  // Get the first element of an array. Passing **n** will return the first N
-+  // values in the array. Aliased as `head` and `take`. The **guard** check
-+  // allows it to work with `_.map`.
-+  _.first = _.head = _.take = function(array, n, guard) {
-+    if (array == null) return void 0;
-+    if ((n == null) || guard) return array[0];
-+    if (n < 0) return [];
-+    return slice.call(array, 0, n);
-+  };
-+
-+  // Returns everything but the last entry of the array. Especially useful on
-+  // the arguments object. Passing **n** will return all the values in
-+  // the array, excluding the last N. The **guard** check allows it to work with
-+  // `_.map`.
-+  _.initial = function(array, n, guard) {
-+    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
-+  };
-+
-+  // Get the last element of an array. Passing **n** will return the last N
-+  // values in the array. The **guard** check allows it to work with `_.map`.
-+  _.last = function(array, n, guard) {
-+    if (array == null) return void 0;
-+    if ((n == null) || guard) return array[array.length - 1];
-+    return slice.call(array, Math.max(array.length - n, 0));
-+  };
-+
-+  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
-+  // Especially useful on the arguments object. Passing an **n** will return
-+  // the rest N values in the array. The **guard**
-+  // check allows it to work with `_.map`.
-+  _.rest = _.tail = _.drop = function(array, n, guard) {
-+    return slice.call(array, (n == null) || guard ? 1 : n);
-+  };
-+
-+  // Trim out all falsy values from an array.
-+  _.compact = function(array) {
-+    return _.filter(array, _.identity);
-+  };
-+
-+  // Internal implementation of a recursive `flatten` function.
-+  var flatten = function(input, shallow, output) {
-+    if (shallow && _.every(input, _.isArray)) {
-+      return concat.apply(output, input);
-+    }
-+    each(input, function(value) {
-+      if (_.isArray(value) || _.isArguments(value)) {
-+        shallow ? push.apply(output, value) : flatten(value, shallow, output);
-+      } else {
-+        output.push(value);
-+      }
-+    });
-+    return output;
-+  };
-+
-+  // Flatten out an array, either recursively (by default), or just one level.
-+  _.flatten = function(array, shallow) {
-+    return flatten(array, shallow, []);
-+  };
-+
-+  // Return a version of the array that does not contain the specified value(s).
-+  _.without = function(array) {
-+    return _.difference(array, slice.call(arguments, 1));
-+  };
-+
-+  // Split an array into two arrays: one whose elements all satisfy the given
-+  // predicate, and one whose elements all do not satisfy the predicate.
-+  _.partition = function(array, predicate) {
-+    var pass = [], fail = [];
-+    each(array, function(elem) {
-+      (predicate(elem) ? pass : fail).push(elem);
-+    });
-+    return [pass, fail];
-+  };
-+
-+  // Produce a duplicate-free version of the array. If the array has already
-+  // been sorted, you have the option of using a faster algorithm.
-+  // Aliased as `unique`.
-+  _.uniq = _.unique = function(array, isSorted, iterator, context) {
-+    if (_.isFunction(isSorted)) {
-+      context = iterator;
-+      iterator = isSorted;
-+      isSorted = false;
-+    }
-+    var initial = iterator ? _.map(array, iterator, context) : array;
-+    var results = [];
-+    var seen = [];
-+    each(initial, function(value, index) {
-+      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
-+        seen.push(value);
-+        results.push(array[index]);
-+      }
-+    });
-+    return results;
-+  };
-+
-+  // Produce an array that contains the union: each distinct element from all of
-+  // the passed-in arrays.
-+  _.union = function() {
-+    return _.uniq(_.flatten(arguments, true));
-+  };
-+
-+  // Produce an array that contains every item shared between all the
-+  // passed-in arrays.
-+  _.intersection = function(array) {
-+    var rest = slice.call(arguments, 1);
-+    return _.filter(_.uniq(array), function(item) {
-+      return _.every(rest, function(other) {
-+        return _.contains(other, item);
-+      });
-+    });
-+  };
-+
-+  // Take the difference between one array and a number of other arrays.
-+  // Only the elements present in just the first array will remain.
-+  _.difference = function(array) {
-+    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
-+    return _.filter(array, function(value){ return !_.contains(rest, value); });
-+  };
-+
-+  // Zip together multiple lists into a single array -- elements that share
-+  // an index go together.
-+  _.zip = function() {
-+    var length = _.max(_.pluck(arguments, 'length').concat(0));
-+    var results = new Array(length);
-+    for (var i = 0; i < length; i++) {
-+      results[i] = _.pluck(arguments, '' + i);
-+    }
-+    return results;
-+  };
-+
-+  // Converts lists into objects. Pass either a single array of `[key, value]`
-+  // pairs, or two parallel arrays of the same length -- one of keys, and one of
-+  // the corresponding values.
-+  _.object = function(list, values) {
-+    if (list == null) return {};
-+    var result = {};
-+    for (var i = 0, length = list.length; i < length; i++) {
-+      if (values) {
-+        result[list[i]] = values[i];
-+      } else {
-+        result[list[i][0]] = list[i][1];
-+      }
-+    }
-+    return result;
-+  };
-+
-+  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
-+  // we need this function. Return the position of the first occurrence of an
-+  // item in an array, or -1 if the item is not included in the array.
-+  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
-+  // If the array is large and already in sort order, pass `true`
-+  // for **isSorted** to use binary search.
-+  _.indexOf = function(array, item, isSorted) {
-+    if (array == null) return -1;
-+    var i = 0, length = array.length;
-+    if (isSorted) {
-+      if (typeof isSorted == 'number') {
-+        i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
-+      } else {
-+        i = _.sortedIndex(array, item);
-+        return array[i] === item ? i : -1;
-+      }
-+    }
-+    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
-+    for (; i < length; i++) if (array[i] === item) return i;
-+    return -1;
-+  };
-+
-+  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
-+  _.lastIndexOf = function(array, item, from) {
-+    if (array == null) return -1;
-+    var hasIndex = from != null;
-+    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
-+      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
-+    }
-+    var i = (hasIndex ? from : array.length);
-+    while (i--) if (array[i] === item) return i;
-+    return -1;
-+  };
-+
-+  // Generate an integer Array containing an arithmetic progression. A port of
-+  // the native Python `range()` function. See
-+  // [the Python documentation](http://docs.python.org/library/functions.html#range).
-+  _.range = function(start, stop, step) {
-+    if (arguments.length <= 1) {
-+      stop = start || 0;
-+      start = 0;
-+    }
-+    step = arguments[2] || 1;
-+
-+    var length = Math.max(Math.ceil((stop - start) / step), 0);
-+    var idx = 0;
-+    var range = new Array(length);
-+
-+    while(idx < length) {
-+      range[idx++] = start;
-+      start += step;
-+    }
-+
-+    return range;
-+  };
-+
-+  // Function (ahem) Functions
-+  // ------------------
-+
-+  // Reusable constructor function for prototype setting.
-+  var ctor = function(){};
-+
-+  // Create a function bound to a given object (assigning `this`, and arguments,
-+  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
-+  // available.
-+  _.bind = function(func, context) {
-+    var args, bound;
-+    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
-+    if (!_.isFunction(func)) throw new TypeError;
-+    args = slice.call(arguments, 2);
-+    return bound = function() {
-+      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
-+      ctor.prototype = func.prototype;
-+      var self = new ctor;
-+      ctor.prototype = null;
-+      var result = func.apply(self, args.concat(slice.call(arguments)));
-+      if (Object(result) === result) return result;
-+      return self;
-+    };
-+  };
-+
-+  // Partially apply a function by creating a version that has had some of its
-+  // arguments pre-filled, without changing its dynamic `this` context. _ acts
-+  // as a placeholder, allowing any combination of arguments to be pre-filled.
-+  _.partial = function(func) {
-+    var boundArgs = slice.call(arguments, 1);
-+    return function() {
-+      var position = 0;
-+      var args = boundArgs.slice();
-+      for (var i = 0, length = args.length; i < length; i++) {
-+        if (args[i] === _) args[i] = arguments[position++];
-+      }
-+      while (position < arguments.length) args.push(arguments[position++]);
-+      return func.apply(this, args);
-+    };
-+  };
-+
-+  // Bind a number of an object's methods to that object. Remaining arguments
-+  // are the method names to be bound. Useful for ensuring that all callbacks
-+  // defined on an object belong to it.
-+  _.bindAll = function(obj) {
-+    var funcs = slice.call(arguments, 1);
-+    if (funcs.length === 0) throw new Error('bindAll must be passed function names');
-+    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
-+    return obj;
-+  };
-+
-+  // Memoize an expensive function by storing its results.
-+  _.memoize = function(func, hasher) {
-+    var memo = {};
-+    hasher || (hasher = _.identity);
-+    return function() {
-+      var key = hasher.apply(this, arguments);
-+      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
-+    };
-+  };
-+
-+  // Delays a function for the given number of milliseconds, and then calls
-+  // it with the arguments supplied.
-+  _.delay = function(func, wait) {
-+    var args = slice.call(arguments, 2);
-+    return setTimeout(function(){ return func.apply(null, args); }, wait);
-+  };
-+
-+  // Defers a function, scheduling it to run after the current call stack has
-+  // cleared.
-+  _.defer = function(func) {
-+    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
-+  };
-+
-+  // Returns a function, that, when invoked, will only be triggered at most once
-+  // during a given window of time. Normally, the throttled function will run
-+  // as much as it can, without ever going more than once per `wait` duration;
-+  // but if you'd like to disable the execution on the leading edge, pass
-+  // `{leading: false}`. To disable execution on the trailing edge, ditto.
-+  _.throttle = function(func, wait, options) {
-+    var context, args, result;
-+    var timeout = null;
-+    var previous = 0;
-+    options || (options = {});
-+    var later = function() {
-+      previous = options.leading === false ? 0 : _.now();
-+      timeout = null;
-+      result = func.apply(context, args);
-+      context = args = null;
-+    };
-+    return function() {
-+      var now = _.now();
-+      if (!previous && options.leading === false) previous = now;
-+      var remaining = wait - (now - previous);
-+      context = this;
-+      args = arguments;
-+      if (remaining <= 0) {
-+        clearTimeout(timeout);
-+        timeout = null;
-+        previous = now;
-+        result = func.apply(context, args);
-+        context = args = null;
-+      } else if (!timeout && options.trailing !== false) {
-+        timeout = setTimeout(later, remaining);
-+      }
-+      return result;
-+    };
-+  };
-+
-+  // Returns a function, that, as long as it continues to be invoked, will not
-+  // be triggered. The function will be called after it stops being called for
-+  // N milliseconds. If `immediate` is passed, trigger the function on the
-+  // leading edge, instead of the trailing.
-+  _.debounce = function(func, wait, immediate) {
-+    var timeout, args, context, timestamp, result;
-+
-+    var later = function() {
-+      var last = _.now() - timestamp;
-+      if (last < wait) {
-+        timeout = setTimeout(later, wait - last);
-+      } else {
-+        timeout = null;
-+        if (!immediate) {
-+          result = func.apply(context, args);
-+          context = args = null;
-+        }
-+      }
-+    };
-+
-+    return function() {
-+      context = this;
-+      args = arguments;
-+      timestamp = _.now();
-+      var callNow = immediate && !timeout;
-+      if (!timeout) {
-+        timeout = setTimeout(later, wait);
-+      }
-+      if (callNow) {
-+        result = func.apply(context, args);
-+        context = args = null;
-+      }
-+
-+      return result;
-+    };
-+  };
-+
-+  // Returns a function that will be executed at most one time, no matter how
-+  // often you call it. Useful for lazy initialization.
-+  _.once = function(func) {
-+    var ran = false, memo;
-+    return function() {
-+      if (ran) return memo;
-+      ran = true;
-+      memo = func.apply(this, arguments);
-+      func = null;
-+      return memo;
-+    };
-+  };
-+
-+  // Returns the first function passed as an argument to the second,
-+  // allowing you to adjust arguments, run code before and after, and
-+  // conditionally execute the original function.
-+  _.wrap = function(func, wrapper) {
-+    return _.partial(wrapper, func);
-+  };
-+
-+  // Returns a function that is the composition of a list of functions, each
-+  // consuming the return value of the function that follows.
-+  _.compose = function() {
-+    var funcs = arguments;
-+    return function() {
-+      var args = arguments;
-+      for (var i = funcs.length - 1; i >= 0; i--) {
-+        args = [funcs[i].apply(this, args)];
-+      }
-+      return args[0];
-+    };
-+  };
-+
-+  // Returns a function that will only be executed after being called N times.
-+  _.after = function(times, func) {
-+    return function() {
-+      if (--times < 1) {
-+        return func.apply(this, arguments);
-+      }
-+    };
-+  };
-+
-+  // Object Functions
-+  // ----------------
-+
-+  // Retrieve the names of an object's properties.
-+  // Delegates to **ECMAScript 5**'s native `Object.keys`
-+  _.keys = function(obj) {
-+    if (!_.isObject(obj)) return [];
-+    if (nativeKeys) return nativeKeys(obj);
-+    var keys = [];
-+    for (var key in obj) if (_.has(obj, key)) keys.push(key);
-+    return keys;
-+  };
-+
-+  // Retrieve the values of an object's properties.
-+  _.values = function(obj) {
-+    var keys = _.keys(obj);
-+    var length = keys.length;
-+    var values = new Array(length);
-+    for (var i = 0; i < length; i++) {
-+      values[i] = obj[keys[i]];
-+    }
-+    return values;
-+  };
-+
-+  // Convert an object into a list of `[key, value]` pairs.
-+  _.pairs = function(obj) {
-+    var keys = _.keys(obj);
-+    var length = keys.length;
-+    var pairs = new Array(length);
-+    for (var i = 0; i < length; i++) {
-+      pairs[i] = [keys[i], obj[keys[i]]];
-+    }
-+    return pairs;
-+  };
-+
-+  // Invert the keys and values of an object. The values must be serializable.
-+  _.invert = function(obj) {
-+    var result = {};
-+    var keys = _.keys(obj);
-+    for (var i = 0, length = keys.length; i < length; i++) {
-+      result[obj[keys[i]]] = keys[i];
-+    }
-+    return result;
-+  };
-+
-+  // Return a sorted list of the function names available on the object.
-+  // Aliased as `methods`
-+  _.functions = _.methods = function(obj) {
-+    var names = [];
-+    for (var key in obj) {
-+      if (_.isFunction(obj[key])) names.push(key);
-+    }
-+    return names.sort();
-+  };
-+
-+  // Extend a given object with all the properties in passed-in object(s).
-+  _.extend = function(obj) {
-+    each(slice.call(arguments, 1), function(source) {
-+      if (source) {
-+        for (var prop in source) {
-+          obj[prop] = source[prop];
-+        }
-+      }
-+    });
-+    return obj;
-+  };
-+
-+  // Return a copy of the object only containing the whitelisted properties.
-+  _.pick = function(obj) {
-+    var copy = {};
-+    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
-+    each(keys, function(key) {
-+      if (key in obj) copy[key] = obj[key];
-+    });
-+    return copy;
-+  };
-+
-+   // Return a copy of the object without the blacklisted properties.
-+  _.omit = function(obj) {
-+    var copy = {};
-+    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
-+    for (var key in obj) {
-+      if (!_.contains(keys, key)) copy[key] = obj[key];
-+    }
-+    return copy;
-+  };
-+
-+  // Fill in a given object with default properties.
-+  _.defaults = function(obj) {
-+    each(slice.call(arguments, 1), function(source) {
-+      if (source) {
-+        for (var prop in source) {
-+          if (obj[prop] === void 0) obj[prop] = source[prop];
-+        }
-+      }
-+    });
-+    return obj;
-+  };
-+
-+  // Create a (shallow-cloned) duplicate of an object.
-+  _.clone = function(obj) {
-+    if (!_.isObject(obj)) return obj;
-+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
-+  };
-+
-+  // Invokes interceptor with the obj, and then returns obj.
-+  // The primary purpose of this method is to "tap into" a method chain, in
-+  // order to perform operations on intermediate results within the chain.
-+  _.tap = function(obj, interceptor) {
-+    interceptor(obj);
-+    return obj;
-+  };
-+
-+  // Internal recursive comparison function for `isEqual`.
-+  var eq = function(a, b, aStack, bStack) {
-+    // Identical objects are equal. `0 === -0`, but they aren't identical.
-+    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
-+    if (a === b) return a !== 0 || 1 / a == 1 / b;
-+    // A strict comparison is necessary because `null == undefined`.
-+    if (a == null || b == null) return a === b;
-+    // Unwrap any wrapped objects.
-+    if (a instanceof _) a = a._wrapped;
-+    if (b instanceof _) b = b._wrapped;
-+    // Compare `[[Class]]` names.
-+    var className = toString.call(a);
-+    if (className != toString.call(b)) return false;
-+    switch (className) {
-+      // Strings, numbers, dates, and booleans are compared by value.
-+      case '[object String]':
-+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
-+        // equivalent to `new String("5")`.
-+        return a == String(b);
-+      case '[object Number]':
-+        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
-+        // other numeric values.
-+        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
-+      case '[object Date]':
-+      case '[object Boolean]':
-+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
-+        // millisecond representations. Note that invalid dates with millisecond representations
-+        // of `NaN` are not equivalent.
-+        return +a == +b;
-+      // RegExps are compared by their source patterns and flags.
-+      case '[object RegExp]':
-+        return a.source == b.source &&
-+               a.global == b.global &&
-+               a.multiline == b.multiline &&
-+               a.ignoreCase == b.ignoreCase;
-+    }
-+    if (typeof a != 'object' || typeof b != 'object') return false;
-+    // Assume equality for cyclic structures. The algorithm for detecting cyclic
-+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
-+    var length = aStack.length;
-+    while (length--) {
-+      // Linear search. Performance is inversely proportional to the number of
-+      // unique nested structures.
-+      if (aStack[length] == a) return bStack[length] == b;
-+    }
-+    // Objects with different constructors are not equivalent, but `Object`s
-+    // from different frames are.
-+    var aCtor = a.constructor, bCtor = b.constructor;
-+    if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
-+                             _.isFunction(bCtor) && (bCtor instanceof bCtor))
-+                        && ('constructor' in a && 'constructor' in b)) {
-+      return false;
-+    }
-+    // Add the first object to the stack of traversed objects.
-+    aStack.push(a);
-+    bStack.push(b);
-+    var size = 0, result = true;
-+    // Recursively compare objects and arrays.
-+    if (className == '[object Array]') {
-+      // Compare array lengths to determine if a deep comparison is necessary.
-+      size = a.length;
-+      result = size == b.length;
-+      if (result) {
-+        // Deep compare the contents, ignoring non-numeric properties.
-+        while (size--) {
-+          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
-+        }
-+      }
-+    } else {
-+      // Deep compare objects.
-+      for (var key in a) {
-+        if (_.has(a, key)) {
-+          // Count the expected number of properties.
-+          size++;
-+          // Deep compare each member.
-+          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
-+        }
-+      }
-+      // Ensure that both objects contain the same number of properties.
-+      if (result) {
-+        for (key in b) {
-+          if (_.has(b, key) && !(size--)) break;
-+        }
-+        result = !size;
-+      }
-+    }
-+    // Remove the first object from the stack of traversed objects.
-+    aStack.pop();
-+    bStack.pop();
-+    return result;
-+  };
-+
-+  // Perform a deep comparison to check if two objects are equal.
-+  _.isEqual = function(a, b) {
-+    return eq(a, b, [], []);
-+  };
-+
-+  // Is a given array, string, or object empty?
-+  // An "empty" object has no enumerable own-properties.
-+  _.isEmpty = function(obj) {
-+    if (obj == null) return true;
-+    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
-+    for (var key in obj) if (_.has(obj, key)) return false;
-+    return true;
-+  };
-+
-+  // Is a given value a DOM element?
-+  _.isElement = function(obj) {
-+    return !!(obj && obj.nodeType === 1);
-+  };
-+
-+  // Is a given value an array?
-+  // Delegates to ECMA5's native Array.isArray
-+  _.isArray = nativeIsArray || function(obj) {
-+    return toString.call(obj) == '[object Array]';
-+  };
-+
-+  // Is a given variable an object?
-+  _.isObject = function(obj) {
-+    return obj === Object(obj);
-+  };
-+
-+  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
-+  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
-+    _['is' + name] = function(obj) {
-+      return toString.call(obj) == '[object ' + name + ']';
-+    };
-+  });
-+
-+  // Define a fallback version of the method in browsers (ahem, IE), where
-+  // there isn't any inspectable "Arguments" type.
-+  if (!_.isArguments(arguments)) {
-+    _.isArguments = function(obj) {
-+      return !!(obj && _.has(obj, 'callee'));
-+    };
-+  }
-+
-+  // Optimize `isFunction` if appropriate.
-+  if (typeof (/./) !== 'function') {
-+    _.isFunction = function(obj) {
-+      return typeof obj === 'function';
-+    };
-+  }
-+
-+  // Is a given object a finite number?
-+  _.isFinite = function(obj) {
-+    return isFinite(obj) && !isNaN(parseFloat(obj));
-+  };
-+
-+  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
-+  _.isNaN = function(obj) {
-+    return _.isNumber(obj) && obj != +obj;
-+  };
-+
-+  // Is a given value a boolean?
-+  _.isBoolean = function(obj) {
-+    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
-+  };
-+
-+  // Is a given value equal to null?
-+  _.isNull = function(obj) {
-+    return obj === null;
-+  };
-+
-+  // Is a given variable undefined?
-+  _.isUndefined = function(obj) {
-+    return obj === void 0;
-+  };
-+
-+  // Shortcut function for checking if an object has a given property directly
-+  // on itself (in other words, not on a prototype).
-+  _.has = function(obj, key) {
-+    return hasOwnProperty.call(obj, key);
-+  };
-+
-+  // Utility Functions
-+  // -----------------
-+
-+  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
-+  // previous owner. Returns a reference to the Underscore object.
-+  _.noConflict = function() {
-+    root._ = previousUnderscore;
-+    return this;
-+  };
-+
-+  // Keep the identity function around for default iterators.
-+  _.identity = function(value) {
-+    return value;
-+  };
-+
-+  _.constant = function(value) {
-+    return function () {
-+      return value;
-+    };
-+  };
-+
-+  _.property = function(key) {
-+    return function(obj) {
-+      return obj[key];
-+    };
-+  };
-+
-+  // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
-+  _.matches = function(attrs) {
-+    return function(obj) {
-+      if (obj === attrs) return true; //avoid comparing an object to itself.
-+      for (var key in attrs) {
-+        if (attrs[key] !== obj[key])
-+          return false;
-+      }
-+      return true;
-+    }
-+  };
-+
-+  // Run a function **n** times.
-+  _.times = function(n, iterator, context) {
-+    var accum = Array(Math.max(0, n));
-+    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
-+    return accum;
-+  };
-+
-+  // Return a random integer between min and max (inclusive).
-+  _.random = function(min, max) {
-+    if (max == null) {
-+      max = min;
-+      min = 0;
-+    }
-+    return min + Math.floor(Math.random() * (max - min + 1));
-+  };
-+
-+  // A (possibly faster) way to get the current timestamp as an integer.
-+  _.now = Date.now || function() { return new Date().getTime(); };
-+
-+  // List of HTML entities for escaping.
-+  var entityMap = {
-+    escape: {
-+      '&': '&',
-+      '<': '<',
-+      '>': '>',
-+      '"': '"',
-+      "'": '&#x27;'
-+    }
-+  };
-+  entityMap.unescape = _.invert(entityMap.escape);
-+
-+  // Regexes containing the keys and values listed immediately above.
-+  var entityRegexes = {
-+    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
-+    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
-+  };
-+
-+  // Functions for escaping and unescaping strings to/from HTML interpolation.
-+  _.each(['escape', 'unescape'], function(method) {
-+    _[method] = function(string) {
-+      if (string == null) return '';
-+      return ('' + string).replace(entityRegexes[method], function(match) {
-+        return entityMap[method][match];
-+      });
-+    };
-+  });
-+
-+  // If the value of the named `property` is a function then invoke it with the
-+  // `object` as context; otherwise, return it.
-+  _.result = function(object, property) {
-+    if (object == null) return void 0;
-+    var value = object[property];
-+    return _.isFunction(value) ? value.call(object) : value;
-+  };
-+
-+  // Add your own custom functions to the Underscore object.
-+  _.mixin = function(obj) {
-+    each(_.functions(obj), function(name) {
-+      var func = _[name] = obj[name];
-+      _.prototype[name] = function() {
-+        var args = [this._wrapped];
-+        push.apply(args, arguments);
-+        return result.call(this, func.apply(_, args));
-+      };
-+    });
-+  };
-+
-+  // Generate a unique integer id (unique within the entire client session).
-+  // Useful for temporary DOM ids.
-+  var idCounter = 0;
-+  _.uniqueId = function(prefix) {
-+    var id = ++idCounter + '';
-+    return prefix ? prefix + id : id;
-+  };
-+
-+  // By default, Underscore uses ERB-style template delimiters, change the
-+  // following template settings to use alternative delimiters.
-+  _.templateSettings = {
-+    evaluate    : /<%([\s\S]+?)%>/g,
-+    interpolate : /<%=([\s\S]+?)%>/g,
-+    escape      : /<%-([\s\S]+?)%>/g
-+  };
-+
-+  // When customizing `templateSettings`, if you don't want to define an
-+  // interpolation, evaluation or escaping regex, we need one that is
-+  // guaranteed not to match.
-+  var noMatch = /(.)^/;
-+
-+  // Certain characters need to be escaped so that they can be put into a
-+  // string literal.
-+  var escapes = {
-+    "'":      "'",
-+    '\\':     '\\',
-+    '\r':     'r',
-+    '\n':     'n',
-+    '\t':     't',
-+    '\u2028': 'u2028',
-+    '\u2029': 'u2029'
-+  };
-+
-+  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
-+
-+  // JavaScript micro-templating, similar to John Resig's implementation.
-+  // Underscore templating handles arbitrary delimiters, preserves whitespace,
-+  // and correctly escapes quotes within interpolated code.
-+  _.template = function(text, data, settings) {
-+    var render;
-+    settings = _.defaults({}, settings, _.templateSettings);
-+
-+    // Combine delimiters into one regular expression via alternation.
-+    var matcher = new RegExp([
-+      (settings.escape || noMatch).source,
-+      (settings.interpolate || noMatch).source,
-+      (settings.evaluate || noMatch).source
-+    ].join('|') + '|$', 'g');
-+
-+    // Compile the template source, escaping string literals appropriately.
-+    var index = 0;
-+    var source = "__p+='";
-+    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-+      source += text.slice(index, offset)
-+        .replace(escaper, function(match) { return '\\' + escapes[match]; });
-+
-+      if (escape) {
-+        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-+      }
-+      if (interpolate) {
-+        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-+      }
-+      if (evaluate) {
-+        source += "';\n" + evaluate + "\n__p+='";
-+      }
-+      index = offset + match.length;
-+      return match;
-+    });
-+    source += "';\n";
-+
-+    // If a variable is not specified, place data values in local scope.
-+    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-+
-+    source = "var __t,__p='',__j=Array.prototype.join," +
-+      "print=function(){__p+=__j.call(arguments,'');};\n" +
-+      source + "return __p;\n";
-+
-+    try {
-+      render = new Function(settings.variable || 'obj', '_', source);
-+    } catch (e) {
-+      e.source = source;
-+      throw e;
-+    }
-+
-+    if (data) return render(data, _);
-+    var template = function(data) {
-+      return render.call(this, data, _);
-+    };
-+
-+    // Provide the compiled function source as a convenience for precompilation.
-+    template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
-+
-+    return template;
-+  };
-+
-+  // Add a "chain" function, which will delegate to the wrapper.
-+  _.chain = function(obj) {
-+    return _(obj).chain();
-+  };
-+
-+  // OOP
-+  // ---------------
-+  // If Underscore is called as a function, it returns a wrapped object that
-+  // can be used OO-style. This wrapper holds altered versions of all the
-+  // underscore functions. Wrapped objects may be chained.
-+
-+  // Helper function to continue chaining intermediate results.
-+  var result = function(obj) {
-+    return this._chain ? _(obj).chain() : obj;
-+  };
-+
-+  // Add all of the Underscore functions to the wrapper object.
-+  _.mixin(_);
-+
-+  // Add all mutator Array functions to the wrapper.
-+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
-+    var method = ArrayProto[name];
-+    _.prototype[name] = function() {
-+      var obj = this._wrapped;
-+      method.apply(obj, arguments);
-+      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
-+      return result.call(this, obj);
-+    };
-+  });
-+
-+  // Add all accessor Array functions to the wrapper.
-+  each(['concat', 'join', 'slice'], function(name) {
-+    var method = ArrayProto[name];
-+    _.prototype[name] = function() {
-+      return result.call(this, method.apply(this._wrapped, arguments));
-+    };
-+  });
-+
-+  _.extend(_.prototype, {
-+
-+    // Start chaining a wrapped Underscore object.
-+    chain: function() {
-+      this._chain = true;
-+      return this;
-+    },
-+
-+    // Extracts the result from a wrapped and chained object.
-+    value: function() {
-+      return this._wrapped;
-+    }
-+
-+  });
-+
-+  // AMD registration happens at the end for compatibility with AMD loaders
-+  // that may not enforce next-turn semantics on modules. Even though general
-+  // practice for AMD registration is to be anonymous, underscore registers
-+  // as a named module because, like jQuery, it is a base library that is
-+  // popular enough to be bundled in a third party lib, but not be part of
-+  // an AMD load request. Those cases could generate an error when an
-+  // anonymous define() is called outside of a loader request.
-+  if (typeof define === 'function' && define.amd) {
-+    define('underscore', [], function() {
-+      return _;
-+    });
-+  }
-+}).call(this);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/package.json
-@@ -0,0 +1,52 @@
-+{
-+  "name": "lastfm",
-+  "description": "Read and write to Last.fm",
-+  "version": "0.9.0",
-+  "author": {
-+    "name": "James Scott",
-+    "email": "jammus at gmail.com"
-+  },
-+  "contributors": [
-+    {
-+      "name": "Garrett Wilkin",
-+      "email": "garrett.wilkin at gmail.com",
-+      "url": "http://geethink.com"
-+    },
-+    {
-+      "name": "Uwe L. Korn",
-+      "email": "uwelk at xhochy.com",
-+      "url": "http://xhochy.com/"
-+    },
-+    {
-+      "name": "Max Kueng",
-+      "url": "http://maxkueng.com/"
-+    }
-+  ],
-+  "repository": {
-+    "type": "git",
-+    "url": "http://github.com/jammus/lastfm-node.git"
-+  },
-+  "engine": [
-+    "node >= 0.4.10"
-+  ],
-+  "directories": {
-+    "lib": "./lib/lastfm"
-+  },
-+  "dependencies": {
-+    "underscore": ""
-+  },
-+  "devDependencies": {
-+    "gently": ""
-+  },
-+  "main": "./lib/lastfm/index",
-+  "engines": {
-+    "node": "*"
-+  },
-+  "readme": "# lastfm-node\n\nRead and write to users recent plays on Last.fm.\n\n## Installation\n\n    npm install lastfm\n\n## Usage\n\n    var LastFmNode = require('lastfm').LastFmNode;\n  \n    var lastfm = new LastFmNode({\n      api_key: 'apikey',    // sign-up for a key at http://www.last.fm/api\n      secret: 'secret',\n      useragent: 'appname/vX.X MyApp' // optional. defaults to lastfm-node.\n    });\n\n## Documentation\n\n### LastFmRequest\n\n    lastfm.request(method, options);\n\nReturns a `LastFmRequest` instance.\n\nSend request to Last.fm. Requests automatically include the API key and are signed and/or sent via POST as described in the Last.fm API documentation.\n\nMethods:\n\nAccepts any Last.fm API method name, eg \"artist.getInfo\". \n\nOptions:\n\nAll options are passed through to Last.fm with the exception of the following.\n\n- *write*\n\n        Force request to act as a write method. Write methods are signed and sent via POST. Useful for new methods not yet recognised by lastfm-node.\n\n- *signed*\n\n        Force request to be signed. See Last.fm API docs for signature details. Useful for new methods not yet recognised by lastfm-node.\n\n- *handlers*\n\n        Default event handlers to attach to the request object on creation.\n\nEvents:\n\n- *success(json)*\n\n        JSON response from Last.fm\n\n- *error(error)*\n\n        Ruh-roh. Either a error returned by Last.fm or a transmission error.\n\n### RecentTracksStream\n\n    lastfm.stream(username);\n\nReturns: a `RecentTracksStream` instance\n\nMethods:\n\n- *start()*\n\n        Start streaming recent track info.\n\n- *stop()*\n\n        Stop streaming recent track info.\n\n- *isStreaming()*\n\n        Boolean. True is nowplaying/recent track data is being actively fetched.\n\n- *on(event, listener)*\n\n        Adds a listener for the specified event.\n\n- *removeListener(event, listener)*\n\n        Removes the listener for the specified event.\n\nOptions:\n\n- *autostart*\n\n        Start streaming automatically. Defaults to false.\n\n- *handlers*\n\n        Default event handlers to attach to the request object on creation.\n\nEvents:\n\n- *lastPlayed(track)*\n\n        The user's last scrobbled track.\n\n- *nowPlaying(track)*\n\n        Track the user is currently listening to.\n\n- *scrobbled(track)*\n        \n        Now playing track has been scrobbled.\n\n- *stoppedPlaying(track)*\n\n        User stopped listening to current track.\n\n- *error(error)*\n\n        Ruh-roh.\n\n### LastFmSession\n\n    lastfm.session(options);\n\nReturns: a `LastFmSession` instance.\n\nIf the user and session key are already known supply these in the options. Otherwise supply a token for authorisation. When a token is supplied the session will be authorised with Last.fm. If the user has not yet approved the token (desktop application flow) then authorisation will be automatically retried.\n\nSee the last.fm API documentation for more info on Last.fm authorisation flow.\n\nOptions:\n\n- *user*\n\n        User name, if known.\n\n- *key*\n\n        Session key, if known.\n\n- *token*\n\n        Token supplied by auth.getToken or web flow callback.\n\n- *retryInterval*\n\n        Time in milliseconds to leave between retries. Defaults to 10 seconds.\n\n- *handlers*\n\n        Default event handlers to attach to the session object on creation.\n\n\nPublic properties:\n\n- *user*\n\n        The username of the Last.fm user associated with the session.\n\n- *key*\n\n        The session key. Either passed in or generated using authorise().\n\nMethods:\n\n- *authorise(token, [options])*\n\n        Deprecated. Use lastfm.session({ token: token }) instead.\n        Authorises user with Last.fm api. See last.fm documentation. Options argument has handlers property that has default event handlers to attach to the LastFmSession instance.\n\n- *on(event, handler)*\n\n        Adds a listener for the specified event.\n\n- *removeListener(event, handler)*\n\n        Removes the listener for the specified event.\n\n- *isAuthorised()*\n\n        Returns true if the session has been authorised or a key was specified in the constructor.\n\n- *cancel()*\n\n        Prevent any further authorisation retries. Only applies if token supplied.\n\nEvents:\n\n- *success(session)*\n\n        Authorisation of session was successful.\n        Note: Only emitted if a token was supplied in options. Username/key combinations supplied in options are assumed to be valid.\n\n- *authorised(session)*\n\n        Deprecated: Use success instead.\n        Authorisation of session was successful.\n\n- *retrying(retry)*\n\n       Authorisation request was not successful but will be retried after a delay. Retry object contains the following properties:  \n       `delay` - The time in milliseconds before the request will be retried.  \n       `error` - The error code returned by the Last.fm API.  \n       `message` - The error message returned by the Last.fm API.\n\n- *error(track, error)*\n\n        The authorisation was not successful and will not be retried.\n\n### LastFmUpdate\n\n    lastfm.update(method, session, options);\n\nReturns a `LastFmUpdate` instance. \n\nValid methods are 'nowplaying' and 'scrobble'.\n\nAn authorised `LastFmSession` instance is required to make a successful update.\n\nIf a scrobble request receives an 11 (service offline), 16 (temporarily unavailable) or 29 (rate limit exceeded) error code from Last.fm then the request is automatically retried until it is permanently rejected or accepted. The first retry attempt is made after 10 seconds with subsequent requests delayed by 30 seconds, 1 minute, 5 minutes, 15 minutes and then every 30 minutes.\n\nOptions:\n\nAccepts all parameters used by track.updateNowPlaying and user.scrobble (see Last.Fm API) as well as:\n\n- *track*\n    \n        Track for nowplaying and scrobble requests. Uses same format as returned by `RecentTracksStream` events.\n\n- *timestamp*\n\n        Required for scrobble requests. Timestamp is in unix time (seconds since 01-01-1970 and is in UTC time).\n\n- *handlers*\n\n        Default event handlers to attach to the request object on creation.\n\nEvents:\n\n- *success(track)*\n\n       Update request was successful. \n\n- *retrying(retry)*\n\n       Scrobble request was not successful but will be retried after a delay. Retry object contains the following properties:  \n       `delay` - The time in milliseconds before the request will be retried.  \n       `error` - The error code returned by the Last.fm API.  \n       `message` - The error message returned by the Last.fm API.\n\n- *error(track, error)*\n\n        Ruh-roh.\n\n### LastFmInfo\n\n    lastfm.info(itemtype, [options]);\n\nReturns: a `LastFmInfo` instance.\n\nGets extended info about specified item.\n\nPublic properties:\n\n- *itemtype*\n\n        Any Last.fm item with a getInfo method. eg user, track, artist, etc.\n\nOptions:\n\n- *handlers*\n\n        Event handlers to attach to object at creation.\n\n- *various*\n\n       Params as specified in Last.fm API, eg user: \"username\"\n\nSpecial cases:\n\nWhen requesting track info the `track` param can be either the track name or a track object as returned by `RecentTracksStream`.\n\n\n## Example\n\n    var LastFmNode = require('lastfm').LastFmNode;\n    \n    var lastfm = new LastFmNode({\n      api_key: 'abc',\n      secret: 'secret'\n    });\n\n    var trackStream = lastfm.stream('username');\n    \n    trackStream.on('lastPlayed', function(track) {\n      console.log('Last played: ' + track.name);\n    });\n    \n    trackStream.on('nowPlaying', function(track) {\n      console.log('Now playing: ' + track.name);\n    });\n\n    trackStream.on('scrobbled', function(track) {\n      console.log('Scrobbled: ' + track.name);\n    });\n\n    trackStream.on('stoppedPlaying', function(track) {\n      console.log('Stopped playing: ' + track.name);\n    });\n\n    trackStream.on('error', function(error) {\n      console.log('Error: '  + error.message);\n    });\n\n    trackStream.start();\n\n    var session = lastfm.session({\n       token: token,\n       handlers: {\n          success: function(session) {\n             lastfm.update('nowplaying', session, { track: track } );\n             lastfm.update('scrobble', session, { track: track, timestamp: 12345678 });\n          }\n       }\n    });\n\n    var request = lastfm.request(\"artist.getInfo\", {\n        artist: \"The Mae Shi\",\n        handlers: {\n            success: function(data) {\n                console.log(\"Success: \" + data);\n            },\n            error: function(error) {\n                console.log(\"Error: \" + error.message);\n            }\n        }\n    });\n\n## Influences\n\nHeavily drawn from technoweenie's twitter-node  \nhttp://github.com/technoweenie/twitter-node\n\n## Contributors\n\n* Garret Wilkin (garrettwilkin) - http://geethink.com\n* Uwe L. Korn (xhochy) - http://xhochy.com\n* Max Kueng (maxkueng) - http://maxkueng.com\n",
-+  "readmeFilename": "README.md",
-+  "bugs": {
-+    "url": "https://github.com/jammus/lastfm-node/issues"
-+  },
-+  "_id": "lastfm at 0.9.0",
-+  "_from": "lastfm@~0.9.0"
-+}
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/TestData.js
-@@ -0,0 +1,36 @@
-+var FakeData = exports.FakeData  = Object.create; 
-+FakeData.SingleRecentTrack = '{\"recenttracks\":{\"track\":42}}';
-+FakeData.UnknownObject = '{\"recentevents\":{\"event\":{}}}';
-+FakeData.MultipleRecentsTracks = '{\"recenttracks\":{\"track\":[\"first\", \"second\"]}}';
-+FakeData.Garbage = 'fi30i\ 32';
-+
-+var FakeTracks = exports.FakeTracks = Object.create;
-+FakeTracks.LambAndTheLion = { name: 'Lamb and the Lion'};
-+
-+FakeTracks.RunToYourGrave_NP = {"artist":{"#text":"The Mae Shi","mbid":"8eb5c47c-4847-4c4b-a041-879d8fc5fbf3"},"name":"Run To Your Grave","streamable":"1","mbid":"","album":{"#text":"HILLYH","mbid":""},"url":"http:\/\/www.last.fm\/music\/The+Mae+Shi\/_\/Run+To+Your+Grave","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34s\/4656031.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64s\/4656031.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/4656031.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/300x300\/4656031.jpg","size":"extralarge"}],"@attr":{"nowplaying":"true"}};
-+
-+FakeTracks.RunToYourGrave = {"artist":{"#text":"The Mae Shi","mbid":"8eb5c47c-4847-4c4b-a041-879d8fc5fbf3"},"name":"Run To Your Grave","streamable":"1","mbid":"fakembid","album":{"#text":"HILLYH","mbid":""},"url":"http:\/\/www.last.fm\/music\/The+Mae+Shi\/_\/Run+To+Your+Grave","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34s\/4656031.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64s\/4656031.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/4656031.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/300x300\/4656031.jpg","size":"extralarge"}]};
-+
-+FakeTracks.NowPlayingAndScrobbled = [{"artist":{"#text":"Super Tennis","mbid":""},"name":"Theme Song","streamable":"1","mbid":"","album":{"#text":"The Quiet Finale","mbid":""},"url":"http:\/\/www.last.fm\/music\/Super+Tennis\/_\/Theme+Song","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34s\/41788301.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64s\/41788301.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/41788301.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/300x300\/41788301.jpg","size":"extralarge"}],"@attr":{"nowplaying":"true"}},{"artist":{"#text":"Colour","mbid":""},"name":"Over The Moon","streamable":"1","mbid":"","album":{"#text":"The 6 Machine","mbid":""},"url":"http:\/\/www.last.fm\/music\/Colour\/_\/Over+The+Moon","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34s\/32970217.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64s\/32970217.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/32970217.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/300x300\/32970217.jpg","size":"extralarge"}]}];
-+
-+FakeData.AuthorisationError = "{ \"error\" : 13, \"message\" : \"Signature is invalid\" }";
-+
-+FakeData.SuccessfulAuthorisation = "{ \"session\":  { \"name\": \"username\", \"key\": \"sessionkey\", \"subscriber\": \"0\"} }"; 
-+
-+FakeData.UpdateError = "{ \"error\" : 13, \"message\" : \"Invalid method signature supplied\" }";
-+
-+FakeData.UpdateNowPlayingSuccess = "{\"nowplaying\":{\"track\":{\"#text\":\"Run To Your Grave\",\"corrected\":\"0\"},\"artist\":{\"#text\":\"The Mai Shi\",\"corrected\":\"0\"},\"album\":{\"#text\":\"\",\"corrected\":\"0\"},\"albumArtist\":{\"#text\":\"\",\"corrected\":\"0\"},\"ignoredMessage\":{\"#text\":\"\",\"code\":\"0\"}}}";
-+
-+FakeData.ScrobbleSuccess= "{\"scrobbles\":{\"scrobble\":{\"track\":{\"#text\":\"Run To Your Grave\",\"corrected\":\"0\"},\"artist\":{\"#text\":\"The Mai Shi\",\"corrected\":\"0\"},\"album\":{\"#text\":\"\",\"corrected\":\"0\"},\"albumArtist\":{\"#text\":\"\",\"corrected\":\"0\"},\"timestamp\":\"1287180538\",\"ignoredMessage\":{\"#text\":\"\",\"code\":\"0\"}},\"@attr\":{\"accepted\":\"1\",\"ignored\":\"0\"}}}";
-+
-+FakeData.UserInfo = "{\"user\":{\"name\":\"jammus\",\"realname\":\"James\",\"image\":[{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/34\/5208646.jpg\",\"size\":\"small\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/64\/5208646.jpg\",\"size\":\"medium\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/126\/5208646.jpg\",\"size\":\"large\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/252\/5208646.jpg\",\"size\":\"extralarge\"}],\"url\":\"http:\/\/www.last.fm\/user\/jammus\",\"id\":\"9421325\",\"country\":\"UK\",\"age\":\"29\",\"gender\":\"m\",\"subscriber\":\"0\",\"playcount\":\"4049\",\"playlists\":\"2\",\"bootstrap\":\"0\",\"registered\":{\"#text\":\"2008-02-14 14:14\",\"unixtime\":\"1202998466\"}}}";
-+
-+FakeData.UnknownUser = "{\"error\":6,\"message\":\"No user with that name was found\"}";
-+
-+FakeData.Error = "{\"error\":1,\"message\":\"Error received\"}";
-+
-+FakeData.NotEnoughTrackInfo = "{\"error\":6,\"message\":\"You must supply either a track & artist name or a track mbid.\"}";
-+
-+FakeData.RunToYourGraveTrackInfo = "{\"track\":{\"id\":\"87962768\",\"name\":\"Run To Your Grave\",\"mbid\":\"\",\"url\":\"http:\/\/www.last.fm\/music\/The+Mae+Shi\/_\/Run+To+Your+Grave\",\"duration\":\"232000\",\"streamable\":{\"#text\":\"1\",\"fulltrack\":\"0\"},\"listeners\":\"38019\",\"playcount\":\"164628\",\"artist\":{\"name\":\"The Mae Shi\",\"mbid\":\"8eb5c47c-4847-4c4b-a041-879d8fc5fbf3\",\"url\":\"http:\/\/www.last.fm\/music\/The+Mae+Shi\"},\"album\":{\"artist\":\"The Mae Shi\",\"title\":\"HILLYH\",\"mbid\":\"\",\"url\":\"http:\/\/www.last.fm\/music\/The+Mae+Shi\/HILLYH\",\"image\":[{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/64s\/4656031.jpg\",\"size\":\"small\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/126\/4656031.jpg\",\"size\":\"medium\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/174s\/4656031.jpg\",\"size\":\"large\"},{\"#text\":\"http:\/\/userserve-ak.last.fm\/serve\/300x300\/4656031.jpg\",\"size\":\"extralarge\"}],\"@attr\":{\"position\":\"7\"}},\"toptags\":{\"tag\":[{\"name\":\"experimental\",\"url\":\"http:\/\/www.last.fm\/tag\/experimental\"},{\"name\":\"00s\",\"url\":\"http:\/\/www.last.fm\/tag\/00s\"},{\"name\":\"fuck yeah\",\"url\":\"http:\/\/www.last.fm\/tag\/fuck%20yeah\"},{\"name\":\"pop\",\"url\":\"http:\/\/www.last.fm\/tag\/pop\"},{\"name\":\"sing-a-long\",\"url\":\"http:\/\/www.last.fm\/tag\/sing-a-long\"}]}}}";
-+
-+FakeData.UnexpectedRecentTracks = "{\"recenttracks\":\"somthing\"}";
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/common.js
-@@ -0,0 +1,16 @@
-+var path = require("path");
-+global.Gently = require("gently");
-+global.GENTLY_HIJACK = new Gently();
-+global.assert = require("assert");
-+global.ntest = require('ntest');
-+global.it = ntest.it;
-+global.describe = ntest.describe;
-+global.before = ntest.before;
-+global.after = ntest.after;
-+global.LastFmNode = require("../lib/lastfm").LastFmNode;
-+global.FakeData = require("./TestData.js").FakeData;
-+global.FakeTracks = require("./TestData.js").FakeTracks;
-+if (process.setMaxListeners) {
-+    process.setMaxListeners(900);
-+}
-+global.emptyFn = function() { };
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/fakes.js
-@@ -0,0 +1,39 @@
-+var EventEmitter = require('events').EventEmitter;
-+
-+var Client = exports.Client = function(port, host) {
-+  EventEmitter.call(this);
-+  this.port = port;
-+  this.host = host;
-+};
-+
-+Client.prototype = Object.create(EventEmitter.prototype);
-+
-+Client.prototype.request = function() {
-+    return new ClientRequest();
-+};
-+
-+var ClientRequest = exports.ClientRequest = function() {
-+  EventEmitter.call(this);
-+};
-+
-+ClientRequest.prototype = Object.create(EventEmitter.prototype);
-+
-+ClientRequest.prototype.write = function() {
-+};
-+
-+ClientRequest.prototype.end = function() {
-+};
-+
-+var ClientResponse = exports.ClientResponse = function() {
-+  EventEmitter.call(this);
-+};
-+
-+ClientResponse.prototype = Object.create(EventEmitter.prototype);
-+
-+var LastFmRequest = exports.LastFmRequest = function(connection, url) {
-+  EventEmitter.call(this);
-+  this.connection = connection;
-+  this.url = url;
-+};
-+
-+LastFmRequest.prototype = Object.create(EventEmitter.prototype);
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/index.js
-@@ -0,0 +1,10 @@
-+require("./lastfm-node-test.js");
-+require("./lastfm-recenttracks-stream-test.js");
-+require("./lastfm-session-test.js");
-+require("./lastfm-session-deprecatedflow-test.js");
-+require("./lastfm-info-test.js");
-+require("./lastfm-read-test.js");
-+require("./lastfm-info-track-test.js");
-+require("./lastfm-update-test.js");
-+require("./lastfm-request-test.js");
-+require("./lastfm-base-test.js");
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-base-test.js
-@@ -0,0 +1,78 @@
-+require('./common');
-+var LastFmBase = require("../lib/lastfm/lastfm-base");
-+
-+(function() {
-+  describe("LastFmBase");
-+
-+  it("is an event emitter", function() {
-+    var events = { expected: function(){} };
-+    var gently = new Gently();
-+    var lastfmBase = new LastFmBase();
-+    gently.expect(events, "expected");
-+    lastfmBase.on("test", function() {
-+      events.expected();
-+    });
-+    lastfmBase.emit("test");
-+  });
-+})();
-+
-+(function() {
-+  describe("LastFmBase.registerHandlers");
-+
-+  it("attaches events specified in handelers parameter", function() {
-+    var handlers = {
-+      error: function() { },
-+      success: function() { },
-+      anything: function() { }
-+    };
-+    var gently = new Gently();
-+    gently.expect(handlers, "error");
-+    gently.expect(handlers, "success");
-+    gently.expect(handlers, "anything");
-+    var lastfmBase = new LastFmBase();
-+    lastfmBase.registerHandlers(handlers);
-+    lastfmBase.emit("error");
-+    lastfmBase.emit("success");
-+    lastfmBase.emit("anything");
-+  });
-+})();
-+
-+(function() {
-+  var lastfmBase, original;
-+
-+  describe("LastFmBase.filterParameters");
-+
-+  before(function() {
-+    lastfmBase = new LastFmBase();
-+    original = { one: 1, two: 2, three: 3 };
-+  });
-+
-+  it("unfiltered object matches original object", function() {
-+    var copy = lastfmBase.filterParameters(original);
-+    assert.deepEqual(copy, original);
-+  });
-+
-+  it("returns copy of original object", function() {
-+    var copy = lastfmBase.filterParameters(original);
-+    copy.four = 4;
-+    assert.notDeepEqual(copy, original);
-+  });
-+
-+  it("filteres out blacklisted parameters", function() {
-+    var copy = lastfmBase.filterParameters(original, ["one", "three"]);
-+    assert.equal(typeof copy.one, "undefined");
-+    assert.equal(typeof copy.three, "undefined");
-+    assert.equal(copy.two, 2);
-+  });
-+
-+  it("automatically removed error, success, handler parameters", function() {
-+    var copy = lastfmBase.filterParameters({
-+        error: emptyFn,
-+        success: emptyFn,
-+        handlers: { }
-+    });
-+    assert.equal(typeof copy.error, "undefined");
-+    assert.equal(typeof copy.success, "undefined");
-+    assert.equal(typeof copy.handlers, "undefined");
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-info-test.js
-@@ -0,0 +1,118 @@
-+require("./common.js");
-+var LastFmInfo = require("../lib/lastfm/lastfm-info");
-+var LastFmRequest = require("../lib/lastfm/lastfm-request");
-+var fakes = require("./fakes");
-+
-+(function() {
-+describe("a new info instance")
-+  var lastfm, gently;
-+  before(function() {
-+    lastfm = new LastFmNode();
-+    gently = new Gently();
-+  });
-+
-+  it("accepts listeners in handler options", function() {
-+    var handlers = { error: function() {}, success: function() {} };
-+    var options = { handlers: handlers };
-+    gently.expect(handlers, "error");
-+    gently.expect(handlers, "success");
-+    var info = new LastFmInfo(lastfm, "", options);
-+    info.emit("success");
-+  });
-+  
-+  it("emits error if type not specified", function() {
-+    var handlers = { error: function() {}};
-+    gently.expect(handlers, "error", function(error) {
-+      assert.equal("Item type not specified", error.message);
-+    });
-+    var info = new LastFmInfo(lastfm, "", { handlers: handlers });
-+  });
-+  
-+  it("allows requests for user info", function() {
-+    gently.expect(lastfm, "request", function() {
-+      return new fakes.LastFmRequest();
-+    });
-+    var info = new LastFmInfo(lastfm, "user");
-+  });
-+
-+  it("allows requests for track info", function() {
-+    gently.expect(lastfm, "request", function() {
-+      return new fakes.LastFmRequest();
-+    });
-+    var info = new LastFmInfo(lastfm, "track");
-+  });
-+
-+  it("allows all [itemtype].getinfo calls", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("event.getinfo", method);
-+      return new fakes.LastFmRequest();
-+    });
-+    new LastFmInfo(lastfm, "event");
-+  });
-+  
-+  it("passes through parameters", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("username", params.user);
-+      assert.equal("anything", params.arbitrary);
-+      return new fakes.LastFmRequest();
-+    });
-+    new LastFmInfo(lastfm, "user", { user: "username", arbitrary: "anything" });
-+  });
-+
-+  it("doesnt pass through callback parameters", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.ok(!params.error);
-+      assert.ok(!params.success);
-+      assert.ok(!params.handlers);
-+      return new fakes.LastFmRequest();
-+    });
-+    new LastFmInfo(lastfm, "user", { handlers:  { error: function() {}, success: function() {} } });
-+  });
-+})();
-+
-+(function() {
-+describe("when receiving data")
-+  var gently, lastfm, request;
-+  before(function() {
-+    gently = new Gently();
-+    lastfm = new LastFmNode();
-+    request = new fakes.LastFmRequest();
-+  });
-+
-+  it("emits error when receiving unexpected data", function() {
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+    new LastFmInfo(lastfm, "track", { handlers: {
-+      error: gently.expect(function errorHandler(error) {
-+        assert.equal("Unexpected error", error.message);
-+      })
-+    }});
-+    request.emit("success", JSON.parse(FakeData.SuccessfulAuthorisation));
-+  });
-+
-+  it("emits success with received data when matches expected type", function() {
-+    gently.expect(lastfm, "request", function() {
-+        return request;
-+    });
-+    new LastFmInfo(lastfm, "track", { handlers: {
-+      success: gently.expect(function success(track) {
-+        assert.equal("Run To Your Grave", track.name);
-+        assert.equal("232000", track.duration);
-+      })
-+    }});
-+    request.emit("success", JSON.parse(FakeData.RunToYourGraveTrackInfo));
-+  });
-+
-+  it("bubbles up errors", function() {
-+    gently.expect(lastfm, "request", function() {
-+        return request;
-+    });
-+    var info = new LastFmInfo(lastfm, "track");
-+    gently.expect(info, "emit", function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal("Bubbled error", error.message);
-+    });
-+    request.emit("error", new Error("Bubbled error"));
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-info-track-test.js
-@@ -0,0 +1,35 @@
-+require("./common.js");
-+
-+var LastFmInfo = require("../lib/lastfm/lastfm-info")
-+  , fakes = require("./fakes");
-+
-+(function() {
-+  describe("a track info request");
-+
-+  before(function() {
-+    this.gently = new Gently();
-+    this.lastfm = new LastFmNode();
-+  });
-+
-+  it("calls method track.getInfo", function() {
-+    this.gently.expect(this.lastfm, "request", function(method, params) {
-+      assert.equal("track.getinfo", method);
-+      return new fakes.LastFmRequest();
-+    });
-+    new LastFmInfo(this.lastfm, "track", { mbid: "mbid" });
-+  });
-+
-+  it("can accept artist, track name and mbid", function() {
-+    this.gently.expect(this.lastfm, "request", function(method, params) {
-+      assert.equal("The Mae Shi", params.artist);
-+      assert.equal("Run To Your Grave", params.track);
-+      assert.equal("1234567890", params.mbid);
-+      return new fakes.LastFmRequest();
-+    });
-+    new LastFmInfo(this.lastfm, "track", {
-+      artist: "The Mae Shi",
-+      track: "Run To Your Grave",
-+      mbid: "1234567890"
-+    });
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-node-test.js
-@@ -0,0 +1,38 @@
-+require("./common.js");
-+
-+var querystring = require("querystring");
-+
-+(function() {
-+  var lastfm;
-+
-+  describe("default LastFmNode instance")
-+    
-+  before(function() {
-+    lastfm = new LastFmNode();
-+  })
-+
-+  it("has default host", function() {
-+    assert.equal("ws.audioscrobbler.com", lastfm.host);
-+  });
-+})();
-+
-+(function() {
-+  var lastfm;
-+
-+  describe("LastFmNode options")
-+
-+  before(function() {
-+    lastfm = new LastFmNode({
-+      api_key: "abcdef12345",
-+      secret: "ghijk67890"
-+    });
-+  })
-+
-+  it("configures api key", function() {
-+    assert.equal("abcdef12345", lastfm.api_key);
-+  });
-+
-+  it("configures secret", function() {
-+    assert.equal("ghijk67890", lastfm.secret);
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-read-test.js
-@@ -0,0 +1,382 @@
-+require('./common');
-+var crypto = require("crypto");
-+var _ = require("underscore");
-+var querystring = require("querystring");
-+var fakes = require("./fakes");
-+var LastFmRequest = fakes.LastFmRequest;
-+
-+(function() {
-+  var gently, lastfm;
-+  var options, expectations;
-+  var notExpected;
-+
-+  describe("a lastfm request");
-+
-+  before(function() {
-+    gently = new Gently();
-+    options = {};
-+    expectations = {
-+      pairs:[],
-+      handlers:[]
-+    };
-+    notExpected = {
-+      keys:[]
-+    }
-+    lastfm = new LastFmNode({
-+      api_key: "key",
-+      secret: "secret"
-+    });
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      verifyCreateClient(options.port, options.host);
-+      var request = new fakes.ClientRequest();
-+      if (options.method == "POST") {
-+          gently.expect(request, "write", function(data) {
-+              verifyRequest(options.method, options.path, options.headers, data);
-+          });
-+      } else {
-+          verifyRequest(options.method, options.path, options.headers);
-+      }
-+      return request;
-+    });
-+  });
-+
-+  after(function() {
-+    var request = doRequest();
-+    verifyHandlers(request);
-+  });
-+
-+  function verifyCreateClient(port, host) {
-+    if (expectations.port) {
-+      assert.equal(expectations.port, port);
-+    }
-+    if (expectations.host) {
-+      assert.equal(expectations.host, host);
-+    }
-+  }
-+
-+  function verifyRequest(method, url, header, data) {
-+    if (expectations.url) {
-+      assert.equal(expectations.url, url);
-+    }
-+    var pairs = querystring.parse(data || url.substr("/2.0?".length));
-+    _(Object.keys(expectations.pairs)).each(function(key) {
-+        assert.equal(expectations.pairs[key], pairs[key]);
-+    });
-+    if (expectations.signed || expectations.signatureHash) {
-+      assert.ok(pairs.api_sig);
-+    }
-+    else if (expectations.signed === false) {
-+      assert.ok(!pairs.api_sig);
-+    }
-+    if (expectations.signatureHash) {
-+      assert.equal(expectations.signatureHash, pairs.api_sig);
-+    }
-+    if (expectations.method) {
-+      assert.equal(expectations.method, method);
-+    }
-+    _(notExpected.keys).each(function(key) {
-+      assert.ok(!pairs[key]);
-+    });
-+    if (expectations.requestData) {
-+      assert.ok(data);
-+    }
-+  }
-+
-+  function whenMethodIs(method) {
-+    options.method = method;
-+  }
-+
-+  function andParamsAre(params) {
-+    options.params = params;
-+  }
-+
-+  function expectHttpMethod(method) {
-+    expectations.method = method;
-+  }
-+
-+  function expectDataPair(key, value) {
-+    expectations.pairs[key] = value;
-+  }
-+
-+  function expectSignature() {
-+    expectations.signed = true;
-+  }
-+
-+  function expectUrl(url) {
-+    expectations.url = url;
-+  }
-+
-+  function expectSignatureHashOf(unhashed) {
-+    var expectedHash = crypto.createHash("md5").update(unhashed, "utf8").digest("hex");
-+    expectSignatureHashToBe(expectedHash);
-+  };
-+
-+    this.expectSignatureHashToBe = function(hash) {
-+      expectations.signatureHash = hash;
-+    }
-+
-+  function expectRequestOnPort(port) {
-+    expectations.port = port;
-+  }
-+
-+  function expectRequestToHost(host) {
-+    expectations.host = host;
-+  }
-+
-+  function expectHandlerFor(event) {
-+    expectations.handlers.push(event);
-+  }
-+
-+  function expectRequestData() {
-+    expectations.requestData = true;
-+  }
-+
-+  function doNotExpectDataKey(key) {
-+    notExpected.keys.push(key);
-+  }
-+
-+  function doRequest() {
-+    return lastfm.request(options.method, options.params);
-+  }
-+
-+  function verifyHandlers(request) {
-+    _(expectations.handlers).each(function(event) {
-+      var listeners = request.listeners(event);
-+      assert.equal(1, listeners.length, "No handler for event: " + event);
-+    });
-+  }
-+
-+  it("default to port 80", function() {
-+    whenMethodIs("any.method");
-+    expectRequestOnPort(80);
-+  });
-+
-+  it("makes request to audioscrobbler", function() {
-+    whenMethodIs("any.method");
-+    expectRequestToHost("ws.audioscrobbler.com");
-+  });
-+
-+  it("always requests as json", function() {
-+    whenMethodIs("any.method");
-+    expectDataPair("format", "json");
-+  });
-+
-+  it("always passes api_key", function() {
-+    whenMethodIs("any.method");
-+    expectDataPair("api_key", "key");
-+  });
-+
-+  it("defaults to get request", function() {
-+    whenMethodIs("any.method");
-+    expectHttpMethod("GET");
-+  });
-+
-+  it("calls the method specified", function() {
-+    whenMethodIs("user.getinfo");
-+    expectDataPair("method", "user.getinfo");
-+  });
-+
-+  it("passes through parameters", function() {
-+    whenMethodIs("user.getinfo");
-+    andParamsAre({ user: "jammus" });
-+    expectDataPair("user", "jammus");
-+  });
-+
-+  it("converts track object to separate parameters", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      track: {
-+        artist: { "#text": "The Mae Shi" },
-+        name: "Run To Your Grave",
-+        mbid: "1234567890"
-+      }
-+    });
-+    expectDataPair("artist", "The Mae Shi");
-+    expectDataPair("track", "Run To Your Grave");
-+    expectDataPair("mbid", "1234567890");
-+  });
-+
-+  it("converts track object album details to separate parameters", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      track: {
-+        artist: { "#text": "The Mae Shi" },
-+        name: "Run To Your Grave",
-+        album: { "#text": "HLLLYH" }
-+      }
-+    });
-+    expectDataPair("album", "HLLLYH");
-+  });
-+
-+  it("does not overwrite explicitly set album parameters", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      track: {
-+        artist: { "#text": "The Mae Shi" },
-+        name: "Run To Your Grave",
-+        album: { "#text": "HLLLYH" }
-+      },
-+      album: "Run To Your Grave"
-+    });
-+    expectDataPair("album", "Run To Your Grave");
-+  });
-+
-+  it("doesn't include mbid if one isn't supplied", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      track: {
-+        artist: { "#text": "The Mae Shi" },
-+        name: "Run To Your Grave"
-+      }
-+    });
-+    expectDataPair("artist", "The Mae Shi");
-+    expectDataPair("track", "Run To Your Grave");
-+    doNotExpectDataKey("mbid");
-+  });
-+
-+  it("does not pass through event handler parameters", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ handlers: "handlers", error: "error", success: "success" });
-+    doNotExpectDataKey("handlers");
-+    doNotExpectDataKey("error");
-+    doNotExpectDataKey("success");
-+  });
-+
-+  it("auth.getsession has signature", function() {
-+    whenMethodIs("auth.getsession");
-+    expectSignature();
-+  });
-+
-+  it("attaches handlers to returned request", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ handlers: {
-+        error: function() {console.log("errrors");},
-+        success: function() {},
-+        arbitrary: function() {},
-+    }});
-+    expectHandlerFor("error");
-+    expectHandlerFor("success");
-+    expectHandlerFor("arbitrary");
-+  });
-+
-+  it("uses signed param to force signature", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      signed: true
-+    });
-+    expectSignature();
-+  });
-+
-+  it("signature hashes api_key, method and secret", function() {
-+    whenMethodIs("auth.getsession");
-+    expectSignatureHashOf("api_keykeymethodauth.getsessionsecret");
-+  });
-+
-+  it("signature includes other parameters", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ foo: "bar" });
-+    expectSignatureHashOf("api_keykeyfoobarmethodauth.getsessionsecret");
-+  });
-+
-+  it("signature hashes all params alphabetically", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ foo : "bar", baz: "bash", flip : "flop" });
-+    expectSignatureHashOf("api_keykeybazbashflipflopfoobarmethodauth.getsessionsecret");
-+  });
-+
-+  it("signature hash ignores format parameter", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ format: "json" });
-+    expectSignatureHashOf("api_keykeymethodauth.getsessionsecret");
-+  });
-+
-+  it("signature hash ignores handlers parameter", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ handlers: "handlers" });
-+    expectSignatureHashOf("api_keykeymethodauth.getsessionsecret");
-+  });
-+
-+  it("signature hash ignores write parameter", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ write: true });
-+    expectSignatureHashOf("api_keykeymethodauth.getsessionsecret");
-+  });
-+
-+  it("signature hash ignores signed parameter", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ signed: true });
-+    expectSignatureHashOf("api_keykeymethodany.methodsecret");
-+  });
-+
-+  it("signature hash handles high characters as expected by last.fm (utf8)", function() {
-+    whenMethodIs("auth.getsession");
-+    andParamsAre({ track: "Tony’s Theme (Remastered)" });
-+    expectSignatureHashToBe("15f5159046bf1e76774b9dd46a4ed993");
-+  });
-+
-+  it("signature hash treats undefined values as blank", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ signed: true, track: 'Replicating Networks', artist: 'Rabbit Milk', albumArtist: undefined });
-+    expectSignatureHashOf("albumArtistapi_keykeyartistRabbit Milkmethodany.methodtrackReplicating Networkssecret");
-+  });
-+
-+  it("signature hash treats null values as blank", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ signed: true, track: 'Replicating Networks', artist: 'Rabbit Milk', albumArtist: null });
-+    expectSignatureHashOf("albumArtistapi_keykeyartistRabbit Milkmethodany.methodtrackReplicating Networkssecret");
-+  });
-+
-+  it("write requests use post", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ write: true });
-+    expectHttpMethod("POST");
-+  });
-+
-+  it("write requests don't use get parameters", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({ write: true });
-+    expectUrl("/2.0");
-+  });
-+
-+  it("write requests send data in request", function() {
-+    whenMethodIs("any.method");
-+    andParamsAre({
-+      write: true,
-+      foo: "bar"
-+    });
-+    expectRequestData();
-+    expectDataPair("foo", "bar");
-+  });
-+
-+  it("write requests are always signed", function() {
-+    whenMethodIs("album.removeTag");
-+    andParamsAre({
-+      write: true
-+    });
-+    expectSignature();
-+  });
-+
-+  _(["album.addTags", "album.removeTag", "album.share",
-+    "artist.addTags", "artist.removeTag", "artist.share", "artist.shout",
-+    "event.attend", "event.share", "event.shout",
-+    "library.addAlbum", "library.addArtist", "library.addTrack",
-+    "playlist.addTrack", "playlist.create",
-+    "radio.tune",
-+    "track.addTags", "track.ban", "track.love", "track.removeTag",
-+    "track.scrobble", "track.share", "track.unban", "track.unlove",
-+    "track.updateNowPlaying",
-+    "user.shout"]).each(function(method) {
-+    it(method + " is a write (post) request", function() {
-+      whenMethodIs(method);
-+      expectHttpMethod("POST");
-+    });
-+  });
-+
-+  _(["auth.getMobileSession", "auth.getSession", "auth.getToken",
-+    "radio.getPlaylist"]).each(function(method) {
-+    it(method + " is signed", function() {
-+      whenMethodIs(method);
-+      expectSignature();
-+    });
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-recenttracks-stream-test.js
-@@ -0,0 +1,324 @@
-+require("./common.js");
-+
-+var _ = require("underscore")
-+  , RecentTracksStream = require("../lib/lastfm/recenttracks-stream")
-+  , LastFmRequest = require("../lib/lastfm/lastfm-request")
-+  , fakes = require("./fakes");
-+
-+(function() {
-+  var gently, lastfm, trackStream;
-+
-+  describe("a new stream instance");
-+
-+  before(function() {
-+    gently = new Gently();
-+    lastfm = new LastFmNode();
-+    trackStream = new RecentTracksStream(lastfm, "username");
-+  });
-+
-+  it("accepts listeners", function() {
-+    trackStream.addListener("event", function() {});
-+  });
-+
-+  it("is not streaming", function() {
-+    assert.ok(!trackStream.isStreaming());
-+  });
-+
-+  it("event handlers can be specified in options", function() {
-+    var handlers = {};
-+   
-+    gently.expect(handlers, "error");
-+    gently.expect(handlers, "lastPlayed");
-+    gently.expect(handlers, "nowPlaying");
-+    gently.expect(handlers, "stoppedPlaying");
-+    gently.expect(handlers, "scrobbled");
-+
-+    var trackStream = new RecentTracksStream(lastfm, "username", {
-+      handlers: {
-+        error: handlers.error,
-+        lastPlayed: handlers.lastPlayed,
-+        nowPlaying: handlers.nowPlaying,
-+        stoppedPlaying: handlers.stoppedPlaying,
-+        scrobbled: handlers.scrobbled
-+      }
-+    });
-+
-+    trackStream.emit("error");
-+    trackStream.emit("lastPlayed");
-+    trackStream.emit("nowPlaying");
-+    trackStream.emit("stoppedPlaying");
-+    trackStream.emit("scrobbled");
-+  });
-+})();
-+
-+(function() {
-+  var requestEmits = [],
-+      previousEmits = [];
-+
-+  function ifRequestHasPreviouslyEmit(emits) {
-+    previousEmits = emits;
-+  }
-+
-+  function whenRequestEmits(count, event, object) {
-+    if (typeof count !== "number") {
-+      object = event;
-+      event = count;
-+      count = 1;
-+    }
-+    if (typeof event !== "string") {
-+      object = event;
-+      event = "success";
-+    }
-+    requestEmits = [event, object, count];
-+  }
-+
-+  function expectStreamToEmit(count, expectation) {
-+    if (typeof count === "function") {
-+      expectation = count;
-+      count = 1;
-+    }
-+    var lastfm = new LastFmNode(),
-+        connection = new fakes.Client(80, lastfm.host),
-+        request = new fakes.LastFmRequest(),
-+        gently = new Gently();
-+
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+
-+    var trackStream = new RecentTracksStream(lastfm, "username");
-+    trackStream.start();
-+    trackStream.stop();
-+    for(var index = 0; index < previousEmits.length; index++) {
-+      request.emit("success", previousEmits[index]);
-+    }
-+    gently.expect(trackStream, "emit", count, expectation);
-+    for(var times = 0; times < requestEmits[2]; times++) {
-+      request.emit(requestEmits[0], requestEmits[1]);
-+    }
-+  }
-+
-+  describe("An active stream");
-+
-+  before(function() {
-+    previousEmits = [];
-+    requestEmits = [];
-+  });
-+
-+  it("bubbles errors", function() {
-+    whenRequestEmits("error", { error: 1, message: "An error" });
-+    expectStreamToEmit(function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal("An error", error.message);
-+    });
-+  });
-+
-+  it("emits last played when track received", function() {
-+    whenRequestEmits({ recenttracks: { track:
-+      FakeTracks.LambAndTheLion
-+    } });
-+    expectStreamToEmit(function(event, track) {
-+      assert.equal("lastPlayed", event);
-+      assert.equal("Lamb and the Lion", track.name);
-+    });
-+  });
-+
-+  it("emits now playing if track flagged now playing", function() {
-+    whenRequestEmits({
-+      recenttracks: { track: FakeTracks.RunToYourGrave_NP }
-+    });
-+    expectStreamToEmit(function(event, track) {
-+      assert.equal("nowPlaying", event);
-+      assert.equal("Run To Your Grave", track.name);
-+    });
-+  });
-+
-+  it("emits now playing and last played if both received", function() {
-+    var count = 0;
-+    whenRequestEmits({
-+      recenttracks: { track: FakeTracks.NowPlayingAndScrobbled }
-+    });
-+    expectStreamToEmit(2, function(event, track) {
-+      if (count == 0) {
-+          assert.equal("nowPlaying", event);
-+          assert.equal("Theme Song", track.name);
-+      }
-+      else {
-+          assert.equal("lastPlayed", event);
-+          assert.equal("Over The Moon", track.name);
-+      }
-+      count++;
-+    });
-+  });
-+
-+  it("does not re-emit lastPlayed on receipt of same track", function() {
-+    whenRequestEmits(2, {
-+      recenttracks: { track: FakeTracks.LambAndTheLion }
-+    });
-+    expectStreamToEmit(1, function(event, track) {
-+      assert.equal("lastPlayed", event);
-+      assert.equal("Lamb and the Lion", track.name);
-+    });
-+  });
-+
-+  it("does not re-emit nowPlaying on receipt of same track", function() {
-+    whenRequestEmits(2, {
-+      recenttracks: { track: FakeTracks.RunToYourGrave_NP }
-+    });
-+    expectStreamToEmit(1, function(event, track) {
-+      assert.equal("nowPlaying", event);
-+      assert.equal("Run To Your Grave", track.name);
-+    });
-+  });
-+
-+  it("emits stoppedPlaying track when now playing stops", function() {
-+    ifRequestHasPreviouslyEmit([
-+      { recenttracks: { track: FakeTracks.RunToYourGrave } },
-+      { recenttracks: { track: FakeTracks.RunToYourGrave_NP } }
-+    ]);
-+    whenRequestEmits({
-+      recenttracks: { track: FakeTracks.RunToYourGrave }
-+    });
-+    expectStreamToEmit(function(event, track) {
-+      assert.equal("stoppedPlaying", event);
-+      assert.equal("Run To Your Grave", track.name);
-+    });
-+  });
-+
-+  it("emits scrobbled when last play changes", function() {
-+    ifRequestHasPreviouslyEmit([
-+      { recenttracks: { track: FakeTracks.LambAndTheLion } },
-+      { recenttracks: { track: FakeTracks.RunToYourGrave_NP } }
-+    ]);
-+    whenRequestEmits({
-+      recenttracks: { track: FakeTracks.RunToYourGrave }
-+    });
-+    expectStreamToEmit(function(event, track) {
-+      assert.equal("scrobbled", event);
-+      assert.equal("Run To Your Grave", track.name);
-+    });
-+  });
-+  
-+  it("emits nowPlaying when track same as lastPlayed", function() {
-+    ifRequestHasPreviouslyEmit([
-+      { recenttracks: { track: FakeTracks.RunToYourGrave } }
-+    ]);
-+    whenRequestEmits({
-+      recenttracks: { track: FakeTracks.RunToYourGrave_NP }
-+    });
-+    expectStreamToEmit(function(event, track) {
-+      assert.equal("nowPlaying", event);
-+      assert.equal("Run To Your Grave", track.name);
-+    });
-+  });
-+
-+  it("emits error when unexpected item is received", function() {
-+    whenRequestEmits({
-+      something: "we've never seen before"
-+    });
-+    expectStreamToEmit(function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal("Unexpected response", error.message);
-+    });
-+  });
-+})();
-+
-+(function() {
-+  var lastfm, gently, request;
-+
-+  describe("Streaming")
-+
-+  before(function() { 
-+    lastfm = new LastFmNode();
-+    gently = new Gently();
-+    request = new fakes.LastFmRequest();
-+  });
-+
-+  it("starts and stops streaming when requested", function() {
-+    gently.expect(lastfm, "request", 1, function(method, params) {
-+      return request;
-+    });
-+    var trackStream = new RecentTracksStream(lastfm);
-+    trackStream.start();
-+    trackStream.stop();
-+    assert.ok(!trackStream.isStreaming());
-+  });
-+
-+  it("starts automatically when autostart set to true", function() {
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+    var trackStream = new RecentTracksStream(lastfm, "username", { autostart: true} );
-+    assert.ok(trackStream.isStreaming());
-+    trackStream.stop();
-+  });
-+
-+  it("calls user.getrecenttracks method for user", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("user.getrecenttracks", method);
-+      assert.equal("username", params.user);
-+      return request;
-+    });
-+    var trackStream = new RecentTracksStream(lastfm, "username", { autostart: true} );
-+    trackStream.stop();
-+  });
-+
-+  it("only fetches most recent track", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal(1, params.limit);
-+      return request;
-+    });
-+    var trackStream = new RecentTracksStream(lastfm, "username", { autostart: true} );
-+    trackStream.stop();
-+  });
-+
-+  it("bubbles up errors", function() {
-+    var errorMessage = "Bubbled error";
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+    var trackStream = new RecentTracksStream(lastfm, "username", { autostart:true });
-+    gently.expect(trackStream, "emit", function(event, error) {
-+      assert.equal(errorMessage, error.message);
-+    });
-+    request.emit("error", new Error(errorMessage));
-+    trackStream.stop();
-+  });
-+})();
-+
-+(function() {
-+  var lastfm, gently;
-+
-+  describe("Streaming")
-+
-+  var tmpScheduleFn;
-+  before(function() { 
-+    tmpScheduleFn = RecentTracksStream.prototype.scheduleCallback;
-+    lastfm = new LastFmNode();
-+    gently = new Gently();
-+  });
-+
-+  after(function() {
-+    RecentTracksStream.prototype.scheduleCallback = tmpScheduleFn;
-+  });
-+
-+  it("queries API every 10 seconds", function() {
-+    var trackStream = new RecentTracksStream(lastfm, "username");
-+    var count = 0;
-+    RecentTracksStream.prototype.scheduleCallback = function(callback, delay) {
-+      count++;
-+      if (count === 10) {
-+        trackStream.stop();
-+      }
-+      assert.ok(delay, 10000);
-+      gently.expect(lastfm, "request", function(method, params) {
-+        return new fakes.LastFmRequest();
-+      });
-+      callback();
-+    };
-+    gently.expect(lastfm, "request", function(method, params) {
-+      return new fakes.LastFmRequest();
-+    });
-+    trackStream.start();
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-request-test.js
-@@ -0,0 +1,186 @@
-+require("./common");
-+var _ = require("underscore"),
-+    LastFmRequest = require("../lib/lastfm/lastfm-request"),
-+    fakes = require("./fakes");
-+
-+(function() {
-+  describe("a LastFm request")
-+
-+  var lastfm, connection, url, gently, request;
-+
-+  before(function() {
-+    lastfm = new LastFmNode();
-+    connection = new fakes.Client(80, lastfm.host);
-+    request = new fakes.ClientRequest();
-+    gently = new Gently();
-+  });
-+
-+  it("creates a get request", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      assert.equal("GET", options.method);
-+      assert.equal(lastfm.host, options.host);
-+      return request;
-+    });
-+    var lastfmRequest = new LastFmRequest(lastfm, "any.method");
-+  });
-+
-+  it("ends the request", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function() {
-+      return request;
-+    });
-+    gently.expect(request, "end");
-+    var lastfmRequest = new LastFmRequest(lastfm);
-+  });
-+
-+  it("defaults user agent to lastfm-node", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      assert.equal("lastfm-node", options.headers["User-Agent"]);
-+      return request;
-+    });
-+    var lastFmRequest = new LastFmRequest(lastfm, "any.method");
-+  });
-+
-+  it("can specify user agent in lastfm options", function() {
-+    var useragent = "custom-user-agent";
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      assert.equal(useragent, options.headers["User-Agent"]);
-+      return request;
-+    });
-+    var lastfm = new LastFmNode({ useragent: useragent });
-+    var lastFmRequest = new LastFmRequest(lastfm, "any.method");
-+  });
-+
-+  it("bubbles up connection errors", function() {
-+    var message = "Bubbled error";
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+        return request;
-+    });
-+    var lastfmRequest = new LastFmRequest(lastfm, "any.method");
-+    gently.expect(lastfmRequest, "emit", function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal(message, error.message);
-+    });
-+    request.emit("error", new Error(message));
-+  });
-+})();
-+
-+(function() {
-+  describe("a LastFm request with a body")
-+
-+  var lastfm, connection, url, gently, request, params;
-+
-+  before(function() {
-+    lastfm = new LastFmNode();
-+    connection = new fakes.Client(80, lastfm.host);
-+    request = new fakes.ClientRequest();
-+    gently = new Gently();
-+    params = { foo:"bar" };
-+  });
-+
-+  it("write parameter forces a post request", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      assert.equal("POST", options.method);
-+      assert.equal(lastfm.url, options.path);
-+      assert.equal(lastfm.host, options.host);
-+      return request;
-+    });
-+    params.write = true;
-+    var lastFmRequest = new LastFmRequest(lastfm, "any.method", params);
-+  });
-+
-+  it("post requests includes additional headers", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      assert.ok(options.headers["Content-Length"]);
-+      assert.equal("application/x-www-form-urlencoded", options.headers["Content-Type"]);
-+      return request;
-+    });
-+    params.write = true;
-+    var lastFmRequest = new LastFmRequest(lastfm, "any.method", params);
-+  });
-+
-+  it("writes body to request", function() {
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function() {
-+        return request;
-+    });
-+    gently.expect(request, "write", function(data) {
-+        assert.ok(data);
-+    });
-+    params.write = true;
-+    var lastFmRequest = new LastFmRequest(lastfm, "any.method", params);
-+  });
-+})();
-+
-+(function() {
-+  var lastfm, connection, url, gently, request, receivedData;
-+
-+  describe("A Lastfm request which returns data")
-+
-+  before(function() {
-+    lastfm = new LastFmNode();
-+    connection = new fakes.Client(80, lastfm.host);
-+    request = new fakes.ClientRequest();
-+    gently = new Gently();
-+  });
-+
-+  it("emits data as json", function() {
-+    whenReceiving("{\"testdata\":\"received\"}");
-+    expectRequestToEmit(function(event, data) {
-+      assert.equal("success", event);
-+      assert.equal("received", data.testdata);
-+    });
-+  });
-+
-+  it("emits error if received data cannot be parsed to json", function() {
-+    whenReceiving("{\"testdata\"");
-+    expectRequestToEmit(function(event, error) {
-+      assert.equal("error", event);
-+      assert.ok(error);
-+    });
-+  });
-+
-+  it("emits error if json response contains a lastfm error", function() {
-+    whenReceiving("{\"error\": 2, \"message\": \"service does not exist\"}");
-+    expectRequestToEmit(function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal("service does not exist", error.message);
-+    });
-+  });
-+
-+  it("accepts data in chunks", function() {
-+    whenReceiving(["{\"testda", "ta\":\"recei", "ved\"}"]);
-+    expectRequestToEmit(function(event, data) {
-+      assert.equal("success", event);
-+      assert.equal("received", data.testdata);
-+    });
-+  });
-+
-+  it("does not covert to json if requested is different format", function() {
-+    var xml = "<somexml />";
-+    lastfm.format = "xml";
-+    whenReceiving(xml);
-+    expectRequestToEmit(function(event, data) {
-+      assert.equal(xml, data);
-+    });
-+  });
-+
-+  function whenReceiving(data) {
-+      if (data.constructor.name !== 'Array') {
-+          data = [data];
-+      }
-+      receivedData = data;
-+  }
-+
-+  function expectRequestToEmit(expectation) {
-+    var response = new fakes.ClientResponse();
-+    gently.expect(GENTLY_HIJACK.hijacked.http, "request", function(options, cb) {
-+      cb(response);
-+      return request;
-+    });
-+    var lastfmRequest = new LastFmRequest(lastfm);
-+    gently.expect(lastfmRequest, "emit", expectation);
-+    _(receivedData).each(function(data) {
-+      response.emit("data", data);
-+    });
-+    response.emit("end");
-+  }
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-session-deprecatedflow-test.js
-@@ -0,0 +1,254 @@
-+require('./common.js');
-+var LastFmSession = require('../lib/lastfm/lastfm-session');
-+var fakes = require("./fakes");
-+
-+
-+(function() {
-+  describe("a new LastFmSession");
-+  var session;
-+
-+  before(function() {
-+     session = new LastFmSession(new LastFmNode());
-+  });
-+
-+  it("has no session key", function() {
-+    assert.ok(!session.key);
-+  });
-+
-+  it("has no user", function() {
-+    assert.ok(!session.user);
-+  });
-+
-+  it("is not authorised", function() {
-+    assert.ok(!session.isAuthorised());
-+  });
-+
-+  it("can configure key and user", function() {
-+    var session = new LastFmSession(new LastFmNode(), "user", "sessionkey");
-+    assert.equal("user", session.user);
-+    assert.equal("sessionkey", session.key);
-+  });
-+
-+  it("is authorised when it has a key", function() {
-+    var session = new LastFmSession(new LastFmNode(), "user", "sessionkey");
-+    assert.ok(session.isAuthorised());
-+  });
-+})();
-+
-+(function() {
-+  var readError, token, returndata, options, request, lastfm, session, gently;
-+
-+  function setupFixture() {
-+    readError = "";
-+    token = "";
-+    returndata = null;
-+    options = null;
-+    request = new fakes.LastFmRequest();
-+    lastfm = new LastFmNode();
-+    session = new LastFmSession(lastfm);
-+    gently = new Gently();
-+    LastFmSession.prototype.scheduleCallback = emptyFn;
-+  }
-+
-+  function expectError(message) {
-+    gently.expect(session, "emit", function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal(message, error.message);
-+    });
-+    doRequest();
-+  }
-+
-+  function doRequest() {
-+    session.authorise(token, options);
-+    if (readError) {
-+      request.emit("error", readError);
-+    }
-+    else {
-+      request.emit("success", returndata);
-+    }
-+  }
-+
-+  function doNotExpectError() {
-+    doRequest();
-+  }
-+
-+  function expectRetry(retry) {
-+    gently.expect(session, "emit", function(event, details) {
-+      assert.equal("retrying", event);
-+      if (retry) {
-+        assert.deepEqual(details, retry);
-+      }
-+    });
-+    doRequest();
-+  }
-+
-+  function expectAuthorisation(assertions) {
-+    gently.expect(session, "emit", function(event, emittedSession) {
-+      assert.equal("authorised", event);
-+      if (assertions) {
-+        assertions(emittedSession);
-+      }
-+    });
-+    session.authorise(token, options);
-+    request.emit("success", returndata);
-+  }
-+
-+  function whenReadRequestReturns(data) {
-+    returndata = JSON.parse(data);
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+
-+  function whenReadRequestThrowsError(code, message) {
-+    readError = {error: code, message: message };
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+  
-+  function andTokenIs(setToken) {
-+    token = setToken;
-+  }
-+
-+  function andOptionsAre(setOptions) {
-+    options = setOptions;
-+  }
-+
-+  describe("a LastFmSession authorisation request")
-+  before(function() {
-+     setupFixture();
-+  });
-+  
-+  it("emits error when no token supplied", function() {
-+    expectError("No token supplied");
-+  });
-+  
-+  it("contains supplied token", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("token", params.token);
-+      return request;
-+    });
-+    session.authorise("token");
-+  });
-+  
-+  it("uses getSession method", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("auth.getsession", method);
-+      return request;
-+    });
-+    session.authorise("token");
-+  });
-+  
-+  describe("a completed LastFmSession authorisation request")
-+  before(function() {
-+     setupFixture();
-+  });
-+  
-+  it("emits error when receiving unexpected return data", function() {
-+    whenReadRequestReturns(FakeData.SingleRecentTrack);
-+    andTokenIs("token");
-+    expectError("Unexpected error");
-+  });
-+  
-+  it("emits authorised when successful", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    andTokenIs("token");
-+    expectAuthorisation();
-+  });
-+  
-+  it("can have error handler specified with authorise call", function() {
-+    var handler = { error: function(error) { } };
-+    gently.expect(handler, "error", function(error) {
-+      assert.equal("No token supplied", error.message); 
-+    });
-+    session.authorise("", { handlers: {
-+      error: handler.error
-+    }});
-+  });
-+  
-+  it("updates session key and user when successful", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    andTokenIs("token");
-+    expectAuthorisation(function(session) {
-+      assert.equal("username", session.user);
-+      assert.equal("sessionkey", session.key);
-+      assert.ok(session.isAuthorised());
-+    });
-+  });
-+
-+  it("can have authorised handler specified with authorise call", function() {
-+    var handler = { authorised: function(session) { } };
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    gently.expect(handler, "authorised");
-+    session.authorise("token", { handlers: {
-+      authorised: handler.authorised
-+    }});
-+    request.emit("success", returndata);
-+  });
-+
-+  it("bubbles up errors", function() {
-+    var errorMessage = "Bubbled error";
-+    whenReadRequestThrowsError('any', errorMessage);
-+    andTokenIs("token");
-+    expectError(errorMessage);
-+  });
-+
-+  it("does not bubble error when not yet authorised", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    doNotExpectError();
-+  });
-+
-+  it("emits a retry event when not yet authorised", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    expectRetry({
-+        error: 14,
-+        message: "This token has not been authorised",
-+        delay: 10000
-+    });
-+  });
-+
-+  it("schedules a another request 10 seconds later when retrying", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    LastFmSession.prototype.scheduleCallback = gently.expect(function(callback, delay) {
-+      assert.equal(delay, 10000);
-+    });
-+    doRequest();
-+  });
-+
-+  it("will retry on temporarily unavailable", function() {
-+    whenReadRequestThrowsError(16, "There was a temporary error processing your request. Please try again.");
-+    andTokenIs("token");
-+    expectRetry();
-+  });
-+
-+  it("will retry on service unavailable", function() {
-+    whenReadRequestThrowsError(11, "Service temporarily unavailable.");
-+    andTokenIs("token");
-+    expectRetry();
-+  });
-+
-+  it("can have the retry interval specified", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    andOptionsAre({ retryInterval: 15000 });
-+    LastFmSession.prototype.scheduleCallback = gently.expect(function(callback, delay) {
-+      assert.equal(delay, 15000);
-+    });
-+    doRequest();
-+  });
-+
-+  it("user defined retry interval in retry event", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    andOptionsAre({ retryInterval: 15000 });
-+    expectRetry({
-+        error: 14,
-+        message: "This token has not been authorised",
-+        delay: 15000
-+    });
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-session-test.js
-@@ -0,0 +1,277 @@
-+require('./common.js');
-+var LastFmSession = require('../lib/lastfm/lastfm-session');
-+var fakes = require("./fakes");
-+
-+
-+(function() {
-+  describe("a new LastFmSession");
-+  var session;
-+
-+  before(function() {
-+     session = new LastFmSession(new LastFmNode());
-+  });
-+
-+  it("has no session key", function() {
-+    assert.ok(!session.key);
-+  });
-+
-+  it("has no user", function() {
-+    assert.ok(!session.user);
-+  });
-+
-+  it("is not authorised", function() {
-+    assert.ok(session.isAuthorised() === false);
-+  });
-+
-+  it("can configure key and user", function() {
-+    var session = new LastFmSession(new LastFmNode(), { user: "user", key: "sessionkey" });
-+    assert.equal("user", session.user);
-+    assert.equal("sessionkey", session.key);
-+  });
-+
-+  it("is authorised when it has a key", function() {
-+    var session = new LastFmSession(new LastFmNode(), { user: "user", key: "sessionkey" });
-+    assert.ok(session.isAuthorised());
-+  });
-+})();
-+
-+(function() {
-+  var readError, token, returndata, options, request, lastfm, session, gently;
-+
-+  function setupFixture() {
-+    readError = "";
-+    token = "";
-+    returndata = null;
-+    options = null;
-+    request = new fakes.LastFmRequest();
-+    lastfm = new LastFmNode();
-+    gently = new Gently();
-+    LastFmSession.prototype.scheduleCallback = emptyFn;
-+  }
-+
-+  function expectError(message) {
-+    gently.expect(session, "emit", function(event, error) {
-+      assert.equal("error", event);
-+      assert.equal(message, error.message);
-+    });
-+    doRequest();
-+  }
-+
-+  function doRequest() {
-+    if (readError) {
-+      request.emit("error", readError);
-+    }
-+    else {
-+      request.emit("success", returndata);
-+    }
-+  }
-+
-+  function doNotExpectError() {
-+    doRequest();
-+  }
-+
-+  function expectRetry(retry) {
-+    gently.expect(session, "emit", function(event, details) {
-+      assert.equal("retrying", event);
-+      if (retry) {
-+        assert.deepEqual(details, retry);
-+      }
-+    });
-+    doRequest();
-+  }
-+
-+  function doNotExpectRetry() {
-+    session.on('retrying', function() {
-+      assert.ok(false);
-+    });
-+    doRequest();
-+  }
-+
-+  function expectAuthorisation(assertions) {
-+    expectSuccess(assertions, "authorised");
-+  }
-+
-+  function expectSuccess(assertions, expectedEvent) {
-+    expectedEvent = expectedEvent || "success";
-+    gently.expect(session, "emit", function(event, emittedSession) {
-+      if (expectedEvent !== event) {
-+        return;
-+      }
-+      assert.equal(expectedEvent, event);
-+      if (assertions) {
-+        assertions(emittedSession);
-+      }
-+    });
-+    request.emit("success", returndata);
-+  }
-+
-+  function whenReadRequestReturns(data) {
-+    returndata = JSON.parse(data);
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+
-+  function whenReadRequestThrowsError(code, message) {
-+    readError = {error: code, message: message };
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+  
-+  function andTokenIs(setToken) {
-+    session = new LastFmSession(lastfm, { token: setToken });
-+  }
-+
-+  function andOptionsAre(setOptions) {
-+    session = new LastFmSession(lastfm, setOptions);
-+  }
-+
-+  describe("a LastFmSession authorisation request")
-+  before(function() {
-+     setupFixture();
-+  });
-+  
-+  it("happens when a token is provided in options", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+        assert.ok(true);
-+        return request;
-+    });
-+    session = new LastFmSession(lastfm, { token: 'token' });
-+  });
-+  
-+  it("contains supplied token", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("token", params.token);
-+      return request;
-+    });
-+    session = new LastFmSession(lastfm, { token: 'token' });
-+  });
-+  
-+  it("uses getSession method", function() {
-+    gently.expect(lastfm, "request", function(method, params) {
-+      assert.equal("auth.getsession", method);
-+      return request;
-+    });
-+    session = new LastFmSession(lastfm, { token: 'token' });
-+  });
-+  
-+  describe("a completed LastFmSession authorisation request")
-+  before(function() {
-+     setupFixture();
-+  });
-+  
-+  it("emits error when receiving unexpected return data", function() {
-+    whenReadRequestReturns(FakeData.SingleRecentTrack);
-+    andTokenIs("token");
-+    expectError("Unexpected error");
-+  });
-+  
-+  it("emits authorised when successful", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    andTokenIs("token");
-+    expectAuthorisation();
-+  });
-+  
-+  it("emits success when authorisation successful", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    andTokenIs("token");
-+    expectSuccess();
-+  });
-+  
-+  it("can have error handler specified in options", function() {
-+    whenReadRequestThrowsError('any', 'error');
-+    session = new LastFmSession(lastfm, { token: 'token', handlers: {
-+      error: gently.expect(function error() { })
-+    }});
-+    doRequest();
-+  });
-+  
-+  it("updates session key and user when successful", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    andTokenIs("token");
-+    expectAuthorisation(function(session) {
-+      assert.equal("username", session.user);
-+      assert.equal("sessionkey", session.key);
-+      assert.ok(session.isAuthorised());
-+    });
-+  });
-+
-+  it("can have authorised handler specified with authorise call", function() {
-+    whenReadRequestReturns(FakeData.SuccessfulAuthorisation);
-+    session = new LastFmSession(lastfm, { token: 'token', handlers: {
-+      authorised: gently.expect(function error() { })
-+    }});
-+    request.emit("success", returndata);
-+  });
-+
-+  it("bubbles up errors", function() {
-+    var errorMessage = "Bubbled error";
-+    whenReadRequestThrowsError('any', errorMessage);
-+    andTokenIs("token");
-+    expectError(errorMessage);
-+  });
-+
-+  it("does not bubble error when not yet authorised", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    doNotExpectError();
-+  });
-+
-+  it("emits a retry event when not yet authorised", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    expectRetry({
-+        error: 14,
-+        message: "This token has not been authorised",
-+        delay: 10000
-+    });
-+  });
-+
-+  it("schedules a another request 10 seconds later when retrying", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    LastFmSession.prototype.scheduleCallback = gently.expect(function(callback, delay) {
-+      assert.equal(delay, 10000);
-+    });
-+    doRequest();
-+  });
-+
-+  it("will retry on temporarily unavailable", function() {
-+    whenReadRequestThrowsError(16, "There was a temporary error processing your request. Please try again.");
-+    andTokenIs("token");
-+    expectRetry();
-+  });
-+
-+  it("will retry on service unavailable", function() {
-+    whenReadRequestThrowsError(11, "Service temporarily unavailable.");
-+    andTokenIs("token");
-+    expectRetry();
-+  });
-+
-+  it("can have the retry interval specified", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andOptionsAre({ token: 'token', retryInterval: 15000 });
-+    LastFmSession.prototype.scheduleCallback = gently.expect(function(callback, delay) {
-+      assert.equal(delay, 15000);
-+    });
-+    doRequest();
-+  });
-+
-+  it("user defined retry interval in retry event", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andOptionsAre({ token: 'token', retryInterval: 15000 });
-+    expectRetry({
-+        error: 14,
-+        message: "This token has not been authorised",
-+        delay: 15000
-+    });
-+  });
-+
-+  it("can cancel retries", function() {
-+    whenReadRequestThrowsError(14, "This token has not been authorised");
-+    andTokenIs("token");
-+    session.cancel();
-+    doNotExpectRetry();
-+  });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/lastfm-update-test.js
-@@ -0,0 +1,485 @@
-+require('./common.js');
-+var LastFmSession = require('../lib/lastfm/lastfm-session');
-+var LastFmUpdate = require('../lib/lastfm/lastfm-update');
-+var fakes = require("./fakes");
-+
-+(function() {
-+  describe("new LastFmUpdate")
-+    it("can have success and error handlers specified in option at creation", function() {
-+      var gently = new Gently();
-+      var lastfm = new LastFmNode();
-+      var update = new LastFmUpdate(lastfm, "method", new LastFmSession(lastfm, "user", "key"), { handlers: {
-+          error: gently.expect(function error() {}),
-+          success: gently.expect(function success() {})
-+      }});
-+      update.emit("error");
-+      update.emit("success");
-+    });
-+})();
-+
-+(function() {
-+  var request, returndata, options, session, method, gently, lastfm, authorisedSession, errorCode, errorMessage, update;
-+
-+  function setupFixture() {
-+    request = new fakes.LastFmRequest();
-+    returndata;
-+    options = {};
-+    session = null;
-+    method = "";
-+    gently = new Gently();
-+    lastfm = new LastFmNode();
-+    authorisedSession = new LastFmSession(lastfm, "user", "key");
-+    errorCode = -1;
-+    errorMessage = null;
-+    update = undefined;
-+  }
-+
-+  function whenRequestReturns(data) {
-+    errorCode = -1;
-+    errorMessage = null;
-+    returndata = JSON.parse(data);
-+    request = new fakes.LastFmRequest();
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+
-+  function whenRequestThrowsError(code, message) {
-+    errorCode = code;
-+    errorMessage = message;
-+    request = new fakes.LastFmRequest();
-+    gently.expect(lastfm, "request", function() {
-+      return request;
-+    });
-+  }
-+
-+  function andOptionsAre(setOptions) {
-+    options = setOptions;
-+  }
-+
-+  function andMethodIs(setMethod) {
-+    method = setMethod;
-+  }
-+
-+  function andSessionIs(setSession) {
-+    session = setSession;
-+  }
-+
-+  function expectSuccess(assertions) {
-+    var checkSuccess = function(track) {
-+      if (assertions) {
-+        assertions(track);
-+      }
-+    };
-+    if (update) {
-+      update.on("success", checkSuccess);
-+    }
-+    else {
-+      options.handlers = options.handlers || {};
-+      options.handlers.success = checkSuccess;
-+    }
-+    doUpdate();
-+  }
-+
-+  function expectError(errorCode, expectedError) {
-+    var checkError = function(error) {
-+      if (errorCode || expectedError) {
-+        assert.equal(expectedError, error.message);
-+        assert.equal(errorCode, error.error);
-+      }
-+    };
-+    if (update) {
-+      update.on("error", checkError);
-+    }
-+    else {
-+      options.handlers = options.handlers || {};
-+      options.handlers.error = gently.expect(checkError);
-+    }
-+    doUpdate();
-+  }
-+
-+  function doNotExpectError() {
-+    options.handlers = options.handlers || {};
-+    options.handlers.error = function checkNoErrorThrown(error) {
-+      assert.ok(false);
-+    };
-+    doUpdate();
-+  }
-+
-+  function expectRetry(callback) {
-+    callback = callback || function() { };
-+    if (update) {
-+      gently.expect(update, "emit", function(event, retry) {
-+        assert.equal(event, "retrying");
-+        callback(retry);
-+      });
-+    }
-+    else {
-+      options.handlers = options.handlers || { };
-+      options.handlers.retrying = gently.expect(callback);
-+    }
-+    doUpdate();
-+  }
-+
-+  function doUpdate() {
-+    update = update || new LastFmUpdate(lastfm, method, session, options);
-+    if (errorMessage) {
-+      request.emit("error", { error: errorCode, message: errorMessage });
-+    }
-+    else {
-+      request.emit("success", returndata);
-+    }
-+  }
-+
-+  describe("update requests")
-+    before(function() {
-+      setupFixture();
-+    });
-+  
-+    it("fail when the session is not authorised", function() {
-+      var session = new LastFmSession()
-+        , update = new LastFmUpdate(lastfm, "method", session, {
-+            handlers: {
-+              error: gently.expect(function(error) {
-+                assert.equal(error.error, 4);
-+                assert.equal(error.message, "Authentication failed");
-+              })
-+            }
-+          });
-+    });
-+  
-+  describe("nowPlaying updates")
-+    before(function() {
-+      setupFixture();
-+    });
-+  
-+    it("uses updateNowPlaying method", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal("track.updateNowPlaying", method);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "nowplaying", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave
-+      });
-+    });
-+    
-+    it("sends required parameters", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal(FakeTracks.RunToYourGrave, params.track);
-+        assert.equal("key", params.sk);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "nowplaying", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave
-+      });
-+    });
-+  
-+    it("emits success when updated", function() {
-+      whenRequestReturns(FakeData.UpdateNowPlayingSuccess);
-+      andMethodIs("nowplaying");
-+      andSessionIs(authorisedSession);
-+      andOptionsAre({
-+        track: FakeTracks.RunToYourGrave
-+      });
-+      expectSuccess(function(track) {
-+        assert.equal("Run To Your Grave", track.name);
-+      });
-+    });
-+  
-+    it("sends duration when supplied", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal(232000, params.duration);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "nowplaying", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave,
-+        duration: 232000
-+      });
-+    });
-+
-+    it("can have artist and track string parameters supplied", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal("The Mae Shi", params.artist);
-+        assert.equal("Run To Your Grave", params.track);
-+        assert.equal("key", params.sk);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "nowplaying", authorisedSession, {
-+        track: "Run To Your Grave",
-+        artist: "The Mae Shi"
-+      });
-+    });
-+  
-+    it("bubbles up errors", function() {
-+      var errorMessage = "Bubbled error";
-+      whenRequestThrowsError(100, errorMessage);
-+      andMethodIs("nowplaying");
-+      andSessionIs(authorisedSession);
-+      andOptionsAre({
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+      expectError(100, errorMessage);
-+    });
-+  
-+  describe("a scrobble request")
-+    before(function() {
-+      setupFixture();
-+    });
-+  
-+    it("emits error when no timestamp supplied", function() {
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave,
-+        handlers: {
-+          error: gently.expect(function error(error) {
-+            assert.equal(6, error.error);
-+            assert.equal("Invalid parameters - Timestamp is required for scrobbling", error.message);
-+          })
-+        }
-+      });
-+    });
-+    
-+    it("uses scrobble method", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal("track.scrobble", method);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+    });
-+  
-+    it("sends required parameters", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal(FakeTracks.RunToYourGrave, params.track);
-+        assert.equal("key", params.sk);
-+        assert.equal(12345678, params.timestamp);
-+        return request;
-+      });
-+  
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+    });
-+  
-+    it("emits success when updated", function() {
-+      whenRequestReturns(FakeData.ScrobbleSuccess);
-+      andMethodIs("scrobble");
-+      andSessionIs(authorisedSession);
-+      andOptionsAre({
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+      expectSuccess(function(track) {
-+        assert.equal("Run To Your Grave", track.name);
-+      });
-+    });
-+  
-+    it("bubbles up errors", function() {
-+      var errorMessage = "Bubbled error";
-+      whenRequestThrowsError(100, errorMessage);
-+      andMethodIs("scrobble");
-+      andSessionIs(authorisedSession);
-+      andOptionsAre({
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+      expectError(100, errorMessage);
-+    });
-+
-+    it("can have artist and track string parameters supplied", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal("The Mae Shi", params.artist);
-+        assert.equal("Run To Your Grave", params.track);
-+        assert.equal("key", params.sk);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: "Run To Your Grave",
-+        artist: "The Mae Shi",
-+        timestamp: 12345678
-+      });
-+    });
-+
-+    it("can have arbitrary parameters supplied", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal("somevalue", params.arbitrary);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: "Run To Your Grave",
-+        artist: "The Mae Shi",
-+        timestamp: 12345678,
-+        arbitrary: "somevalue"
-+      });
-+    });
-+
-+    it("does not include handler parameters", function() {
-+      gently.expect(lastfm, "request", function(method, params) {
-+        assert.equal(undefined, params.handlers);
-+        assert.equal(undefined, params.error);
-+        assert.equal(undefined, params.success);
-+        return request;
-+      });
-+      new LastFmUpdate(lastfm, "scrobble", authorisedSession, {
-+        track: "Run To Your Grave",
-+        artist: "The Mae Shi",
-+        timestamp: 12345678,
-+        handlers: { success: function() { } },
-+        success: function() { },
-+        error: function() { }
-+      });
-+    });
-+
-+  var tmpFn;
-+  describe("update retries")
-+    before(function() {
-+      tmpFn = LastFmUpdate.prototype.scheduleCallback;
-+      LastFmUpdate.prototype.scheduleCallback = function(callback, delay) { };
-+      setupFixture();
-+      andMethodIs("scrobble");
-+      andSessionIs(authorisedSession);
-+      andOptionsAre({
-+        track: FakeTracks.RunToYourGrave,
-+        timestamp: 12345678
-+      });
-+    });
-+  
-+    after(function() {
-+      LastFmUpdate.prototype.scheduleCallback = tmpFn;
-+    });
-+
-+    it("a error which should trigger a retry does not bubble errors", function() {
-+      whenRequestThrowsError(11, "Service Offline");
-+      doNotExpectError();
-+    });
-+  
-+    it("service offline triggers a retry", function() {
-+      whenRequestThrowsError(11, "Service Offline");
-+      expectRetry();
-+    });
-+  
-+    it("rate limit exceeded triggers a retry", function() {
-+      whenRequestThrowsError(29, "Rate limit exceeded");
-+      expectRetry();
-+    });
-+  
-+    it("temporarily unavailable triggers a retry", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      expectRetry();
-+    });
-+
-+    it("nowplaying update never trigger retries", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      andMethodIs("nowplaying");
-+      expectError();
-+    });
-+
-+    it("first retry schedules a request after a 10 second delay", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      LastFmUpdate.prototype.scheduleCallback = gently.expect(function testSchedule(callback, delay) {
-+          assert.equal(delay, 10000);
-+      });
-+      doUpdate();
-+    });
-+
-+    function onNextRequests(callback, count) {
-+      count = count || 1;
-+      var gently = new Gently();
-+      LastFmUpdate.prototype.scheduleCallback = gently.expect(count, callback);
-+      doUpdate();
-+    }
-+
-+    function lastRequest() {
-+      LastFmUpdate.prototype.scheduleCallback = function() { };
-+    }
-+
-+    function whenNextRequestThrowsError(request, code, message) {
-+      whenRequestThrowsError(code, message);
-+      request();
-+    }
-+
-+    function whenNextRequestReturns(request, data) {
-+      whenRequestReturns(data);
-+      request();
-+    }
-+
-+    it("retry triggers another request", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      onNextRequests(function(nextRequest) {
-+        lastRequest();
-+        whenNextRequestThrowsError(nextRequest, 16, "Temporarily unavailable");
-+        expectRetry();
-+      });
-+    });
-+
-+    it("emits succes if retry is successful", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      onNextRequests(function(nextRequest) {
-+        whenNextRequestReturns(nextRequest, FakeData.ScrobbleSuccess);
-+        expectSuccess(function(track) {
-+          assert.equal("Run To Your Grave", track.name);
-+        });
-+      });
-+    });
-+
-+    it("emits succes if retry is non-retry error", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      onNextRequests(function(nextRequest) {
-+        whenNextRequestThrowsError(nextRequest, 6, "Invalid parameter");
-+        expectError(6, "Invalid parameter");
-+      });
-+    });
-+
-+    it("retrying events include error received and delay details", function() {
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      expectRetry(function(retry) {
-+          assert.equal(retry.delay, 10000);
-+          assert.equal(retry.error, 16);
-+          assert.equal(retry.message, "Temporarily unavailable");
-+      });
-+    });
-+
-+    var retrySchedule = [
-+      10 * 1000,
-+      30 * 1000,
-+      60 * 1000,
-+      5 * 60 * 1000,
-+      15 * 60 * 1000,
-+      30 * 60 * 1000,
-+      30 * 60 * 1000,
-+      30 * 60 * 1000
-+    ];
-+
-+    it("follows a retry schedule on subsequent failures", function() {
-+      var count = 0;
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      onNextRequests(function(nextRequest, delay) {
-+        var expectedDelay = retrySchedule[count++];
-+        assert.equal(delay, expectedDelay);
-+        if (count >= retrySchedule.length) {
-+          lastRequest();
-+        }
-+        whenNextRequestThrowsError(nextRequest, 16, "Temporarily unavailable");
-+        expectRetry();
-+      }, retrySchedule.length);
-+    });
-+
-+    it("includes delay in subsequent retry events", function() {
-+      var count = 0;
-+      whenRequestThrowsError(16, "Temporarily unavailable");
-+      onNextRequests(function(nextRequest, delay) {
-+        count++;
-+        if (count >= retrySchedule.length) {
-+          lastRequest();
-+        }
-+        var expectedDelay = retrySchedule[Math.min(count, retrySchedule.length - 1)];
-+        whenNextRequestThrowsError(nextRequest, 16, "Temporarily unavailable");
-+        expectRetry(function(retry) {
-+          assert.equal(retry.delay, expectedDelay);
-+        });
-+      }, retrySchedule.length);
-+    });
-+})();
---- /dev/null
-+++ groovebasin-1.2.0/bundled_node_modules/lastfm/tests/tests.sh
-@@ -0,0 +1,16 @@
-+#!/bin/bash
-+. ~/.nvm/nvm.sh
-+nvm use v0.2.6
-+node ./index.js
-+nvm use v0.3.3
-+node ./index.js
-+nvm use v0.4.0
-+node ./index.js
-+nvm use v0.4.3
-+node ./index.js
-+nvm use v0.4.7
-+node ./index.js
-+nvm use v0.4.8
-+node ./index.js
-+nvm use v0.6.2
-+node ./index.js
---- /dev/null
-+++ groovebasin-1.2.0/public/app.css
-@@ -0,0 +1,15 @@
-+/*
-+YUI 3.4.1 (build 4118)
-+Copyright 2011 Yahoo! Inc. All rights reserved.
-+Licensed under the BSD License.
-+http://yuilibrary.com/license/
-+*/
-+html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{*font-size:100%}legend{color:#000}
-+/*! jQuery UI - v1.10.4 - 2014-03-04
-+* http://jqueryui.com
-+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
-+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2Csans-serif&fwDefault=bold&fsDefault=1.3em&cornerRadius=4px&bgColorHeader=0b3e6f&bgTextureHeader=diagonals_thick&bgImgOpacityHeader=15&borderColorHeader=0b3e6f&fcHeader=f6f6f6&iconColorHeader=98d2fb&bgColorContent=111111&bgTextureContent=gloss_wave&bgImgOpacityContent=20&borderColorContent=000000&fcContent=d9d9d9&iconColorContent=9ccdfc&bgColorDefault=333333&bgTextureDefault=dots_small&bgImgOpacityDefault=20&borderColorDefault=333333&fcDefault=ffffff&iconColorDefault=9ccdfc&bgColorHover=00498f&bgTextureHover=dots_small&bgImgOpacityHover=40&borderColorHover=222222&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=292929&bgTextureActive=flat&bgImgOpacityActive=40&borderColorActive=096ac8&fcActive=75abff&iconColorActive=00498f&bgColorHighlight=0b58a2&bgTextureHighlight=dots_medium&bgImgOpacityHighlight=30&borderColorHighlight=052f57&fcHighlight=ffffff&iconColorHighlight=ffffff&bgColorError=a32d00&bgTextureError=dots_small&bgImgOpacityError=30&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffffff&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
-+* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
-+
-+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,sans-serif;font-size:1.3em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #000;background:#111 url(images/ui-bg_gloss-wave_20_111111_500x100.png) 50% top repeat-x;color:#d9d9d9}.ui-widget-content a{color:#d9d9d9}.ui-widget-header{border:1px solid #0b3e6f;background:#0b3e6f url(images/ui-bg_diagonals-thick_15_0b3e6f_40x40.png) 50% 50% repeat;color:#f6f6f6;font-weight:bold}.ui-widget-header a{color:#f6f6f6}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #333;background:#333 url(images/ui-bg_dots-small_20_333333_2x2.png) 50% 50% repeat;font-weight:bold;color:#fff}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#fff;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #222;background:#00498f url(images/ui-bg_dots-small_40_00498f_2x2.png) 50% 50% repeat;font-weight:bold;color:#fff}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#fff;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #096ac8;background:#292929 url(images/ui-bg_flat_40_292929_40x100.png) 50% 50% repeat-x;font-weight:bold;color:#75abff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#75abff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #052f57;background:#0b58a2 url(images/ui-bg_dots-medium_30_0b58a2_4x4.png) 50% 50% repeat;color:#fff}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#fff}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#a32d00 url(images/ui-bg_dots-small_30_a32d00_2x2.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_9ccdfc_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_98d2fb_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_9ccdfc_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_00498f_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
-+html{background:url("images/ui-bg_diagonals-thick_15_0b3e6f_40x40.png")}html.groovebasin{background:url("img/groovebasin.jpg")}html.nggyu{background:url("img/nggyu.jpg")}body{font-family:Arial,Helvetica,sans-serif}a:hover,a:active,a:focus{outline:0}#track-slider{margin:10px 10px 5px;background:url("img/bright-10.png") left no-repeat;background-size:0% 100%}#nowplaying{margin:6px auto;text-align:center;}#nowplaying .playback-btns{float:left;}#nowplaying .playback-btns li{cursor:pointer;float:left;list-style:none outside none;margin:2px;padding:4px}#nowplaying h1{letter-spacing:.1em;margin-top:8px;font-weight:bold}#nowplaying .time{margin:4px;font-weight:bold;font-family:monospace}#nowplaying .left{float:right}#nowplaying .elapsed{float:left}#vol{margin:10px;}#vol span{float:left;margin:-2px 2px 0 10px}#vol-slider{float:left;width:60px;height:10px;}#vol-slider .ui-slider-handle{height:16px;width:16px;margin-top:2px}#more-playback-btns{float:left;font-size:.6em;margin:-8px 0 0 8px}#left-window{width:400px;position:absolute}#library-pane .window-header{height:30px}#tabs{-moz-user-select:none;-khtml-user-select:none;user-select:none;}#tabs ul{margin-bottom:-1px;}#tabs ul li{display:inline;cursor:pointer}#tabs ul li span{font-size:.625em;padding:2px 4px;font-weight:normal}#library,#playlists{overflow-y:auto;-moz-user-select:none;-khtml-user-select:none;user-select:none;cursor:default;}#library div.ui-icon,#playlists div.ui-icon{float:left}#library p,#playlists p{text-align:center;margin:20px auto 0;padding:4px;width:150px;}#library p span,#playlists p span{float:left;margin-right:.3em}#library p strong,#playlists p strong{font-weight:bold}#library ul ul,#playlists ul ul{margin-left:9px;}#library ul ul ul,#playlists ul ul ul{margin-left:16px}#library ul div.selected,#playlists ul div.selected{background:#00498f url("images/ui-bg_dots-small_40_00498f_2x2.png") 50% 50% repeat;color:#fff}#library ul div.cursor,#playlists ul div.cursor{text-decoration:underline}#lib-filter{margin:4px;width:175px}#user-id{cursor:pointer}#organize{width:200px}#queue-window{width:700px;position:absolute;}#queue-window .window-header{margin-bottom:4px;font-size:.6em}#queue-list .header{font-weight:bold;overflow-x:hidden;overflow-y:hidden;height:1.2em}#queue-list span.track{width:26px}#queue-list span.title{width:30%}#queue-list span.artist{width:30%}#queue-list span.album{width:30%}#queue-list span.time{width:36px}#queue-list span{white-space:nowrap;height:1.2em;overflow-x:hidden;overflow-y:hidden;float:left;margin-right:4px}#queue-items{overflow-y:auto;overflow-x:hidden;clear:both;width:100%;-moz-user-select:none;-khtml-user-select:none;user-select:none;}#queue-items div{clear:both;overflow-x:hidden;overflow-y:hidden;height:1.2em;cursor:default}#queue-items div:nth-child(2n+1){background-color:#2a2a2a}#queue-items div.random{color:#96b7eb}#queue-items div.old{color:#555}#queue-items div.selected{background:#00498f url("images/ui-bg_dots-small_40_00498f_2x2.png") 50% 50% repeat;color:#fff}#queue-items div.current{border:1px solid #096ac8;background-color:#292929;font-weight:bold;color:#75abff}#queue-items div.cursor span{text-decoration:underline}#queue-items div.border-bottom{border-bottom:2px dashed #fff}#queue-items div.border-top{border-top:2px dashed #fff}#queue-items span.track{text-align:right}#queue-items span.time{text-align:right}#upload{overflow-y:auto}#upload-widget{padding:10px}#upload-by-url{margin:4px;width:90%}.ui-menu{width:240px;font-size:1em}#menu-library .ui-state-disabled.ui-state-focus,#menu-queue .ui-state-disabled.ui-state-focus{margin:.3em -1px .2em}#shortcuts h1{margin-bottom:10px;margin-top:10px;font-weight:bold}#shortcuts dl{font-size:.8em;margin-bottom:4px;}#shortcuts dl dt{font-family:monospace;display:inline;padding:3px;background-color:#272727;font-weight:bold;text-shadow:1px 1px 0 #000;-moz-border-radius:4px;-webkit-border-radius:4px;-khtml-border-radius:4px;border-radius:4px;}#shortcuts dl dt em{font-weight:normal;color:#afafaf;text-shadow:none}#shortcuts dl dd{display:inline}#main-err-msg{margin:200px auto;width:300px;padding:4px;}#main-err-msg span{float:left;margin-right:.3em}#main-err-msg strong{font-weight:bold}#settings{padding:6px;}#settings .section{margin-bottom:14px;}#settings .section h1{font-weight:bold;font-size:1.4em}#settings .section h2{font-size:1.1em;font-weight:bold}#settings .section button,#settings .section label{font-size:.8em}#settings .section em{font-style:italic}#settings .section ul{font-size:.9em;}#settings .section ul li:before{content:"\2713"}.accesskey{text-decoration:underline}
-\ No newline at end of file
---- /dev/null
-+++ groovebasin-1.2.0/public/app.js
-@@ -0,0 +1,10670 @@
-+(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){
-+/*!
-+ * The buffer module from node.js, for the browser.
-+ *
-+ * @author   Feross Aboukhadijeh <feross at feross.org> <http://feross.org>
-+ * @license  MIT
-+ */
-+
-+var base64 = require('base64-js')
-+var ieee754 = require('ieee754')
-+
-+exports.Buffer = Buffer
-+exports.SlowBuffer = Buffer
-+exports.INSPECT_MAX_BYTES = 50
-+Buffer.poolSize = 8192
-+
-+/**
-+ * If `Buffer._useTypedArrays`:
-+ *   === true    Use Uint8Array implementation (fastest)
-+ *   === false   Use Object implementation (compatible down to IE6)
-+ */
-+Buffer._useTypedArrays = (function () {
-+  // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,
-+  // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding
-+  // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support
-+  // because we need to be able to add all the node Buffer API methods. This is an issue
-+  // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438
-+  try {
-+    var buf = new ArrayBuffer(0)
-+    var arr = new Uint8Array(buf)
-+    arr.foo = function () { return 42 }
-+    return 42 === arr.foo() &&
-+        typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`
-+  } catch (e) {
-+    return false
-+  }
-+})()
-+
-+/**
-+ * 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 (subject, encoding, noZero) {
-+  if (!(this instanceof Buffer))
-+    return new Buffer(subject, encoding, noZero)
-+
-+  var type = typeof subject
-+
-+  if (encoding === 'base64' && type === 'string') {
-+    subject = base64clean(subject)
-+  }
-+
-+  // Find the length
-+  var length
-+  if (type === 'number')
-+    length = coerce(subject)
-+  else if (type === 'string')
-+    length = Buffer.byteLength(subject, encoding)
-+  else if (type === 'object')
-+    length = coerce(subject.length) // assume that object is array-like
-+  else
-+    throw new Error('First argument needs to be a number, array or string.')
-+
-+  var buf
-+  if (Buffer._useTypedArrays) {
-+    // Preferred: Return an augmented `Uint8Array` instance for best performance
-+    buf = Buffer._augment(new Uint8Array(length))
-+  } else {
-+    // Fallback: Return THIS instance of Buffer (created by `new`)
-+    buf = this
-+    buf.length = length
-+    buf._isBuffer = true
-+  }
-+
-+  var i
-+  if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {
-+    // Speed optimization -- use set if we're copying from a typed array
-+    buf._set(subject)
-+  } else if (isArrayish(subject)) {
-+    // Treat array-ish objects as a byte array
-+    if (Buffer.isBuffer(subject)) {
-+      for (i = 0; i < length; i++)
-+        buf[i] = subject.readUInt8(i)
-+    } else {
-+      for (i = 0; i < length; i++)
-+        buf[i] = ((subject[i] % 256) + 256) % 256
-+    }
-+  } else if (type === 'string') {
-+    buf.write(subject, 0, encoding)
-+  } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {
-+    for (i = 0; i < length; i++) {
-+      buf[i] = 0
-+    }
-+  }
-+
-+  return buf
-+}
-+
-+// STATIC METHODS
-+// ==============
-+
-+Buffer.isEncoding = function (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.isBuffer = function (b) {
-+  return !!(b !== null && b !== undefined && b._isBuffer)
-+}
-+
-+Buffer.byteLength = function (str, encoding) {
-+  var ret
-+  str = str.toString()
-+  switch (encoding || 'utf8') {
-+    case 'hex':
-+      ret = str.length / 2
-+      break
-+    case 'utf8':
-+    case 'utf-8':
-+      ret = utf8ToBytes(str).length
-+      break
-+    case 'ascii':
-+    case 'binary':
-+    case 'raw':
-+      ret = str.length
-+      break
-+    case 'base64':
-+      ret = base64ToBytes(str).length
-+      break
-+    case 'ucs2':
-+    case 'ucs-2':
-+    case 'utf16le':
-+    case 'utf-16le':
-+      ret = str.length * 2
-+      break
-+    default:
-+      throw new Error('Unknown encoding')
-+  }
-+  return ret
-+}
-+
-+Buffer.concat = function (list, totalLength) {
-+  assert(isArray(list), 'Usage: Buffer.concat(list[, length])')
-+
-+  if (list.length === 0) {
-+    return new Buffer(0)
-+  } else if (list.length === 1) {
-+    return list[0]
-+  }
-+
-+  var i
-+  if (totalLength === undefined) {
-+    totalLength = 0
-+    for (i = 0; i < list.length; i++) {
-+      totalLength += list[i].length
-+    }
-+  }
-+
-+  var buf = new Buffer(totalLength)
-+  var pos = 0
-+  for (i = 0; i < list.length; i++) {
-+    var item = list[i]
-+    item.copy(buf, pos)
-+    pos += item.length
-+  }
-+  return buf
-+}
-+
-+Buffer.compare = function (a, b) {
-+  assert(Buffer.isBuffer(a) && Buffer.isBuffer(b), 'Arguments must be Buffers')
-+  var x = a.length
-+  var y = b.length
-+  for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
-+  if (i !== len) {
-+    x = a[i]
-+    y = b[i]
-+  }
-+  if (x < y) {
-+    return -1
-+  }
-+  if (y < x) {
-+    return 1
-+  }
-+  return 0
-+}
-+
-+// BUFFER INSTANCE METHODS
-+// =======================
-+
-+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
-+  assert(strLen % 2 === 0, 'Invalid hex string')
-+
-+  if (length > strLen / 2) {
-+    length = strLen / 2
-+  }
-+  for (var i = 0; i < length; i++) {
-+    var byte = parseInt(string.substr(i * 2, 2), 16)
-+    assert(!isNaN(byte), 'Invalid hex string')
-+    buf[offset + i] = byte
-+  }
-+  return i
-+}
-+
-+function utf8Write (buf, string, offset, length) {
-+  var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length)
-+  return charsWritten
-+}
-+
-+function asciiWrite (buf, string, offset, length) {
-+  var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
-+  return charsWritten
-+}
-+
-+function binaryWrite (buf, string, offset, length) {
-+  return asciiWrite(buf, string, offset, length)
-+}
-+
-+function base64Write (buf, string, offset, length) {
-+  var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
-+  return charsWritten
-+}
-+
-+function utf16leWrite (buf, string, offset, length) {
-+  var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length)
-+  return charsWritten
-+}
-+
-+Buffer.prototype.write = function (string, offset, length, encoding) {
-+  // Support both (string, offset, length, encoding)
-+  // and the legacy (string, encoding, offset, length)
-+  if (isFinite(offset)) {
-+    if (!isFinite(length)) {
-+      encoding = length
-+      length = undefined
-+    }
-+  } else {  // legacy
-+    var swap = encoding
-+    encoding = offset
-+    offset = length
-+    length = swap
-+  }
-+
-+  offset = Number(offset) || 0
-+  var remaining = this.length - offset
-+  if (!length) {
-+    length = remaining
-+  } else {
-+    length = Number(length)
-+    if (length > remaining) {
-+      length = remaining
-+    }
-+  }
-+  encoding = String(encoding || 'utf8').toLowerCase()
-+
-+  var ret
-+  switch (encoding) {
-+    case 'hex':
-+      ret = hexWrite(this, string, offset, length)
-+      break
-+    case 'utf8':
-+    case 'utf-8':
-+      ret = utf8Write(this, string, offset, length)
-+      break
-+    case 'ascii':
-+      ret = asciiWrite(this, string, offset, length)
-+      break
-+    case 'binary':
-+      ret = binaryWrite(this, string, offset, length)
-+      break
-+    case 'base64':
-+      ret = base64Write(this, string, offset, length)
-+      break
-+    case 'ucs2':
-+    case 'ucs-2':
-+    case 'utf16le':
-+    case 'utf-16le':
-+      ret = utf16leWrite(this, string, offset, length)
-+      break
-+    default:
-+      throw new Error('Unknown encoding')
-+  }
-+  return ret
-+}
-+
-+Buffer.prototype.toString = function (encoding, start, end) {
-+  var self = this
-+
-+  encoding = String(encoding || 'utf8').toLowerCase()
-+  start = Number(start) || 0
-+  end = (end === undefined) ? self.length : Number(end)
-+
-+  // Fastpath empty strings
-+  if (end === start)
-+    return ''
-+
-+  var ret
-+  switch (encoding) {
-+    case 'hex':
-+      ret = hexSlice(self, start, end)
-+      break
-+    case 'utf8':
-+    case 'utf-8':
-+      ret = utf8Slice(self, start, end)
-+      break
-+    case 'ascii':
-+      ret = asciiSlice(self, start, end)
-+      break
-+    case 'binary':
-+      ret = binarySlice(self, start, end)
-+      break
-+    case 'base64':
-+      ret = base64Slice(self, start, end)
-+      break
-+    case 'ucs2':
-+    case 'ucs-2':
-+    case 'utf16le':
-+    case 'utf-16le':
-+      ret = utf16leSlice(self, start, end)
-+      break
-+    default:
-+      throw new Error('Unknown encoding')
-+  }
-+  return ret
-+}
-+
-+Buffer.prototype.toJSON = function () {
-+  return {
-+    type: 'Buffer',
-+    data: Array.prototype.slice.call(this._arr || this, 0)
-+  }
-+}
-+
-+Buffer.prototype.equals = function (b) {
-+  assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
-+  return Buffer.compare(this, b) === 0
-+}
-+
-+Buffer.prototype.compare = function (b) {
-+  assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
-+  return Buffer.compare(this, b)
-+}
-+
-+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
-+Buffer.prototype.copy = function (target, target_start, start, end) {
-+  var source = this
-+
-+  if (!start) start = 0
-+  if (!end && end !== 0) end = this.length
-+  if (!target_start) target_start = 0
-+
-+  // Copy 0 bytes; we're done
-+  if (end === start) return
-+  if (target.length === 0 || source.length === 0) return
-+
-+  // Fatal error conditions
-+  assert(end >= start, 'sourceEnd < sourceStart')
-+  assert(target_start >= 0 && target_start < target.length,
-+      'targetStart out of bounds')
-+  assert(start >= 0 && start < source.length, 'sourceStart out of bounds')
-+  assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')
-+
-+  // Are we oob?
-+  if (end > this.length)
-+    end = this.length
-+  if (target.length - target_start < end - start)
-+    end = target.length - target_start + start
-+
-+  var len = end - start
-+
-+  if (len < 100 || !Buffer._useTypedArrays) {
-+    for (var i = 0; i < len; i++) {
-+      target[i + target_start] = this[i + start]
-+    }
-+  } else {
-+    target._set(this.subarray(start, start + len), target_start)
-+  }
-+}
-+
-+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) {
-+  var res = ''
-+  var tmp = ''
-+  end = Math.min(buf.length, end)
-+
-+  for (var i = start; i < end; i++) {
-+    if (buf[i] <= 0x7F) {
-+      res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
-+      tmp = ''
-+    } else {
-+      tmp += '%' + buf[i].toString(16)
-+    }
-+  }
-+
-+  return res + decodeUtf8Char(tmp)
-+}
-+
-+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])
-+  }
-+  return ret
-+}
-+
-+function binarySlice (buf, start, end) {
-+  return asciiSlice(buf, start, end)
-+}
-+
-+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 (start, end) {
-+  var len = this.length
-+  start = clamp(start, len, 0)
-+  end = clamp(end, len, len)
-+
-+  if (Buffer._useTypedArrays) {
-+    return Buffer._augment(this.subarray(start, end))
-+  } else {
-+    var sliceLen = end - start
-+    var newBuf = new Buffer(sliceLen, undefined, true)
-+    for (var i = 0; i < sliceLen; i++) {
-+      newBuf[i] = this[i + start]
-+    }
-+    return newBuf
-+  }
-+}
-+
-+// `get` will be removed in Node 0.13+
-+Buffer.prototype.get = function (offset) {
-+  console.log('.get() is deprecated. Access using array indexes instead.')
-+  return this.readUInt8(offset)
-+}
-+
-+// `set` will be removed in Node 0.13+
-+Buffer.prototype.set = function (v, offset) {
-+  console.log('.set() is deprecated. Access using array indexes instead.')
-+  return this.writeUInt8(v, offset)
-+}
-+
-+Buffer.prototype.readUInt8 = function (offset, noAssert) {
-+  if (!noAssert) {
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset < this.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  if (offset >= this.length)
-+    return
-+
-+  return this[offset]
-+}
-+
-+function readUInt16 (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  var val
-+  if (littleEndian) {
-+    val = buf[offset]
-+    if (offset + 1 < len)
-+      val |= buf[offset + 1] << 8
-+  } else {
-+    val = buf[offset] << 8
-+    if (offset + 1 < len)
-+      val |= buf[offset + 1]
-+  }
-+  return val
-+}
-+
-+Buffer.prototype.readUInt16LE = function (offset, noAssert) {
-+  return readUInt16(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readUInt16BE = function (offset, noAssert) {
-+  return readUInt16(this, offset, false, noAssert)
-+}
-+
-+function readUInt32 (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  var val
-+  if (littleEndian) {
-+    if (offset + 2 < len)
-+      val = buf[offset + 2] << 16
-+    if (offset + 1 < len)
-+      val |= buf[offset + 1] << 8
-+    val |= buf[offset]
-+    if (offset + 3 < len)
-+      val = val + (buf[offset + 3] << 24 >>> 0)
-+  } else {
-+    if (offset + 1 < len)
-+      val = buf[offset + 1] << 16
-+    if (offset + 2 < len)
-+      val |= buf[offset + 2] << 8
-+    if (offset + 3 < len)
-+      val |= buf[offset + 3]
-+    val = val + (buf[offset] << 24 >>> 0)
-+  }
-+  return val
-+}
-+
-+Buffer.prototype.readUInt32LE = function (offset, noAssert) {
-+  return readUInt32(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readUInt32BE = function (offset, noAssert) {
-+  return readUInt32(this, offset, false, noAssert)
-+}
-+
-+Buffer.prototype.readInt8 = function (offset, noAssert) {
-+  if (!noAssert) {
-+    assert(offset !== undefined && offset !== null,
-+        'missing offset')
-+    assert(offset < this.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  if (offset >= this.length)
-+    return
-+
-+  var neg = this[offset] & 0x80
-+  if (neg)
-+    return (0xff - this[offset] + 1) * -1
-+  else
-+    return this[offset]
-+}
-+
-+function readInt16 (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  var val = readUInt16(buf, offset, littleEndian, true)
-+  var neg = val & 0x8000
-+  if (neg)
-+    return (0xffff - val + 1) * -1
-+  else
-+    return val
-+}
-+
-+Buffer.prototype.readInt16LE = function (offset, noAssert) {
-+  return readInt16(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readInt16BE = function (offset, noAssert) {
-+  return readInt16(this, offset, false, noAssert)
-+}
-+
-+function readInt32 (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  var val = readUInt32(buf, offset, littleEndian, true)
-+  var neg = val & 0x80000000
-+  if (neg)
-+    return (0xffffffff - val + 1) * -1
-+  else
-+    return val
-+}
-+
-+Buffer.prototype.readInt32LE = function (offset, noAssert) {
-+  return readInt32(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readInt32BE = function (offset, noAssert) {
-+  return readInt32(this, offset, false, noAssert)
-+}
-+
-+function readFloat (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  return ieee754.read(buf, offset, littleEndian, 23, 4)
-+}
-+
-+Buffer.prototype.readFloatLE = function (offset, noAssert) {
-+  return readFloat(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readFloatBE = function (offset, noAssert) {
-+  return readFloat(this, offset, false, noAssert)
-+}
-+
-+function readDouble (buf, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')
-+  }
-+
-+  return ieee754.read(buf, offset, littleEndian, 52, 8)
-+}
-+
-+Buffer.prototype.readDoubleLE = function (offset, noAssert) {
-+  return readDouble(this, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.readDoubleBE = function (offset, noAssert) {
-+  return readDouble(this, offset, false, noAssert)
-+}
-+
-+Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset < this.length, 'trying to write beyond buffer length')
-+    verifuint(value, 0xff)
-+  }
-+
-+  if (offset >= this.length) return
-+
-+  this[offset] = value
-+  return offset + 1
-+}
-+
-+function writeUInt16 (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 1 < buf.length, 'trying to write beyond buffer length')
-+    verifuint(value, 0xffff)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {
-+    buf[offset + i] =
-+        (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
-+            (littleEndian ? i : 1 - i) * 8
-+  }
-+  return offset + 2
-+}
-+
-+Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
-+  return writeUInt16(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
-+  return writeUInt16(this, value, offset, false, noAssert)
-+}
-+
-+function writeUInt32 (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 3 < buf.length, 'trying to write beyond buffer length')
-+    verifuint(value, 0xffffffff)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {
-+    buf[offset + i] =
-+        (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
-+  }
-+  return offset + 4
-+}
-+
-+Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
-+  return writeUInt32(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
-+  return writeUInt32(this, value, offset, false, noAssert)
-+}
-+
-+Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset < this.length, 'Trying to write beyond buffer length')
-+    verifsint(value, 0x7f, -0x80)
-+  }
-+
-+  if (offset >= this.length)
-+    return
-+
-+  if (value >= 0)
-+    this.writeUInt8(value, offset, noAssert)
-+  else
-+    this.writeUInt8(0xff + value + 1, offset, noAssert)
-+  return offset + 1
-+}
-+
-+function writeInt16 (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')
-+    verifsint(value, 0x7fff, -0x8000)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  if (value >= 0)
-+    writeUInt16(buf, value, offset, littleEndian, noAssert)
-+  else
-+    writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)
-+  return offset + 2
-+}
-+
-+Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
-+  return writeInt16(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
-+  return writeInt16(this, value, offset, false, noAssert)
-+}
-+
-+function writeInt32 (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
-+    verifsint(value, 0x7fffffff, -0x80000000)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  if (value >= 0)
-+    writeUInt32(buf, value, offset, littleEndian, noAssert)
-+  else
-+    writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)
-+  return offset + 4
-+}
-+
-+Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
-+  return writeInt32(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
-+  return writeInt32(this, value, offset, false, noAssert)
-+}
-+
-+function writeFloat (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
-+    verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
-+  return offset + 4
-+}
-+
-+Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
-+  return writeFloat(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
-+  return writeFloat(this, value, offset, false, noAssert)
-+}
-+
-+function writeDouble (buf, value, offset, littleEndian, noAssert) {
-+  if (!noAssert) {
-+    assert(value !== undefined && value !== null, 'missing value')
-+    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
-+    assert(offset !== undefined && offset !== null, 'missing offset')
-+    assert(offset + 7 < buf.length,
-+        'Trying to write beyond buffer length')
-+    verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)
-+  }
-+
-+  var len = buf.length
-+  if (offset >= len)
-+    return
-+
-+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
-+  return offset + 8
-+}
-+
-+Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
-+  return writeDouble(this, value, offset, true, noAssert)
-+}
-+
-+Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
-+  return writeDouble(this, value, offset, false, noAssert)
-+}
-+
-+// fill(value, start=0, end=buffer.length)
-+Buffer.prototype.fill = function (value, start, end) {
-+  if (!value) value = 0
-+  if (!start) start = 0
-+  if (!end) end = this.length
-+
-+  assert(end >= start, 'end < start')
-+
-+  // Fill 0 bytes; we're done
-+  if (end === start) return
-+  if (this.length === 0) return
-+
-+  assert(start >= 0 && start < this.length, 'start out of bounds')
-+  assert(end >= 0 && end <= this.length, '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
-+}
-+
-+Buffer.prototype.inspect = function () {
-+  var out = []
-+  var len = this.length
-+  for (var i = 0; i < len; i++) {
-+    out[i] = toHex(this[i])
-+    if (i === exports.INSPECT_MAX_BYTES) {
-+      out[i + 1] = '...'
-+      break
-+    }
-+  }
-+  return '<Buffer ' + out.join(' ') + '>'
-+}
-+
-+/**
-+ * 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 () {
-+  if (typeof Uint8Array !== 'undefined') {
-+    if (Buffer._useTypedArrays) {
-+      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 Error('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 (arr) {
-+  arr._isBuffer = true
-+
-+  // save reference to original Uint8Array get/set methods before overwriting
-+  arr._get = arr.get
-+  arr._set = arr.set
-+
-+  // deprecated, will be removed in node 0.13+
-+  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.copy = BP.copy
-+  arr.slice = BP.slice
-+  arr.readUInt8 = BP.readUInt8
-+  arr.readUInt16LE = BP.readUInt16LE
-+  arr.readUInt16BE = BP.readUInt16BE
-+  arr.readUInt32LE = BP.readUInt32LE
-+  arr.readUInt32BE = BP.readUInt32BE
-+  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.writeUInt16LE = BP.writeUInt16LE
-+  arr.writeUInt16BE = BP.writeUInt16BE
-+  arr.writeUInt32LE = BP.writeUInt32LE
-+  arr.writeUInt32BE = BP.writeUInt32BE
-+  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-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 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, '')
-+}
-+
-+// slice(start, end)
-+function clamp (index, len, defaultValue) {
-+  if (typeof index !== 'number') return defaultValue
-+  index = ~~index;  // Coerce to integer.
-+  if (index >= len) return len
-+  if (index >= 0) return index
-+  index += len
-+  if (index >= 0) return index
-+  return 0
-+}
-+
-+function coerce (length) {
-+  // Coerce length to a number (possibly NaN), round up
-+  // in case it's fractional (e.g. 123.456) then do a
-+  // double negate to coerce a NaN to 0. Easy, right?
-+  length = ~~Math.ceil(+length)
-+  return length < 0 ? 0 : length
-+}
-+
-+function isArray (subject) {
-+  return (Array.isArray || function (subject) {
-+    return Object.prototype.toString.call(subject) === '[object Array]'
-+  })(subject)
-+}
-+
-+function isArrayish (subject) {
-+  return isArray(subject) || Buffer.isBuffer(subject) ||
-+      subject && typeof subject === 'object' &&
-+      typeof subject.length === 'number'
-+}
-+
-+function toHex (n) {
-+  if (n < 16) return '0' + n.toString(16)
-+  return n.toString(16)
-+}
-+
-+function utf8ToBytes (str) {
-+  var byteArray = []
-+  for (var i = 0; i < str.length; i++) {
-+    var b = str.charCodeAt(i)
-+    if (b <= 0x7F) {
-+      byteArray.push(b)
-+    } else {
-+      var start = i
-+      if (b >= 0xD800 && b <= 0xDFFF) i++
-+      var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')
-+      for (var j = 0; j < h.length; j++) {
-+        byteArray.push(parseInt(h[j], 16))
-+      }
-+    }
-+  }
-+  return byteArray
-+}
-+
-+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) {
-+  var c, hi, lo
-+  var byteArray = []
-+  for (var i = 0; i < str.length; i++) {
-+    c = str.charCodeAt(i)
-+    hi = c >> 8
-+    lo = c % 256
-+    byteArray.push(lo)
-+    byteArray.push(hi)
-+  }
-+
-+  return byteArray
-+}
-+
-+function base64ToBytes (str) {
-+  return base64.toByteArray(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
-+}
-+
-+function decodeUtf8Char (str) {
-+  try {
-+    return decodeURIComponent(str)
-+  } catch (err) {
-+    return String.fromCharCode(0xFFFD) // UTF 8 invalid char
-+  }
-+}
-+
-+/*
-+ * We have to make sure that the value is a valid integer. This means that it
-+ * is non-negative. It has no fractional component and that it does not
-+ * exceed the maximum allowed value.
-+ */
-+function verifuint (value, max) {
-+  assert(typeof value === 'number', 'cannot write a non-number as a number')
-+  assert(value >= 0, 'specified a negative value for writing an unsigned value')
-+  assert(value <= max, 'value is larger than maximum value for type')
-+  assert(Math.floor(value) === value, 'value has a fractional component')
-+}
-+
-+function verifsint (value, max, min) {
-+  assert(typeof value === 'number', 'cannot write a non-number as a number')
-+  assert(value <= max, 'value larger than maximum allowed value')
-+  assert(value >= min, 'value smaller than minimum allowed value')
-+  assert(Math.floor(value) === value, 'value has a fractional component')
-+}
-+
-+function verifIEEE754 (value, max, min) {
-+  assert(typeof value === 'number', 'cannot write a non-number as a number')
-+  assert(value <= max, 'value larger than maximum allowed value')
-+  assert(value >= min, 'value smaller than minimum allowed value')
-+}
-+
-+function assert (test, message) {
-+  if (!test) throw new Error(message || 'Failed assertion')
-+}
-+
-+},{"base64-js":2,"ieee754":3}],2:[function(require,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)
-+
-+	function decode (elt) {
-+		var code = elt.charCodeAt(0)
-+		if (code === PLUS)
-+			return 62 // '+'
-+		if (code === SLASH)
-+			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))
-+
-+},{}],3:[function(require,module,exports){
-+exports.read = function(buffer, offset, isLE, mLen, nBytes) {
-+  var e, m,
-+      eLen = nBytes * 8 - mLen - 1,
-+      eMax = (1 << eLen) - 1,
-+      eBias = eMax >> 1,
-+      nBits = -7,
-+      i = isLE ? (nBytes - 1) : 0,
-+      d = isLE ? -1 : 1,
-+      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,
-+      eLen = nBytes * 8 - mLen - 1,
-+      eMax = (1 << eLen) - 1,
-+      eBias = eMax >> 1,
-+      rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
-+      i = isLE ? 0 : (nBytes - 1),
-+      d = isLE ? 1 : -1,
-+      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;
-+};
-+
-+},{}],4:[function(require,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);
-+      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;
-+}
-+
-+},{}],5:[function(require,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
-+  }
-+}
-+
-+},{}],6:[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 = [];
-+
-+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');
-+}
-+
-+// TODO(shtylman)
-+process.cwd = function () { return '/' };
-+process.chdir = function (dir) {
-+    throw new Error('process.chdir is not supported');
-+};
-+
-+},{}],7:[function(require,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.
-+
-+'use strict';
-+
-+// If obj.hasOwnProperty has been overridden, then calling
-+// obj.hasOwnProperty(prop) will break.
-+// See: https://github.com/joyent/node/issues/1707
-+function hasOwnProperty(obj, prop) {
-+  return Object.prototype.hasOwnProperty.call(obj, prop);
-+}
-+
-+module.exports = function(qs, sep, eq, options) {
-+  sep = sep || '&';
-+  eq = eq || '=';
-+  var obj = {};
-+
-+  if (typeof qs !== 'string' || qs.length === 0) {
-+    return obj;
-+  }
-+
-+  var regexp = /\+/g;
-+  qs = qs.split(sep);
-+
-+  var maxKeys = 1000;
-+  if (options && typeof options.maxKeys === 'number') {
-+    maxKeys = options.maxKeys;
-+  }
-+
-+  var len = qs.length;
-+  // maxKeys <= 0 means that we should not limit keys count
-+  if (maxKeys > 0 && len > maxKeys) {
-+    len = maxKeys;
-+  }
-+
-+  for (var i = 0; i < len; ++i) {
-+    var x = qs[i].replace(regexp, '%20'),
-+        idx = x.indexOf(eq),
-+        kstr, vstr, k, v;
-+
-+    if (idx >= 0) {
-+      kstr = x.substr(0, idx);
-+      vstr = x.substr(idx + 1);
-+    } else {
-+      kstr = x;
-+      vstr = '';
-+    }
-+
-+    k = decodeURIComponent(kstr);
-+    v = decodeURIComponent(vstr);
-+
-+    if (!hasOwnProperty(obj, k)) {
-+      obj[k] = v;
-+    } else if (isArray(obj[k])) {
-+      obj[k].push(v);
-+    } else {
-+      obj[k] = [obj[k], v];
-+    }
-+  }
-+
-+  return obj;
-+};
-+
-+var isArray = Array.isArray || function (xs) {
-+  return Object.prototype.toString.call(xs) === '[object Array]';
-+};
-+
-+},{}],8:[function(require,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.
-+
-+'use strict';
-+
-+var stringifyPrimitive = function(v) {
-+  switch (typeof v) {
-+    case 'string':
-+      return v;
-+
-+    case 'boolean':
-+      return v ? 'true' : 'false';
-+
-+    case 'number':
-+      return isFinite(v) ? v : '';
-+
-+    default:
-+      return '';
-+  }
-+};
-+
-+module.exports = function(obj, sep, eq, name) {
-+  sep = sep || '&';
-+  eq = eq || '=';
-+  if (obj === null) {
-+    obj = undefined;
-+  }
-+
-+  if (typeof obj === 'object') {
-+    return map(objectKeys(obj), function(k) {
-+      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
-+      if (isArray(obj[k])) {
-+        return map(obj[k], function(v) {
-+          return ks + encodeURIComponent(stringifyPrimitive(v));
-+        }).join(sep);
-+      } else {
-+        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
-+      }
-+    }).join(sep);
-+
-+  }
-+
-+  if (!name) return '';
-+  return encodeURIComponent(stringifyPrimitive(name)) + eq +
-+         encodeURIComponent(stringifyPrimitive(obj));
-+};
-+
-+var isArray = Array.isArray || function (xs) {
-+  return Object.prototype.toString.call(xs) === '[object Array]';
-+};
-+
-+function map (xs, f) {
-+  if (xs.map) return xs.map(f);
-+  var res = [];
-+  for (var i = 0; i < xs.length; i++) {
-+    res.push(f(xs[i], i));
-+  }
-+  return res;
-+}
-+
-+var objectKeys = Object.keys || function (obj) {
-+  var res = [];
-+  for (var key in obj) {
-+    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
-+  }
-+  return res;
-+};
-+
-+},{}],9:[function(require,module,exports){
-+'use strict';
-+
-+exports.decode = exports.parse = require('./decode');
-+exports.encode = exports.stringify = require('./encode');
-+
-+},{"./decode":7,"./encode":8}],10:[function(require,module,exports){
-+module.exports = function isBuffer(arg) {
-+  return arg && typeof arg === 'object'
-+    && typeof arg.copy === 'function'
-+    && typeof arg.fill === 'function'
-+    && typeof arg.readUInt8 === 'function';
-+}
-+},{}],11:[function(require,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 = require('./support/isBuffer');
-+
-+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 = require('inherits');
-+
-+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,require("FWaASH"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-+},{"./support/isBuffer":10,"FWaASH":6,"inherits":5}],12:[function(require,module,exports){
-+/**
-+ * Diff Match and Patch
-+ *
-+ * Copyright 2006 Google Inc.
-+ * http://code.google.com/p/google-diff-match-patch/
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the "License");
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ *   http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an "AS IS" BASIS,
-+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+/**
-+ * @fileoverview Computes the difference between two texts to create a patch.
-+ * Applies the patch onto another text, allowing for errors.
-+ * @author fraser at google.com (Neil Fraser)
-+ */
-+
-+/**
-+ * Class containing the diff, match and patch methods.
-+ * @constructor
-+ */
-+function diff_match_patch() {
-+
-+  // Defaults.
-+  // Redefine these in your program to override the defaults.
-+
-+  // Number of seconds to map a diff before giving up (0 for infinity).
-+  this.Diff_Timeout = 1.0;
-+  // Cost of an empty edit operation in terms of edit characters.
-+  this.Diff_EditCost = 4;
-+  // At what point is no match declared (0.0 = perfection, 1.0 = very loose).
-+  this.Match_Threshold = 0.5;
-+  // How far to search for a match (0 = exact location, 1000+ = broad match).
-+  // A match this many characters away from the expected location will add
-+  // 1.0 to the score (0.0 is a perfect match).
-+  this.Match_Distance = 1000;
-+  // When deleting a large block of text (over ~64 characters), how close does
-+  // the contents have to match the expected contents. (0.0 = perfection,
-+  // 1.0 = very loose).  Note that Match_Threshold controls how closely the
-+  // end points of a delete need to match.
-+  this.Patch_DeleteThreshold = 0.5;
-+  // Chunk size for context length.
-+  this.Patch_Margin = 4;
-+
-+  // The number of bits in an int.
-+  this.Match_MaxBits = 32;
-+}
-+
-+
-+//  DIFF FUNCTIONS
-+
-+
-+/**
-+ * The data structure representing a diff is an array of tuples:
-+ * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]
-+ * which means: delete 'Hello', add 'Goodbye' and keep ' world.'
-+ */
-+var DIFF_DELETE = -1;
-+var DIFF_INSERT = 1;
-+var DIFF_EQUAL = 0;
-+
-+/** @typedef {!Array.<number|string>} */
-+diff_match_patch.Diff;
-+
-+
-+/**
-+ * Find the differences between two texts.  Simplifies the problem by stripping
-+ * any common prefix or suffix off the texts before diffing.
-+ * @param {string} text1 Old string to be diffed.
-+ * @param {string} text2 New string to be diffed.
-+ * @param {boolean=} opt_checklines Optional speedup flag. If present and false,
-+ *     then don't run a line-level diff first to identify the changed areas.
-+ *     Defaults to true, which does a faster, slightly less optimal diff.
-+ * @param {number} opt_deadline Optional time when the diff should be complete
-+ *     by.  Used internally for recursive calls.  Users should set DiffTimeout
-+ *     instead.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ */
-+diff_match_patch.prototype.diff_main = function(text1, text2, opt_checklines,
-+    opt_deadline) {
-+  // Set a deadline by which time the diff must be complete.
-+  if (typeof opt_deadline == 'undefined') {
-+    if (this.Diff_Timeout <= 0) {
-+      opt_deadline = Number.MAX_VALUE;
-+    } else {
-+      opt_deadline = (new Date).getTime() + this.Diff_Timeout * 1000;
-+    }
-+  }
-+  var deadline = opt_deadline;
-+
-+  // Check for null inputs.
-+  if (text1 == null || text2 == null) {
-+    throw new Error('Null input. (diff_main)');
-+  }
-+
-+  // Check for equality (speedup).
-+  if (text1 == text2) {
-+    if (text1) {
-+      return [[DIFF_EQUAL, text1]];
-+    }
-+    return [];
-+  }
-+
-+  if (typeof opt_checklines == 'undefined') {
-+    opt_checklines = true;
-+  }
-+  var checklines = opt_checklines;
-+
-+  // Trim off common prefix (speedup).
-+  var commonlength = this.diff_commonPrefix(text1, text2);
-+  var commonprefix = text1.substring(0, commonlength);
-+  text1 = text1.substring(commonlength);
-+  text2 = text2.substring(commonlength);
-+
-+  // Trim off common suffix (speedup).
-+  commonlength = this.diff_commonSuffix(text1, text2);
-+  var commonsuffix = text1.substring(text1.length - commonlength);
-+  text1 = text1.substring(0, text1.length - commonlength);
-+  text2 = text2.substring(0, text2.length - commonlength);
-+
-+  // Compute the diff on the middle block.
-+  var diffs = this.diff_compute_(text1, text2, checklines, deadline);
-+
-+  // Restore the prefix and suffix.
-+  if (commonprefix) {
-+    diffs.unshift([DIFF_EQUAL, commonprefix]);
-+  }
-+  if (commonsuffix) {
-+    diffs.push([DIFF_EQUAL, commonsuffix]);
-+  }
-+  this.diff_cleanupMerge(diffs);
-+  return diffs;
-+};
-+
-+
-+/**
-+ * Find the differences between two texts.  Assumes that the texts do not
-+ * have any common prefix or suffix.
-+ * @param {string} text1 Old string to be diffed.
-+ * @param {string} text2 New string to be diffed.
-+ * @param {boolean} checklines Speedup flag.  If false, then don't run a
-+ *     line-level diff first to identify the changed areas.
-+ *     If true, then run a faster, slightly less optimal diff.
-+ * @param {number} deadline Time when the diff should be complete by.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_compute_ = function(text1, text2, checklines,
-+    deadline) {
-+  var diffs;
-+
-+  if (!text1) {
-+    // Just add some text (speedup).
-+    return [[DIFF_INSERT, text2]];
-+  }
-+
-+  if (!text2) {
-+    // Just delete some text (speedup).
-+    return [[DIFF_DELETE, text1]];
-+  }
-+
-+  var longtext = text1.length > text2.length ? text1 : text2;
-+  var shorttext = text1.length > text2.length ? text2 : text1;
-+  var i = longtext.indexOf(shorttext);
-+  if (i != -1) {
-+    // Shorter text is inside the longer text (speedup).
-+    diffs = [[DIFF_INSERT, longtext.substring(0, i)],
-+             [DIFF_EQUAL, shorttext],
-+             [DIFF_INSERT, longtext.substring(i + shorttext.length)]];
-+    // Swap insertions for deletions if diff is reversed.
-+    if (text1.length > text2.length) {
-+      diffs[0][0] = diffs[2][0] = DIFF_DELETE;
-+    }
-+    return diffs;
-+  }
-+
-+  if (shorttext.length == 1) {
-+    // Single character string.
-+    // After the previous speedup, the character can't be an equality.
-+    return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
-+  }
-+  longtext = shorttext = null;  // Garbage collect.
-+
-+  // Check to see if the problem can be split in two.
-+  var hm = this.diff_halfMatch_(text1, text2);
-+  if (hm) {
-+    // A half-match was found, sort out the return data.
-+    var text1_a = hm[0];
-+    var text1_b = hm[1];
-+    var text2_a = hm[2];
-+    var text2_b = hm[3];
-+    var mid_common = hm[4];
-+    // Send both pairs off for separate processing.
-+    var diffs_a = this.diff_main(text1_a, text2_a, checklines, deadline);
-+    var diffs_b = this.diff_main(text1_b, text2_b, checklines, deadline);
-+    // Merge the results.
-+    return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);
-+  }
-+
-+  if (checklines && text1.length > 100 && text2.length > 100) {
-+    return this.diff_lineMode_(text1, text2, deadline);
-+  }
-+
-+  return this.diff_bisect_(text1, text2, deadline);
-+};
-+
-+
-+/**
-+ * Do a quick line-level diff on both strings, then rediff the parts for
-+ * greater accuracy.
-+ * This speedup can produce non-minimal diffs.
-+ * @param {string} text1 Old string to be diffed.
-+ * @param {string} text2 New string to be diffed.
-+ * @param {number} deadline Time when the diff should be complete by.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_lineMode_ = function(text1, text2, deadline) {
-+  // Scan the text on a line-by-line basis first.
-+  var a = this.diff_linesToChars_(text1, text2);
-+  text1 = /** @type {string} */(a[0]);
-+  text2 = /** @type {string} */(a[1]);
-+  var linearray = /** @type {!Array.<string>} */(a[2]);
-+
-+  var diffs = this.diff_bisect_(text1, text2, deadline);
-+
-+  // Convert the diff back to original text.
-+  this.diff_charsToLines_(diffs, linearray);
-+  // Eliminate freak matches (e.g. blank lines)
-+  this.diff_cleanupSemantic(diffs);
-+
-+  // Rediff any replacement blocks, this time character-by-character.
-+  // Add a dummy entry at the end.
-+  diffs.push([DIFF_EQUAL, '']);
-+  var pointer = 0;
-+  var count_delete = 0;
-+  var count_insert = 0;
-+  var text_delete = '';
-+  var text_insert = '';
-+  while (pointer < diffs.length) {
-+    switch (diffs[pointer][0]) {
-+      case DIFF_INSERT:
-+        count_insert++;
-+        text_insert += diffs[pointer][1];
-+        break;
-+      case DIFF_DELETE:
-+        count_delete++;
-+        text_delete += diffs[pointer][1];
-+        break;
-+      case DIFF_EQUAL:
-+        // Upon reaching an equality, check for prior redundancies.
-+        if (count_delete >= 1 && count_insert >= 1) {
-+          // Delete the offending records and add the merged ones.
-+          var a = this.diff_main(text_delete, text_insert, false, deadline);
-+          diffs.splice(pointer - count_delete - count_insert,
-+                       count_delete + count_insert);
-+          pointer = pointer - count_delete - count_insert;
-+          for (var j = a.length - 1; j >= 0; j--) {
-+            diffs.splice(pointer, 0, a[j]);
-+          }
-+          pointer = pointer + a.length;
-+        }
-+        count_insert = 0;
-+        count_delete = 0;
-+        text_delete = '';
-+        text_insert = '';
-+        break;
-+    }
-+    pointer++;
-+  }
-+  diffs.pop();  // Remove the dummy entry at the end.
-+
-+  return diffs;
-+};
-+
-+
-+/**
-+ * Find the 'middle snake' of a diff, split the problem in two
-+ * and return the recursively constructed diff.
-+ * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
-+ * @param {string} text1 Old string to be diffed.
-+ * @param {string} text2 New string to be diffed.
-+ * @param {number} deadline Time at which to bail if not yet complete.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_bisect_ = function(text1, text2, deadline) {
-+  // Cache the text lengths to prevent multiple calls.
-+  var text1_length = text1.length;
-+  var text2_length = text2.length;
-+  var max_d = Math.ceil((text1_length + text2_length) / 2);
-+  var v_offset = max_d;
-+  var v_length = 2 * max_d;
-+  var v1 = new Array(v_length);
-+  var v2 = new Array(v_length);
-+  // Setting all elements to -1 is faster in Chrome & Firefox than mixing
-+  // integers and undefined.
-+  for (var x = 0; x < v_length; x++) {
-+    v1[x] = -1;
-+    v2[x] = -1;
-+  }
-+  v1[v_offset + 1] = 0;
-+  v2[v_offset + 1] = 0;
-+  var delta = text1_length - text2_length;
-+  // If the total number of characters is odd, then the front path will collide
-+  // with the reverse path.
-+  var front = (delta % 2 != 0);
-+  // Offsets for start and end of k loop.
-+  // Prevents mapping of space beyond the grid.
-+  var k1start = 0;
-+  var k1end = 0;
-+  var k2start = 0;
-+  var k2end = 0;
-+  for (var d = 0; d < max_d; d++) {
-+    // Bail out if deadline is reached.
-+    if ((new Date()).getTime() > deadline) {
-+      break;
-+    }
-+
-+    // Walk the front path one step.
-+    for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
-+      var k1_offset = v_offset + k1;
-+      var x1;
-+      if (k1 == -d || k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1]) {
-+        x1 = v1[k1_offset + 1];
-+      } else {
-+        x1 = v1[k1_offset - 1] + 1;
-+      }
-+      var y1 = x1 - k1;
-+      while (x1 < text1_length && y1 < text2_length &&
-+             text1.charAt(x1) == text2.charAt(y1)) {
-+        x1++;
-+        y1++;
-+      }
-+      v1[k1_offset] = x1;
-+      if (x1 > text1_length) {
-+        // Ran off the right of the graph.
-+        k1end += 2;
-+      } else if (y1 > text2_length) {
-+        // Ran off the bottom of the graph.
-+        k1start += 2;
-+      } else if (front) {
-+        var k2_offset = v_offset + delta - k1;
-+        if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) {
-+          // Mirror x2 onto top-left coordinate system.
-+          var x2 = text1_length - v2[k2_offset];
-+          if (x1 >= x2) {
-+            // Overlap detected.
-+            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
-+          }
-+        }
-+      }
-+    }
-+
-+    // Walk the reverse path one step.
-+    for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
-+      var k2_offset = v_offset + k2;
-+      var x2;
-+      if (k2 == -d || k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1]) {
-+        x2 = v2[k2_offset + 1];
-+      } else {
-+        x2 = v2[k2_offset - 1] + 1;
-+      }
-+      var y2 = x2 - k2;
-+      while (x2 < text1_length && y2 < text2_length &&
-+             text1.charAt(text1_length - x2 - 1) ==
-+             text2.charAt(text2_length - y2 - 1)) {
-+        x2++;
-+        y2++;
-+      }
-+      v2[k2_offset] = x2;
-+      if (x2 > text1_length) {
-+        // Ran off the left of the graph.
-+        k2end += 2;
-+      } else if (y2 > text2_length) {
-+        // Ran off the top of the graph.
-+        k2start += 2;
-+      } else if (!front) {
-+        var k1_offset = v_offset + delta - k2;
-+        if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) {
-+          var x1 = v1[k1_offset];
-+          var y1 = v_offset + x1 - k1_offset;
-+          // Mirror x2 onto top-left coordinate system.
-+          x2 = text1_length - x2;
-+          if (x1 >= x2) {
-+            // Overlap detected.
-+            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
-+          }
-+        }
-+      }
-+    }
-+  }
-+  // Diff took too long and hit the deadline or
-+  // number of diffs equals number of characters, no commonality at all.
-+  return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
-+};
-+
-+
-+/**
-+ * Given the location of the 'middle snake', split the diff in two parts
-+ * and recurse.
-+ * @param {string} text1 Old string to be diffed.
-+ * @param {string} text2 New string to be diffed.
-+ * @param {number} x Index of split point in text1.
-+ * @param {number} y Index of split point in text2.
-+ * @param {number} deadline Time at which to bail if not yet complete.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_bisectSplit_ = function(text1, text2, x, y,
-+    deadline) {
-+  var text1a = text1.substring(0, x);
-+  var text2a = text2.substring(0, y);
-+  var text1b = text1.substring(x);
-+  var text2b = text2.substring(y);
-+
-+  // Compute both diffs serially.
-+  var diffs = this.diff_main(text1a, text2a, false, deadline);
-+  var diffsb = this.diff_main(text1b, text2b, false, deadline);
-+
-+  return diffs.concat(diffsb);
-+};
-+
-+
-+/**
-+ * Split two texts into an array of strings.  Reduce the texts to a string of
-+ * hashes where each Unicode character represents one line.
-+ * @param {string} text1 First string.
-+ * @param {string} text2 Second string.
-+ * @return {!Array.<string|!Array.<string>>} Three element Array, containing the
-+ *     encoded text1, the encoded text2 and the array of unique strings.  The
-+ *     zeroth element of the array of unique strings is intentionally blank.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_linesToChars_ = function(text1, text2) {
-+  var lineArray = [];  // e.g. lineArray[4] == 'Hello\n'
-+  var lineHash = {};   // e.g. lineHash['Hello\n'] == 4
-+
-+  // '\x00' is a valid character, but various debuggers don't like it.
-+  // So we'll insert a junk entry to avoid generating a null character.
-+  lineArray[0] = '';
-+
-+  /**
-+   * Split a text into an array of strings.  Reduce the texts to a string of
-+   * hashes where each Unicode character represents one line.
-+   * Modifies linearray and linehash through being a closure.
-+   * @param {string} text String to encode.
-+   * @return {string} Encoded string.
-+   * @private
-+   */
-+  function diff_linesToCharsMunge_(text) {
-+    var chars = '';
-+    // Walk the text, pulling out a substring for each line.
-+    // text.split('\n') would would temporarily double our memory footprint.
-+    // Modifying text would create many large strings to garbage collect.
-+    var lineStart = 0;
-+    var lineEnd = -1;
-+    // Keeping our own length variable is faster than looking it up.
-+    var lineArrayLength = lineArray.length;
-+    while (lineEnd < text.length - 1) {
-+      lineEnd = text.indexOf('\n', lineStart);
-+      if (lineEnd == -1) {
-+        lineEnd = text.length - 1;
-+      }
-+      var line = text.substring(lineStart, lineEnd + 1);
-+      lineStart = lineEnd + 1;
-+
-+      if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :
-+          (lineHash[line] !== undefined)) {
-+        chars += String.fromCharCode(lineHash[line]);
-+      } else {
-+        chars += String.fromCharCode(lineArrayLength);
-+        lineHash[line] = lineArrayLength;
-+        lineArray[lineArrayLength++] = line;
-+      }
-+    }
-+    return chars;
-+  }
-+
-+  var chars1 = diff_linesToCharsMunge_(text1);
-+  var chars2 = diff_linesToCharsMunge_(text2);
-+  return [chars1, chars2, lineArray];
-+};
-+
-+
-+/**
-+ * Rehydrate the text in a diff from a string of line hashes to real lines of
-+ * text.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @param {!Array.<string>} lineArray Array of unique strings.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_charsToLines_ = function(diffs, lineArray) {
-+  for (var x = 0; x < diffs.length; x++) {
-+    var chars = diffs[x][1];
-+    var text = [];
-+    for (var y = 0; y < chars.length; y++) {
-+      text[y] = lineArray[chars.charCodeAt(y)];
-+    }
-+    diffs[x][1] = text.join('');
-+  }
-+};
-+
-+
-+/**
-+ * Determine the common prefix of two strings.
-+ * @param {string} text1 First string.
-+ * @param {string} text2 Second string.
-+ * @return {number} The number of characters common to the start of each
-+ *     string.
-+ */
-+diff_match_patch.prototype.diff_commonPrefix = function(text1, text2) {
-+  // Quick check for common null cases.
-+  if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) {
-+    return 0;
-+  }
-+  // Binary search.
-+  // Performance analysis: http://neil.fraser.name/news/2007/10/09/
-+  var pointermin = 0;
-+  var pointermax = Math.min(text1.length, text2.length);
-+  var pointermid = pointermax;
-+  var pointerstart = 0;
-+  while (pointermin < pointermid) {
-+    if (text1.substring(pointerstart, pointermid) ==
-+        text2.substring(pointerstart, pointermid)) {
-+      pointermin = pointermid;
-+      pointerstart = pointermin;
-+    } else {
-+      pointermax = pointermid;
-+    }
-+    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
-+  }
-+  return pointermid;
-+};
-+
-+
-+/**
-+ * Determine the common suffix of two strings.
-+ * @param {string} text1 First string.
-+ * @param {string} text2 Second string.
-+ * @return {number} The number of characters common to the end of each string.
-+ */
-+diff_match_patch.prototype.diff_commonSuffix = function(text1, text2) {
-+  // Quick check for common null cases.
-+  if (!text1 || !text2 ||
-+      text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) {
-+    return 0;
-+  }
-+  // Binary search.
-+  // Performance analysis: http://neil.fraser.name/news/2007/10/09/
-+  var pointermin = 0;
-+  var pointermax = Math.min(text1.length, text2.length);
-+  var pointermid = pointermax;
-+  var pointerend = 0;
-+  while (pointermin < pointermid) {
-+    if (text1.substring(text1.length - pointermid, text1.length - pointerend) ==
-+        text2.substring(text2.length - pointermid, text2.length - pointerend)) {
-+      pointermin = pointermid;
-+      pointerend = pointermin;
-+    } else {
-+      pointermax = pointermid;
-+    }
-+    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
-+  }
-+  return pointermid;
-+};
-+
-+
-+/**
-+ * Determine if the suffix of one string is the prefix of another.
-+ * @param {string} text1 First string.
-+ * @param {string} text2 Second string.
-+ * @return {number} The number of characters common to the end of the first
-+ *     string and the start of the second string.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_commonOverlap_ = function(text1, text2) {
-+  // Cache the text lengths to prevent multiple calls.
-+  var text1_length = text1.length;
-+  var text2_length = text2.length;
-+  // Eliminate the null case.
-+  if (text1_length == 0 || text2_length == 0) {
-+    return 0;
-+  }
-+  // Truncate the longer string.
-+  if (text1_length > text2_length) {
-+    text1 = text1.substring(text1_length - text2_length);
-+  } else if (text1_length < text2_length) {
-+    text2 = text2.substring(0, text1_length);
-+  }
-+  var text_length = Math.min(text1_length, text2_length);
-+  // Quick check for the worst case.
-+  if (text1 == text2) {
-+    return text_length;
-+  }
-+
-+  // Start by looking for a single character match
-+  // and increase length until no match is found.
-+  // Performance analysis: http://neil.fraser.name/news/2010/11/04/
-+  var best = 0;
-+  var length = 1;
-+  while (true) {
-+    var pattern = text1.substring(text_length - length);
-+    var found = text2.indexOf(pattern);
-+    if (found == -1) {
-+      return best;
-+    }
-+    length += found;
-+    if (found == 0 || text1.substring(text_length - length) ==
-+        text2.substring(0, length)) {
-+      best = length;
-+      length++;
-+    }
-+  }
-+};
-+
-+
-+/**
-+ * Do the two texts share a substring which is at least half the length of the
-+ * longer text?
-+ * This speedup can produce non-minimal diffs.
-+ * @param {string} text1 First string.
-+ * @param {string} text2 Second string.
-+ * @return {Array.<string>} Five element Array, containing the prefix of
-+ *     text1, the suffix of text1, the prefix of text2, the suffix of
-+ *     text2 and the common middle.  Or null if there was no match.
-+ * @private
-+ */
-+diff_match_patch.prototype.diff_halfMatch_ = function(text1, text2) {
-+  if (this.Diff_Timeout <= 0) {
-+    // Don't risk returning a non-optimal diff if we have unlimited time.
-+    return null;
-+  }
-+  var longtext = text1.length > text2.length ? text1 : text2;
-+  var shorttext = text1.length > text2.length ? text2 : text1;
-+  if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
-+    return null;  // Pointless.
-+  }
-+  var dmp = this;  // 'this' becomes 'window' in a closure.
-+
-+  /**
-+   * Does a substring of shorttext exist within longtext such that the substring
-+   * is at least half the length of longtext?
-+   * Closure, but does not reference any external variables.
-+   * @param {string} longtext Longer string.
-+   * @param {string} shorttext Shorter string.
-+   * @param {number} i Start index of quarter length substring within longtext.
-+   * @return {Array.<string>} Five element Array, containing the prefix of
-+   *     longtext, the suffix of longtext, the prefix of shorttext, the suffix
-+   *     of shorttext and the common middle.  Or null if there was no match.
-+   * @private
-+   */
-+  function diff_halfMatchI_(longtext, shorttext, i) {
-+    // Start with a 1/4 length substring at position i as a seed.
-+    var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
-+    var j = -1;
-+    var best_common = '';
-+    var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
-+    while ((j = shorttext.indexOf(seed, j + 1)) != -1) {
-+      var prefixLength = dmp.diff_commonPrefix(longtext.substring(i),
-+                                               shorttext.substring(j));
-+      var suffixLength = dmp.diff_commonSuffix(longtext.substring(0, i),
-+                                               shorttext.substring(0, j));
-+      if (best_common.length < suffixLength + prefixLength) {
-+        best_common = shorttext.substring(j - suffixLength, j) +
-+            shorttext.substring(j, j + prefixLength);
-+        best_longtext_a = longtext.substring(0, i - suffixLength);
-+        best_longtext_b = longtext.substring(i + prefixLength);
-+        best_shorttext_a = shorttext.substring(0, j - suffixLength);
-+        best_shorttext_b = shorttext.substring(j + prefixLength);
-+      }
-+    }
-+    if (best_common.length * 2 >= longtext.length) {
-+      return [best_longtext_a, best_longtext_b,
-+              best_shorttext_a, best_shorttext_b, best_common];
-+    } else {
-+      return null;
-+    }
-+  }
-+
-+  // First check if the second quarter is the seed for a half-match.
-+  var hm1 = diff_halfMatchI_(longtext, shorttext,
-+                             Math.ceil(longtext.length / 4));
-+  // Check again based on the third quarter.
-+  var hm2 = diff_halfMatchI_(longtext, shorttext,
-+                             Math.ceil(longtext.length / 2));
-+  var hm;
-+  if (!hm1 && !hm2) {
-+    return null;
-+  } else if (!hm2) {
-+    hm = hm1;
-+  } else if (!hm1) {
-+    hm = hm2;
-+  } else {
-+    // Both matched.  Select the longest.
-+    hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
-+  }
-+
-+  // A half-match was found, sort out the return data.
-+  var text1_a, text1_b, text2_a, text2_b;
-+  if (text1.length > text2.length) {
-+    text1_a = hm[0];
-+    text1_b = hm[1];
-+    text2_a = hm[2];
-+    text2_b = hm[3];
-+  } else {
-+    text2_a = hm[0];
-+    text2_b = hm[1];
-+    text1_a = hm[2];
-+    text1_b = hm[3];
-+  }
-+  var mid_common = hm[4];
-+  return [text1_a, text1_b, text2_a, text2_b, mid_common];
-+};
-+
-+
-+/**
-+ * Reduce the number of edits by eliminating semantically trivial equalities.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ */
-+diff_match_patch.prototype.diff_cleanupSemantic = function(diffs) {
-+  var changes = false;
-+  var equalities = [];  // Stack of indices where equalities are found.
-+  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.
-+  /** @type {?string} */
-+  var lastequality = null;  // Always equal to equalities[equalitiesLength-1][1]
-+  var pointer = 0;  // Index of current position.
-+  // Number of characters that changed prior to the equality.
-+  var length_insertions1 = 0;
-+  var length_deletions1 = 0;
-+  // Number of characters that changed after the equality.
-+  var length_insertions2 = 0;
-+  var length_deletions2 = 0;
-+  while (pointer < diffs.length) {
-+    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.
-+      equalities[equalitiesLength++] = pointer;
-+      length_insertions1 = length_insertions2;
-+      length_deletions1 = length_deletions2;
-+      length_insertions2 = 0;
-+      length_deletions2 = 0;
-+      lastequality = /** @type {string} */(diffs[pointer][1]);
-+    } else {  // An insertion or deletion.
-+      if (diffs[pointer][0] == DIFF_INSERT) {
-+        length_insertions2 += diffs[pointer][1].length;
-+      } else {
-+        length_deletions2 += diffs[pointer][1].length;
-+      }
-+      // Eliminate an equality that is smaller or equal to the edits on both
-+      // sides of it.
-+      if (lastequality !== null && (lastequality.length <=
-+          Math.max(length_insertions1, length_deletions1)) &&
-+          (lastequality.length <= Math.max(length_insertions2,
-+                                           length_deletions2))) {
-+        // Duplicate record.
-+        diffs.splice(equalities[equalitiesLength - 1], 0,
-+                     [DIFF_DELETE, lastequality]);
-+        // Change second copy to insert.
-+        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
-+        // Throw away the equality we just deleted.
-+        equalitiesLength--;
-+        // Throw away the previous equality (it needs to be reevaluated).
-+        equalitiesLength--;
-+        pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
-+        length_insertions1 = 0;  // Reset the counters.
-+        length_deletions1 = 0;
-+        length_insertions2 = 0;
-+        length_deletions2 = 0;
-+        lastequality = null;
-+        changes = true;
-+      }
-+    }
-+    pointer++;
-+  }
-+
-+  // Normalize the diff.
-+  if (changes) {
-+    this.diff_cleanupMerge(diffs);
-+  }
-+  this.diff_cleanupSemanticLossless(diffs);
-+
-+  // Find any overlaps between deletions and insertions.
-+  // e.g: <del>abcxxx</del><ins>xxxdef</ins>
-+  //   -> <del>abc</del>xxx<ins>def</ins>
-+  // Only extract an overlap if it is as big as the edit ahead or behind it.
-+  pointer = 1;
-+  while (pointer < diffs.length) {
-+    if (diffs[pointer - 1][0] == DIFF_DELETE &&
-+        diffs[pointer][0] == DIFF_INSERT) {
-+      var deletion = /** @type {string} */(diffs[pointer - 1][1]);
-+      var insertion = /** @type {string} */(diffs[pointer][1]);
-+      var overlap_length = this.diff_commonOverlap_(deletion, insertion);
-+      if (overlap_length >= deletion.length / 2 ||
-+          overlap_length >= insertion.length / 2) {
-+        // Overlap found.  Insert an equality and trim the surrounding edits.
-+        diffs.splice(pointer, 0,
-+            [DIFF_EQUAL, insertion.substring(0, overlap_length)]);
-+        diffs[pointer - 1][1] =
-+            deletion.substring(0, deletion.length - overlap_length);
-+        diffs[pointer + 1][1] = insertion.substring(overlap_length);
-+        pointer++;
-+      }
-+      pointer++;
-+    }
-+    pointer++;
-+  }
-+};
-+
-+
-+/**
-+ * Look for single edits surrounded on both sides by equalities
-+ * which can be shifted sideways to align the edit to a word boundary.
-+ * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ */
-+diff_match_patch.prototype.diff_cleanupSemanticLossless = function(diffs) {
-+  // Define some regex patterns for matching boundaries.
-+  var punctuation = /[^a-zA-Z0-9]/;
-+  var whitespace = /\s/;
-+  var linebreak = /[\r\n]/;
-+  var blanklineEnd = /\n\r?\n$/;
-+  var blanklineStart = /^\r?\n\r?\n/;
-+
-+  /**
-+   * Given two strings, compute a score representing whether the internal
-+   * boundary falls on logical boundaries.
-+   * Scores range from 5 (best) to 0 (worst).
-+   * Closure, makes reference to regex patterns defined above.
-+   * @param {string} one First string.
-+   * @param {string} two Second string.
-+   * @return {number} The score.
-+   * @private
-+   */
-+  function diff_cleanupSemanticScore_(one, two) {
-+    if (!one || !two) {
-+      // Edges are the best.
-+      return 5;
-+    }
-+
-+    // Each port of this function behaves slightly differently due to
-+    // subtle differences in each language's definition of things like
-+    // 'whitespace'.  Since this function's purpose is largely cosmetic,
-+    // the choice has been made to use each language's native features
-+    // rather than force total conformity.
-+    var score = 0;
-+    // One point for non-alphanumeric.
-+    if (one.charAt(one.length - 1).match(punctuation) ||
-+        two.charAt(0).match(punctuation)) {
-+      score++;
-+      // Two points for whitespace.
-+      if (one.charAt(one.length - 1).match(whitespace) ||
-+          two.charAt(0).match(whitespace)) {
-+        score++;
-+        // Three points for line breaks.
-+        if (one.charAt(one.length - 1).match(linebreak) ||
-+            two.charAt(0).match(linebreak)) {
-+          score++;
-+          // Four points for blank lines.
-+          if (one.match(blanklineEnd) || two.match(blanklineStart)) {
-+            score++;
-+          }
-+        }
-+      }
-+    }
-+    return score;
-+  }
-+
-+  var pointer = 1;
-+  // Intentionally ignore the first and last element (don't need checking).
-+  while (pointer < diffs.length - 1) {
-+    if (diffs[pointer - 1][0] == DIFF_EQUAL &&
-+        diffs[pointer + 1][0] == DIFF_EQUAL) {
-+      // This is a single edit surrounded by equalities.
-+      var equality1 = /** @type {string} */(diffs[pointer - 1][1]);
-+      var edit = /** @type {string} */(diffs[pointer][1]);
-+      var equality2 = /** @type {string} */(diffs[pointer + 1][1]);
-+
-+      // First, shift the edit as far left as possible.
-+      var commonOffset = this.diff_commonSuffix(equality1, edit);
-+      if (commonOffset) {
-+        var commonString = edit.substring(edit.length - commonOffset);
-+        equality1 = equality1.substring(0, equality1.length - commonOffset);
-+        edit = commonString + edit.substring(0, edit.length - commonOffset);
-+        equality2 = commonString + equality2;
-+      }
-+
-+      // Second, step character by character right, looking for the best fit.
-+      var bestEquality1 = equality1;
-+      var bestEdit = edit;
-+      var bestEquality2 = equality2;
-+      var bestScore = diff_cleanupSemanticScore_(equality1, edit) +
-+          diff_cleanupSemanticScore_(edit, equality2);
-+      while (edit.charAt(0) === equality2.charAt(0)) {
-+        equality1 += edit.charAt(0);
-+        edit = edit.substring(1) + equality2.charAt(0);
-+        equality2 = equality2.substring(1);
-+        var score = diff_cleanupSemanticScore_(equality1, edit) +
-+            diff_cleanupSemanticScore_(edit, equality2);
-+        // The >= encourages trailing rather than leading whitespace on edits.
-+        if (score >= bestScore) {
-+          bestScore = score;
-+          bestEquality1 = equality1;
-+          bestEdit = edit;
-+          bestEquality2 = equality2;
-+        }
-+      }
-+
-+      if (diffs[pointer - 1][1] != bestEquality1) {
-+        // We have an improvement, save it back to the diff.
-+        if (bestEquality1) {
-+          diffs[pointer - 1][1] = bestEquality1;
-+        } else {
-+          diffs.splice(pointer - 1, 1);
-+          pointer--;
-+        }
-+        diffs[pointer][1] = bestEdit;
-+        if (bestEquality2) {
-+          diffs[pointer + 1][1] = bestEquality2;
-+        } else {
-+          diffs.splice(pointer + 1, 1);
-+          pointer--;
-+        }
-+      }
-+    }
-+    pointer++;
-+  }
-+};
-+
-+
-+/**
-+ * Reduce the number of edits by eliminating operationally trivial equalities.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ */
-+diff_match_patch.prototype.diff_cleanupEfficiency = function(diffs) {
-+  var changes = false;
-+  var equalities = [];  // Stack of indices where equalities are found.
-+  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.
-+  var lastequality = '';  // Always equal to equalities[equalitiesLength-1][1]
-+  var pointer = 0;  // Index of current position.
-+  // Is there an insertion operation before the last equality.
-+  var pre_ins = false;
-+  // Is there a deletion operation before the last equality.
-+  var pre_del = false;
-+  // Is there an insertion operation after the last equality.
-+  var post_ins = false;
-+  // Is there a deletion operation after the last equality.
-+  var post_del = false;
-+  while (pointer < diffs.length) {
-+    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.
-+      if (diffs[pointer][1].length < this.Diff_EditCost &&
-+          (post_ins || post_del)) {
-+        // Candidate found.
-+        equalities[equalitiesLength++] = pointer;
-+        pre_ins = post_ins;
-+        pre_del = post_del;
-+        lastequality = diffs[pointer][1];
-+      } else {
-+        // Not a candidate, and can never become one.
-+        equalitiesLength = 0;
-+        lastequality = '';
-+      }
-+      post_ins = post_del = false;
-+    } else {  // An insertion or deletion.
-+      if (diffs[pointer][0] == DIFF_DELETE) {
-+        post_del = true;
-+      } else {
-+        post_ins = true;
-+      }
-+      /*
-+       * Five types to be split:
-+       * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>
-+       * <ins>A</ins>X<ins>C</ins><del>D</del>
-+       * <ins>A</ins><del>B</del>X<ins>C</ins>
-+       * <ins>A</del>X<ins>C</ins><del>D</del>
-+       * <ins>A</ins><del>B</del>X<del>C</del>
-+       */
-+      if (lastequality && ((pre_ins && pre_del && post_ins && post_del) ||
-+                           ((lastequality.length < this.Diff_EditCost / 2) &&
-+                            (pre_ins + pre_del + post_ins + post_del) == 3))) {
-+        // Duplicate record.
-+        diffs.splice(equalities[equalitiesLength - 1], 0,
-+                     [DIFF_DELETE, lastequality]);
-+        // Change second copy to insert.
-+        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
-+        equalitiesLength--;  // Throw away the equality we just deleted;
-+        lastequality = '';
-+        if (pre_ins && pre_del) {
-+          // No changes made which could affect previous entry, keep going.
-+          post_ins = post_del = true;
-+          equalitiesLength = 0;
-+        } else {
-+          equalitiesLength--;  // Throw away the previous equality.
-+          pointer = equalitiesLength > 0 ?
-+              equalities[equalitiesLength - 1] : -1;
-+          post_ins = post_del = false;
-+        }
-+        changes = true;
-+      }
-+    }
-+    pointer++;
-+  }
-+
-+  if (changes) {
-+    this.diff_cleanupMerge(diffs);
-+  }
-+};
-+
-+
-+/**
-+ * Reorder and merge like edit sections.  Merge equalities.
-+ * Any edit section can move as long as it doesn't cross an equality.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ */
-+diff_match_patch.prototype.diff_cleanupMerge = function(diffs) {
-+  diffs.push([DIFF_EQUAL, '']);  // Add a dummy entry at the end.
-+  var pointer = 0;
-+  var count_delete = 0;
-+  var count_insert = 0;
-+  var text_delete = '';
-+  var text_insert = '';
-+  var commonlength;
-+  while (pointer < diffs.length) {
-+    switch (diffs[pointer][0]) {
-+      case DIFF_INSERT:
-+        count_insert++;
-+        text_insert += diffs[pointer][1];
-+        pointer++;
-+        break;
-+      case DIFF_DELETE:
-+        count_delete++;
-+        text_delete += diffs[pointer][1];
-+        pointer++;
-+        break;
-+      case DIFF_EQUAL:
-+        // Upon reaching an equality, check for prior redundancies.
-+        if (count_delete + count_insert > 1) {
-+          if (count_delete !== 0 && count_insert !== 0) {
-+            // Factor out any common prefixies.
-+            commonlength = this.diff_commonPrefix(text_insert, text_delete);
-+            if (commonlength !== 0) {
-+              if ((pointer - count_delete - count_insert) > 0 &&
-+                  diffs[pointer - count_delete - count_insert - 1][0] ==
-+                  DIFF_EQUAL) {
-+                diffs[pointer - count_delete - count_insert - 1][1] +=
-+                    text_insert.substring(0, commonlength);
-+              } else {
-+                diffs.splice(0, 0, [DIFF_EQUAL,
-+                                    text_insert.substring(0, commonlength)]);
-+                pointer++;
-+              }
-+              text_insert = text_insert.substring(commonlength);
-+              text_delete = text_delete.substring(commonlength);
-+            }
-+            // Factor out any common suffixies.
-+            commonlength = this.diff_commonSuffix(text_insert, text_delete);
-+            if (commonlength !== 0) {
-+              diffs[pointer][1] = text_insert.substring(text_insert.length -
-+                  commonlength) + diffs[pointer][1];
-+              text_insert = text_insert.substring(0, text_insert.length -
-+                  commonlength);
-+              text_delete = text_delete.substring(0, text_delete.length -
-+                  commonlength);
-+            }
-+          }
-+          // Delete the offending records and add the merged ones.
-+          if (count_delete === 0) {
-+            diffs.splice(pointer - count_delete - count_insert,
-+                count_delete + count_insert, [DIFF_INSERT, text_insert]);
-+          } else if (count_insert === 0) {
-+            diffs.splice(pointer - count_delete - count_insert,
-+                count_delete + count_insert, [DIFF_DELETE, text_delete]);
-+          } else {
-+            diffs.splice(pointer - count_delete - count_insert,
-+                count_delete + count_insert, [DIFF_DELETE, text_delete],
-+                [DIFF_INSERT, text_insert]);
-+          }
-+          pointer = pointer - count_delete - count_insert +
-+                    (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1;
-+        } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) {
-+          // Merge this equality with the previous one.
-+          diffs[pointer - 1][1] += diffs[pointer][1];
-+          diffs.splice(pointer, 1);
-+        } else {
-+          pointer++;
-+        }
-+        count_insert = 0;
-+        count_delete = 0;
-+        text_delete = '';
-+        text_insert = '';
-+        break;
-+    }
-+  }
-+  if (diffs[diffs.length - 1][1] === '') {
-+    diffs.pop();  // Remove the dummy entry at the end.
-+  }
-+
-+  // Second pass: look for single edits surrounded on both sides by equalities
-+  // which can be shifted sideways to eliminate an equality.
-+  // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC
-+  var changes = false;
-+  pointer = 1;
-+  // Intentionally ignore the first and last element (don't need checking).
-+  while (pointer < diffs.length - 1) {
-+    if (diffs[pointer - 1][0] == DIFF_EQUAL &&
-+        diffs[pointer + 1][0] == DIFF_EQUAL) {
-+      // This is a single edit surrounded by equalities.
-+      if (diffs[pointer][1].substring(diffs[pointer][1].length -
-+          diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) {
-+        // Shift the edit over the previous equality.
-+        diffs[pointer][1] = diffs[pointer - 1][1] +
-+            diffs[pointer][1].substring(0, diffs[pointer][1].length -
-+                                        diffs[pointer - 1][1].length);
-+        diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
-+        diffs.splice(pointer - 1, 1);
-+        changes = true;
-+      } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==
-+          diffs[pointer + 1][1]) {
-+        // Shift the edit over the next equality.
-+        diffs[pointer - 1][1] += diffs[pointer + 1][1];
-+        diffs[pointer][1] =
-+            diffs[pointer][1].substring(diffs[pointer + 1][1].length) +
-+            diffs[pointer + 1][1];
-+        diffs.splice(pointer + 1, 1);
-+        changes = true;
-+      }
-+    }
-+    pointer++;
-+  }
-+  // If shifts were made, the diff needs reordering and another shift sweep.
-+  if (changes) {
-+    this.diff_cleanupMerge(diffs);
-+  }
-+};
-+
-+
-+/**
-+ * loc is a location in text1, compute and return the equivalent location in
-+ * text2.
-+ * e.g. 'The cat' vs 'The big cat', 1->1, 5->8
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @param {number} loc Location within text1.
-+ * @return {number} Location within text2.
-+ */
-+diff_match_patch.prototype.diff_xIndex = function(diffs, loc) {
-+  var chars1 = 0;
-+  var chars2 = 0;
-+  var last_chars1 = 0;
-+  var last_chars2 = 0;
-+  var x;
-+  for (x = 0; x < diffs.length; x++) {
-+    if (diffs[x][0] !== DIFF_INSERT) {  // Equality or deletion.
-+      chars1 += diffs[x][1].length;
-+    }
-+    if (diffs[x][0] !== DIFF_DELETE) {  // Equality or insertion.
-+      chars2 += diffs[x][1].length;
-+    }
-+    if (chars1 > loc) {  // Overshot the location.
-+      break;
-+    }
-+    last_chars1 = chars1;
-+    last_chars2 = chars2;
-+  }
-+  // Was the location was deleted?
-+  if (diffs.length != x && diffs[x][0] === DIFF_DELETE) {
-+    return last_chars2;
-+  }
-+  // Add the remaining character length.
-+  return last_chars2 + (loc - last_chars1);
-+};
-+
-+
-+/**
-+ * Convert a diff array into a pretty HTML report.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @return {string} HTML representation.
-+ */
-+diff_match_patch.prototype.diff_prettyHtml = function(diffs) {
-+  var html = [];
-+  var i = 0;
-+  var pattern_amp = /&/g;
-+  var pattern_lt = /</g;
-+  var pattern_gt = />/g;
-+  var pattern_para = /\n/g;
-+  for (var x = 0; x < diffs.length; x++) {
-+    var op = diffs[x][0];    // Operation (insert, delete, equal)
-+    var data = diffs[x][1];  // Text of change.
-+    var text = data.replace(pattern_amp, '&').replace(pattern_lt, '<')
-+        .replace(pattern_gt, '>').replace(pattern_para, '¶<br>');
-+    switch (op) {
-+      case DIFF_INSERT:
-+        html[x] = '<ins style="background:#e6ffe6;">' + text + '</ins>';
-+        break;
-+      case DIFF_DELETE:
-+        html[x] = '<del style="background:#ffe6e6;">' + text + '</del>';
-+        break;
-+      case DIFF_EQUAL:
-+        html[x] = '<span>' + text + '</span>';
-+        break;
-+    }
-+    if (op !== DIFF_DELETE) {
-+      i += data.length;
-+    }
-+  }
-+  return html.join('');
-+};
-+
-+
-+/**
-+ * Compute and return the source text (all equalities and deletions).
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @return {string} Source text.
-+ */
-+diff_match_patch.prototype.diff_text1 = function(diffs) {
-+  var text = [];
-+  for (var x = 0; x < diffs.length; x++) {
-+    if (diffs[x][0] !== DIFF_INSERT) {
-+      text[x] = diffs[x][1];
-+    }
-+  }
-+  return text.join('');
-+};
-+
-+
-+/**
-+ * Compute and return the destination text (all equalities and insertions).
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @return {string} Destination text.
-+ */
-+diff_match_patch.prototype.diff_text2 = function(diffs) {
-+  var text = [];
-+  for (var x = 0; x < diffs.length; x++) {
-+    if (diffs[x][0] !== DIFF_DELETE) {
-+      text[x] = diffs[x][1];
-+    }
-+  }
-+  return text.join('');
-+};
-+
-+
-+/**
-+ * Compute the Levenshtein distance; the number of inserted, deleted or
-+ * substituted characters.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @return {number} Number of changes.
-+ */
-+diff_match_patch.prototype.diff_levenshtein = function(diffs) {
-+  var levenshtein = 0;
-+  var insertions = 0;
-+  var deletions = 0;
-+  for (var x = 0; x < diffs.length; x++) {
-+    var op = diffs[x][0];
-+    var data = diffs[x][1];
-+    switch (op) {
-+      case DIFF_INSERT:
-+        insertions += data.length;
-+        break;
-+      case DIFF_DELETE:
-+        deletions += data.length;
-+        break;
-+      case DIFF_EQUAL:
-+        // A deletion and an insertion is one substitution.
-+        levenshtein += Math.max(insertions, deletions);
-+        insertions = 0;
-+        deletions = 0;
-+        break;
-+    }
-+  }
-+  levenshtein += Math.max(insertions, deletions);
-+  return levenshtein;
-+};
-+
-+
-+/**
-+ * Crush the diff into an encoded string which describes the operations
-+ * required to transform text1 into text2.
-+ * E.g. =3\t-2\t+ing  -> Keep 3 chars, delete 2 chars, insert 'ing'.
-+ * Operations are tab-separated.  Inserted text is escaped using %xx notation.
-+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
-+ * @return {string} Delta text.
-+ */
-+diff_match_patch.prototype.diff_toDelta = function(diffs) {
-+  var text = [];
-+  for (var x = 0; x < diffs.length; x++) {
-+    switch (diffs[x][0]) {
-+      case DIFF_INSERT:
-+        text[x] = '+' + encodeURI(diffs[x][1]);
-+        break;
-+      case DIFF_DELETE:
-+        text[x] = '-' + diffs[x][1].length;
-+        break;
-+      case DIFF_EQUAL:
-+        text[x] = '=' + diffs[x][1].length;
-+        break;
-+    }
-+  }
-+  return text.join('\t').replace(/%20/g, ' ');
-+};
-+
-+
-+/**
-+ * Given the original text1, and an encoded string which describes the
-+ * operations required to transform text1 into text2, compute the full diff.
-+ * @param {string} text1 Source string for the diff.
-+ * @param {string} delta Delta text.
-+ * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
-+ * @throws {!Error} If invalid input.
-+ */
-+diff_match_patch.prototype.diff_fromDelta = function(text1, delta) {
-+  var diffs = [];
-+  var diffsLength = 0;  // Keeping our own length var is faster in JS.
-+  var pointer = 0;  // Cursor in text1
-+  var tokens = delta.split(/\t/g);
-+  for (var x = 0; x < tokens.length; x++) {
-+    // Each token begins with a one character parameter which specifies the
-+    // operation of this token (delete, insert, equality).
-+    var param = tokens[x].substring(1);
-+    switch (tokens[x].charAt(0)) {
-+      case '+':
-+        try {
-+          diffs[diffsLength++] = [DIFF_INSERT, decodeURI(param)];
-+        } catch (ex) {
-+          // Malformed URI sequence.
-+          throw new Error('Illegal escape in diff_fromDelta: ' + param);
-+        }
-+        break;
-+      case '-':
-+        // Fall through.
-+      case '=':
-+        var n = parseInt(param, 10);
-+        if (isNaN(n) || n < 0) {
-+          throw new Error('Invalid number in diff_fromDelta: ' + param);
-+        }
-+        var text = text1.substring(pointer, pointer += n);
-+        if (tokens[x].charAt(0) == '=') {
-+          diffs[diffsLength++] = [DIFF_EQUAL, text];
-+        } else {
-+          diffs[diffsLength++] = [DIFF_DELETE, text];
-+        }
-+        break;
-+      default:
-+        // Blank tokens are ok (from a trailing \t).
-+        // Anything else is an error.
-+        if (tokens[x]) {
-+          throw new Error('Invalid diff operation in diff_fromDelta: ' +
-+                          tokens[x]);
-+        }
-+    }
-+  }
-+  if (pointer != text1.length) {
-+    throw new Error('Delta length (' + pointer +
-+        ') does not equal source text length (' + text1.length + ').');
-+  }
-+  return diffs;
-+};
-+
-+
-+//  MATCH FUNCTIONS
-+
-+
-+/**
-+ * Locate the best instance of 'pattern' in 'text' near 'loc'.
-+ * @param {string} text The text to search.
-+ * @param {string} pattern The pattern to search for.
-+ * @param {number} loc The location to search around.
-+ * @return {number} Best match index or -1.
-+ */
-+diff_match_patch.prototype.match_main = function(text, pattern, loc) {
-+  // Check for null inputs.
-+  if (text == null || pattern == null || loc == null) {
-+    throw new Error('Null input. (match_main)');
-+  }
-+
-+  loc = Math.max(0, Math.min(loc, text.length));
-+  if (text == pattern) {
-+    // Shortcut (potentially not guaranteed by the algorithm)
-+    return 0;
-+  } else if (!text.length) {
-+    // Nothing to match.
-+    return -1;
-+  } else if (text.substring(loc, loc + pattern.length) == pattern) {
-+    // Perfect match at the perfect spot!  (Includes case of null pattern)
-+    return loc;
-+  } else {
-+    // Do a fuzzy compare.
-+    return this.match_bitap_(text, pattern, loc);
-+  }
-+};
-+
-+
-+/**
-+ * Locate the best instance of 'pattern' in 'text' near 'loc' using the
-+ * Bitap algorithm.
-+ * @param {string} text The text to search.
-+ * @param {string} pattern The pattern to search for.
-+ * @param {number} loc The location to search around.
-+ * @return {number} Best match index or -1.
-+ * @private
-+ */
-+diff_match_patch.prototype.match_bitap_ = function(text, pattern, loc) {
-+  if (pattern.length > this.Match_MaxBits) {
-+    throw new Error('Pattern too long for this browser.');
-+  }
-+
-+  // Initialise the alphabet.
-+  var s = this.match_alphabet_(pattern);
-+
-+  var dmp = this;  // 'this' becomes 'window' in a closure.
-+
-+  /**
-+   * Compute and return the score for a match with e errors and x location.
-+   * Accesses loc and pattern through being a closure.
-+   * @param {number} e Number of errors in match.
-+   * @param {number} x Location of match.
-+   * @return {number} Overall score for match (0.0 = good, 1.0 = bad).
-+   * @private
-+   */
-+  function match_bitapScore_(e, x) {
-+    var accuracy = e / pattern.length;
-+    var proximity = Math.abs(loc - x);
-+    if (!dmp.Match_Distance) {
-+      // Dodge divide by zero error.
-+      return proximity ? 1.0 : accuracy;
-+    }
-+    return accuracy + (proximity / dmp.Match_Distance);
-+  }
-+
-+  // Highest score beyond which we give up.
-+  var score_threshold = this.Match_Threshold;
-+  // Is there a nearby exact match? (speedup)
-+  var best_loc = text.indexOf(pattern, loc);
-+  if (best_loc != -1) {
-+    score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);
-+    // What about in the other direction? (speedup)
-+    best_loc = text.lastIndexOf(pattern, loc + pattern.length);
-+    if (best_loc != -1) {
-+      score_threshold =
-+          Math.min(match_bitapScore_(0, best_loc), score_threshold);
-+    }
-+  }
-+
-+  // Initialise the bit arrays.
-+  var matchmask = 1 << (pattern.length - 1);
-+  best_loc = -1;
-+
-+  var bin_min, bin_mid;
-+  var bin_max = pattern.length + text.length;
-+  var last_rd;
-+  for (var d = 0; d < pattern.length; d++) {
-+    // Scan for the best match; each iteration allows for one more error.
-+    // Run a binary search to determine how far from 'loc' we can stray at this
-+    // error level.
-+    bin_min = 0;
-+    bin_mid = bin_max;
-+    while (bin_min < bin_mid) {
-+      if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {
-+        bin_min = bin_mid;
-+      } else {
-+        bin_max = bin_mid;
-+      }
-+      bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);
-+    }
-+    // Use the result from this iteration as the maximum for the next.
-+    bin_max = bin_mid;
-+    var start = Math.max(1, loc - bin_mid + 1);
-+    var finish = Math.min(loc + bin_mid, text.length) + pattern.length;
-+
-+    var rd = Array(finish + 2);
-+    rd[finish + 1] = (1 << d) - 1;
-+    for (var j = finish; j >= start; j--) {
-+      // The alphabet (s) is a sparse hash, so the following line generates
-+      // warnings.
-+      var charMatch = s[text.charAt(j - 1)];
-+      if (d === 0) {  // First pass: exact match.
-+        rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
-+      } else {  // Subsequent passes: fuzzy match.
-+        rd[j] = ((rd[j + 1] << 1) | 1) & charMatch |
-+                (((last_rd[j + 1] | last_rd[j]) << 1) | 1) |
-+                last_rd[j + 1];
-+      }
-+      if (rd[j] & matchmask) {
-+        var score = match_bitapScore_(d, j - 1);
-+        // This match will almost certainly be better than any existing match.
-+        // But check anyway.
-+        if (score <= score_threshold) {
-+          // Told you so.
-+          score_threshold = score;
-+          best_loc = j - 1;
-+          if (best_loc > loc) {
-+            // When passing loc, don't exceed our current distance from loc.
-+            start = Math.max(1, 2 * loc - best_loc);
-+          } else {
-+            // Already passed loc, downhill from here on in.
-+            break;
-+          }
-+        }
-+      }
-+    }
-+    // No hope for a (better) match at greater error levels.
-+    if (match_bitapScore_(d + 1, loc) > score_threshold) {
-+      break;
-+    }
-+    last_rd = rd;
-+  }
-+  return best_loc;
-+};
-+
-+
-+/**
-+ * Initialise the alphabet for the Bitap algorithm.
-+ * @param {string} pattern The text to encode.
-+ * @return {!Object} Hash of character locations.
-+ * @private
-+ */
-+diff_match_patch.prototype.match_alphabet_ = function(pattern) {
-+  var s = {};
-+  for (var i = 0; i < pattern.length; i++) {
-+    s[pattern.charAt(i)] = 0;
-+  }
-+  for (var i = 0; i < pattern.length; i++) {
-+    s[pattern.charAt(i)] |= 1 << (pattern.length - i - 1);
-+  }
-+  return s;
-+};
-+
-+
-+//  PATCH FUNCTIONS
-+
-+
-+/**
-+ * Increase the context until it is unique,
-+ * but don't let the pattern expand beyond Match_MaxBits.
-+ * @param {!diff_match_patch.patch_obj} patch The patch to grow.
-+ * @param {string} text Source text.
-+ * @private
-+ */
-+diff_match_patch.prototype.patch_addContext_ = function(patch, text) {
-+  if (text.length == 0) {
-+    return;
-+  }
-+  var pattern = text.substring(patch.start2, patch.start2 + patch.length1);
-+  var padding = 0;
-+
-+  // Look for the first and last matches of pattern in text.  If two different
-+  // matches are found, increase the pattern length.
-+  while (text.indexOf(pattern) != text.lastIndexOf(pattern) &&
-+         pattern.length < this.Match_MaxBits - this.Patch_Margin -
-+         this.Patch_Margin) {
-+    padding += this.Patch_Margin;
-+    pattern = text.substring(patch.start2 - padding,
-+                             patch.start2 + patch.length1 + padding);
-+  }
-+  // Add one chunk for good luck.
-+  padding += this.Patch_Margin;
-+
-+  // Add the prefix.
-+  var prefix = text.substring(patch.start2 - padding, patch.start2);
-+  if (prefix) {
-+    patch.diffs.unshift([DIFF_EQUAL, prefix]);
-+  }
-+  // Add the suffix.
-+  var suffix = text.substring(patch.start2 + patch.length1,
-+                              patch.start2 + patch.length1 + padding);
-+  if (suffix) {
-+    patch.diffs.push([DIFF_EQUAL, suffix]);
-+  }
-+
-+  // Roll back the start points.
-+  patch.start1 -= prefix.length;
-+  patch.start2 -= prefix.length;
-+  // Extend the lengths.
-+  patch.length1 += prefix.length + suffix.length;
-+  patch.length2 += prefix.length + suffix.length;
-+};
-+
-+
-+/**
-+ * Compute a list of patches to turn text1 into text2.
-+ * Use diffs if provided, otherwise compute it ourselves.
-+ * There are four ways to call this function, depending on what data is
-+ * available to the caller:
-+ * Method 1:
-+ * a = text1, b = text2
-+ * Method 2:
-+ * a = diffs
-+ * Method 3 (optimal):
-+ * a = text1, b = diffs
-+ * Method 4 (deprecated, use method 3):
-+ * a = text1, b = text2, c = diffs
-+ *
-+ * @param {string|!Array.<!diff_match_patch.Diff>} a text1 (methods 1,3,4) or
-+ * Array of diff tuples for text1 to text2 (method 2).
-+ * @param {string|!Array.<!diff_match_patch.Diff>} opt_b text2 (methods 1,4) or
-+ * Array of diff tuples for text1 to text2 (method 3) or undefined (method 2).
-+ * @param {string|!Array.<!diff_match_patch.Diff>} opt_c Array of diff tuples
-+ * for text1 to text2 (method 4) or undefined (methods 1,2,3).
-+ * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
-+ */
-+diff_match_patch.prototype.patch_make = function(a, opt_b, opt_c) {
-+  var text1, diffs;
-+  if (typeof a == 'string' && typeof opt_b == 'string' &&
-+      typeof opt_c == 'undefined') {
-+    // Method 1: text1, text2
-+    // Compute diffs from text1 and text2.
-+    text1 = /** @type {string} */(a);
-+    diffs = this.diff_main(text1, /** @type {string} */(opt_b), true);
-+    if (diffs.length > 2) {
-+      this.diff_cleanupSemantic(diffs);
-+      this.diff_cleanupEfficiency(diffs);
-+    }
-+  } else if (a && typeof a == 'object' && typeof opt_b == 'undefined' &&
-+      typeof opt_c == 'undefined') {
-+    // Method 2: diffs
-+    // Compute text1 from diffs.
-+    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(a);
-+    text1 = this.diff_text1(diffs);
-+  } else if (typeof a == 'string' && opt_b && typeof opt_b == 'object' &&
-+      typeof opt_c == 'undefined') {
-+    // Method 3: text1, diffs
-+    text1 = /** @type {string} */(a);
-+    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_b);
-+  } else if (typeof a == 'string' && typeof opt_b == 'string' &&
-+      opt_c && typeof opt_c == 'object') {
-+    // Method 4: text1, text2, diffs
-+    // text2 is not used.
-+    text1 = /** @type {string} */(a);
-+    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_c);
-+  } else {
-+    throw new Error('Unknown call format to patch_make.');
-+  }
-+
-+  if (diffs.length === 0) {
-+    return [];  // Get rid of the null case.
-+  }
-+  var patches = [];
-+  var patch = new diff_match_patch.patch_obj();
-+  var patchDiffLength = 0;  // Keeping our own length var is faster in JS.
-+  var char_count1 = 0;  // Number of characters into the text1 string.
-+  var char_count2 = 0;  // Number of characters into the text2 string.
-+  // Start with text1 (prepatch_text) and apply the diffs until we arrive at
-+  // text2 (postpatch_text).  We recreate the patches one by one to determine
-+  // context info.
-+  var prepatch_text = text1;
-+  var postpatch_text = text1;
-+  for (var x = 0; x < diffs.length; x++) {
-+    var diff_type = diffs[x][0];
-+    var diff_text = diffs[x][1];
-+
-+    if (!patchDiffLength && diff_type !== DIFF_EQUAL) {
-+      // A new patch starts here.
-+      patch.start1 = char_count1;
-+      patch.start2 = char_count2;
-+    }
-+
-+    switch (diff_type) {
-+      case DIFF_INSERT:
-+        patch.diffs[patchDiffLength++] = diffs[x];
-+        patch.length2 += diff_text.length;
-+        postpatch_text = postpatch_text.substring(0, char_count2) + diff_text +
-+                         postpatch_text.substring(char_count2);
-+        break;
-+      case DIFF_DELETE:
-+        patch.length1 += diff_text.length;
-+        patch.diffs[patchDiffLength++] = diffs[x];
-+        postpatch_text = postpatch_text.substring(0, char_count2) +
-+                         postpatch_text.substring(char_count2 +
-+                             diff_text.length);
-+        break;
-+      case DIFF_EQUAL:
-+        if (diff_text.length <= 2 * this.Patch_Margin &&
-+            patchDiffLength && diffs.length != x + 1) {
-+          // Small equality inside a patch.
-+          patch.diffs[patchDiffLength++] = diffs[x];
-+          patch.length1 += diff_text.length;
-+          patch.length2 += diff_text.length;
-+        } else if (diff_text.length >= 2 * this.Patch_Margin) {
-+          // Time for a new patch.
-+          if (patchDiffLength) {
-+            this.patch_addContext_(patch, prepatch_text);
-+            patches.push(patch);
-+            patch = new diff_match_patch.patch_obj();
-+            patchDiffLength = 0;
-+            // Unlike Unidiff, our patch lists have a rolling context.
-+            // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff
-+            // Update prepatch text & pos to reflect the application of the
-+            // just completed patch.
-+            prepatch_text = postpatch_text;
-+            char_count1 = char_count2;
-+          }
-+        }
-+        break;
-+    }
-+
-+    // Update the current character count.
-+    if (diff_type !== DIFF_INSERT) {
-+      char_count1 += diff_text.length;
-+    }
-+    if (diff_type !== DIFF_DELETE) {
-+      char_count2 += diff_text.length;
-+    }
-+  }
-+  // Pick up the leftover patch if not empty.
-+  if (patchDiffLength) {
-+    this.patch_addContext_(patch, prepatch_text);
-+    patches.push(patch);
-+  }
-+
-+  return patches;
-+};
-+
-+
-+/**
-+ * Given an array of patches, return another array that is identical.
-+ * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
-+ * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
-+ */
-+diff_match_patch.prototype.patch_deepCopy = function(patches) {
-+  // Making deep copies is hard in JavaScript.
-+  var patchesCopy = [];
-+  for (var x = 0; x < patches.length; x++) {
-+    var patch = patches[x];
-+    var patchCopy = new diff_match_patch.patch_obj();
-+    patchCopy.diffs = [];
-+    for (var y = 0; y < patch.diffs.length; y++) {
-+      patchCopy.diffs[y] = patch.diffs[y].slice();
-+    }
-+    patchCopy.start1 = patch.start1;
-+    patchCopy.start2 = patch.start2;
-+    patchCopy.length1 = patch.length1;
-+    patchCopy.length2 = patch.length2;
-+    patchesCopy[x] = patchCopy;
-+  }
-+  return patchesCopy;
-+};
-+
-+
-+/**
-+ * Merge a set of patches onto the text.  Return a patched text, as well
-+ * as a list of true/false values indicating which patches were applied.
-+ * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
-+ * @param {string} text Old text.
-+ * @return {!Array.<string|!Array.<boolean>>} Two element Array, containing the
-+ *      new text and an array of boolean values.
-+ */
-+diff_match_patch.prototype.patch_apply = function(patches, text) {
-+  if (patches.length == 0) {
-+    return [text, []];
-+  }
-+
-+  // Deep copy the patches so that no changes are made to originals.
-+  patches = this.patch_deepCopy(patches);
-+
-+  var nullPadding = this.patch_addPadding(patches);
-+  text = nullPadding + text + nullPadding;
-+
-+  this.patch_splitMax(patches);
-+  // delta keeps track of the offset between the expected and actual location
-+  // of the previous patch.  If there are patches expected at positions 10 and
-+  // 20, but the first patch was found at 12, delta is 2 and the second patch
-+  // has an effective expected position of 22.
-+  var delta = 0;
-+  var results = [];
-+  for (var x = 0; x < patches.length; x++) {
-+    var expected_loc = patches[x].start2 + delta;
-+    var text1 = this.diff_text1(patches[x].diffs);
-+    var start_loc;
-+    var end_loc = -1;
-+    if (text1.length > this.Match_MaxBits) {
-+      // patch_splitMax will only provide an oversized pattern in the case of
-+      // a monster delete.
-+      start_loc = this.match_main(text, text1.substring(0, this.Match_MaxBits),
-+                                  expected_loc);
-+      if (start_loc != -1) {
-+        end_loc = this.match_main(text,
-+            text1.substring(text1.length - this.Match_MaxBits),
-+            expected_loc + text1.length - this.Match_MaxBits);
-+        if (end_loc == -1 || start_loc >= end_loc) {
-+          // Can't find valid trailing context.  Drop this patch.
-+          start_loc = -1;
-+        }
-+      }
-+    } else {
-+      start_loc = this.match_main(text, text1, expected_loc);
-+    }
-+    if (start_loc == -1) {
-+      // No match found.  :(
-+      results[x] = false;
-+      // Subtract the delta for this failed patch from subsequent patches.
-+      delta -= patches[x].length2 - patches[x].length1;
-+    } else {
-+      // Found a match.  :)
-+      results[x] = true;
-+      delta = start_loc - expected_loc;
-+      var text2;
-+      if (end_loc == -1) {
-+        text2 = text.substring(start_loc, start_loc + text1.length);
-+      } else {
-+        text2 = text.substring(start_loc, end_loc + this.Match_MaxBits);
-+      }
-+      if (text1 == text2) {
-+        // Perfect match, just shove the replacement text in.
-+        text = text.substring(0, start_loc) +
-+               this.diff_text2(patches[x].diffs) +
-+               text.substring(start_loc + text1.length);
-+      } else {
-+        // Imperfect match.  Run a diff to get a framework of equivalent
-+        // indices.
-+        var diffs = this.diff_main(text1, text2, false);
-+        if (text1.length > this.Match_MaxBits &&
-+            this.diff_levenshtein(diffs) / text1.length >
-+            this.Patch_DeleteThreshold) {
-+          // The end points match, but the content is unacceptably bad.
-+          results[x] = false;
-+        } else {
-+          this.diff_cleanupSemanticLossless(diffs);
-+          var index1 = 0;
-+          var index2;
-+          for (var y = 0; y < patches[x].diffs.length; y++) {
-+            var mod = patches[x].diffs[y];
-+            if (mod[0] !== DIFF_EQUAL) {
-+              index2 = this.diff_xIndex(diffs, index1);
-+            }
-+            if (mod[0] === DIFF_INSERT) {  // Insertion
-+              text = text.substring(0, start_loc + index2) + mod[1] +
-+                     text.substring(start_loc + index2);
-+            } else if (mod[0] === DIFF_DELETE) {  // Deletion
-+              text = text.substring(0, start_loc + index2) +
-+                     text.substring(start_loc + this.diff_xIndex(diffs,
-+                         index1 + mod[1].length));
-+            }
-+            if (mod[0] !== DIFF_DELETE) {
-+              index1 += mod[1].length;
-+            }
-+          }
-+        }
-+      }
-+    }
-+  }
-+  // Strip the padding off.
-+  text = text.substring(nullPadding.length, text.length - nullPadding.length);
-+  return [text, results];
-+};
-+
-+
-+/**
-+ * Add some padding on text start and end so that edges can match something.
-+ * Intended to be called only from within patch_apply.
-+ * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
-+ * @return {string} The padding string added to each side.
-+ */
-+diff_match_patch.prototype.patch_addPadding = function(patches) {
-+  var paddingLength = this.Patch_Margin;
-+  var nullPadding = '';
-+  for (var x = 1; x <= paddingLength; x++) {
-+    nullPadding += String.fromCharCode(x);
-+  }
-+
-+  // Bump all the patches forward.
-+  for (var x = 0; x < patches.length; x++) {
-+    patches[x].start1 += paddingLength;
-+    patches[x].start2 += paddingLength;
-+  }
-+
-+  // Add some padding on start of first diff.
-+  var patch = patches[0];
-+  var diffs = patch.diffs;
-+  if (diffs.length == 0 || diffs[0][0] != DIFF_EQUAL) {
-+    // Add nullPadding equality.
-+    diffs.unshift([DIFF_EQUAL, nullPadding]);
-+    patch.start1 -= paddingLength;  // Should be 0.
-+    patch.start2 -= paddingLength;  // Should be 0.
-+    patch.length1 += paddingLength;
-+    patch.length2 += paddingLength;
-+  } else if (paddingLength > diffs[0][1].length) {
-+    // Grow first equality.
-+    var extraLength = paddingLength - diffs[0][1].length;
-+    diffs[0][1] = nullPadding.substring(diffs[0][1].length) + diffs[0][1];
-+    patch.start1 -= extraLength;
-+    patch.start2 -= extraLength;
-+    patch.length1 += extraLength;
-+    patch.length2 += extraLength;
-+  }
-+
-+  // Add some padding on end of last diff.
-+  patch = patches[patches.length - 1];
-+  diffs = patch.diffs;
-+  if (diffs.length == 0 || diffs[diffs.length - 1][0] != DIFF_EQUAL) {
-+    // Add nullPadding equality.
-+    diffs.push([DIFF_EQUAL, nullPadding]);
-+    patch.length1 += paddingLength;
-+    patch.length2 += paddingLength;
-+  } else if (paddingLength > diffs[diffs.length - 1][1].length) {
-+    // Grow last equality.
-+    var extraLength = paddingLength - diffs[diffs.length - 1][1].length;
-+    diffs[diffs.length - 1][1] += nullPadding.substring(0, extraLength);
-+    patch.length1 += extraLength;
-+    patch.length2 += extraLength;
-+  }
-+
-+  return nullPadding;
-+};
-+
-+
-+/**
-+ * Look through the patches and break up any which are longer than the maximum
-+ * limit of the match algorithm.
-+ * Intended to be called only from within patch_apply.
-+ * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
-+ */
-+diff_match_patch.prototype.patch_splitMax = function(patches) {
-+  var patch_size = this.Match_MaxBits;
-+  for (var x = 0; x < patches.length; x++) {
-+    if (patches[x].length1 > patch_size) {
-+      var bigpatch = patches[x];
-+      // Remove the big old patch.
-+      patches.splice(x--, 1);
-+      var start1 = bigpatch.start1;
-+      var start2 = bigpatch.start2;
-+      var precontext = '';
-+      while (bigpatch.diffs.length !== 0) {
-+        // Create one of several smaller patches.
-+        var patch = new diff_match_patch.patch_obj();
-+        var empty = true;
-+        patch.start1 = start1 - precontext.length;
-+        patch.start2 = start2 - precontext.length;
-+        if (precontext !== '') {
-+          patch.length1 = patch.length2 = precontext.length;
-+          patch.diffs.push([DIFF_EQUAL, precontext]);
-+        }
-+        while (bigpatch.diffs.length !== 0 &&
-+               patch.length1 < patch_size - this.Patch_Margin) {
-+          var diff_type = bigpatch.diffs[0][0];
-+          var diff_text = bigpatch.diffs[0][1];
-+          if (diff_type === DIFF_INSERT) {
-+            // Insertions are harmless.
-+            patch.length2 += diff_text.length;
-+            start2 += diff_text.length;
-+            patch.diffs.push(bigpatch.diffs.shift());
-+            empty = false;
-+          } else if (diff_type === DIFF_DELETE && patch.diffs.length == 1 &&
-+                     patch.diffs[0][0] == DIFF_EQUAL &&
-+                     diff_text.length > 2 * patch_size) {
-+            // This is a large deletion.  Let it pass in one chunk.
-+            patch.length1 += diff_text.length;
-+            start1 += diff_text.length;
-+            empty = false;
-+            patch.diffs.push([diff_type, diff_text]);
-+            bigpatch.diffs.shift();
-+          } else {
-+            // Deletion or equality.  Only take as much as we can stomach.
-+            diff_text = diff_text.substring(0,
-+                patch_size - patch.length1 - this.Patch_Margin);
-+            patch.length1 += diff_text.length;
-+            start1 += diff_text.length;
-+            if (diff_type === DIFF_EQUAL) {
-+              patch.length2 += diff_text.length;
-+              start2 += diff_text.length;
-+            } else {
-+              empty = false;
-+            }
-+            patch.diffs.push([diff_type, diff_text]);
-+            if (diff_text == bigpatch.diffs[0][1]) {
-+              bigpatch.diffs.shift();
-+            } else {
-+              bigpatch.diffs[0][1] =
-+                  bigpatch.diffs[0][1].substring(diff_text.length);
-+            }
-+          }
-+        }
-+        // Compute the head context for the next patch.
-+        precontext = this.diff_text2(patch.diffs);
-+        precontext =
-+            precontext.substring(precontext.length - this.Patch_Margin);
-+        // Append the end context for this patch.
-+        var postcontext = this.diff_text1(bigpatch.diffs)
-+                              .substring(0, this.Patch_Margin);
-+        if (postcontext !== '') {
-+          patch.length1 += postcontext.length;
-+          patch.length2 += postcontext.length;
-+          if (patch.diffs.length !== 0 &&
-+              patch.diffs[patch.diffs.length - 1][0] === DIFF_EQUAL) {
-+            patch.diffs[patch.diffs.length - 1][1] += postcontext;
-+          } else {
-+            patch.diffs.push([DIFF_EQUAL, postcontext]);
-+          }
-+        }
-+        if (!empty) {
-+          patches.splice(++x, 0, patch);
-+        }
-+      }
-+    }
-+  }
-+};
-+
-+
-+/**
-+ * Take a list of patches and return a textual representation.
-+ * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
-+ * @return {string} Text representation of patches.
-+ */
-+diff_match_patch.prototype.patch_toText = function(patches) {
-+  var text = [];
-+  for (var x = 0; x < patches.length; x++) {
-+    text[x] = patches[x];
-+  }
-+  return text.join('');
-+};
-+
-+
-+/**
-+ * Parse a textual representation of patches and return a list of patch objects.
-+ * @param {string} textline Text representation of patches.
-+ * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
-+ * @throws {!Error} If invalid input.
-+ */
-+diff_match_patch.prototype.patch_fromText = function(textline) {
-+  var patches = [];
-+  if (!textline) {
-+    return patches;
-+  }
-+  var text = textline.split('\n');
-+  var textPointer = 0;
-+  var patchHeader = /^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;
-+  while (textPointer < text.length) {
-+    var m = text[textPointer].match(patchHeader);
-+    if (!m) {
-+      throw new Error('Invalid patch string: ' + text[textPointer]);
-+    }
-+    var patch = new diff_match_patch.patch_obj();
-+    patches.push(patch);
-+    patch.start1 = parseInt(m[1], 10);
-+    if (m[2] === '') {
-+      patch.start1--;
-+      patch.length1 = 1;
-+    } else if (m[2] == '0') {
-+      patch.length1 = 0;
-+    } else {
-+      patch.start1--;
-+      patch.length1 = parseInt(m[2], 10);
-+    }
-+
-+    patch.start2 = parseInt(m[3], 10);
-+    if (m[4] === '') {
-+      patch.start2--;
-+      patch.length2 = 1;
-+    } else if (m[4] == '0') {
-+      patch.length2 = 0;
-+    } else {
-+      patch.start2--;
-+      patch.length2 = parseInt(m[4], 10);
-+    }
-+    textPointer++;
-+
-+    while (textPointer < text.length) {
-+      var sign = text[textPointer].charAt(0);
-+      try {
-+        var line = decodeURI(text[textPointer].substring(1));
-+      } catch (ex) {
-+        // Malformed URI sequence.
-+        throw new Error('Illegal escape in patch_fromText: ' + line);
-+      }
-+      if (sign == '-') {
-+        // Deletion.
-+        patch.diffs.push([DIFF_DELETE, line]);
-+      } else if (sign == '+') {
-+        // Insertion.
-+        patch.diffs.push([DIFF_INSERT, line]);
-+      } else if (sign == ' ') {
-+        // Minor equality.
-+        patch.diffs.push([DIFF_EQUAL, line]);
-+      } else if (sign == '@') {
-+        // Start of next patch.
-+        break;
-+      } else if (sign === '') {
-+        // Blank line?  Whatever.
-+      } else {
-+        // WTF?
-+        throw new Error('Invalid patch mode "' + sign + '" in: ' + line);
-+      }
-+      textPointer++;
-+    }
-+  }
-+  return patches;
-+};
-+
-+
-+/**
-+ * Class representing one patch operation.
-+ * @constructor
-+ */
-+diff_match_patch.patch_obj = function() {
-+  /** @type {!Array.<!diff_match_patch.Diff>} */
-+  this.diffs = [];
-+  /** @type {?number} */
-+  this.start1 = null;
-+  /** @type {?number} */
-+  this.start2 = null;
-+  /** @type {number} */
-+  this.length1 = 0;
-+  /** @type {number} */
-+  this.length2 = 0;
-+};
-+
-+
-+/**
-+ * Emmulate GNU diff's format.
-+ * Header: @@ -382,8 +481,9 @@
-+ * Indicies are printed as 1-based, not 0-based.
-+ * @return {string} The GNU diff string.
-+ */
-+diff_match_patch.patch_obj.prototype.toString = function() {
-+  var coords1, coords2;
-+  if (this.length1 === 0) {
-+    coords1 = this.start1 + ',0';
-+  } else if (this.length1 == 1) {
-+    coords1 = this.start1 + 1;
-+  } else {
-+    coords1 = (this.start1 + 1) + ',' + this.length1;
-+  }
-+  if (this.length2 === 0) {
-+    coords2 = this.start2 + ',0';
-+  } else if (this.length2 == 1) {
-+    coords2 = this.start2 + 1;
-+  } else {
-+    coords2 = (this.start2 + 1) + ',' + this.length2;
-+  }
-+  var text = ['@@ -' + coords1 + ' +' + coords2 + ' @@\n'];
-+  var op;
-+  // Escape the body of the patch with %xx notation.
-+  for (var x = 0; x < this.diffs.length; x++) {
-+    switch (this.diffs[x][0]) {
-+      case DIFF_INSERT:
-+        op = '+';
-+        break;
-+      case DIFF_DELETE:
-+        op = '-';
-+        break;
-+      case DIFF_EQUAL:
-+        op = ' ';
-+        break;
-+    }
-+    text[x + 1] = op + encodeURI(this.diffs[x][1]) + '\n';
-+  }
-+  return text.join('').replace(/%20/g, ' ');
-+};
-+
-+
-+// Export these global variables so that they survive Google's JS compiler.
-+// In a browser, 'this' will be 'window'.
-+// In node.js 'this' will be a global object.
-+this['diff_match_patch'] = diff_match_patch;
-+this['DIFF_DELETE'] = DIFF_DELETE;
-+this['DIFF_INSERT'] = DIFF_INSERT;
-+this['DIFF_EQUAL'] = DIFF_EQUAL;
-+
-+
-+},{}],13:[function(require,module,exports){
-+
-+var Pipe = require('../pipe').Pipe;
-+
-+var Context = function Context(){
-+};
-+
-+Context.prototype.setResult = function(result) {
-+	this.result = result;
-+	this.hasResult = true;
-+	return this;
-+};
-+
-+Context.prototype.exit = function() {
-+	this.exiting = true;
-+	return this;
-+};
-+
-+Context.prototype.switchTo = function(next, pipe) {
-+	if (typeof next === 'string' || next instanceof Pipe) {
-+		this.nextPipe = next;
-+	} else {
-+		this.next = next;
-+		if (pipe) {
-+			this.nextPipe = pipe;
-+		}
-+	}
-+	return this;
-+};
-+
-+Context.prototype.push = function(child, name) {
-+	child.parent = this;
-+	if (typeof name !== 'undefined') {
-+		child.childName = name;
-+	}
-+	child.root = this.root || this;
-+	child.options = child.options || this.options;
-+	if (!this.children) {
-+		this.children = [child];
-+		this.nextAfterChildren = this.next || null;
-+		this.next = child;
-+	} else {
-+		this.children[this.children.length - 1].next = child;
-+		this.children.push(child);
-+	}
-+	child.next = this;
-+	return this;
-+};
-+
-+exports.Context = Context;
-+},{"../pipe":26}],14:[function(require,module,exports){
-+
-+var Context = require('./context').Context;
-+
-+var DiffContext = function DiffContext(left, right){
-+    this.left = left;
-+    this.right = right;
-+    this.pipe = 'diff';
-+};
-+
-+DiffContext.prototype = new Context();
-+
-+exports.DiffContext = DiffContext;
-+},{"./context":13}],15:[function(require,module,exports){
-+
-+var Context = require('./context').Context;
-+
-+var PatchContext = function PatchContext(left, delta){
-+    this.left = left;
-+    this.delta = delta;
-+    this.pipe = 'patch';
-+};
-+
-+PatchContext.prototype = new Context();
-+
-+exports.PatchContext = PatchContext;
-+},{"./context":13}],16:[function(require,module,exports){
-+
-+var Context = require('./context').Context;
-+
-+var ReverseContext = function ReverseContext(delta){
-+    this.delta = delta;
-+    this.pipe = 'reverse';
-+};
-+
-+ReverseContext.prototype = new Context();
-+
-+exports.ReverseContext = ReverseContext;
-+},{"./context":13}],17:[function(require,module,exports){
-+
-+// use as 2nd parameter for JSON.parse to revive Date instances
-+module.exports = function dateReviver(key, value) {
-+    var parts;
-+    if (typeof value === 'string') {
-+        parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d*))?(Z|([+\-])(\d{2}):(\d{2}))$/.exec(value);
-+        if (parts) {
-+            return new Date(Date.UTC(+parts[1], +parts[2] - 1, +parts[3],
-+              +parts[4], +parts[5], +parts[6], +(parts[7] || 0)));
-+        }
-+    }
-+    return value;
-+};
-+
-+},{}],18:[function(require,module,exports){
-+
-+var Processor = require('./processor').Processor;
-+var Pipe = require('./pipe').Pipe;
-+var DiffContext = require('./contexts/diff').DiffContext;
-+var PatchContext = require('./contexts/patch').PatchContext;
-+var ReverseContext = require('./contexts/reverse').ReverseContext;
-+
-+var trivial = require('./filters/trivial');
-+var nested = require('./filters/nested');
-+var arrays = require('./filters/arrays');
-+var dates = require('./filters/dates');
-+var texts = require('./filters/texts');
-+
-+var DiffPatcher = function DiffPatcher(options){
-+    this.processor = new Processor(options);
-+    this.processor.pipe(new Pipe('diff').append(
-+        nested.collectChildrenDiffFilter,
-+        trivial.diffFilter,
-+        dates.diffFilter,
-+        texts.diffFilter,
-+        nested.objectsDiffFilter,
-+        arrays.diffFilter
-+        ).shouldHaveResult());
-+    this.processor.pipe(new Pipe('patch').append(
-+        nested.collectChildrenPatchFilter,
-+        arrays.collectChildrenPatchFilter,
-+        trivial.patchFilter,
-+        texts.patchFilter,
-+        nested.patchFilter,
-+        arrays.patchFilter
-+        ).shouldHaveResult());
-+    this.processor.pipe(new Pipe('reverse').append(
-+        nested.collectChildrenReverseFilter,
-+        arrays.collectChildrenReverseFilter,
-+        trivial.reverseFilter,
-+        texts.reverseFilter,
-+        nested.reverseFilter,
-+        arrays.reverseFilter
-+        ).shouldHaveResult());
-+};
-+
-+DiffPatcher.prototype.options = function() {
-+    return this.processor.options.apply(this.processor, arguments);
-+};
-+
-+DiffPatcher.prototype.diff = function(left, right) {
-+    return this.processor.process(new DiffContext(left, right));
-+};
-+
-+DiffPatcher.prototype.patch = function(left, delta) {
-+    return this.processor.process(new PatchContext(left, delta));
-+};
-+
-+DiffPatcher.prototype.reverse = function(delta) {
-+    return this.processor.process(new ReverseContext(delta));
-+};
-+
-+DiffPatcher.prototype.unpatch = function(right, delta) {
-+    return this.patch(right, this.reverse(delta));
-+};
-+
-+exports.DiffPatcher = DiffPatcher;
-+
-+},{"./contexts/diff":14,"./contexts/patch":15,"./contexts/reverse":16,"./filters/arrays":19,"./filters/dates":20,"./filters/nested":22,"./filters/texts":23,"./filters/trivial":24,"./pipe":26,"./processor":27}],19:[function(require,module,exports){
-+
-+var DiffContext = require('../contexts/diff').DiffContext;
-+var PatchContext = require('../contexts/patch').PatchContext;
-+var ReverseContext = require('../contexts/reverse').ReverseContext;
-+
-+var lcs = require('./lcs');
-+
-+var ARRAY_MOVE = 3;
-+
-+var isArray = (typeof Array.isArray === 'function') ?
-+    // use native function
-+    Array.isArray :
-+    // use instanceof operator
-+    function(a) {
-+        return a instanceof Array;
-+    };
-+
-+var arrayIndexOf = typeof Array.prototype.indexOf === 'function' ?
-+    function(array, item) {
-+        return array.indexOf(item);
-+    } : function(array, item) {
-+        var length = array.length;
-+        for (var i = 0; i < length; i++) {
-+            if (array[i] === item) {
-+                return i;
-+            }
-+        }
-+        return -1;
-+    };
-+
-+var diffFilter = function arraysDiffFilter(context){
-+    if (!context.leftIsArray) { return; }
-+
-+    var objectHash = context.options && context.options.objectHash;
-+
-+    var match = function(array1, array2, index1, index2, context) {
-+        var value1 = array1[index1];
-+        var value2 = array2[index2];
-+        if (value1 === value2) {
-+            return true;
-+        }
-+        if (typeof value1 !== 'object' || typeof value2 !== 'object') {
-+            return false;
-+        }
-+        if (!objectHash) { return false; }
-+        var hash1, hash2;
-+        if (typeof index1 === 'number') {
-+            context.hashCache1 = context.hashCache1 || [];
-+            hash1 = context.hashCache1[index1];
-+            if (typeof hash1 === 'undefined') {
-+                context.hashCache1[index1] = hash1 = objectHash(value1, index1);
-+            }
-+        } else {
-+            hash1 = objectHash(value1);
-+        }
-+        if (typeof hash1 === 'undefined') {
-+            return false;
-+        }
-+        if (typeof index2 === 'number') {
-+            context.hashCache2 = context.hashCache2 || [];
-+            hash2 = context.hashCache2[index2];
-+            if (typeof hash2 === 'undefined') {
-+                context.hashCache2[index2] = hash2 = objectHash(value2, index2);
-+            }
-+        } else {
-+            hash2 = objectHash(value2);
-+        }
-+        if (typeof hash2 === 'undefined') {
-+            return false;
-+        }
-+        return hash1 === hash2;
-+    };
-+
-+    var matchContext = {};
-+    var commonHead = 0, commonTail = 0, index, index1, index2;
-+    var array1 = context.left;
-+    var array2 = context.right;
-+    var len1 = array1.length;
-+    var len2 = array2.length;
-+
-+    var child;
-+
-+    // separate common head
-+    while (commonHead < len1 && commonHead < len2 &&
-+        match(array1, array2, commonHead, commonHead, matchContext)) {
-+        index = commonHead;
-+        child = new DiffContext(context.left[index], context.right[index]);
-+        context.push(child, index);
-+        commonHead++;
-+    }
-+    // separate common tail
-+    while (commonTail + commonHead < len1 && commonTail + commonHead < len2 &&
-+        match(array1, array2, len1 - 1 - commonTail, len2 - 1 - commonTail, matchContext)) {
-+        index1 = len1 - 1 - commonTail;
-+        index2 = len2 - 1 - commonTail;
-+        child = new DiffContext(context.left[index1], context.right[index2]);
-+        context.push(child, index2);
-+        commonTail++;
-+    }
-+    var result;
-+    if (commonHead + commonTail === len1) {
-+        if (len1 === len2) {
-+            // arrays are identical
-+            context.setResult(undefined).exit();
-+            return;
-+        }
-+        // trivial case, a block (1 or more consecutive items) was added
-+        result = result || { _t: 'a' };
-+        for (index = commonHead; index < len2 - commonTail; index++) {
-+            result[index] = [array2[index]];
-+        }
-+        context.setResult(result).exit();
-+        return;
-+    }
-+    if (commonHead + commonTail === len2) {
-+        // trivial case, a block (1 or more consecutive items) was removed
-+        result = result || { _t: 'a' };
-+        for (index = commonHead; index < len1 - commonTail; index++) {
-+            result['_'+index] = [array1[index], 0, 0];
-+        }
-+        context.setResult(result).exit();
-+        return;
-+    }
-+    // reset hash cache
-+    matchContext = {};
-+    // diff is not trivial, find the LCS (Longest Common Subsequence)
-+    var trimmed1 = array1.slice(commonHead, len1 - commonTail);
-+    var trimmed2 = array2.slice(commonHead, len2 - commonTail);
-+    var seq = lcs.get(
-+        trimmed1, trimmed2,
-+        match,
-+        matchContext
-+    );
-+    var removedItems = [];
-+    result = result || { _t: 'a' };
-+    for (index = commonHead; index < len1 - commonTail; index++) {
-+        if (arrayIndexOf(seq.indices1, index - commonHead) < 0) {
-+            // removed
-+            result['_'+index] = [array1[index], 0, 0];
-+            removedItems.push(index);
-+        }
-+    }
-+
-+    var detectMove = true;
-+    if (context.options && context.options.arrays && context.options.arrays.detectMove === false) {
-+        detectMove = false;
-+    }
-+    var includeValueOnMove = false;
-+    if (context.options && context.options.arrays && context.options.arrays.includeValueOnMove) {
-+        includeValueOnMove = true;
-+    }
-+
-+    var removedItemsLength = removedItems.length;
-+    for (index = commonHead; index < len2 - commonTail; index++) {
-+        var indexOnArray2 = arrayIndexOf(seq.indices2, index - commonHead);
-+        if (indexOnArray2 < 0) {
-+            // added, try to match with a removed item and register as position move
-+            var isMove = false;
-+            if (detectMove && removedItemsLength > 0) {
-+                for (var removeItemIndex1 = 0; removeItemIndex1 < removedItemsLength; removeItemIndex1++) {
-+                    index1 = removedItems[removeItemIndex1];
-+                    if (match(trimmed1, trimmed2, index1 - commonHead,
-+                        index - commonHead, matchContext)) {
-+                        // store position move as: [originalValue, newPosition, ARRAY_MOVE]
-+                        result['_' + index1].splice(1, 2, index, ARRAY_MOVE);
-+                        if (!includeValueOnMove) {
-+                            // don't include moved value on diff, to save bytes
-+                            result['_' + index1][0] = '';
-+                        }
-+
-+                        index2 = index;
-+                        child = new DiffContext(context.left[index1], context.right[index2]);
-+                        context.push(child, index2);
-+                        removedItems.splice(removeItemIndex1, 1);
-+                        isMove = true;
-+                        break;
-+                    }
-+                }
-+            }
-+            if (!isMove) {
-+                // added
-+                result[index] = [array2[index]];
-+            }
-+        } else {
-+            // match, do inner diff
-+            index1 = seq.indices1[indexOnArray2] + commonHead;
-+            index2 = seq.indices2[indexOnArray2] + commonHead;
-+            child = new DiffContext(context.left[index1], context.right[index2]);
-+            context.push(child, index2);
-+        }
-+    }
-+
-+    context.setResult(result).exit();
-+
-+};
-+diffFilter.filterName = 'arrays';
-+
-+var compare = {
-+    numerically: function(a, b) {
-+        return a - b;
-+    },
-+    numericallyBy: function(name) {
-+        return function(a, b) {
-+            return a[name] - b[name];
-+        };
-+    }
-+};
-+
-+var patchFilter = function nestedPatchFilter(context) {
-+    if (!context.nested) { return; }
-+    if (context.delta._t !== 'a') { return; }
-+    var index, index1;
-+
-+    var delta = context.delta;
-+    var array = context.left;
-+
-+    // first, separate removals, insertions and modifications
-+    var toRemove = [];
-+    var toInsert = [];
-+    var toModify = [];
-+    for (index in delta) {
-+        if (index !== '_t') {
-+            if (index[0] === '_') {
-+                // removed item from original array
-+                if (delta[index][2] === 0 || delta[index][2] === ARRAY_MOVE) {
-+                    toRemove.push(parseInt(index.slice(1), 10));
-+                } else {
-+                    throw new Error('only removal or move can be applied at original array indices' +
-+                        ', invalid diff type: ' + delta[index][2]);
-+                }
-+            } else {
-+                if (delta[index].length === 1) {
-+                    // added item at new array
-+                    toInsert.push({
-+                        index: parseInt(index, 10),
-+                        value: delta[index][0]
-+                    });
-+                } else {
-+                    // modified item at new array
-+                    toModify.push({
-+                        index: parseInt(index, 10),
-+                        delta: delta[index]
-+                    });
-+                }
-+            }
-+        }
-+    }
-+
-+    // remove items, in reverse order to avoid sawing our own floor
-+    toRemove = toRemove.sort(compare.numerically);
-+    for (index = toRemove.length - 1; index >= 0; index--) {
-+        index1 = toRemove[index];
-+        var indexDiff = delta['_' + index1];
-+        var removedValue = array.splice(index1, 1)[0];
-+        if (indexDiff[2] === ARRAY_MOVE) {
-+            // reinsert later
-+            toInsert.push({
-+                index: indexDiff[1],
-+                value: removedValue
-+            });
-+        }
-+    }
-+
-+    // insert items, in reverse order to avoid moving our own floor
-+    toInsert = toInsert.sort(compare.numericallyBy('index'));
-+    var toInsertLength = toInsert.length;
-+    for (index = 0; index < toInsertLength; index++) {
-+        var insertion = toInsert[index];
-+        array.splice(insertion.index, 0, insertion.value);
-+    }
-+
-+    // apply modifications
-+    var toModifyLength = toModify.length;
-+    var child;
-+    if (toModifyLength > 0) {
-+        for (index = 0; index < toModifyLength; index++) {
-+            var modification = toModify[index];
-+            child = new PatchContext(context.left[modification.index], modification.delta);
-+            context.push(child, modification.index);
-+        }
-+    }
-+
-+    if (!context.children) {
-+        context.setResult(context.left).exit();
-+        return;
-+    }
-+    context.exit();
-+};
-+patchFilter.filterName = 'arrays';
-+
-+var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
-+    if (!context || !context.children) { return; }
-+    if (context.delta._t !== 'a') { return; }
-+    var length = context.children.length;
-+    var child;
-+    for (var index = 0; index < length; index++) {
-+        child = context.children[index];
-+        context.left[child.childName] = child.result;
-+    }
-+    context.setResult(context.left).exit();
-+};
-+collectChildrenPatchFilter.filterName = 'arraysCollectChildren';
-+
-+var reverseFilter = function arraysReverseFilter(context) {
-+    if (!context.nested) {
-+        if (context.delta[2] === ARRAY_MOVE) {
-+            context.newName = '_' + context.delta[1];
-+            context.setResult([context.delta[0], parseInt(context.childName.substr(1), 10), ARRAY_MOVE]).exit();
-+        }
-+        return;
-+    }
-+    if (context.delta._t !== 'a') { return; }
-+    var name, child;
-+    for (name in context.delta) {
-+        if (name === '_t') { continue; }
-+        child = new ReverseContext(context.delta[name]);
-+        context.push(child, name);
-+    }
-+    context.exit();
-+};
-+reverseFilter.filterName = 'arrays';
-+
-+var reverseArrayDeltaIndex = function(delta, index, itemDelta) {
-+    var newIndex = index;
-+    if (typeof index === 'string' && index[0] === '_') {
-+        newIndex = parseInt(index.substr(1), 10);
-+    } else {
-+        var uindex = '_' + index;
-+        if (isArray(itemDelta) && itemDelta[2] === 0) {
-+            newIndex = uindex;
-+        } else {
-+            for (var index2 in delta) {
-+                var itemDelta2 = delta[index2];
-+                if (isArray(itemDelta2) && itemDelta2[2] === ARRAY_MOVE && itemDelta2[1].toString() === index) {
-+                    newIndex = index2.substr(1);
-+                }
-+            }
-+        }
-+    }
-+    return newIndex;
-+};
-+
-+var collectChildrenReverseFilter = function collectChildrenReverseFilter(context) {
-+    if (!context || !context.children) { return; }
-+    if (context.delta._t !== 'a') { return; }
-+    var length = context.children.length;
-+    var child;
-+    var delta = { _t: 'a' };
-+    for (var index = 0; index < length; index++) {
-+        child = context.children[index];
-+        var name = child.newName;
-+        if (typeof name === 'undefined') {
-+            name = reverseArrayDeltaIndex(context.delta, child.childName, child.result);
-+        }
-+        if (delta[name] !== child.result) {
-+            delta[name] = child.result;
-+        }
-+    }
-+    context.setResult(delta).exit();
-+};
-+collectChildrenReverseFilter.filterName = 'arraysCollectChildren';
-+
-+exports.diffFilter = diffFilter;
-+exports.patchFilter = patchFilter;
-+exports.collectChildrenPatchFilter = collectChildrenPatchFilter;
-+exports.reverseFilter = reverseFilter;
-+exports.collectChildrenReverseFilter = collectChildrenReverseFilter;
-+
-+},{"../contexts/diff":14,"../contexts/patch":15,"../contexts/reverse":16,"./lcs":21}],20:[function(require,module,exports){
-+var diffFilter = function datesDiffFilter(context) {
-+    if (context.left instanceof Date) {
-+        if (context.right instanceof Date) {
-+            if (context.left.getTime() !== context.right.getTime()) {
-+                context.setResult([context.left, context.right]);
-+            } else {
-+                context.setResult(undefined);
-+            }
-+        } else {
-+            context.setResult([context.left, context.right]);
-+        }
-+        context.exit();
-+    } else if (context.right instanceof Date) {
-+        context.setResult([context.left, context.right]).exit();
-+    }
-+};
-+diffFilter.filterName = 'dates';
-+
-+exports.diffFilter = diffFilter;
-+},{}],21:[function(require,module,exports){
-+/*
-+
-+LCS implementation that supports arrays or strings
-+
-+reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
-+
-+*/
-+
-+var defaultMatch = function(array1, array2, index1, index2) {
-+    return array1[index1] === array2[index2];
-+};
-+
-+var lengthMatrix = function(array1, array2, match, context) {
-+    var len1 = array1.length;
-+    var len2 = array2.length;
-+    var x, y;
-+
-+    // initialize empty matrix of len1+1 x len2+1
-+    var matrix = [len1 + 1];
-+    for (x = 0; x < len1 + 1; x++) {
-+        matrix[x] = [len2 + 1];
-+        for (y = 0; y < len2 + 1; y++) {
-+            matrix[x][y] = 0;
-+        }
-+    }
-+    matrix.match = match;
-+    // save sequence lengths for each coordinate
-+    for (x = 1; x < len1 + 1; x++) {
-+        for (y = 1; y < len2 + 1; y++) {
-+            if (match(array1, array2, x - 1, y - 1, context)) {
-+                matrix[x][y] = matrix[x - 1][y - 1] + 1;
-+            } else {
-+                matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
-+            }
-+        }
-+    }
-+    return matrix;
-+};
-+
-+var backtrack = function(matrix, array1, array2, index1, index2, context) {
-+    if (index1 === 0 || index2 === 0) {
-+        return {
-+            sequence: [],
-+            indices1: [],
-+            indices2: []
-+        };
-+    }
-+
-+    if (matrix.match(array1, array2, index1 - 1, index2 - 1, context)) {
-+        var subsequence = backtrack(matrix, array1, array2, index1 - 1, index2 - 1, context);
-+        subsequence.sequence.push(array1[index1 - 1]);
-+        subsequence.indices1.push(index1 - 1);
-+        subsequence.indices2.push(index2 - 1);
-+        return subsequence;
-+    }
-+
-+    if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) {
-+        return backtrack(matrix, array1, array2, index1, index2 - 1, context);
-+    } else {
-+        return backtrack(matrix, array1, array2, index1 - 1, index2, context);
-+    }
-+};
-+
-+var get = function(array1, array2, match, context) {
-+    context = context || {};
-+    var matrix = lengthMatrix(array1, array2, match || defaultMatch, context);
-+    var result = backtrack(matrix, array1, array2, array1.length, array2.length, context);
-+    if (typeof array1 === 'string' && typeof array2 === 'string') {
-+        result.sequence = result.sequence.join('');
-+    }
-+    return result;
-+};
-+
-+exports.get = get;
-+
-+},{}],22:[function(require,module,exports){
-+
-+var DiffContext = require('../contexts/diff').DiffContext;
-+var PatchContext = require('../contexts/patch').PatchContext;
-+var ReverseContext = require('../contexts/reverse').ReverseContext;
-+
-+var collectChildrenDiffFilter = function collectChildrenDiffFilter(context) {
-+    if (!context || !context.children) { return; }
-+    var length = context.children.length;
-+    var child;
-+    var result = context.result;
-+    for (var index = 0; index < length; index++) {
-+        child = context.children[index];
-+        if (typeof child.result === 'undefined') {
-+            continue;
-+        }
-+        result = result || {};
-+        result[child.childName] = child.result;
-+    }
-+    if (result && context.leftIsArray) {
-+        result._t = 'a';
-+    }
-+    context.setResult(result).exit();
-+};
-+collectChildrenDiffFilter.filterName = 'collectChildren';
-+
-+var objectsDiffFilter = function objectsDiffFilter(context) {
-+    if (context.leftIsArray || context.leftType !== 'object') { return; }
-+
-+    var name, child;
-+    for (name in context.left) {
-+        child = new DiffContext(context.left[name], context.right[name]);
-+        context.push(child, name);
-+    }
-+    for (name in context.right) {
-+        if (typeof context.left[name] === 'undefined') {
-+            child = new DiffContext(undefined, context.right[name]);
-+            context.push(child, name);
-+        }
-+    }
-+
-+    if (!context.children || context.children.length === 0) {
-+        context.setResult(undefined).exit();
-+        return;
-+    }
-+    context.exit();
-+};
-+objectsDiffFilter.filterName = 'objects';
-+
-+var patchFilter = function nestedPatchFilter(context) {
-+    if (!context.nested) { return; }
-+    if (context.delta._t) { return; }
-+    var name, child;
-+    for (name in context.delta) {
-+        child = new PatchContext(context.left[name], context.delta[name]);
-+        context.push(child, name);
-+    }
-+    context.exit();
-+};
-+patchFilter.filterName = 'objects';
-+
-+var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
-+    if (!context || !context.children) { return; }
-+    if (context.delta._t) { return; }
-+    var length = context.children.length;
-+    var child;
-+    for (var index = 0; index < length; index++) {
-+        child = context.children[index];
-+        if (context.left[child.childName] !== child.result) {
-+            context.left[child.childName] = child.result;
-+        }
-+    }
-+    context.setResult(context.left).exit();
-+};
-+collectChildrenPatchFilter.filterName = 'collectChildren';
-+
-+var reverseFilter = function nestedReverseFilter(context) {
-+    if (!context.nested) { return; }
-+    if (context.delta._t) { return; }
-+    var name, child;
-+    for (name in context.delta) {
-+        child = new ReverseContext(context.delta[name]);
-+        context.push(child, name);
-+    }
-+    context.exit();
-+};
-+reverseFilter.filterName = 'objects';
-+
-+var collectChildrenReverseFilter = function collectChildrenReverseFilter(context) {
-+    if (!context || !context.children) { return; }
-+    if (context.delta._t) { return; }
-+    var length = context.children.length;
-+    var child;
-+    var delta = {};
-+    for (var index = 0; index < length; index++) {
-+        child = context.children[index];
-+        if (delta[child.childName] !== child.result) {
-+            delta[child.childName] = child.result;
-+        }
-+    }
-+    context.setResult(delta).exit();
-+};
-+collectChildrenReverseFilter.filterName = 'collectChildren';
-+
-+exports.collectChildrenDiffFilter = collectChildrenDiffFilter;
-+exports.objectsDiffFilter = objectsDiffFilter;
-+exports.patchFilter = patchFilter;
-+exports.collectChildrenPatchFilter = collectChildrenPatchFilter;
-+exports.reverseFilter = reverseFilter;
-+exports.collectChildrenReverseFilter = collectChildrenReverseFilter;
-+},{"../contexts/diff":14,"../contexts/patch":15,"../contexts/reverse":16}],23:[function(require,module,exports){
-+/* global diff_match_patch */
-+var TEXT_DIFF = 2;
-+var DEFAULT_MIN_LENGTH = 60;
-+var cachedDiffPatch = null;
-+
-+var getDiffMatchPatch = function(){
-+    /*jshint camelcase: false */
-+
-+    if (!cachedDiffPatch) {
-+        var instance;
-+        if (typeof diff_match_patch !== 'undefined') {
-+            // already loaded, probably a browser
-+            instance = new diff_match_patch();
-+        } else if (typeof require === 'function') {
-+            var dmp = require('../../external/diff_match_patch_uncompressed');
-+            instance = new dmp.diff_match_patch();
-+        }
-+        if (!instance) {
-+            var error = new Error('text diff_match_patch library not found');
-+            error.diff_match_patch_not_found = true;
-+            throw error;
-+        }
-+        cachedDiffPatch = {
-+            diff: function(txt1, txt2){
-+                return instance.patch_toText(instance.patch_make(txt1, txt2));
-+            },
-+            patch: function(txt1, patch){
-+                var results = instance.patch_apply(instance.patch_fromText(patch), txt1);
-+                for (var i = 0; i < results[1].length; i++) {
-+                    if (!results[1][i]) {
-+                        var error = new Error('text patch failed');
-+                        error.textPatchFailed = true;
-+                    }
-+                }
-+                return results[0];
-+            }
-+        };
-+    }
-+    return cachedDiffPatch;
-+};
-+
-+var diffFilter = function textsDiffFilter(context) {
-+    if (context.leftType !== 'string') { return; }
-+    var minLength = (context.options && context.options.textDiff &&
-+        context.options.textDiff.minLength) || DEFAULT_MIN_LENGTH;
-+    if (context.left.length < minLength ||
-+        context.right.length < minLength) {
-+        context.setResult([context.left, context.right]).exit();
-+        return;
-+    }
-+    // large text, use a text-diff algorithm
-+    var diff = getDiffMatchPatch().diff;
-+    context.setResult([diff(context.left, context.right), 0, TEXT_DIFF]).exit();
-+};
-+diffFilter.filterName = 'texts';
-+
-+var patchFilter = function textsPatchFilter(context) {
-+    if (context.nested) { return; }
-+    if (context.delta[2] !== TEXT_DIFF) { return; }
-+
-+    // text-diff, use a text-patch algorithm
-+    var patch = getDiffMatchPatch().patch;
-+    context.setResult(patch(context.left, context.delta[0])).exit();
-+};
-+patchFilter.filterName = 'texts';
-+
-+var textDeltaReverse = function(delta){
-+    var i, l, lines, line, lineTmp, header = null,
-+    headerRegex = /^@@ +\-(\d+),(\d+) +\+(\d+),(\d+) +@@$/,
-+    lineHeader, lineAdd, lineRemove;
-+    lines = delta.split('\n');
-+    for (i = 0, l = lines.length; i<l; i++) {
-+        line = lines[i];
-+        var lineStart = line.slice(0,1);
-+        if (lineStart==='@'){
-+            header = headerRegex.exec(line);
-+            lineHeader = i;
-+            lineAdd = null;
-+            lineRemove = null;
-+
-+            // fix header
-+            lines[lineHeader] = '@@ -' + header[3] + ',' + header[4] + ' +' + header[1] + ',' + header[2] + ' @@';
-+        } else if (lineStart === '+'){
-+            lineAdd = i;
-+            lines[i] = '-' + lines[i].slice(1);
-+            if (lines[i-1].slice(0,1)==='+') {
-+                // swap lines to keep default order (-+)
-+                lineTmp = lines[i];
-+                lines[i] = lines[i-1];
-+                lines[i-1] = lineTmp;
-+            }
-+        } else if (lineStart === '-'){
-+            lineRemove = i;
-+            lines[i] = '+' + lines[i].slice(1);
-+        }
-+    }
-+    return lines.join('\n');
-+};
-+
-+var reverseFilter = function textsReverseFilter(context) {
-+    if (context.nested) { return; }
-+    if (context.delta[2] !== TEXT_DIFF) { return; }
-+
-+    // text-diff, use a text-diff algorithm
-+    context.setResult([textDeltaReverse(context.delta[0]), 0, TEXT_DIFF]).exit();
-+};
-+reverseFilter.filterName = 'texts';
-+
-+exports.diffFilter = diffFilter;
-+exports.patchFilter = patchFilter;
-+exports.reverseFilter = reverseFilter;
-+},{"../../external/diff_match_patch_uncompressed":12}],24:[function(require,module,exports){
-+
-+var isArray = (typeof Array.isArray === 'function') ?
-+    // use native function
-+    Array.isArray :
-+    // use instanceof operator
-+    function(a) {
-+        return a instanceof Array;
-+    };
-+
-+var diffFilter = function trivialMatchesDiffFilter(context) {
-+    if (context.left === context.right) {
-+        context.setResult(undefined).exit();
-+        return;
-+    }
-+    if (typeof context.left === 'undefined') {
-+        if (typeof context.right === 'function') {
-+            throw new Error('functions are not supported');
-+        }
-+        context.setResult([context.right]).exit();
-+        return;
-+    }
-+    if (typeof context.right === 'undefined') {
-+        context.setResult([context.left, 0, 0]).exit();
-+        return;
-+    }
-+    if (typeof context.left === 'function' || typeof context.right === 'function' ) {
-+        throw new Error('functions are not supported');
-+    }
-+    context.leftType = context.left === null ? 'null' : typeof context.left;
-+    context.rightType = context.right === null ? 'null' : typeof context.right;
-+    if (context.leftType !== context.rightType) {
-+        context.setResult([context.left, context.right]).exit();
-+        return;
-+    }
-+    if (context.leftType === 'boolean' || context.leftType === 'number') {
-+        context.setResult([context.left, context.right]).exit();
-+        return;
-+    }
-+    if (context.leftType === 'object') {
-+        context.leftIsArray = isArray(context.left);
-+    }
-+    if (context.rightType === 'object') {
-+        context.rightIsArray = isArray(context.right);
-+    }
-+    if (context.leftIsArray !== context.rightIsArray) {
-+        context.setResult([context.left, context.right]).exit();
-+        return;
-+    }
-+};
-+diffFilter.filterName = 'trivial';
-+
-+var patchFilter = function trivialMatchesPatchFilter(context) {
-+    if (typeof context.delta === 'undefined') {
-+        context.setResult(context.left).exit();
-+        return;
-+    }
-+    context.nested = !isArray(context.delta);
-+    if (context.nested) { return; }
-+    if (context.delta.length === 1) {
-+        context.setResult(context.delta[0]).exit();
-+        return;
-+    }
-+    if (context.delta.length === 2) {
-+        context.setResult(context.delta[1]).exit();
-+        return;
-+    }
-+    if (context.delta.length === 3 && context.delta[2] === 0) {
-+        context.setResult(undefined).exit();
-+        return;
-+    }
-+};
-+patchFilter.filterName = 'trivial';
-+
-+var reverseFilter = function trivialReferseFilter(context) {
-+    if (typeof context.delta === 'undefined') {
-+        context.setResult(context.delta).exit();
-+        return;
-+    }
-+    context.nested = !isArray(context.delta);
-+    if (context.nested) { return; }
-+    if (context.delta.length === 1) {
-+        context.setResult([context.delta[0], 0, 0]).exit();
-+        return;
-+    }
-+    if (context.delta.length === 2) {
-+        context.setResult([context.delta[1], context.delta[0]]).exit();
-+        return;
-+    }
-+    if (context.delta.length === 3 && context.delta[2] === 0) {
-+        context.setResult([context.delta[0]]).exit();
-+        return;
-+    }
-+};
-+reverseFilter.filterName = 'trivial';
-+
-+exports.diffFilter = diffFilter;
-+exports.patchFilter = patchFilter;
-+exports.reverseFilter = reverseFilter;
-+
-+},{}],25:[function(require,module,exports){
-+(function (process){
-+
-+var DiffPatcher = require('./diffpatcher').DiffPatcher;
-+exports.DiffPatcher = DiffPatcher;
-+
-+exports.create = function(options){
-+	return new DiffPatcher(options);
-+};
-+
-+exports.dateReviver = require('./date-reviver');
-+
-+var defaultInstance;
-+
-+exports.diff = function() {
-+	if (!defaultInstance) {
-+		defaultInstance = new DiffPatcher();
-+	}
-+	return defaultInstance.diff.apply(defaultInstance, arguments);
-+};
-+
-+exports.patch = function() {
-+	if (!defaultInstance) {
-+		defaultInstance = new DiffPatcher();
-+	}
-+	return defaultInstance.patch.apply(defaultInstance, arguments);
-+};
-+
-+exports.unpatch = function() {
-+	if (!defaultInstance) {
-+		defaultInstance = new DiffPatcher();
-+	}
-+	return defaultInstance.unpatch.apply(defaultInstance, arguments);
-+};
-+
-+exports.reverse = function() {
-+	if (!defaultInstance) {
-+		defaultInstance = new DiffPatcher();
-+	}
-+	return defaultInstance.reverse.apply(defaultInstance, arguments);
-+};
-+
-+var inNode = typeof process !== 'undefined' && typeof process.execPath === 'string';
-+if (inNode) {
-+	var formatters = require('./formatters' + '/index');
-+	exports.formatters = formatters;
-+	// shortcut for console
-+	exports.console = formatters.console;
-+} else {
-+	exports.homepage = '{{package-homepage}}';
-+	exports.version = '{{package-version}}';
-+}
-+
-+}).call(this,require("FWaASH"))
-+},{"./date-reviver":17,"./diffpatcher":18,"FWaASH":6}],26:[function(require,module,exports){
-+
-+var Pipe = function Pipe(name){
-+    this.name = name;
-+    this.filters = [];
-+};
-+
-+Pipe.prototype.process = function(input) {
-+    if (!this.processor) {
-+        throw new Error('add this pipe to a processor before using it');
-+    }
-+    var debug = this.debug;
-+    var length = this.filters.length;
-+    var context = input;
-+    for (var index = 0; index < length; index++) {
-+        var filter = this.filters[index];
-+        if (debug) {
-+            this.log('filter: ' + filter.filterName);
-+        }
-+        filter(context);
-+        if (typeof context === 'object' && context.exiting) {
-+            context.exiting = false;
-+            break;
-+        }
-+    }
-+    if (!context.next && this.resultCheck) {
-+        this.resultCheck(context);
-+    }
-+};
-+
-+Pipe.prototype.log = function(msg) {
-+    console.log('[jsondiffpatch] ' + this.name + ' pipe, ' + msg);
-+};
-+
-+Pipe.prototype.append = function() {
-+    this.filters.push.apply(this.filters, arguments);
-+    return this;
-+};
-+
-+Pipe.prototype.prepend = function() {
-+    this.filters.unshift.apply(this.filters, arguments);
-+    return this;
-+};
-+
-+Pipe.prototype.indexOf = function(filterName) {
-+    if (!filterName) {
-+        throw new Error('a filter name is required');
-+    }
-+    for (var index = 0; index < this.filters.length; index++) {
-+        var filter = this.filters[index];
-+        if (filter.filterName === filterName) {
-+            return index;
-+        }
-+    }
-+    throw new Error('filter not found: ' + filterName);
-+};
-+
-+Pipe.prototype.list = function() {
-+    var names = [];
-+    for (var index = 0; index < this.filters.length; index++) {
-+        var filter = this.filters[index];
-+        names.push(filter.filterName);
-+    }
-+    return names;
-+};
-+
-+Pipe.prototype.after = function(filterName) {
-+    var index = this.indexOf(filterName);
-+    var params = Array.prototype.slice.call(arguments, 1);
-+    if (!params.length) {
-+        throw new Error('a filter is required');
-+    }
-+    params.unshift(index + 1, 0);
-+    Array.prototype.splice.apply(this.filters, params);
-+    return this;
-+};
-+
-+Pipe.prototype.before = function(filterName) {
-+    var index = this.indexOf(filterName);
-+    var params = Array.prototype.slice.call(arguments, 1);
-+    if (!params.length) {
-+        throw new Error('a filter is required');
-+    }
-+    params.unshift(index, 0);
-+    Array.prototype.splice.apply(this.filters, params);
-+    return this;
-+};
-+
-+Pipe.prototype.clear = function() {
-+    this.filters.length = 0;
-+    return this;
-+};
-+
-+Pipe.prototype.shouldHaveResult = function(should) {
-+    if (should === false) {
-+        this.resultCheck = null;
-+        return;
-+    }
-+    if (this.resultCheck) { return; }
-+    var pipe = this;
-+    this.resultCheck = function(context) {
-+        if (!context.hasResult) {
-+            console.log(context);
-+            var error = new Error(pipe.name + ' failed');
-+            error.noResult = true;
-+            throw error;
-+        }
-+    };
-+    return this;
-+};
-+
-+exports.Pipe = Pipe;
-+},{}],27:[function(require,module,exports){
-+
-+var Processor = function Processor(options){
-+	this.selfOptions = options;
-+	this.pipes = {};
-+};
-+
-+Processor.prototype.options = function(options) {
-+	if (options) {
-+		this.selfOptions = options;
-+	}
-+	return this.selfOptions;
-+};
-+
-+Processor.prototype.pipe = function(name, pipe) {
-+	if (typeof name === 'string') {
-+		if (typeof pipe === 'undefined') {
-+			return this.pipes[name];
-+		} else {
-+			this.pipes[name] = pipe;
-+		}
-+	}
-+	if (name && name.name) {
-+		pipe = name;
-+		if (pipe.processor === this) { return pipe; }
-+		this.pipes[pipe.name] = pipe;
-+	}
-+	pipe.processor = this;
-+	return pipe;
-+};
-+
-+Processor.prototype.process = function(input, pipe) {
-+	var context = input;
-+	context.options = this.options();
-+	var nextPipe = pipe || input.pipe || 'default';
-+	var lastPipe, lastContext;
-+	while (nextPipe) {
-+		if (typeof context.nextAfterChildren !== 'undefined') {
-+			// children processed and coming back to parent
-+			context.next = context.nextAfterChildren;
-+			context.nextAfterChildren = null;
-+		}
-+
-+		if (typeof nextPipe === 'string') {
-+			nextPipe = this.pipe(nextPipe);
-+		}
-+		nextPipe.process(context);
-+		lastContext = context;
-+		lastPipe = nextPipe;
-+		nextPipe = null;
-+		if (context) {
-+			if (context.next) {
-+				context = context.next;
-+				nextPipe = lastContext.nextPipe || context.pipe || lastPipe;
-+			}
-+		}
-+	}
-+	return context.hasResult ? context.result : undefined;
-+};
-+
-+exports.Processor = Processor;
-+
-+},{}],28:[function(require,module,exports){
-+
-+// the basic characters in sorted order
-+var alphabet = "0123456789?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-+var radix = alphabet.length;
-+// bigger than all the basic characters
-+var order_specifier = "~";
-+
-+// character to numerical value aka index of the character
-+// "0": 0, "z": 63, etc.
-+var values = (function() {
-+  var values = {};
-+  for (var i = 0; i < alphabet.length; i++) values[alphabet[i]] = i;
-+  return values;
-+})();
-+
-+module.exports = keese;
-+function keese(low, high) {
-+  if (low == null) {
-+    if (high == null) {
-+      // return anything above 0
-+      return "1";
-+    } else {
-+      // go smaller
-+      return average("0", high);
-+    }
-+  } else {
-+    if (high == null) {
-+      // go bigger
-+      return increment(low);
-+    } else {
-+      // go in between
-+      return average(low, high);
-+    }
-+  }
-+}
-+
-+function increment(value) {
-+  var n = parse(value);
-+  // drop the fraction
-+  n.digits = n.digits.substr(0, n.order_length + 1);
-+  return add(n, parse("1"));
-+}
-+
-+function average(low, high) {
-+  if (!(low < high)) {
-+    throw new Error("assertion failed: " + JSON.stringify(low) + " < " + JSON.stringify(high));
-+  }
-+  var a = parse(low);
-+  var b = parse(high);
-+  pad_to_equal_order(a, b);
-+  var b_carry = 0;
-+  var max_digit_length = Math.max(a.digits.length, b.digits.length);
-+  for (var i = 0; i < max_digit_length || b_carry > 0; i++) {
-+    var a_value =            values[a.digits[i]] || 0;
-+    var b_value = b_carry + (values[b.digits[i]] || 0);
-+    if (a_value === b_value) continue;
-+    if (a_value === b_value - 1) {
-+      // we need more digits, but remember that b is ahead
-+      b_carry = radix;
-+      continue;
-+    }
-+    // we have a distance of at least 2 between the values.
-+    // half the distance floored is sure to be a positive single digit.
-+    var half_distance_value = Math.floor((b_value - a_value) / 2);
-+    var half_distance_digits = "";
-+    for (var j = 0; j < i; j++)
-+      half_distance_digits += "0";
-+    half_distance_digits += alphabet[half_distance_value];
-+    var half_distance = parse(construct(a.order_length, half_distance_digits));
-+    // truncate insignificant digits of a
-+    a.digits = a.digits.substr(0, i + 1);
-+    return add(a, half_distance);
-+  }
-+  throw new Error; // unreachable
-+}
-+
-+function add(a, b) {
-+  pad_to_equal_order(a, b);
-+  var result_digits = "";
-+  var order_length = a.order_length;
-+  var value = 0;
-+  for (var i = Math.max(a.digits.length, b.digits.length) - 1; i >= 0; i--) {
-+    value += values[a.digits[i]] || 0;
-+    value += values[b.digits[i]] || 0;
-+    result_digits = alphabet[value % radix] + result_digits;
-+    value = Math.floor(value / radix);
-+  }
-+  // overflow up to moar digits
-+  while (value > 0) {
-+    result_digits = alphabet[value % radix] + result_digits;
-+    value = Math.floor(value / radix);
-+    order_length++;
-+  }
-+  return construct(order_length, result_digits);
-+}
-+
-+function parse(value) {
-+  var order_length = value.lastIndexOf(order_specifier) + 1;
-+  return {
-+    order_length: order_length,
-+    digits: value.substr(order_length)
-+  };
-+}
-+function construct(order_length, digits) {
-+  // strip unnecessary leading zeros
-+  while (order_length > 0 && digits.charAt(0) == "0") {
-+    digits = digits.substr(1);
-+    order_length--;
-+  }
-+  var result = "";
-+  for (var i = 0; i < order_length; i++)
-+    result += order_specifier;
-+  return result + digits;
-+}
-+
-+function pad_to_equal_order(a, b) {
-+  pad_in_place(a, b.order_length);
-+  pad_in_place(b, a.order_length);
-+}
-+function pad_in_place(n, order_length) {
-+  while (n.order_length < order_length) {
-+    n.digits = "0" + n.digits;
-+    n.order_length++;
-+  }
-+}
-+
-+},{}],29:[function(require,module,exports){
-+(function(module) {
-+    // see https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
-+    // and http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript#6274398
-+    module.exports = function shuffle(array) {
-+        var counter = array.length,
-+            temp,
-+            index;
-+
-+        while (counter) {
-+            index = Math.floor(Math.random() * counter--);
-+
-+            temp = array[counter];
-+            array[counter] = array[index];
-+            array[index] = temp;
-+        }
-+
-+        return array;
-+    }
-+})(module);
-+
-+},{}],30:[function(require,module,exports){
-+var removeDiacritics = require('diacritics').remove;
-+
-+module.exports = MusicLibraryIndex;
-+
-+MusicLibraryIndex.defaultPrefixesToStrip = [/^\s*the\s+/, /^\s*a\s+/,
-+  /^\s*an\s+/];
-+MusicLibraryIndex.defaultVariousArtistsKey = "VariousArtists";
-+MusicLibraryIndex.defaultVariousArtistsName = "Various Artists";
-+MusicLibraryIndex.defaultSearchFields = ['artistName', 'albumArtistName',
-+  'albumName', 'name'];
-+
-+function MusicLibraryIndex(options) {
-+  options = options || {};
-+  this.searchFields = options.searchFields ||
-+    MusicLibraryIndex.defaultSearchFields;
-+  this.variousArtistsKey = options.variousArtistsKey ||
-+    MusicLibraryIndex.defaultVariousArtistsKey;
-+  this.variousArtistsName = options.variousArtistsName ||
-+    MusicLibraryIndex.defaultVariousArtistsName;
-+  this.prefixesToStrip = options.prefixesToStrip ||
-+    MusicLibraryIndex.defaultPrefixesToStrip;
-+
-+  this.artistComparator = this.artistComparator.bind(this);
-+  this.albumComparator = this.albumComparator.bind(this);
-+  this.trackComparator = this.trackComparator.bind(this);
-+  this.clear();
-+}
-+
-+MusicLibraryIndex.prototype.stripPrefixes = function(str) {
-+  for (var i = 0; i < this.prefixesToStrip.length; i += 1) {
-+    var regex = this.prefixesToStrip[i];
-+    str = str.replace(regex, '');
-+    break;
-+  }
-+  return str;
-+};
-+
-+MusicLibraryIndex.prototype.sortableTitle = function(title) {
-+  return this.stripPrefixes(formatSearchable(title));
-+};
-+
-+MusicLibraryIndex.prototype.titleCompare = function(a, b) {
-+  var _a = this.sortableTitle(a);
-+  var _b = this.sortableTitle(b);
-+  if (_a < _b) {
-+    return -1;
-+  } else if (_a > _b) {
-+    return 1;
-+  } else {
-+    if (a < b) {
-+      return -1;
-+    } else if (a > b) {
-+      return 1;
-+    } else {
-+      return 0;
-+    }
-+  }
-+};
-+
-+MusicLibraryIndex.prototype.trackComparator = function(a, b) {
-+  if (a.disc < b.disc) {
-+    return -1;
-+  } else if (a.disc > b.disc) {
-+    return 1;
-+  } else if (a.track < b.track) {
-+    return -1;
-+  } else if (a.track > b.track) {
-+    return 1;
-+  } else {
-+    return this.titleCompare(a.name, b.name);
-+  }
-+}
-+
-+MusicLibraryIndex.prototype.albumComparator = function(a, b) {
-+  if (a.year < b.year) {
-+    return -1;
-+  } else if (a.year > b.year) {
-+    return 1;
-+  } else {
-+    return this.titleCompare(a.name, b.name);
-+  }
-+}
-+
-+MusicLibraryIndex.prototype.artistComparator = function(a, b) {
-+  return this.titleCompare(a.name, b.name);
-+}
-+
-+MusicLibraryIndex.prototype.getAlbumKey = function(track) {
-+  var artistName = track.albumArtistName ||
-+    (track.compilation ? this.variousArtistsName : track.artistName);
-+  return formatSearchable(track.albumName + "\n" + artistName);
-+};
-+
-+MusicLibraryIndex.prototype.getArtistKey = function(artistName) {
-+  return formatSearchable(artistName);
-+};
-+
-+MusicLibraryIndex.prototype.clear = function() {
-+  this.trackTable = {};
-+  this.artistTable = {};
-+  this.artistList = [];
-+  this.albumTable = {};
-+  this.albumList = [];
-+  this.dirty = false;
-+  this.dirtyAlbumTable = false;
-+};
-+
-+MusicLibraryIndex.prototype.rebuildAlbumTable = function() {
-+  if (!this.dirtyAlbumTable) return;
-+
-+  // builds everything from trackTable
-+  this.artistTable = {};
-+  this.artistList = [];
-+  this.albumTable = {};
-+  this.albumList = [];
-+  var thisAlbumList = this.albumList;
-+  for (var trackKey in this.trackTable) {
-+    var track = this.trackTable[trackKey];
-+    this.trackTable[track.key] = track;
-+
-+    var searchTags = "";
-+    for (var i = 0; i < this.searchFields.length; i += 1) {
-+      searchTags += track[this.searchFields[i]] + "\n";
-+    }
-+    track.searchTags = formatSearchable(searchTags);
-+
-+    if (track.albumArtistName === this.variousArtistsName) {
-+      track.albumArtistName = "";
-+      track.compilation = true;
-+    }
-+    track.albumArtistName = track.albumArtistName || "";
-+
-+    var albumKey = this.getAlbumKey(track);
-+    var album = getOrCreate(albumKey, this.albumTable, createAlbum);
-+    track.album = album;
-+    album.trackList.push(track);
-+    if (album.year == null) {
-+      album.year = track.year;
-+    }
-+  }
-+
-+  this.dirtyAlbumTable = false;
-+
-+  function createAlbum() {
-+    var album = {
-+      name: track.albumName,
-+      year: track.year,
-+      trackList: [],
-+      key: albumKey,
-+    };
-+    thisAlbumList.push(album);
-+    return album;
-+  }
-+};
-+
-+MusicLibraryIndex.prototype.rebuild = function() {
-+  if (!this.dirty) return;
-+  this.rebuildAlbumTable();
-+  this.albumList.sort(this.albumComparator);
-+
-+  var albumArtistName, artistKey, artist;
-+  var albumKey, track, album;
-+  var i;
-+  for (albumKey in this.albumTable) {
-+    album = this.albumTable[albumKey];
-+    var albumArtistSet = {};
-+    album.trackList.sort(this.trackComparator);
-+    albumArtistName = "";
-+    var isCompilation = false;
-+    for (i = 0; i < album.trackList.length; i += 1) {
-+      track = album.trackList[i];
-+      track.index = i;
-+      if (track.albumArtistName) {
-+        albumArtistName = track.albumArtistName;
-+        albumArtistSet[this.getArtistKey(albumArtistName)] = true;
-+      }
-+      if (!albumArtistName) albumArtistName = track.artistName;
-+      albumArtistSet[this.getArtistKey(albumArtistName)] = true;
-+      isCompilation = isCompilation || track.compilation;
-+    }
-+    if (isCompilation || moreThanOneKey(albumArtistSet)) {
-+      albumArtistName = this.variousArtistsName;
-+      artistKey = this.variousArtistsKey;
-+      for (i = 0; i < album.trackList.length; i += 1) {
-+        track = album.trackList[i];
-+        track.compilation = true;
-+      }
-+    } else {
-+      artistKey = this.getArtistKey(albumArtistName);
-+    }
-+    artist = getOrCreate(artistKey, this.artistTable, createArtist);
-+    album.artist = artist;
-+    artist.albumList.push(album);
-+  }
-+
-+  this.artistList = [];
-+  var variousArtist = null;
-+  for (artistKey in this.artistTable) {
-+    artist = this.artistTable[artistKey];
-+    artist.albumList.sort(this.albumComparator);
-+    for (i = 0; i < artist.albumList.length; i += 1) {
-+      album = artist.albumList[i];
-+      album.index = i;
-+    }
-+    if (artist.key === this.variousArtistsKey) {
-+      variousArtist = artist;
-+    } else {
-+      this.artistList.push(artist);
-+    }
-+  }
-+  this.artistList.sort(this.artistComparator);
-+  if (variousArtist) {
-+    this.artistList.unshift(variousArtist);
-+  }
-+  for (i = 0; i < this.artistList.length; i += 1) {
-+    artist = this.artistList[i];
-+    artist.index = i;
-+  }
-+
-+  this.dirty = false;
-+
-+  function createArtist() {
-+    return {
-+      name: albumArtistName,
-+      albumList: [],
-+      key: artistKey,
-+    };
-+  }
-+}
-+
-+MusicLibraryIndex.prototype.addTrack = function(track) {
-+  var oldTrack = this.trackTable[track.key];
-+  this.dirty = this.dirty ||
-+      oldTrack == null ||
-+      oldTrack.artistName !== track.artistName ||
-+      oldTrack.albumArtistName !== track.albumArtistName ||
-+      oldTrack.albumName !== track.albumName ||
-+      oldTrack.track !== track.track ||
-+      oldTrack.disc !== track.disc ||
-+      oldTrack.year !== track.year;
-+  this.dirtyAlbumTable = this.dirty;
-+  this.trackTable[track.key] = track;
-+}
-+
-+MusicLibraryIndex.prototype.removeTrack = function(key) {
-+  delete this.trackTable[key];
-+  this.dirty = true;
-+  this.dirtyAlbumTable = true;
-+}
-+
-+MusicLibraryIndex.prototype.search = function(query) {
-+  query = query.trim();
-+
-+  var searchResults = new MusicLibraryIndex({
-+    searchFields: this.searchFields,
-+    variousArtistsKey: this.variousArtistsKey,
-+    variousArtistsName: this.variousArtistsName,
-+    prefixesToStrip: this.prefixesToStrip,
-+  });
-+
-+  var words = formatSearchable(query).split(/\s+/);
-+
-+  var track;
-+  for (var trackKey in this.trackTable) {
-+    track = this.trackTable[trackKey];
-+    if (testMatch()) {
-+      searchResults.trackTable[track.key] = track;
-+    }
-+  }
-+  searchResults.dirty = true;
-+  searchResults.dirtyAlbumTable = true;
-+  searchResults.rebuild();
-+
-+  return searchResults;
-+
-+  function testMatch() {
-+    for (var i = 0; i < words.length; i += 1) {
-+      var word = words[i];
-+      if (track.searchTags.indexOf(word) === -1) {
-+        return false;
-+      }
-+    }
-+    return true;
-+  }
-+};
-+
-+function getOrCreate(key, table, initObjFunc) {
-+  var result = table[key];
-+  if (result == null) {
-+    result = initObjFunc();
-+    table[key] = result;
-+  }
-+  return result;
-+}
-+
-+function moreThanOneKey(object){
-+  var count = -2;
-+  for (var k in object) {
-+    if (!++count) {
-+      return true;
-+    }
-+  }
-+  return false;
-+}
-+
-+function formatSearchable(str) {
-+  return removeDiacritics(str).toLowerCase();
-+}
-+
-+},{"diacritics":31}],31:[function(require,module,exports){
-+exports.remove = removeDiacritics;
-+
-+var replacementList = [
-+  {
-+    base: ' ',
-+    chars: "\u00A0",
-+  }, {
-+    base: '0',
-+    chars: "\u07C0",
-+  }, {
-+    base: 'A',
-+    chars: "\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F",
-+  }, {
-+    base: 'AA',
-+    chars: "\uA732",
-+  }, {
-+    base: 'AE',
-+    chars: "\u00C6\u01FC\u01E2",
-+  }, {
-+    base: 'AO',
-+    chars: "\uA734",
-+  }, {
-+    base: 'AU',
-+    chars: "\uA736",
-+  }, {
-+    base: 'AV',
-+    chars: "\uA738\uA73A",
-+  }, {
-+    base: 'AY',
-+    chars: "\uA73C",
-+  }, {
-+    base: 'B',
-+    chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
-+  }, {
-+    base: 'C',
-+    chars: "\uFF43\u24b8\uff23\uA73E\u1E08",
-+  }, {
-+    base: 'D',
-+    chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
-+  }, {
-+    base: 'Dh',
-+    chars: "\u00D0",
-+  }, {
-+    base: 'DZ',
-+    chars: "\u01F1\u01C4",
-+  }, {
-+    base: 'Dz',
-+    chars: "\u01F2\u01C5",
-+  }, {
-+    base: 'E',
-+    chars: "\u025B\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07",
-+  }, {
-+    base: 'F',
-+    chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
-+  }, {
-+    base: 'G',
-+    chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
-+  }, {
-+    base: 'H',
-+    chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
-+  }, {
-+    base: 'I',
-+    chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
-+  }, {
-+    base: 'J',
-+    chars: "\u24BF\uFF2A\u0134\u0248\u0237",
-+  }, {
-+    base: 'K',
-+    chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
-+  }, {
-+    base: 'L',
-+    chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
-+  }, {
-+    base: 'LJ',
-+    chars: "\u01C7",
-+  }, {
-+    base: 'Lj',
-+    chars: "\u01C8",
-+  }, {
-+    base: 'M',
-+    chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
-+  }, {
-+    base: 'N',
-+    chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
-+  }, {
-+    base: 'NJ',
-+    chars: "\u01CA",
-+  }, {
-+    base: 'Nj',
-+    chars: "\u01CB",
-+  }, {
-+    base: 'O',
-+    chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C",
-+  }, {
-+    base: 'OE',
-+    chars: "\u0152",
-+  }, {
-+    base: 'OI',
-+    chars: "\u01A2",
-+  }, {
-+    base: 'OO',
-+    chars: "\uA74E",
-+  }, {
-+    base: 'OU',
-+    chars: "\u0222",
-+  }, {
-+    base: 'P',
-+    chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
-+  }, {
-+    base: 'Q',
-+    chars: "\u24C6\uFF31\uA756\uA758\u024A",
-+  }, {
-+    base: 'R',
-+    chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
-+  }, {
-+    base: 'S',
-+    chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
-+  }, {
-+    base: 'T',
-+    chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
-+  }, {
-+    base: 'Th',
-+    chars: "\u00DE",
-+  }, {
-+    base: 'TZ',
-+    chars: "\uA728",
-+  }, {
-+    base: 'U',
-+    chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244",
-+  }, {
-+    base: 'V',
-+    chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
-+  }, {
-+    base: 'VY',
-+    chars: "\uA760",
-+  }, {
-+    base: 'W',
-+    chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
-+  }, {
-+    base: 'X',
-+    chars: "\u24CD\uFF38\u1E8A\u1E8C",
-+  }, {
-+    base: 'Y',
-+    chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
-+  }, {
-+    base: 'Z',
-+    chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
-+  }, {
-+    base: 'a',
-+    chars: "\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251",
-+  }, {
-+    base: 'aa',
-+    chars: "\uA733",
-+  }, {
-+    base: 'ae',
-+    chars: "\u00E6\u01FD\u01E3",
-+  }, {
-+    base: 'ao',
-+    chars: "\uA735",
-+  }, {
-+    base: 'au',
-+    chars: "\uA737",
-+  }, {
-+    base: 'av',
-+    chars: "\uA739\uA73B",
-+  }, {
-+    base: 'ay',
-+    chars: "\uA73D",
-+  }, {
-+    base: 'b',
-+    chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
-+  }, {
-+    base: 'c',
-+    chars: "\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184\u0043\u0106\u0108\u010A\u010C\u00C7\u0187\u023B",
-+  }, {
-+    base: 'd',
-+    chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
-+  }, {
-+    base: 'dh',
-+    chars: "\u00F0",
-+  }, {
-+    base: 'dz',
-+    chars: "\u01F3\u01C6",
-+  }, {
-+    base: 'e',
-+    chars: "\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD",
-+  }, {
-+    base: 'f',
-+    chars: "\u24D5\uFF46\u1E1F\u0192",
-+  }, {
-+    base: 'ff',
-+    chars: "\uFB00",
-+  }, {
-+    base: 'fi',
-+    chars: "\uFB01",
-+  }, {
-+    base: 'fl',
-+    chars: "\uFB02",
-+  }, {
-+    base: 'ffi',
-+    chars: "\uFB03",
-+  }, {
-+    base: 'ffl',
-+    chars: "\uFB04",
-+  }, {
-+    base: 'g',
-+    chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
-+  }, {
-+    base: 'h',
-+    chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
-+  }, {
-+    base: 'hv',
-+    chars: "\u0195",
-+  }, {
-+    base: 'i',
-+    chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
-+  }, {
-+    base: 'j',
-+    chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
-+  }, {
-+    base: 'k',
-+    chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
-+  }, {
-+    base: 'l',
-+    chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
-+  }, {
-+    base: 'lj',
-+    chars: "\u01C9",
-+  }, {
-+    base: 'm',
-+    chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
-+  }, {
-+    base: 'n',
-+    chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
-+  }, {
-+    base: 'nj',
-+    chars: "\u01CC",
-+  }, {
-+    base: 'o',
-+    chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11",
-+  }, {
-+    base: 'oe',
-+    chars: "\u0153",
-+  }, {
-+    base: 'oi',
-+    chars: "\u01A3",
-+  }, {
-+    base: 'oo',
-+    chars: "\uA74F",
-+  }, {
-+    base: 'ou',
-+    chars: "\u0223",
-+  }, {
-+    base: 'p',
-+    chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
-+  }, {
-+    base: 'q',
-+    chars: "\u24E0\uFF51\u024B\uA757\uA759",
-+  }, {
-+    base: 'r',
-+    chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
-+  }, {
-+    base: 's',
-+    chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
-+  }, {
-+    base: 'ss',
-+    chars: "\xDF",
-+  }, {
-+    base: 't',
-+    chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
-+  }, {
-+    base: 'th',
-+    chars: "\u00FE",
-+  }, {
-+    base: 'tz',
-+    chars: "\uA729",
-+  }, {
-+    base: 'u',
-+    chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289",
-+  }, {
-+    base: 'v',
-+    chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
-+  }, {
-+    base: 'vy',
-+    chars: "\uA761",
-+  }, {
-+    base: 'w',
-+    chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
-+  }, {
-+    base: 'x',
-+    chars: "\u24E7\uFF58\u1E8B\u1E8D",
-+  }, {
-+    base: 'y',
-+    chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
-+  }, {
-+    base: 'z',
-+    chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
-+  }
-+];
-+
-+var diacriticsMap = {};
-+for (var i = 0; i < replacementList.length; i += 1) {
-+  var chars = replacementList[i].chars;
-+  for (var j = 0; j < chars.length; j += 1) {
-+    diacriticsMap[chars[j]] = replacementList[i].base;
-+  }
-+}
-+
-+function removeDiacritics(str) {
-+  return str.replace(/[^\u0000-\u007e]/g, function(c) {
-+    return diacriticsMap[c] || c;
-+  });
-+}
-+
-+},{}],32:[function(require,module,exports){
-+(function (global){
-+
-+var rng;
-+
-+if (global.crypto && crypto.getRandomValues) {
-+  // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
-+  // Moderately fast, high quality
-+  var _rnds8 = new Uint8Array(16);
-+  rng = function whatwgRNG() {
-+    crypto.getRandomValues(_rnds8);
-+    return _rnds8;
-+  };
-+}
-+
-+if (!rng) {
-+  // Math.random()-based (RNG)
-+  //
-+  // If all else fails, use Math.random().  It's fast, but is of unspecified
-+  // quality.
-+  var  _rnds = new Array(16);
-+  rng = function() {
-+    for (var i = 0, r; i < 16; i++) {
-+      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
-+      _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
-+    }
-+
-+    return _rnds;
-+  };
-+}
-+
-+module.exports = rng;
-+
-+
-+}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-+},{}],33:[function(require,module,exports){
-+(function (Buffer){
-+//     uuid.js
-+//
-+//     Copyright (c) 2010-2012 Robert Kieffer
-+//     MIT License - http://opensource.org/licenses/mit-license.php
-+
-+// Unique ID creation requires a high quality random # generator.  We feature
-+// detect to determine the best RNG source, normalizing to a function that
-+// returns 128-bits of randomness, since that's what's usually required
-+var _rng = require('./rng');
-+
-+// Buffer class to use
-+var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;
-+
-+// Maps for number <-> hex string conversion
-+var _byteToHex = [];
-+var _hexToByte = {};
-+for (var i = 0; i < 256; i++) {
-+  _byteToHex[i] = (i + 0x100).toString(16).substr(1);
-+  _hexToByte[_byteToHex[i]] = i;
-+}
-+
-+// **`parse()` - Parse a UUID into it's component bytes**
-+function parse(s, buf, offset) {
-+  var i = (buf && offset) || 0, ii = 0;
-+
-+  buf = buf || [];
-+  s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
-+    if (ii < 16) { // Don't overflow!
-+      buf[i + ii++] = _hexToByte[oct];
-+    }
-+  });
-+
-+  // Zero out remaining bytes if string was short
-+  while (ii < 16) {
-+    buf[i + ii++] = 0;
-+  }
-+
-+  return buf;
-+}
-+
-+// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
-+function unparse(buf, offset) {
-+  var i = offset || 0, bth = _byteToHex;
-+  return  bth[buf[i++]] + bth[buf[i++]] +
-+          bth[buf[i++]] + bth[buf[i++]] + '-' +
-+          bth[buf[i++]] + bth[buf[i++]] + '-' +
-+          bth[buf[i++]] + bth[buf[i++]] + '-' +
-+          bth[buf[i++]] + bth[buf[i++]] + '-' +
-+          bth[buf[i++]] + bth[buf[i++]] +
-+          bth[buf[i++]] + bth[buf[i++]] +
-+          bth[buf[i++]] + bth[buf[i++]];
-+}
-+
-+// **`v1()` - Generate time-based UUID**
-+//
-+// Inspired by https://github.com/LiosK/UUID.js
-+// and http://docs.python.org/library/uuid.html
-+
-+// random #'s we need to init node and clockseq
-+var _seedBytes = _rng();
-+
-+// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
-+var _nodeId = [
-+  _seedBytes[0] | 0x01,
-+  _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
-+];
-+
-+// Per 4.2.2, randomize (14 bit) clockseq
-+var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
-+
-+// Previous uuid creation time
-+var _lastMSecs = 0, _lastNSecs = 0;
-+
-+// See https://github.com/broofa/node-uuid for API details
-+function v1(options, buf, offset) {
-+  var i = buf && offset || 0;
-+  var b = buf || [];
-+
-+  options = options || {};
-+
-+  var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
-+
-+  // UUID timestamps are 100 nano-second units since the Gregorian epoch,
-+  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
-+  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
-+  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
-+  var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
-+
-+  // Per 4.2.1.2, use count of uuid's generated during the current clock
-+  // cycle to simulate higher resolution clock
-+  var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
-+
-+  // Time since last uuid creation (in msecs)
-+  var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
-+
-+  // Per 4.2.1.2, Bump clockseq on clock regression
-+  if (dt < 0 && options.clockseq === undefined) {
-+    clockseq = clockseq + 1 & 0x3fff;
-+  }
-+
-+  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
-+  // time interval
-+  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
-+    nsecs = 0;
-+  }
-+
-+  // Per 4.2.1.2 Throw error if too many uuids are requested
-+  if (nsecs >= 10000) {
-+    throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
-+  }
-+
-+  _lastMSecs = msecs;
-+  _lastNSecs = nsecs;
-+  _clockseq = clockseq;
-+
-+  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
-+  msecs += 12219292800000;
-+
-+  // `time_low`
-+  var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
-+  b[i++] = tl >>> 24 & 0xff;
-+  b[i++] = tl >>> 16 & 0xff;
-+  b[i++] = tl >>> 8 & 0xff;
-+  b[i++] = tl & 0xff;
-+
-+  // `time_mid`
-+  var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
-+  b[i++] = tmh >>> 8 & 0xff;
-+  b[i++] = tmh & 0xff;
-+
-+  // `time_high_and_version`
-+  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
-+  b[i++] = tmh >>> 16 & 0xff;
-+
-+  // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
-+  b[i++] = clockseq >>> 8 | 0x80;
-+
-+  // `clock_seq_low`
-+  b[i++] = clockseq & 0xff;
-+
-+  // `node`
-+  var node = options.node || _nodeId;
-+  for (var n = 0; n < 6; n++) {
-+    b[i + n] = node[n];
-+  }
-+
-+  return buf ? buf : unparse(b);
-+}
-+
-+// **`v4()` - Generate random UUID**
-+
-+// See https://github.com/broofa/node-uuid for API details
-+function v4(options, buf, offset) {
-+  // Deprecated - 'format' argument, as supported in v1.2
-+  var i = buf && offset || 0;
-+
-+  if (typeof(options) == 'string') {
-+    buf = options == 'binary' ? new BufferClass(16) : null;
-+    options = null;
-+  }
-+  options = options || {};
-+
-+  var rnds = options.random || (options.rng || _rng)();
-+
-+  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
-+  rnds[6] = (rnds[6] & 0x0f) | 0x40;
-+  rnds[8] = (rnds[8] & 0x3f) | 0x80;
-+
-+  // Copy bytes to buffer, if provided
-+  if (buf) {
-+    for (var ii = 0; ii < 16; ii++) {
-+      buf[i + ii] = rnds[ii];
-+    }
-+  }
-+
-+  return buf || unparse(rnds);
-+}
-+
-+// Export public API
-+var uuid = v4;
-+uuid.v1 = v1;
-+uuid.v4 = v4;
-+uuid.parse = parse;
-+uuid.unparse = unparse;
-+uuid.BufferClass = BufferClass;
-+
-+module.exports = uuid;
-+
-+}).call(this,require("buffer").Buffer)
-+},{"./rng":32,"buffer":1}],34:[function(require,module,exports){
-+module.exports = zfill;
-+
-+function zfill(number, size) {
-+  number = number.toString();
-+  while (number.length < size) number = "0" + number;
-+  return number;
-+}
-+
-+},{}],35:[function(require,module,exports){
-+var $ = window.$;
-+
-+var shuffle = require('mess');
-+var querystring = require('querystring');
-+var zfill = require('zfill');
-+var PlayerClient = require('./playerclient');
-+var streaming = require('./streaming');
-+var Socket = require('./socket');
-+var uuid = require('uuid');
-+
-+var dynamicModeOn = false;
-+var hardwarePlaybackOn = false;
-+
-+var downloadMenuZipName = null;
-+
-+var selection = {
-+  ids: {
-+    queue: {},
-+    artist: {},
-+    album: {},
-+    track: {},
-+    stored_playlist: {},
-+    stored_playlist_item: {}
-+  },
-+  cursor: null,
-+  rangeSelectAnchor: null,
-+  rangeSelectAnchorType: null,
-+  type: null,
-+  isLibrary: function(){
-+    return this.type === 'artist' || this.type === 'album' || this.type === 'track';
-+  },
-+  isQueue: function(){
-+    return this.type === 'queue';
-+  },
-+  isStoredPlaylist: function(){
-+    return this.type === 'stored_playlist' || this.type === 'stored_playlist_item';
-+  },
-+  clear: function(){
-+    this.ids.artist = {};
-+    this.ids.album = {};
-+    this.ids.track = {};
-+    this.ids.queue = {};
-+    this.ids.stored_playlist = {};
-+    this.ids.stored_playlist_item = {};
-+  },
-+  fullClear: function(){
-+    this.clear();
-+    this.type = null;
-+    this.cursor = null;
-+    this.rangeSelectAnchor = null;
-+    this.rangeSelectAnchorType = null;
-+  },
-+  selectOnly: function(selName, key){
-+    this.clear();
-+    this.type = selName;
-+    this.ids[selName][key] = true;
-+    this.cursor = key;
-+    this.rangeSelectAnchor = key;
-+    this.rangeSelectAnchorType = selName;
-+  },
-+  isMulti: function(){
-+    var result, k;
-+    if (this.isLibrary()) {
-+      result = 2;
-+      for (k in this.ids.artist) {
-+        if (!--result) return true;
-+      }
-+      for (k in this.ids.album) {
-+        if (!--result) return true;
-+      }
-+      for (k in this.ids.track) {
-+        if (!--result) return true;
-+      }
-+      return false;
-+    } else if (this.isQueue()) {
-+      result = 2;
-+      for (k in this.ids.queue) {
-+        if (!--result) return true;
-+      }
-+      return false;
-+    } else if (this.isStoredPlaylist()) {
-+      result = 2;
-+      for (k in this.ids.stored_playlist) {
-+        if (!--result) return true;
-+      }
-+      for (k in this.ids.stored_playlist_item) {
-+        if (!--result) return true;
-+      }
-+      return false;
-+    } else {
-+      return false;
-+    }
-+  },
-+  getPos: function(type, key){
-+    if (type == null) type = this.type;
-+    if (key == null) key = this.cursor;
-+    var val;
-+    if (this.isLibrary()) {
-+      val = {
-+        type: 'library',
-+        artist: null,
-+        album: null,
-+        track: null
-+      };
-+      if (key != null) {
-+        switch (type) {
-+          case 'track':
-+            val.track = player.searchResults.trackTable[key];
-+            val.album = val.track.album;
-+            val.artist = val.album.artist;
-+            break;
-+          case 'album':
-+            val.album = player.searchResults.albumTable[key];
-+            val.artist = val.album.artist;
-+            break;
-+          case 'artist':
-+            val.artist = player.searchResults.artistTable[key];
-+            break;
-+        }
-+      } else {
-+        val.artist = player.searchResults.artistList[0];
-+      }
-+    } else if (this.isStoredPlaylist()) {
-+      val = {
-+        type: 'stored_playlist',
-+        stored_playlist: null,
-+        stored_playlist_item: null
-+      };
-+      if (key != null) {
-+        switch (type) {
-+          case 'stored_playlist_item':
-+            val.stored_playlist_item = player.stored_playlist_item_table[key];
-+            val.stored_playlist = val.stored_playlist_item.playlist;
-+            break;
-+          case 'stored_playlist':
-+            val.stored_playlist = player.stored_playlist_table[key];
-+            break;
-+        }
-+      } else {
-+        val.stored_playlist = player.stored_playlists[0];
-+      }
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+    return val;
-+  },
-+  posToArr: function(pos){
-+    var ref$;
-+    if (pos.type === 'library') {
-+      return [(ref$ = pos.artist) != null ? ref$.index : void 8, (ref$ = pos.album) != null ? ref$.index : void 8, (ref$ = pos.track) != null ? ref$.index : void 8];
-+    } else if (pos.type === 'stored_playlist') {
-+      return [(ref$ = pos.stored_playlist) != null ? ref$.index : void 8, (ref$ = pos.stored_playlist_item) != null ? ref$.index : void 8];
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+  },
-+  posEqual: function(pos1, pos2){
-+    var arr1 = this.posToArr(pos1);
-+    var arr2 = this.posToArr(pos2);
-+    return compareArrays(arr1, arr2) === 0;
-+  },
-+  posInBounds: function(pos){
-+    if (pos.type === 'library') {
-+      return pos.artist != null;
-+    } else if (pos.type === 'stored_playlist') {
-+      return pos.stored_playlist != null;
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+  },
-+  selectPos: function(pos){
-+    if (pos.type === 'library') {
-+      if (pos.track != null) {
-+        selection.ids.track[pos.track.key] = true;
-+      } else if (pos.album != null) {
-+        selection.ids.album[pos.album.key] = true;
-+      } else if (pos.artist != null) {
-+        selection.ids.artist[pos.artist.key] = true;
-+      }
-+    } else if (pos.type === 'stored_playlist') {
-+      if (pos.stored_playlist_item != null) {
-+        selection.ids.stored_playlist_item[pos.stored_playlist_item] = true;
-+      } else if (pos.stored_playlist != null) {
-+        selection.ids.stored_playlist[pos.stored_playlist] = true;
-+      }
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+  },
-+  incrementPos: function(pos){
-+    if (pos.type === 'library') {
-+      if (pos.track != null) {
-+        pos.track = pos.track.album.trackList[pos.track.index + 1];
-+        if (pos.track == null) {
-+          pos.album = pos.artist.albumList[pos.album.index + 1];
-+          if (pos.album == null) {
-+            pos.artist = player.searchResults.artistList[pos.artist.index + 1];
-+          }
-+        }
-+      } else if (pos.album != null) {
-+        if (isAlbumExpanded(pos.album)) {
-+          pos.track = pos.album.trackList[0];
-+        } else {
-+          var nextAlbum = pos.artist.albumList[pos.album.index + 1];
-+          if (nextAlbum) {
-+            pos.album = nextAlbum;
-+          } else {
-+            pos.artist = player.searchResults.artistList[pos.artist.index + 1];
-+            pos.album = null;
-+          }
-+        }
-+      } else if (pos.artist != null) {
-+        if (isArtistExpanded(pos.artist)) {
-+          pos.album = pos.artist.albumList[0];
-+        } else {
-+          pos.artist = player.searchResults.artistList[pos.artist.index + 1];
-+        }
-+      }
-+    } else if (pos.type === 'stored_playlist') {
-+      if (pos.stored_playlist_item != null) {
-+        pos.stored_playlist_item = pos.stored_playlist_item.playlist.itemList[pos.stored_playlist_item.index + 1];
-+        if (pos.stored_playlist_item == null) {
-+          pos.stored_playlist = player.stored_playlists[pos.stored_playlist.index + 1];
-+        }
-+      } else if (pos.stored_playlist != null) {
-+        if (isStoredPlaylistExpanded(pos.stored_playlist)) {
-+          pos.stored_playlist_item = pos.stored_playlist.itemList[0];
-+          if (pos.stored_playlist_item == null) {
-+            pos.stored_playlist = player.stored_playlists[pos.stored_playlist.index + 1];
-+          }
-+        } else {
-+          pos.stored_playlist = player.stored_playlists[pos.stored_playlist.index + 1];
-+        }
-+      }
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+  },
-+  toTrackKeys: function(random){
-+    var this$ = this;
-+    if (random == null) random = false;
-+    if (this.isLibrary()) {
-+      return libraryToTrackKeys();
-+    } else if (this.isQueue()) {
-+      return queueToTrackKeys();
-+    } else if (this.isStoredPlaylist()) {
-+      return storedPlaylistToTrackKeys();
-+    } else {
-+      throw new Error("NothingSelected");
-+    }
-+
-+    function libraryToTrackKeys() {
-+      var key;
-+      var track_set = {};
-+      function selRenderArtist(artist){
-+        var i, ref$, len$, album;
-+        for (i = 0, len$ = (ref$ = artist.albumList).length; i < len$; ++i) {
-+          album = ref$[i];
-+          selRenderAlbum(album);
-+        }
-+      }
-+      function selRenderAlbum(album){
-+        var i, ref$, len$, track;
-+        for (i = 0, len$ = (ref$ = album.trackList).length; i < len$; ++i) {
-+          track = ref$[i];
-+          selRenderTrack(track);
-+        }
-+      }
-+      function selRenderTrack(track){
-+        track_set[track.key] = this$.posToArr(getTrackSelPos(track));
-+      }
-+      function getTrackSelPos(track){
-+        return {
-+          type: 'library',
-+          artist: track.album.artist,
-+          album: track.album,
-+          track: track
-+        };
-+      }
-+      for (key in selection.ids.artist) {
-+        selRenderArtist(player.searchResults.artistTable[key]);
-+      }
-+      for (key in selection.ids.album) {
-+        selRenderAlbum(player.searchResults.albumTable[key]);
-+      }
-+      for (key in selection.ids.track) {
-+        selRenderTrack(player.searchResults.trackTable[key]);
-+      }
-+      return trackSetToKeys(track_set);
-+    }
-+    function queueToTrackKeys(){
-+      var keys = [];
-+      for (var key in selection.ids.queue) {
-+        keys.push(player.queue.itemTable[key].track.key);
-+      }
-+      if (random) shuffle(keys);
-+      return keys;
-+    }
-+    function storedPlaylistToTrackKeys(){
-+      var track_set = {};
-+      function renderQueue(playlist){
-+        var i, ref$, len$, item;
-+        for (i = 0, len$ = (ref$ = playlist.itemList).length; i < len$; ++i) {
-+          item = ref$[i];
-+          renderPlaylistItem(item);
-+        }
-+      }
-+      function renderPlaylistItem(item){
-+        track_set[item.track.key] = this$.posToArr(getItemSelPos(item));
-+      }
-+      function getItemSelPos(item){
-+        return {
-+          type: 'stored_playlist',
-+          stored_playlist: item.playlist,
-+          stored_playlist_item: item
-+        };
-+      }
-+      for (var key in selection.ids.stored_playlist) {
-+        renderQueue(player.stored_playlist_table[key]);
-+      }
-+      for (key in selection.ids.stored_playlist_item) {
-+        renderPlaylistItem(player.stored_playlist_item_table[key]);
-+      }
-+      return trackSetToKeys(track_set);
-+    }
-+
-+    function trackSetToKeys(track_set){
-+      var key;
-+      var keys = [];
-+      if (random) {
-+        for (key in track_set) {
-+          keys.push(key);
-+        }
-+        shuffle(keys);
-+        return keys;
-+      }
-+      var track_arr = [];
-+      for (key in track_set) {
-+        track_arr.push({
-+          key: key,
-+          pos: track_set[key],
-+        });
-+      }
-+      track_arr.sort(function(a, b) {
-+        return compareArrays(a.pos, b.pos);
-+      });
-+      for (var i = 0; i < track_arr.length; i += 1) {
-+        var track = track_arr[i];
-+        keys.push(track.key);
-+      }
-+      return keys;
-+    }
-+  }
-+};
-+var BASE_TITLE = document.title;
-+var MARGIN = 10;
-+var AUTO_EXPAND_LIMIT = 30;
-+var ICON_COLLAPSED = 'ui-icon-triangle-1-e';
-+var ICON_EXPANDED = 'ui-icon-triangle-1-se';
-+var permissions = {};
-+var socket = null;
-+var player = null;
-+var userIsSeeking = false;
-+var userIsVolumeSliding = false;
-+var started_drag = false;
-+var abortDrag = function(){};
-+var myUserId = null;
-+var lastFmApiKey = null;
-+var LoadStatus = {
-+  Init: 'Loading...',
-+  NoServer: 'Server is down.',
-+  GoodToGo: '[good to go]'
-+};
-+var repeatModeNames = ["Off", "One", "All"];
-+var load_status = LoadStatus.Init;
-+var settings_ui = {
-+  auth: {
-+    show_edit: false,
-+    password: ""
-+  }
-+};
-+var localState = {
-+  myUserIds: {},
-+  userName: null,
-+  lastfm: {
-+    username: null,
-+    session_key: null,
-+    scrobbling_on: false
-+  },
-+  authPassword: null,
-+  autoQueueUploads: true,
-+};
-+var $document = $(document);
-+var $window = $(window);
-+var $queueWindow = $('#queue-window');
-+var $leftWindow = $('#left-window');
-+var $queueItems = $('#queue-items');
-+var $dynamicMode = $('#dynamic-mode');
-+var $queueBtnRepeat = $('#queue-btn-repeat');
-+var $tabs = $('#tabs');
-+var $library = $('#library');
-+var $libFilter = $('#lib-filter');
-+var $trackSlider = $('#track-slider');
-+var $nowplaying = $('#nowplaying');
-+var $nowplaying_elapsed = $nowplaying.find('.elapsed');
-+var $nowplaying_left = $nowplaying.find('.left');
-+var $volSlider = $('#vol-slider');
-+var $settings = $('#settings');
-+var $uploadByUrl = $('#upload-by-url');
-+var $mainErrMsg = $('#main-err-msg');
-+var $mainErrMsgText = $('#main-err-msg-text');
-+var $playlistsList = $('#playlists-list');
-+var $playlists = $('#playlists');
-+var $upload = $('#upload');
-+var $trackDisplay = $('#track-display');
-+var $libHeader = $('#lib-window-header');
-+var $queueHeader = $('#queue-header');
-+var $autoQueueUploads = $('#auto-queue-uploads');
-+var uploadInput = document.getElementById("upload-input");
-+var $uploadWidget = $("#upload-widget");
-+var $settingsEditPassword = $('#settings-edit-password');
-+var $settingsShowPassword = $('#settings-show-password');
-+var $settingsAuthCancel = $('#settings-auth-cancel');
-+var $settingsAuthSave = $('#settings-auth-save');
-+var $settingsAuthEdit = $('#settings-auth-edit');
-+var $settingsAuthClear = $('#settings-auth-clear');
-+var streamUrlDom = document.getElementById('settings-stream-url');
-+var $authPermRead = $('#auth-perm-read');
-+var $authPermAdd = $('#auth-perm-add');
-+var $authPermControl = $('#auth-perm-control');
-+var $authPermAdmin = $('#auth-perm-admin');
-+var $lastFmSignOut = $('#lastfm-sign-out');
-+var $authPassword = $('#auth-password');
-+var lastFmAuthUrlDom = document.getElementById('lastfm-auth-url');
-+var $settingsLastFmIn = $('#settings-lastfm-in');
-+var $settingsLastFmOut = $('#settings-lastfm-out');
-+var settingsLastFmUserDom = document.getElementById('settings-lastfm-user');
-+var $toggleScrobble = $('#toggle-scrobble');
-+var $shortcuts = $('#shortcuts');
-+var $editTagsDialog = $('#edit-tags');
-+var $queueMenu = $('#menu-queue');
-+var $libraryMenu = $('#menu-library');
-+var $toggleHardwarePlayback = $('#toggle-hardware-playback');
-+var $newPlaylistBtn = $('#new-playlist-btn');
-+var $emptyLibraryMessage = $('#empty-library-message');
-+var $libraryNoItems = $('#library-no-items');
-+var $libraryArtists = $('#library-artists');
-+
-+var tabs = {
-+  library: {
-+    $pane: $('#library-pane'),
-+    $tab: $('#library-tab'),
-+  },
-+  upload: {
-+    $pane: $('#upload-pane'),
-+    $tab: $('#upload-tab'),
-+  },
-+  playlists: {
-+    $pane: $('#playlists-pane'),
-+    $tab: $('#playlists-tab'),
-+  },
-+  settings: {
-+    $pane: $('#settings-pane'),
-+    $tab: $('#settings-tab'),
-+  },
-+};
-+
-+function saveLocalState(){
-+  localStorage.setItem('state', JSON.stringify(localState));
-+}
-+
-+function loadLocalState() {
-+  var stateString = localStorage.getItem('state');
-+  if (!stateString) return;
-+  var obj;
-+  try {
-+    obj = JSON.parse(stateString);
-+  } catch (err) {
-+    return;
-+  }
-+  // this makes sure it still works when we change the format of localState
-+  for (var key in localState) {
-+    if (obj[key] !== undefined) {
-+      localState[key] = obj[key];
-+    }
-+  }
-+}
-+
-+function scrollLibraryToSelection() {
-+  var helpers = getSelectionHelpers();
-+  if (!helpers) return;
-+  delete helpers.queue;
-+  scrollThingToSelection($library, helpers);
-+}
-+
-+function scrollPlaylistToSelection(){
-+  var helpers = getSelectionHelpers();
-+  if (!helpers) return;
-+  delete helpers.track;
-+  delete helpers.artist;
-+  delete helpers.album;
-+  scrollThingToSelection($queueItems, helpers);
-+}
-+
-+function scrollThingToSelection($scrollArea, helpers){
-+  var topPos = null;
-+  var bottomPos = null;
-+  for (var selName in helpers) {
-+    var helper = helpers[selName];
-+    for (var id in helper.ids) {
-+      var $div = helper.$getDiv(id);
-+      var itemTop = $div.offset().top;
-+      var itemBottom = itemTop + $div.height();
-+      if (topPos == null || itemTop < topPos) {
-+        topPos = itemTop;
-+      }
-+      if (bottomPos == null || itemBottom > bottomPos) {
-+        bottomPos = itemBottom;
-+      }
-+    }
-+  }
-+  if (topPos != null) {
-+    var scrollAreaTop = $scrollArea.offset().top;
-+    var selectionTop = topPos - scrollAreaTop;
-+    var selectionBottom = bottomPos - scrollAreaTop - $scrollArea.height();
-+    var scrollAmt = $scrollArea.scrollTop();
-+    if (selectionTop < 0) {
-+      return $scrollArea.scrollTop(scrollAmt + selectionTop);
-+    } else if (selectionBottom > 0) {
-+      return $scrollArea.scrollTop(scrollAmt + selectionBottom);
-+    }
-+  }
-+}
-+
-+function downloadKeys(keys, zipName) {
-+  var $form = $(document.createElement('form'));
-+  $form.attr('action', "/download/custom");
-+  $form.attr('method', "post");
-+  $form.attr('target', "_blank");
-+  for (var i = 0; i < keys.length; i += 1) {
-+    var key = keys[i];
-+    var $input = $(document.createElement('input'));
-+    $input.attr('type', 'hidden');
-+    $input.attr('name', 'key');
-+    $input.attr('value', key);
-+    $form.append($input);
-+  }
-+  var $zipNameInput = $(document.createElement('input'));
-+  $zipNameInput.attr('type', 'hidden');
-+  $zipNameInput.attr('name', 'zipName');
-+  $zipNameInput.attr('value', zipName);
-+  $form.append($zipNameInput);
-+
-+  $form.submit();
-+}
-+
-+function getDragPosition(x, y){
-+  var ref$;
-+  var result = {};
-+  for (var i = 0, len$ = (ref$ = $queueItems.find(".pl-item").get()).length; i < len$; ++i) {
-+    var item = ref$[i];
-+    var $item = $(item);
-+    var middle = $item.offset().top + $item.height() / 2;
-+    var track = player.queue.itemTable[$item.attr('data-id')];
-+    if (middle < y) {
-+      if (result.previous_key == null || track.sortKey > result.previous_key) {
-+        result.$previous = $item;
-+        result.previous_key = track.sortKey;
-+      }
-+    } else {
-+      if (result.next_key == null || track.sortKey < result.next_key) {
-+        result.$next = $item;
-+        result.next_key = track.sortKey;
-+      }
-+    }
-+  }
-+  return result;
-+}
-+
-+function renderPlaylistButtons(){
-+  $dynamicMode
-+    .prop("checked", dynamicModeOn)
-+    .button("refresh");
-+  var repeatModeName = repeatModeNames[player.repeat];
-+  $queueBtnRepeat
-+    .button("option", "label", "Repeat: " + repeatModeName)
-+    .prop("checked", player.repeat !== PlayerClient.REPEAT_OFF)
-+    .button("refresh");
-+}
-+
-+function renderQueue(){
-+  var itemList = player.queue.itemList || [];
-+  var scrollTop = $queueItems.scrollTop();
-+
-+  // add the missing dom entries
-+  var i;
-+  var playlistItemsDom = $queueItems.get(0);
-+  for (i = playlistItemsDom.childElementCount; i < itemList.length; i += 1) {
-+    $queueItems.append(
-+      '<div class="pl-item">' +
-+        '<span class="track"></span>' +
-+        '<span class="title"></span>' +
-+        '<span class="artist"></span>' +
-+        '<span class="album"></span>' +
-+        '<span class="time"></span>' +
-+      '</div>');
-+  }
-+  // remove the extra dom entries
-+  var domItem;
-+  while (itemList.length < playlistItemsDom.childElementCount) {
-+    playlistItemsDom.removeChild(playlistItemsDom.lastChild);
-+  }
-+
-+  // overwrite existing dom entries
-+  var $domItems = $queueItems.children();
-+  var item, track;
-+  for (i = 0; i < itemList.length; i += 1) {
-+    var $domItem = $($domItems[i]);
-+    item = itemList[i];
-+    $domItem.attr('id', 'playlist-track-' + item.id);
-+    $domItem.attr('data-id', item.id);
-+    track = item.track;
-+    $domItem.find('.track').text(track.track || "");
-+    $domItem.find('.title').text(track.name || "");
-+    $domItem.find('.artist').text(track.artistName || "");
-+    $domItem.find('.album').text(track.albumName || "");
-+    var timeText = player.isScanning(track) ? "scan" : formatTime(track.duration);
-+    $domItem.find('.time').text(timeText);
-+  }
-+
-+  refreshSelection();
-+  labelPlaylistItems();
-+  $queueItems.scrollTop(scrollTop);
-+}
-+
-+function labelPlaylistItems() {
-+  var item;
-+  var curItem = player.currentItem;
-+  $queueItems.find(".pl-item")
-+    .removeClass('current')
-+    .removeClass('old')
-+    .removeClass('random');
-+  if (curItem != null && dynamicModeOn) {
-+    for (var index = 0; index < curItem.index; ++index) {
-+      item = player.queue.itemList[index];
-+      var itemId = item && item.id;
-+      if (itemId != null) {
-+        $("#playlist-track-" + itemId).addClass('old');
-+      }
-+    }
-+  }
-+  for (var i = 0; i < player.queue.itemList.length; i += 1) {
-+    item = player.queue.itemList[i];
-+    if (item.isRandom) {
-+      $("#playlist-track-" + item.id).addClass('random');
-+    }
-+  }
-+  if (curItem != null) {
-+    $("#playlist-track-" + curItem.id).addClass('current');
-+  }
-+}
-+
-+function getSelectionHelpers(){
-+  if (player == null) return null;
-+  if (player.queue == null) return null;
-+  if (player.queue.itemTable == null) return null;
-+  if (player.searchResults == null) return null;
-+  if (player.searchResults.artistTable == null) return null;
-+  return {
-+    queue: {
-+      ids: selection.ids.queue,
-+      table: player.queue.itemTable,
-+      $getDiv: function(id){
-+        return $("#playlist-track-" + id);
-+      },
-+    },
-+    artist: {
-+      ids: selection.ids.artist,
-+      table: player.searchResults.artistTable,
-+      $getDiv: function(id){
-+        return $("#lib-artist-" + toHtmlId(id));
-+      },
-+    },
-+    album: {
-+      ids: selection.ids.album,
-+      table: player.searchResults.albumTable,
-+      $getDiv: function(id){
-+        return $("#lib-album-" + toHtmlId(id));
-+      },
-+    },
-+    track: {
-+      ids: selection.ids.track,
-+      table: player.searchResults.trackTable,
-+      $getDiv: function(id){
-+        return $("#lib-track-" + toHtmlId(id));
-+      },
-+    },
-+    stored_playlist: {
-+      ids: selection.ids.stored_playlist,
-+      table: player.stored_playlist_table,
-+      $getDiv: function(id){
-+        return $("#stored-pl-pl-" + toHtmlId(id));
-+      },
-+    },
-+    stored_playlist_item: {
-+      ids: selection.ids.stored_playlist_item,
-+      table: player.stored_playlist_item_table,
-+      $getDiv: function(id){
-+        return $("#stored-pl-item-" + toHtmlId(id));
-+      },
-+    },
-+  };
-+}
-+
-+function refreshSelection() {
-+  var helpers = getSelectionHelpers();
-+  if (!helpers) return;
-+  $queueItems.find(".pl-item").removeClass('selected').removeClass('cursor');
-+  $libraryArtists.find(".clickable").removeClass('selected').removeClass('cursor');
-+  $playlistsList.find(".clickable").removeClass('selected').removeClass('cursor');
-+  if (selection.type == null) return;
-+  for (var selectionType in helpers) {
-+    var helper = helpers[selectionType];
-+    var id;
-+    // clean out stale ids
-+    for (id in helper.ids) {
-+      if (helper.table[id] == null) {
-+        delete helper.ids[id];
-+      }
-+    }
-+    for (id in helper.ids) {
-+      helper.$getDiv(id).addClass('selected');
-+    }
-+    if (selection.cursor != null && selectionType === selection.type) {
-+      var validIds = getValidIds(selectionType);
-+      if (validIds[selection.cursor] == null) {
-+        // server just deleted our current cursor item.
-+        // select another of our ids randomly, if we have any.
-+        selection.cursor = Object.keys(helper.ids)[0];
-+        selection.rangeSelectAnchor = selection.cursor;
-+        selection.rangeSelectAnchorType = selectionType;
-+        if (selection.cursor == null) {
-+          // no selected items
-+          selection.fullClear();
-+        }
-+      }
-+      if (selection.cursor != null) {
-+        helper.$getDiv(selection.cursor).addClass('cursor');
-+      }
-+    }
-+  }
-+}
-+
-+function getValidIds(selectionType) {
-+  switch (selectionType) {
-+    case 'queue':  return player.queue.itemTable;
-+    case 'artist': return player.library.artistTable;
-+    case 'album':  return player.library.albumTable;
-+    case 'track':  return player.library.trackTable;
-+    case 'stored_playlist':  return player.stored_playlist_table;
-+    case 'stored_playlist_item':  return player.stored_playlist_item_table;
-+  }
-+  throw new Error("BadSelectionType");
-+}
-+
-+function artistId(s) {
-+  return "lib-artist-" + toHtmlId(s);
-+}
-+
-+function artistDisplayName(name) {
-+  return name || '[Unknown Artist]';
-+}
-+
-+var triggerRenderLibrary = makeRenderCall(renderLibrary, 100);
-+var triggerRenderQueue = makeRenderCall(renderQueue, 100);
-+var triggerPlaylistsUpdate = makeRenderCall(renderPlaylists, 100);
-+
-+function makeRenderCall(renderFn, interval) {
-+  var renderTimeout = null;
-+  var renderWanted = false;
-+
-+  return ensureRenderHappensSoon;
-+
-+  function ensureRenderHappensSoon() {
-+    if (renderTimeout) {
-+      renderWanted = true;
-+      return;
-+    }
-+
-+    renderFn();
-+    renderWanted = false;
-+    renderTimeout = setTimeout(checkRender, interval);
-+  }
-+
-+  function checkRender() {
-+    renderTimeout = null;
-+    if (renderWanted) {
-+      ensureRenderHappensSoon();
-+    }
-+  }
-+}
-+
-+function renderPlaylists() {
-+  var playlistList = player.stored_playlists;
-+  var scrollTop = $playlists.scrollTop();
-+
-+  // add the missing dom entries
-+  var i;
-+  var playlistListDom = $playlistsList.get(0);
-+  for (i = playlistListDom.childElementCount; i < playlistList.length; i += 1) {
-+    $playlistsList.append(
-+      '<li>' +
-+        '<div class="clickable expandable" data-type="stored_playlist">' +
-+          '<div class="ui-icon"></div>' +
-+          '<span></span>' +
-+        '</div>' +
-+        '<ul></ul>' +
-+      '</li>');
-+  }
-+  // remove the extra dom entries
-+  var domItem;
-+  while (playlistList.length < playlistListDom.childElementCount) {
-+    playlistListDom.removeChild(playlistListDom.lastChild);
-+  }
-+
-+  // overwrite existing dom entries
-+  var playlist;
-+  var $domItems = $playlistsList.children();
-+  for (i = 0; i < playlistList.length; i += 1) {
-+    domItem = $domItems[i];
-+    playlist = playlistList[i];
-+    $(domItem).data('cached', false);
-+    var divDom = domItem.children[0];
-+    divDom.setAttribute('id', toStoredPlaylistId(playlist.id));
-+    divDom.setAttribute('data-key', playlist.id);
-+    var iconDom = divDom.children[0];
-+    $(iconDom)
-+      .addClass(ICON_COLLAPSED)
-+      .removeClass(ICON_EXPANDED);
-+    var spanDom = divDom.children[1];
-+    spanDom.textContent = playlist.name;
-+    var ulDom = domItem.children[1];
-+    ulDom.style.display = 'block';
-+    while (ulDom.firstChild) {
-+      ulDom.removeChild(ulDom.firstChild);
-+    }
-+  }
-+
-+  $playlists.scrollTop(scrollTop);
-+  refreshSelection();
-+  // TODO expandPlaylistsToSelection()
-+}
-+
-+function renderLibrary() {
-+  var artistList = player.searchResults.artistList || [];
-+  var scrollTop = $library.scrollTop();
-+
-+  $emptyLibraryMessage.text(player.haveFileListCache ? "No Results" : "loading...");
-+  $libraryNoItems.toggle(!artistList.length);
-+
-+  // add the missing dom entries
-+  var i;
-+  var artistListDom = $libraryArtists.get(0);
-+  for (i = artistListDom.childElementCount; i < artistList.length; i += 1) {
-+    $libraryArtists.append(
-+      '<li>' +
-+        '<div class="clickable expandable" data-type="artist">' +
-+          '<div class="ui-icon"></div>' +
-+          '<span></span>' +
-+        '</div>' +
-+        '<ul></ul>' +
-+      '</li>');
-+  }
-+  // remove the extra dom entries
-+  var domItem;
-+  while (artistList.length < artistListDom.childElementCount) {
-+    artistListDom.removeChild(artistListDom.lastChild);
-+  }
-+
-+  // overwrite existing dom entries
-+  var artist;
-+  var $domItems = $libraryArtists.children();
-+  for (i = 0; i < artistList.length; i += 1) {
-+    domItem = $domItems[i];
-+    artist = artistList[i];
-+    $(domItem).data('cached', false);
-+    var divDom = domItem.children[0];
-+    divDom.setAttribute('id', artistId(artist.key));
-+    divDom.setAttribute('data-key', artist.key);
-+    var iconDom = divDom.children[0];
-+    $(iconDom)
-+      .addClass(ICON_COLLAPSED)
-+      .removeClass(ICON_EXPANDED);
-+    var spanDom = divDom.children[1];
-+    spanDom.textContent = artistDisplayName(artist.name);
-+    var ulDom = domItem.children[1];
-+    ulDom.style.display = 'block';
-+    while (ulDom.firstChild) {
-+      ulDom.removeChild(ulDom.firstChild);
-+    }
-+  }
-+
-+  var $artists = $library.children("ul").children("li");
-+  var nodeCount = $artists.length;
-+  expandStuff($artists);
-+  $library.scrollTop(scrollTop);
-+  refreshSelection();
-+  expandLibraryToSelection();
-+
-+  function expandStuff($liSet) {
-+    if (nodeCount >= AUTO_EXPAND_LIMIT) return;
-+    for (var i = 0; i < $liSet.length; i += 1) {
-+      var li = $liSet[i];
-+      var $li = $(li);
-+      var $ul = $li.children("ul");
-+      var $subLiSet = $ul.children("li");
-+      var proposedNodeCount = nodeCount + $subLiSet.length;
-+      if (proposedNodeCount <= AUTO_EXPAND_LIMIT) {
-+        toggleLibraryExpansion($li);
-+        $ul = $li.children("ul");
-+        $subLiSet = $ul.children("li");
-+        nodeCount = proposedNodeCount;
-+        expandStuff($subLiSet);
-+      }
-+    }
-+  }
-+
-+}
-+
-+function getCurrentTrackPosition(){
-+  if (player.trackStartDate != null && player.isPlaying === true) {
-+    return (new Date() - player.trackStartDate) / 1000;
-+  } else {
-+    return player.pausedTime;
-+  }
-+}
-+
-+function updateSliderPos() {
-+  if (userIsSeeking) return;
-+
-+  var duration, disabled, elapsed, sliderPos;
-+  if (player.currentItem && player.isPlaying != null && player.currentItem.track) {
-+    disabled = false;
-+    elapsed = getCurrentTrackPosition();
-+    duration = player.currentItem.track.duration;
-+    sliderPos = elapsed / duration;
-+  } else {
-+    disabled = true;
-+    elapsed = duration = sliderPos = 0;
-+  }
-+  $trackSlider.slider("option", "disabled", disabled).slider("option", "value", sliderPos);
-+  $nowplaying_elapsed.html(formatTime(elapsed));
-+  $nowplaying_left.html(formatTime(duration));
-+}
-+
-+function renderVolumeSlider() {
-+  if (userIsVolumeSliding) return;
-+
-+  var enabled = player.volume != null;
-+  if (enabled) {
-+    $volSlider.slider('option', 'value', player.volume);
-+  }
-+  $volSlider.slider('option', 'disabled', !enabled);
-+}
-+
-+function renderNowPlaying() {
-+  var track = null;
-+  if (player.currentItem != null) {
-+    track = player.currentItem.track;
-+  }
-+  var trackDisplay;
-+  if (track != null) {
-+    trackDisplay = track.name + " - " + track.artistName;
-+    if (track.albumName.length) {
-+      trackDisplay += " - " + track.albumName;
-+    }
-+    document.title = trackDisplay + " - " + BASE_TITLE;
-+    if (/Groove Basin/.test(track.name)) {
-+      $("html").addClass('groovebasin');
-+    } else {
-+      $("html").removeClass('groovebasin');
-+    }
-+    if (/Never Gonna Give You Up/.test(track.name) && /Rick Astley/.test(track.artistName)) {
-+      $("html").addClass('nggyu');
-+    } else {
-+      $("html").removeClass('nggyu');
-+    }
-+  } else {
-+    trackDisplay = " ";
-+    document.title = BASE_TITLE;
-+  }
-+  $trackDisplay.html(trackDisplay);
-+  var oldClass;
-+  var newClass;
-+  if (player.isPlaying === true) {
-+    oldClass = 'ui-icon-play';
-+    newClass = 'ui-icon-pause';
-+  } else {
-+    oldClass = 'ui-icon-pause';
-+    newClass = 'ui-icon-play';
-+  }
-+  $nowplaying.find(".toggle span").removeClass(oldClass).addClass(newClass);
-+  $trackSlider.slider("option", "disabled", player.isPlaying == null);
-+  updateSliderPos();
-+  renderVolumeSlider();
-+}
-+
-+function render(){
-+  var hide_main_err = load_status === LoadStatus.GoodToGo;
-+  $queueWindow.toggle(hide_main_err);
-+  $leftWindow.toggle(hide_main_err);
-+  $nowplaying.toggle(hide_main_err);
-+  $mainErrMsg.toggle(!hide_main_err);
-+  if (!hide_main_err) {
-+    document.title = BASE_TITLE;
-+    $mainErrMsgText.text(load_status);
-+    return;
-+  }
-+  renderQueue();
-+  renderPlaylistButtons();
-+  renderLibrary();
-+  renderNowPlaying();
-+  updateSettingsAuthUi();
-+  updateLastFmSettingsUi();
-+  handleResize();
-+}
-+
-+function renderArtist($ul, albumList) {
-+  albumList.forEach(function(album) {
-+    $ul.append(
-+      '<li>' +
-+        '<div class="clickable expandable" data-type="album">' +
-+          '<div class="ui-icon ui-icon-triangle-1-e"></div>' +
-+          '<span></span>' +
-+        '</div>' +
-+        '<ul style="display: none;"></ul>' +
-+      '</li>');
-+    var liDom = $ul.get(0).lastChild;
-+    var divDom = liDom.children[0];
-+    divDom.setAttribute('id', toAlbumId(album.key));
-+    divDom.setAttribute('data-key', album.key);
-+    var spanDom = divDom.children[1];
-+    spanDom.textContent = album.name || '[Unknown Album]';
-+
-+    var artistUlDom = liDom.children[1];
-+    var $artistUlDom = $(artistUlDom);
-+    album.trackList.forEach(function(track) {
-+      $artistUlDom.append(
-+        '<li>' +
-+          '<div class="clickable" data-type="track">' +
-+            '<span></span>' +
-+          '</div>' +
-+        '</li>');
-+      var trackLiDom = artistUlDom.lastChild;
-+      var trackDivDom = trackLiDom.children[0];
-+      trackDivDom.setAttribute('id', toTrackId(track.key));
-+      trackDivDom.setAttribute('data-key', track.key);
-+      var trackSpanDom = trackDivDom.children[0];
-+      var caption = "";
-+      if (track.track) {
-+        caption += track.track + ". ";
-+      }
-+      if (track.compilation) {
-+        caption += track.artistName + " - ";
-+      }
-+      caption += track.name;
-+      trackSpanDom.textContent = caption;
-+    });
-+  });
-+}
-+
-+function renderPlaylist($ul, playlist) {
-+  playlist.itemList.forEach(function(item) {
-+    debugger;
-+    $ul.append(
-+      '<li>' +
-+        '<div class="clickable" data-type="stored_playlist_item">' +
-+          '<span></span>' +
-+        '</div>' +
-+      '</li>');
-+    var liDom = $ul.get(0).lastChild;
-+    var divDom = liDom.children[0];
-+    divDom.setAttribute('id', toStoredPlaylistItemId(item.id));
-+    divDom.setAttribute('data-key', item.id);
-+    var spanDom = divDom.children[0];
-+    var track = item.track;
-+    var caption = track.artistName + " - " + track.name;
-+    spanDom.textContent = caption;
-+  });
-+}
-+
-+function genericToggleExpansion($li, options) {
-+  var topLevelType = options.topLevelType;
-+  var renderDom = options.renderDom;
-+  var $div = $li.find("> div");
-+  var $ul = $li.find("> ul");
-+  if ($div.attr('data-type') === topLevelType) {
-+    if (!$li.data('cached')) {
-+      $li.data('cached', true);
-+      var key = $div.attr('data-key');
-+      renderDom($ul, key);
-+
-+      $ul.toggle();
-+      refreshSelection();
-+    }
-+  }
-+  $ul.toggle();
-+  var oldClass = ICON_EXPANDED;
-+  var newClass = ICON_COLLAPSED;
-+  if ($ul.is(":visible")) {
-+    var tmp = oldClass;
-+    oldClass = newClass;
-+    newClass = tmp;
-+  }
-+  $div.find("div").removeClass(oldClass).addClass(newClass);
-+}
-+
-+function toggleLibraryExpansion($li) {
-+  genericToggleExpansion($li, {
-+    topLevelType: 'artist',
-+    renderDom: function($ul, key) {
-+      var albumList = player.searchResults.artistTable[key].albumList;
-+      renderArtist($ul, albumList);
-+    },
-+  });
-+}
-+
-+function togglePlaylistExpansion($li) {
-+  genericToggleExpansion($li, {
-+    topLevelType: 'stored_playlist',
-+    renderDom: function($ul, key) {
-+      var playlist = player.stored_playlist_table[key];
-+      renderPlaylist($ul, playlist);
-+    },
-+  });
-+}
-+
-+function maybeDeleteTracks(keysList) {
-+  var fileList = keysList.map(function(key) {
-+    return player.library.trackTable[key].file;
-+  });
-+  var listText = fileList.slice(0, 7).join("\n  ");
-+  if (fileList.length > 7) {
-+    listText += "\n  ...";
-+  }
-+  var songText = fileList.length === 1 ? "song" : "songs";
-+  var message = "You are about to delete " + fileList.length + " " + songText + " permanently:\n\n  " + listText;
-+  if (!confirm(message)) return false;
-+  player.deleteTracks(keysList);
-+  return true;
-+}
-+
-+function handleDeletePressed(shift) {
-+  var keysList;
-+  if (selection.isLibrary()) {
-+    keysList = selection.toTrackKeys();
-+    maybeDeleteTracks(keysList);
-+  } else if (selection.isStoredPlaylist()) {
-+    if (shift) {
-+      keysList = selection.toTrackKeys();
-+      maybeDeleteTracks(keysList);
-+    } else {
-+      maybeDeleteSelectedPlaylists();
-+    }
-+  } else if (selection.isQueue()) {
-+    if (shift) {
-+      keysList = [];
-+      for (var id in selection.ids.queue) {
-+        keysList.push(player.queue.itemTable[id].track.key);
-+      }
-+      if (!maybeDeleteTracks(keysList)) return;
-+    }
-+    var sortKey = player.queue.itemTable[selection.cursor].sortKey;
-+    player.removeIds(Object.keys(selection.ids.queue));
-+    var item = null;
-+    for (var i = 0; i < player.queue.itemList.length; i++) {
-+      item = player.queue.itemList[i];
-+      if (item.sortKey > sortKey) {
-+        // select the very next one
-+        break;
-+      }
-+      // if we deleted the last item, select the new last item.
-+    }
-+    // if there's no items, select nothing.
-+    if (item != null) {
-+      selection.selectOnly('queue', item.id);
-+    }
-+    refreshSelection();
-+  }
-+}
-+
-+function togglePlayback(){
-+  if (player.isPlaying === true) {
-+    player.pause();
-+  } else if (player.isPlaying === false) {
-+    player.play();
-+  }
-+  // else we haven't received state from server yet
-+}
-+
-+function setDynamicMode(value) {
-+  dynamicModeOn = value;
-+  player.sendCommand('dynamicModeOn', dynamicModeOn);
-+}
-+
-+function toggleDynamicMode(){
-+  setDynamicMode(!dynamicModeOn);
-+}
-+
-+function nextRepeatState(){
-+  player.setRepeatMode((player.repeat + 1) % repeatModeNames.length);
-+}
-+
-+var keyboardHandlers = (function(){
-+  function upDownHandler(event){
-+    var defaultIndex, dir, nextPos;
-+    if (event.which === 38) {
-+      // up
-+      defaultIndex = player.currentItem ? player.currentItem.index - 1 : player.queue.itemList.length - 1;
-+      dir = -1;
-+    } else {
-+      // down
-+      defaultIndex = player.currentItem ? player.currentItem.index + 1 : 0;
-+      dir = 1;
-+    }
-+    if (defaultIndex >= player.queue.itemList.length) {
-+      defaultIndex = player.queue.itemList.length - 1;
-+    } else if (defaultIndex < 0) {
-+      defaultIndex = 0;
-+    }
-+    if (event.altKey) {
-+      if (selection.isQueue()) {
-+        player.shiftIds(selection.ids.queue, dir);
-+      }
-+    } else {
-+      if (selection.isQueue()) {
-+        nextPos = player.queue.itemTable[selection.cursor].index + dir;
-+        if (nextPos < 0 || nextPos >= player.queue.itemList.length) {
-+          return;
-+        }
-+        selection.cursor = player.queue.itemList[nextPos].id;
-+        if (!event.ctrlKey && !event.shiftKey) {
-+          // single select
-+          selection.clear();
-+          selection.ids.queue[selection.cursor] = true;
-+          selection.rangeSelectAnchor = selection.cursor;
-+          selection.rangeSelectAnchorType = selection.type;
-+        } else if (!event.ctrlKey && event.shiftKey) {
-+          // range select
-+          selectPlaylistRange();
-+        } else {
-+          // ghost selection
-+          selection.rangeSelectAnchor = selection.cursor;
-+          selection.rangeSelectAnchorType = selection.type;
-+        }
-+      } else if (selection.isLibrary()) {
-+        nextPos = selection.getPos();
-+        if (dir > 0) {
-+          selection.incrementPos(nextPos);
-+        } else {
-+          prevLibPos(nextPos);
-+        }
-+        if (nextPos.artist == null) return;
-+        if (nextPos.track != null) {
-+          selection.type = 'track';
-+          selection.cursor = nextPos.track.key;
-+        } else if (nextPos.album != null) {
-+          selection.type = 'album';
-+          selection.cursor = nextPos.album.key;
-+        } else {
-+          selection.type = 'artist';
-+          selection.cursor = nextPos.artist.key;
-+        }
-+        if (!event.ctrlKey && !event.shiftKey) {
-+          // single select
-+          selection.selectOnly(selection.type, selection.cursor);
-+        } else if (!event.ctrlKey && event.shiftKey) {
-+          // range select
-+          selectTreeRange();
-+        } else {
-+          // ghost selection
-+          selection.rangeSelectAnchor = selection.cursor;
-+          selection.rangeSelectAnchorType = selection.type;
-+        }
-+      } else {
-+        if (player.queue.itemList.length === 0) return;
-+        selection.selectOnly('queue', player.queue.itemList[defaultIndex].id);
-+      }
-+      refreshSelection();
-+    }
-+    if (selection.isQueue()) scrollPlaylistToSelection();
-+    if (selection.isLibrary()) scrollLibraryToSelection();
-+  }
-+  function leftRightHandler(event){
-+    var dir = event.which === 37 ? -1 : 1;
-+    if (selection.isLibrary()) {
-+      var helpers = getSelectionHelpers();
-+      if (!helpers) return;
-+      var helper = helpers[selection.type];
-+      var selected_item = helper.table[selection.cursor];
-+      var is_expanded_funcs = {
-+        artist: isArtistExpanded,
-+        album: isAlbumExpanded,
-+        track: function(){
-+          return true;
-+        }
-+      };
-+      var is_expanded = is_expanded_funcs[selection.type](selected_item);
-+      var $li = helper.$getDiv(selection.cursor).closest("li");
-+      if (dir > 0) {
-+        if (!is_expanded) {
-+          toggleLibraryExpansion($li);
-+        }
-+      } else {
-+        if (is_expanded) {
-+          toggleLibraryExpansion($li);
-+        }
-+      }
-+    } else {
-+      if (event.ctrlKey) {
-+        if (dir > 0) {
-+          player.next();
-+        } else {
-+          player.prev();
-+        }
-+      } else if (event.shiftKey) {
-+        if (!player.currentItem) return;
-+        player.seek(null, getCurrentTrackPosition() + dir * player.currentItem.track.duration * 0.10);
-+      } else {
-+        player.seek(null, getCurrentTrackPosition() + dir * 10);
-+      }
-+    }
-+  }
-+  var volumeDownHandler = {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(){
-+        player.setVolume(player.volume - 0.10);
-+      }
-+  };
-+  var volumeUpHandler = {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(){
-+        player.setVolume(player.volume + 0.10);
-+      }
-+  };
-+  return {
-+    // Enter
-+    13: {
-+      ctrl: false,
-+      alt: null,
-+      shift: null,
-+      handler: function(event){
-+        if (selection.isQueue()) {
-+          player.seek(selection.cursor, 0);
-+          player.play();
-+        } else if (selection.isLibrary()) {
-+          queueSelection(event);
-+        }
-+        return false;
-+      },
-+    },
-+    // Escape
-+    27: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: function(){
-+        if (started_drag) {
-+          abortDrag();
-+          return;
-+        }
-+        if (removeContextMenu()) return;
-+        selection.fullClear();
-+        refreshSelection();
-+      },
-+    },
-+    // Space
-+    32: {
-+      ctrl: null,
-+      alt: false,
-+      shift: false,
-+      handler: function() {
-+        if (event.ctrlKey) {
-+          toggleSelectionUnderCursor();
-+          refreshSelection();
-+        } else {
-+          togglePlayback();
-+        }
-+      },
-+    },
-+    // Left
-+    37: {
-+      ctrl: null,
-+      alt: false,
-+      shift: null,
-+      handler: leftRightHandler,
-+    },
-+    // Up
-+    38: {
-+      ctrl: null,
-+      alt: null,
-+      shift: null,
-+      handler: upDownHandler,
-+    },
-+    // Right
-+    39: {
-+      ctrl: null,
-+      alt: false,
-+      shift: null,
-+      handler: leftRightHandler,
-+    },
-+    // Down
-+    40: {
-+      ctrl: null,
-+      alt: null,
-+      shift: null,
-+      handler: upDownHandler,
-+    },
-+    // Delete
-+    46: {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(event){
-+        handleDeletePressed(event.shiftKey);
-+      },
-+    },
-+    // =
-+    61: volumeUpHandler,
-+    // C
-+    67: {
-+      ctrl: false,
-+      alt: false,
-+      shift: true,
-+      handler: function(){
-+        player.clear();
-+      },
-+    },
-+    // d
-+    68: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: toggleDynamicMode,
-+    },
-+    // S
-+    72: {
-+      ctrl: false,
-+      alt: false,
-+      shift: true,
-+      handler: function(){
-+        player.shuffle();
-+      },
-+    },
-+    // l
-+    76: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: function(){
-+        clickTab(tabs.library);
-+      },
-+    },
-+    // r
-+    82: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: nextRepeatState
-+    },
-+    // s
-+    83: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: streaming.toggleStatus
-+    },
-+    // i
-+    73: {
-+      ctrl: false,
-+      alt: false,
-+      shift: false,
-+      handler: function(){
-+        clickTab(tabs.upload);
-+        $uploadByUrl.focus().select();
-+      },
-+    },
-+    // - maybe?
-+    173: volumeDownHandler,
-+    // +
-+    187: volumeUpHandler,
-+    // , <
-+    188: {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(){
-+        player.prev();
-+      },
-+    },
-+    // _ maybe?
-+    189: volumeDownHandler,
-+    // . >
-+    190: {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(){
-+        player.next();
-+      },
-+    },
-+    // ?
-+    191: {
-+      ctrl: false,
-+      alt: false,
-+      shift: null,
-+      handler: function(event){
-+        if (event.shiftKey) {
-+          $shortcuts.dialog({
-+            modal: true,
-+            title: "Keyboard Shortcuts",
-+            minWidth: 600,
-+            height: $document.height() - 40,
-+          });
-+          $shortcuts.focus();
-+        } else {
-+          clickTab(tabs.library);
-+          $libFilter.focus().select();
-+        }
-+      },
-+    },
-+  };
-+})();
-+
-+function removeContextMenu() {
-+  if ($queueMenu.is(":visible")) {
-+    $queueMenu.hide();
-+    return true;
-+  }
-+  if ($libraryMenu.is(":visible")) {
-+    $libraryMenu.hide();
-+    return true;
-+  }
-+  return false;
-+}
-+
-+function isArtistExpanded(artist){
-+  var artistHtmlId = artistId(artist.key);
-+  var artistElem = document.getElementById(artistHtmlId);
-+  var $li = $(artistElem).closest('li');
-+  if (!$li.data('cached')) return false;
-+  return $li.find("> ul").is(":visible");
-+}
-+
-+function expandArtist(artist) {
-+  if (isArtistExpanded(artist)) return;
-+
-+  var artistElem = document.getElementById(artistId(artist.key));
-+  var $li = $(artistElem).closest('li');
-+  toggleLibraryExpansion($li);
-+}
-+
-+function isAlbumExpanded(album){
-+  var albumElem = document.getElementById(toAlbumId(album.key));
-+  var $li = $(albumElem).closest('li');
-+  return $li.find("> ul").is(":visible");
-+}
-+
-+function expandAlbum(album) {
-+  if (isAlbumExpanded(album)) return;
-+
-+  expandArtist(album.artist);
-+  var elem = document.getElementById(toAlbumId(album.key));
-+  var $li = $(elem).closest('li');
-+  toggleLibraryExpansion($li);
-+}
-+
-+function expandLibraryToSelection() {
-+  if (!selection.isLibrary()) return;
-+  for (var trackKey in selection.ids.track) {
-+    var track = player.library.trackTable[trackKey];
-+    expandAlbum(track.album);
-+  }
-+  for (var albumKey in selection.ids.album) {
-+    var album = player.library.albumTable[albumKey];
-+    expandArtist(album.artist);
-+  }
-+  scrollLibraryToSelection();
-+}
-+
-+function isStoredPlaylistExpanded(stored_playlist){
-+  var $li = $("#stored-pl-pl-" + toHtmlId(stored_playlist.name)).closest("li");
-+  return $li.find("> ul").is(":visible");
-+}
-+
-+function prevLibPos(libPos){
-+  if (libPos.track != null) {
-+    libPos.track = libPos.track.album.trackList[libPos.track.index - 1];
-+  } else if (libPos.album != null) {
-+    libPos.album = libPos.artist.albumList[libPos.album.index - 1];
-+    if (libPos.album != null && isAlbumExpanded(libPos.album)) {
-+      libPos.track = libPos.album.trackList[libPos.album.trackList.length - 1];
-+    }
-+  } else if (libPos.artist != null) {
-+    libPos.artist = player.searchResults.artistList[libPos.artist.index - 1];
-+    if (libPos.artist != null && isArtistExpanded(libPos.artist)) {
-+      libPos.album = libPos.artist.albumList[libPos.artist.albumList.length - 1];
-+      if (libPos.album != null && isAlbumExpanded(libPos.album)) {
-+        libPos.track = libPos.album.trackList[libPos.album.trackList.length - 1];
-+      }
-+    }
-+  }
-+}
-+function queueSelection(event){
-+  var keys = selection.toTrackKeys(event.altKey);
-+  if (event.shiftKey) {
-+    player.queueTracksNext(keys);
-+  } else {
-+    player.queueTracks(keys);
-+  }
-+  return false;
-+}
-+
-+function toggleSelectionUnderCursor() {
-+  var key = selection.cursor;
-+  var type = selection.type;
-+  if (selection.ids[type][key] != null) {
-+    delete selection.ids[type][key];
-+  } else {
-+    selection.ids[type][key] = true;
-+  }
-+}
-+
-+function selectPlaylistRange() {
-+  selection.clear();
-+  var anchor = selection.rangeSelectAnchor;
-+  if (anchor == null) anchor = selection.cursor;
-+  var min_pos = player.queue.itemTable[anchor].index;
-+  var max_pos = player.queue.itemTable[selection.cursor].index;
-+  if (max_pos < min_pos) {
-+    var tmp = min_pos;
-+    min_pos = max_pos;
-+    max_pos = tmp;
-+  }
-+  for (var i = min_pos; i <= max_pos; i++) {
-+    selection.ids.queue[player.queue.itemList[i].id] = true;
-+  }
-+}
-+function selectTreeRange() {
-+  selection.clear();
-+  var old_pos = selection.getPos(selection.rangeSelectAnchorType, selection.rangeSelectAnchor);
-+  var new_pos = selection.getPos(selection.type, selection.cursor);
-+  if (compareArrays(selection.posToArr(old_pos), selection.posToArr(new_pos)) > 0) {
-+    var tmp = old_pos;
-+    old_pos = new_pos;
-+    new_pos = tmp;
-+  }
-+  while (selection.posInBounds(old_pos)) {
-+    selection.selectPos(old_pos);
-+    if (selection.posEqual(old_pos, new_pos)) {
-+      break;
-+    }
-+    selection.incrementPos(old_pos);
-+  }
-+}
-+
-+function sendAuth() {
-+  var pass = localState.authPassword;
-+  if (!pass) return;
-+  socket.send('password', pass);
-+}
-+
-+function settingsAuthSave(){
-+  settings_ui.auth.show_edit = false;
-+  localState.authPassword = $authPassword.val();
-+  saveLocalState();
-+  updateSettingsAuthUi();
-+  sendAuth();
-+}
-+
-+function settingsAuthCancel(){
-+  settings_ui.auth.show_edit = false;
-+  updateSettingsAuthUi();
-+}
-+
-+function performDrag(event, callbacks){
-+  abortDrag();
-+  var start_drag_x = event.pageX;
-+  var start_drag_y = event.pageY;
-+  abortDrag = function(){
-+    $document.off('mousemove', onDragMove).off('mouseup', onDragEnd);
-+    if (started_drag) {
-+      $queueItems.find(".pl-item").removeClass('border-top').removeClass('border-bottom');
-+      started_drag = false;
-+    }
-+    abortDrag = function(){};
-+  };
-+  function onDragMove(event){
-+    var dist, result;
-+    if (!started_drag) {
-+      dist = Math.pow(event.pageX - start_drag_x, 2) + Math.pow(event.pageY - start_drag_y, 2);
-+      if (dist > 64) {
-+        started_drag = true;
-+      }
-+      if (!started_drag) {
-+        return;
-+      }
-+    }
-+    result = getDragPosition(event.pageX, event.pageY);
-+    $queueItems.find(".pl-item").removeClass('border-top').removeClass('border-bottom');
-+    if (result.$next != null) {
-+      result.$next.addClass("border-top");
-+    } else if (result.$previous != null) {
-+      result.$previous.addClass("border-bottom");
-+    }
-+  }
-+  function onDragEnd(event){
-+    if (event.which !== 1) {
-+      return false;
-+    }
-+    if (started_drag) {
-+      callbacks.complete(getDragPosition(event.pageX, event.pageY), event);
-+    } else {
-+      callbacks.cancel();
-+    }
-+    abortDrag();
-+  }
-+  $document.on('mousemove', onDragMove).on('mouseup', onDragEnd);
-+  onDragMove(event);
-+}
-+
-+function setUpGenericUi(){
-+  $document.on('mouseover', '.hoverable', function(event){
-+    $(this).addClass("ui-state-hover");
-+  });
-+  $document.on('mouseout', '.hoverable', function(event){
-+    $(this).removeClass("ui-state-hover");
-+  });
-+  $(".jquery-button").button().on('click', blur);
-+  $document.on('mousedown', function(){
-+    removeContextMenu();
-+    selection.fullClear();
-+    refreshSelection();
-+  });
-+  $document.on('keydown', function(event){
-+    var handler = keyboardHandlers[event.which];
-+    if (handler == null) return true;
-+    if (handler.ctrl  != null && handler.ctrl  !== event.ctrlKey)  return true;
-+    if (handler.alt   != null && handler.alt   !== event.altKey)   return true;
-+    if (handler.shift != null && handler.shift !== event.shiftKey) return true;
-+    handler.handler(event);
-+    return false;
-+  });
-+  $shortcuts.on('keydown', function(event) {
-+    event.stopPropagation();
-+    if (event.which === 27) {
-+      $shortcuts.dialog('close');
-+    }
-+  });
-+}
-+
-+function blur() {
-+  $(this).blur();
-+}
-+
-+var dynamicModeLabel = document.getElementById('dynamic-mode-label');
-+var plBtnRepeatLabel = document.getElementById('queue-btn-repeat-label');
-+function setUpPlayQueueUi() {
-+  $queueWindow.on('click', 'button.clear', function(event){
-+    player.clear();
-+  });
-+  $queueWindow.on('mousedown', 'button.clear', stopPropagation);
-+
-+  $queueWindow.on('click', 'button.shuffle', function(){
-+    player.shuffle();
-+  });
-+  $queueWindow.on('mousedown', 'button.shuffle', stopPropagation);
-+
-+  $queueBtnRepeat.on('click', nextRepeatState);
-+  plBtnRepeatLabel.addEventListener('mousedown', stopPropagation, false);
-+
-+  $dynamicMode.on('click', function(){
-+    var value = $(this).prop("checked");
-+    setDynamicMode(value);
-+    return false;
-+  });
-+  dynamicModeLabel.addEventListener('mousedown', stopPropagation, false);
-+
-+  $queueItems.on('dblclick', '.pl-item', function(event){
-+    var trackId = $(this).attr('data-id');
-+    player.seek(trackId, 0);
-+    player.play();
-+  });
-+  $queueItems.on('contextmenu', function(event){
-+    return event.altKey;
-+  });
-+  $queueItems.on('mousedown', '.pl-item', function(event){
-+    var trackId, skipDrag;
-+    if (started_drag) return true;
-+    $(document.activeElement).blur();
-+    if (event.which === 1) {
-+      event.preventDefault();
-+      removeContextMenu();
-+      trackId = $(this).attr('data-id');
-+      skipDrag = false;
-+      if (!selection.isQueue()) {
-+        selection.selectOnly('queue', trackId);
-+      } else if (event.ctrlKey || event.shiftKey) {
-+        skipDrag = true;
-+        if (event.shiftKey && !event.ctrlKey) {
-+          // range select click
-+          selection.cursor = trackId;
-+          selectPlaylistRange();
-+        } else if (!event.shiftKey && event.ctrlKey) {
-+          // individual item selection toggle
-+          selection.cursor = trackId;
-+          selection.rangeSelectAnchor = trackId;
-+          selection.rangeSelectAnchorType = selection.type;
-+          toggleSelectionUnderCursor();
-+        }
-+      } else if (selection.ids.queue[trackId] == null) {
-+        selection.selectOnly('queue', trackId);
-+      }
-+      refreshSelection();
-+      if (!skipDrag) {
-+        return performDrag(event, {
-+          complete: function(result, event){
-+            var delta, id;
-+            delta = {
-+              top: 0,
-+              bottom: 1
-+            };
-+            player.moveIds((function(){
-+              var results$ = [];
-+              for (var id in selection.ids.queue) {
-+                results$.push(id);
-+              }
-+              return results$;
-+            })(), result.previous_key, result.next_key);
-+          },
-+          cancel: function(){
-+            selection.selectOnly('queue', trackId);
-+            refreshSelection();
-+          }
-+        });
-+      }
-+    } else if (event.which === 3) {
-+      if (event.altKey) return;
-+      event.preventDefault();
-+      removeContextMenu();
-+      trackId = $(this).attr('data-id');
-+      if (!selection.isQueue() || selection.ids.queue[trackId] == null) {
-+        selection.selectOnly('queue', trackId);
-+        refreshSelection();
-+      }
-+      if (!selection.isMulti()) {
-+        var item = player.queue.itemTable[trackId];
-+        downloadMenuZipName = null;
-+        $queueMenu.find('.download').attr('href', encodeDownloadHref(item.track.file));
-+      } else {
-+        downloadMenuZipName = "songs";
-+        $queueMenu.find('.download').attr('href', '#');
-+      }
-+      $queueMenu.show().offset({
-+        left: event.pageX + 1,
-+        top: event.pageY + 1
-+      });
-+      updateMenuDisableState($queueMenu);
-+    }
-+  });
-+  $queueItems.on('mousedown', function(){
-+    return false;
-+  });
-+  $queueMenu.menu();
-+  $queueMenu.on('mousedown', function(){
-+    return false;
-+  });
-+  $queueMenu.on('click', '.remove', function(){
-+    handleDeletePressed(false);
-+    removeContextMenu();
-+    return false;
-+  });
-+  $queueMenu.on('click', '.download', onDownloadContextMenu);
-+  $queueMenu.on('click', '.delete', onDeleteContextMenu);
-+  $queueMenu.on('click', '.edit-tags', onEditTagsContextMenu);
-+}
-+
-+function niceDateString() {
-+  var now = new Date();
-+  var year = 1900 + now.getYear();
-+  var month = zfill(now.getMonth() + 1, 2);
-+  var day = zfill(now.getDate(), 2);
-+  return year + '-' + month + '-' + day;
-+}
-+
-+function setUpPlaylistsUi() {
-+  $newPlaylistBtn.on('click', function(event) {
-+    player.createPlaylist("New Playlist " + niceDateString());
-+  });
-+  genericTreeUi($playlistsList, {
-+    toggleExpansion: togglePlaylistExpansion,
-+    isSelectionOwner: function() {
-+      return selection.isStoredPlaylist();
-+    },
-+  });
-+}
-+
-+function stopPropagation(event) {
-+  event.stopPropagation();
-+}
-+
-+function onDownloadContextMenu() {
-+  removeContextMenu();
-+
-+  if (downloadMenuZipName) {
-+    downloadKeys(selection.toTrackKeys(), downloadMenuZipName);
-+    return false;
-+  }
-+
-+  return true;
-+}
-+function onDeleteContextMenu() {
-+  if (!permissions.admin) return false;
-+  removeContextMenu();
-+  handleDeletePressed(true);
-+  return false;
-+}
-+var editTagsTrackKeys = null;
-+var editTagsTrackIndex = null;
-+function onEditTagsContextMenu() {
-+  if (!permissions.admin) return false;
-+  removeContextMenu();
-+  editTagsTrackKeys = selection.toTrackKeys();
-+  editTagsTrackIndex = 0;
-+  showEditTags();
-+  return false;
-+}
-+var EDITABLE_PROPS = {
-+  name: {
-+    type: 'string',
-+    write: true,
-+  },
-+  artistName: {
-+    type: 'string',
-+    write: true,
-+  },
-+  albumArtistName: {
-+    type: 'string',
-+    write: true,
-+  },
-+  albumName: {
-+    type: 'string',
-+    write: true,
-+  },
-+  compilation: {
-+    type: 'boolean',
-+    write: true,
-+  },
-+  track: {
-+    type: 'integer',
-+    write: true,
-+  },
-+  trackCount: {
-+    type: 'integer',
-+    write: true,
-+  },
-+  disc: {
-+    type: 'integer',
-+    write: true,
-+  },
-+  discCount: {
-+    type: 'integer',
-+    write: true,
-+  },
-+  year: {
-+    type: 'integer',
-+    write: true,
-+  },
-+  genre: {
-+    type: 'string',
-+    write: true,
-+  },
-+  composerName: {
-+    type: 'string',
-+    write: true,
-+  },
-+  performerName: {
-+    type: 'string',
-+    write: true,
-+  },
-+  file: {
-+    type: 'string',
-+    write: false,
-+  },
-+};
-+var EDIT_TAG_TYPES = {
-+  'string': {
-+    get: function(domItem) {
-+      return domItem.value;
-+    },
-+    set: function(domItem, value) {
-+      domItem.value = value || "";
-+    },
-+  },
-+  'integer': {
-+    get: function(domItem) {
-+      var n = parseInt(domItem.value, 10);
-+      if (isNaN(n)) return null;
-+      return n;
-+    },
-+    set: function(domItem, value) {
-+      domItem.value = value == null ? "" : value;
-+    },
-+  },
-+  'boolean': {
-+    get: function(domItem) {
-+      return domItem.checked;
-+    },
-+    set: function(domItem, value) {
-+      domItem.checked = !!value;
-+    },
-+  },
-+};
-+var perDom = document.getElementById('edit-tags-per');
-+var perLabelDom = document.getElementById('edit-tags-per-label');
-+var prevDom = document.getElementById('edit-tags-prev');
-+var nextDom = document.getElementById('edit-tags-next');
-+var editTagsFocusDom = document.getElementById('edit-tag-name');
-+function updateEditTagsUi() {
-+  var multiple = editTagsTrackKeys.length > 1;
-+  prevDom.disabled = !perDom.checked || editTagsTrackIndex === 0;
-+  nextDom.disabled = !perDom.checked || (editTagsTrackIndex === editTagsTrackKeys.length - 1);
-+  prevDom.style.visibility = multiple ? 'visible' : 'hidden';
-+  nextDom.style.visibility = multiple ? 'visible' : 'hidden';
-+  perLabelDom.style.visibility = multiple ? 'visible' : 'hidden';
-+  var multiCheckBoxVisible = multiple && !perDom.checked;
-+  var trackKeysToUse = perDom.checked ? [editTagsTrackKeys[editTagsTrackIndex]] : editTagsTrackKeys;
-+
-+  for (var propName in EDITABLE_PROPS) {
-+    var propInfo = EDITABLE_PROPS[propName];
-+    var type = propInfo.type;
-+    var setter = EDIT_TAG_TYPES[type].set;
-+    var domItem = document.getElementById('edit-tag-' + propName);
-+    domItem.disabled = !propInfo.write;
-+    var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
-+    multiCheckBoxDom.style.visibility = (multiCheckBoxVisible && propInfo.write) ? 'visible' : 'hidden';
-+    var commonValue = null;
-+    var consistent = true;
-+    for (var i = 0; i < trackKeysToUse.length; i += 1) {
-+      var key = trackKeysToUse[i];
-+      var track = player.library.trackTable[key];
-+      var value = track[propName];
-+      if (commonValue == null) {
-+        commonValue = value;
-+      } else if (commonValue !== value) {
-+        consistent = false;
-+        break;
-+      }
-+    }
-+    multiCheckBoxDom.checked = consistent;
-+    setter(domItem, consistent ? commonValue : null);
-+  }
-+}
-+function showEditTags() {
-+  $editTagsDialog.dialog({
-+    modal: true,
-+    title: "Edit Tags",
-+    minWidth: 800,
-+    height: $document.height() - 40,
-+  });
-+  perDom.checked = false;
-+  updateEditTagsUi();
-+  editTagsFocusDom.focus();
-+}
-+
-+function setUpEditTagsUi() {
-+  $editTagsDialog.find("input").on("keydown", function(event) {
-+    event.stopPropagation();
-+    if (event.which === 27) {
-+      $editTagsDialog.dialog('close');
-+    } else if (event.which === 13) {
-+      saveAndClose();
-+    }
-+  });
-+  for (var propName in EDITABLE_PROPS) {
-+    var domItem = document.getElementById('edit-tag-' + propName);
-+    var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
-+    var listener = createChangeListener(multiCheckBoxDom);
-+    domItem.addEventListener('change', listener, false);
-+    domItem.addEventListener('keypress', listener, false);
-+    domItem.addEventListener('focus', onFocus, false);
-+  }
-+
-+  function onFocus(event) {
-+    editTagsFocusDom = event.target;
-+  }
-+
-+  function createChangeListener(multiCheckBoxDom) {
-+    return function() {
-+      multiCheckBoxDom.checked = true;
-+    };
-+  }
-+  $("#edit-tags-ok").on('click', saveAndClose);
-+  $("#edit-tags-cancel").on('click', closeDialog);
-+  perDom.addEventListener('click', updateEditTagsUi, false);
-+  nextDom.addEventListener('click', saveAndNext, false);
-+  prevDom.addEventListener('click', saveAndPrev, false);
-+
-+  function saveAndMoveOn(dir) {
-+    save();
-+    editTagsTrackIndex += dir;
-+    updateEditTagsUi();
-+    editTagsFocusDom.focus();
-+    editTagsFocusDom.select();
-+  }
-+
-+  function saveAndNext() {
-+    saveAndMoveOn(1);
-+  }
-+
-+  function saveAndPrev() {
-+    saveAndMoveOn(-1);
-+  }
-+
-+  function save() {
-+    var trackKeysToUse = perDom.checked ? [editTagsTrackKeys[editTagsTrackIndex]] : editTagsTrackKeys;
-+    var cmd = {};
-+    for (var i = 0; i < trackKeysToUse.length; i += 1) {
-+      var key = trackKeysToUse[i];
-+      var track = player.library.trackTable[key];
-+      var props = cmd[track.key] = {};
-+      for (var propName in EDITABLE_PROPS) {
-+        var propInfo = EDITABLE_PROPS[propName];
-+        var type = propInfo.type;
-+        var getter = EDIT_TAG_TYPES[type].get;
-+        var domItem = document.getElementById('edit-tag-' + propName);
-+        var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
-+        if (multiCheckBoxDom.checked && propInfo.write) {
-+          props[propName] = getter(domItem);
-+        }
-+      }
-+    }
-+    player.sendCommand('updateTags', cmd);
-+  }
-+
-+  function saveAndClose() {
-+    save();
-+    closeDialog();
-+  }
-+
-+  function closeDialog() {
-+    $editTagsDialog.dialog('close');
-+  }
-+}
-+
-+function updateSliderUi(value){
-+  var percent = value * 100;
-+  $trackSlider.css('background-size', percent + "% 100%");
-+}
-+
-+function setUpNowPlayingUi(){
-+  var actions = {
-+    toggle: togglePlayback,
-+    prev: function(){
-+      player.prev();
-+    },
-+    next: function(){
-+      player.next();
-+    },
-+    stop: function(){
-+      player.stop();
-+    }
-+  };
-+  for (var cls in actions) {
-+    var action = actions[cls];
-+    setUpMouseDownListener(cls, action);
-+  }
-+  $trackSlider.slider({
-+    step: 0.0001,
-+    min: 0,
-+    max: 1,
-+    change: function(event, ui){
-+      updateSliderUi(ui.value);
-+      if (event.originalEvent == null) {
-+        return;
-+      }
-+      if (!player.currentItem) return;
-+      player.seek(null, ui.value * player.currentItem.track.duration);
-+    },
-+    slide: function(event, ui){
-+      updateSliderUi(ui.value);
-+      if (!player.currentItem) return;
-+      $nowplaying_elapsed.html(formatTime(ui.value * player.currentItem.track.duration));
-+    },
-+    start: function(event, ui){
-+      userIsSeeking = true;
-+    },
-+    stop: function(event, ui){
-+      userIsSeeking = false;
-+    }
-+  });
-+  function setVol(event, ui){
-+    if (event.originalEvent == null) return;
-+    player.setVolume(ui.value);
-+  }
-+  $volSlider.slider({
-+    step: 0.01,
-+    min: 0,
-+    max: 1,
-+    change: setVol,
-+    start: function(event, ui){
-+      userIsVolumeSliding = true;
-+    },
-+    stop: function(event, ui){
-+      userIsVolumeSliding = false;
-+    }
-+  });
-+  setInterval(updateSliderPos, 100);
-+  function setUpMouseDownListener(cls, action){
-+    $nowplaying.on('mousedown', "li." + cls, function(event){
-+      action();
-+      return false;
-+    });
-+  }
-+}
-+
-+function clickTab(tab) {
-+  unselectTabs();
-+  tab.$tab.addClass('ui-state-active');
-+  tab.$pane.show();
-+  handleResize();
-+}
-+
-+function setUpTabListener(tab) {
-+  tab.$tab.on('click', function(event) {
-+    clickTab(tab);
-+  });
-+}
-+
-+function setUpTabsUi() {
-+  for (var name in tabs) {
-+    var tab = tabs[name];
-+    setUpTabListener(tab);
-+  }
-+}
-+
-+function unselectTabs() {
-+  for (var name in tabs) {
-+    var tab = tabs[name];
-+    tab.$tab.removeClass('ui-state-active');
-+    tab.$pane.hide();
-+  }
-+}
-+
-+function uploadFiles(files) {
-+  if (files.length === 0) return;
-+
-+  var formData = new FormData();
-+
-+  for (var i = 0; i < files.length; i += 1) {
-+    var file = files[i];
-+    formData.append("file", file);
-+  }
-+
-+  var $progressBar = $('<div></div>');
-+  $progressBar.progressbar();
-+  var $cancelBtn = $('<button>Cancel</button>');
-+  $cancelBtn.on('click', onCancel);
-+
-+  $uploadWidget.append($progressBar);
-+  $uploadWidget.append($cancelBtn);
-+
-+  var req = new XMLHttpRequest();
-+  req.upload.addEventListener('progress', onProgress, false);
-+  req.addEventListener('load', onLoad, false);
-+  req.open('POST', '/upload');
-+  req.send(formData);
-+  uploadInput.value = null;
-+
-+  function onProgress(e) {
-+    if (!e.lengthComputable) return;
-+    var progress = e.loaded / e.total;
-+    $progressBar.progressbar("option", "value", progress * 100);
-+  }
-+
-+  function onLoad(e) {
-+    if (localState.autoQueueUploads) {
-+      var keys = JSON.parse(this.response);
-+      // sort them the same way the library is sorted
-+      player.queueTracks(player.sortKeys(keys));
-+    }
-+    cleanup();
-+  }
-+
-+  function onCancel() {
-+    req.abort();
-+    cleanup();
-+  }
-+
-+  function cleanup() {
-+    $progressBar.remove();
-+    $cancelBtn.remove();
-+  }
-+}
-+
-+function setAutoUploadBtnState() {
-+  $autoQueueUploads
-+    .button('option', 'label', localState.autoQueueUploads ? 'On' : 'Off')
-+    .prop('checked', localState.autoQueueUploads)
-+    .button('refresh');
-+}
-+
-+function setUpUploadUi(){
-+  $autoQueueUploads.button({ label: "..." });
-+  setAutoUploadBtnState();
-+  $autoQueueUploads.on('click', function(event) {
-+    var value = $(this).prop('checked');
-+    localState.autoQueueUploads = value;
-+    saveLocalState();
-+    setAutoUploadBtnState();
-+  });
-+  uploadInput.addEventListener('change', onChange, false);
-+
-+  function onChange(e) {
-+    uploadFiles(this.files);
-+  }
-+
-+  $uploadByUrl.on('keydown', function(event){
-+    event.stopPropagation();
-+    if (event.which === 27) {
-+      $uploadByUrl.val("").blur();
-+    } else if (event.which === 13) {
-+      importUrl();
-+    }
-+  });
-+
-+  function importUrl() {
-+    var url = $uploadByUrl.val();
-+    var id = uuid();
-+    $uploadByUrl.val("").blur();
-+    socket.on('importUrl', onImportUrl);
-+    socket.send('importUrl', {
-+      url: url,
-+      id: id,
-+    });
-+
-+    function onImportUrl(args) {
-+      if (args.id !== id) return;
-+      socket.removeListener('importUrl', onImportUrl);
-+      if (!args.key) return;
-+      if (localState.autoQueueUploads) {
-+        player.queueTracks([args.key]);
-+      }
-+    }
-+  }
-+}
-+
-+function updateLastFmApiKey(key) {
-+  lastFmApiKey = key;
-+  updateLastFmSettingsUi();
-+}
-+
-+function updateLastFmSettingsUi() {
-+  if (localState.lastfm.username) {
-+    $settingsLastFmIn.show();
-+    $settingsLastFmOut.hide();
-+  } else {
-+    $settingsLastFmIn.hide();
-+    $settingsLastFmOut.show();
-+  }
-+  settingsLastFmUserDom.setAttribute('href', "http://last.fm/user/" +
-+      encodeURIComponent(localState.lastfm.username));
-+  settingsLastFmUserDom.textContent = localState.lastfm.username;
-+  var authUrl = "http://www.last.fm/api/auth/?api_key=" +
-+        encodeURIComponent(lastFmApiKey) + "&cb=" +
-+        encodeURIComponent(location.protocol + "//" + location.host + "/");
-+  lastFmAuthUrlDom.setAttribute('href', authUrl);
-+  $toggleScrobble
-+    .button('option', 'label', localState.lastfm.scrobbling_on ? 'On' : 'Off')
-+    .prop('checked', localState.lastfm.scrobbling_on)
-+    .button('refresh');
-+}
-+
-+function updateSettingsAuthUi() {
-+  var showEdit = !!(localState.authPassword == null || settings_ui.auth.show_edit);
-+  $settingsEditPassword.toggle(showEdit);
-+  $settingsShowPassword.toggle(!showEdit);
-+  $settingsAuthCancel.toggle(!!localState.authPassword);
-+  $authPassword.val("");
-+  $authPermRead.toggle(!!permissions.read);
-+  $authPermAdd.toggle(!!permissions.add);
-+  $authPermControl.toggle(!!permissions.control);
-+  $authPermAdmin.toggle(!!permissions.admin);
-+  streamUrlDom.setAttribute('href', streaming.getUrl());
-+}
-+
-+function updateSettingsAdminUi() {
-+  $toggleHardwarePlayback
-+    .button('option', 'label', hardwarePlaybackOn ? 'On' : 'Off')
-+    .prop('checked', hardwarePlaybackOn)
-+    .button('refresh');
-+}
-+
-+function setUpSettingsUi(){
-+  $toggleScrobble.button();
-+  $toggleHardwarePlayback.button();
-+  $lastFmSignOut.button();
-+  $settingsAuthCancel.button();
-+  $settingsAuthSave.button();
-+  $settingsAuthEdit.button();
-+  $settingsAuthClear.button();
-+
-+  $lastFmSignOut.on('click', function(event) {
-+    localState.lastfm.username = null;
-+    localState.lastfm.session_key = null;
-+    localState.lastfm.scrobbling_on = false;
-+    saveLocalState();
-+    updateLastFmSettingsUi();
-+    return false;
-+  });
-+  $toggleScrobble.on('click', function(event) {
-+    var msg;
-+    var value = $(this).prop("checked");
-+    if (value) {
-+      msg = 'LastFmScrobblersAdd';
-+      localState.lastfm.scrobbling_on = true;
-+    } else {
-+      msg = 'LastFmScrobblersRemove';
-+      localState.lastfm.scrobbling_on = false;
-+    }
-+    saveLocalState();
-+    var params = {
-+      username: localState.lastfm.username,
-+      session_key: localState.lastfm.session_key
-+    };
-+    socket.send(msg, params);
-+    updateLastFmSettingsUi();
-+  });
-+  $toggleHardwarePlayback.on('click', function(event) {
-+    var value = $(this).prop('checked');
-+    socket.send('hardwarePlayback', value);
-+    updateSettingsAdminUi();
-+  });
-+  $settingsAuthEdit.on('click', function(event) {
-+    settings_ui.auth.show_edit = true;
-+    updateSettingsAuthUi();
-+    $authPassword
-+      .focus()
-+      .val("")
-+      .select();
-+  });
-+  $settingsAuthClear.on('click', function(event) {
-+    localState.authPassword = null;
-+    saveLocalState();
-+    settings_ui.auth.password = "";
-+    updateSettingsAuthUi();
-+  });
-+  $settingsAuthSave.on('click', function(event){
-+    settingsAuthSave();
-+  });
-+  $settingsAuthCancel.on('click', function(event) {
-+    settingsAuthCancel();
-+  });
-+  $authPassword.on('keydown', function(event) {
-+    event.stopPropagation();
-+    settings_ui.auth.password = $authPassword.val();
-+    if (event.which === 27) {
-+      settingsAuthCancel();
-+    } else if (event.which === 13) {
-+      settingsAuthSave();
-+    }
-+  });
-+  $authPassword.on('keyup', function(event) {
-+    settings_ui.auth.password = $authPassword.val();
-+  });
-+}
-+
-+var searchTimer = null;
-+function ensureSearchHappensSoon() {
-+  if (searchTimer != null) {
-+    clearTimeout(searchTimer);
-+  }
-+  // give the user a small timeout between key presses to finish typing.
-+  // otherwise, we might be bogged down displaying the search results for "a" or the like.
-+  searchTimer = setTimeout(function() {
-+    player.search($libFilter.val());
-+    searchTimer = null;
-+  }, 100);
-+}
-+
-+function setUpLibraryUi(){
-+  $libFilter.on('keydown', function(event){
-+    var keys, i, ref$, len$, artist, j$, ref1$, len1$, album, k$, ref2$, len2$, track;
-+    event.stopPropagation();
-+    switch (event.which) {
-+    case 27: // Escape
-+      if ($(event.target).val().length === 0) {
-+        $(event.target).blur();
-+      } else {
-+        setTimeout(function(){
-+          $libFilter.val("");
-+          // queue up a search refresh now, because if the user holds Escape,
-+          // it will blur the search box, and we won't get a keyup for Escape.
-+          ensureSearchHappensSoon();
-+        }, 0);
-+      }
-+      return false;
-+    case 13: // Enter
-+      keys = [];
-+      for (i = 0, len$ = (ref$ = player.searchResults.artistList).length; i < len$; ++i) {
-+        artist = ref$[i];
-+        for (j$ = 0, len1$ = (ref1$ = artist.albumList).length; j$ < len1$; ++j$) {
-+          album = ref1$[j$];
-+          for (k$ = 0, len2$ = (ref2$ = album.trackList).length; k$ < len2$; ++k$) {
-+            track = ref2$[k$];
-+            keys.push(track.key);
-+          }
-+        }
-+      }
-+      if (event.altKey) shuffle(keys);
-+      if (keys.length > 2000) {
-+        if (!confirm("You are about to queue " + keys.length + " songs.")) {
-+          return false;
-+        }
-+      }
-+      if (event.shiftKey) {
-+        player.queueTracksNext(keys);
-+      } else {
-+        player.queueTracks(keys);
-+      }
-+      return false;
-+    case 40:
-+      selection.selectOnly('artist', player.searchResults.artistList[0].key);
-+      refreshSelection();
-+      $libFilter.blur();
-+      return false;
-+    case 38:
-+      selection.selectOnly('artist', player.searchResults.artistList[player.searchResults.artistList.length - 1].key);
-+      refreshSelection();
-+      $libFilter.blur();
-+      return false;
-+    }
-+  });
-+  $libFilter.on('keyup', function(event){
-+    ensureSearchHappensSoon();
-+  });
-+  genericTreeUi($library, {
-+    toggleExpansion: toggleLibraryExpansion,
-+    isSelectionOwner: function(){
-+      return selection.isLibrary();
-+    }
-+  });
-+  $libraryMenu.menu();
-+  $libraryMenu.on('mousedown', function(){
-+    return false;
-+  });
-+  $libraryMenu.on('click', '.queue', function(){
-+    player.queueTracks(selection.toTrackKeys());
-+    removeContextMenu();
-+    return false;
-+  });
-+  $libraryMenu.on('click', '.queue-next', function(){
-+    player.queueTracksNext(selection.toTrackKeys());
-+    removeContextMenu();
-+    return false;
-+  });
-+  $libraryMenu.on('click', '.queue-random', function(){
-+    player.queueTracks(selection.toTrackKeys(true));
-+    removeContextMenu();
-+    return false;
-+  });
-+  $libraryMenu.on('click', '.queue-next-random', function(){
-+    player.queueTracksNext(selection.toTrackKeys(true));
-+    removeContextMenu();
-+    return false;
-+  });
-+  $libraryMenu.on('click', '.download', onDownloadContextMenu);
-+  $libraryMenu.on('click', '.delete', onDeleteContextMenu);
-+  $libraryMenu.on('click', '.edit-tags', onEditTagsContextMenu);
-+  $libraryMenu.on('click', '.delete-playlist', onDeletePlaylistContextMenu);
-+  $libraryMenu.on('click', '.remove', onRemoveFromPlaylistContextMenu);
-+}
-+
-+function maybeDeleteSelectedPlaylists() {
-+  var ids = Object.keys(selection.ids.stored_playlist);
-+  var nameList = ids.map(function(id) {
-+    return player.stored_playlist_table[id].name;
-+  });
-+  var listText = nameList.slice(0, 7).join("\n  ");
-+  if (nameList.length > 7) {
-+    listText += "\n  ...";
-+  }
-+  var playlistText = nameList.length === 1 ? "playlist" : "playlists";
-+  var message = "You are about to delete " + nameList.length + " " + playlistText +
-+    " permanently:\n\n  " + listText;
-+  if (!confirm(message)) return false;
-+  player.deletePlaylists(ids);
-+  return true;
-+}
-+
-+function onDeletePlaylistContextMenu() {
-+  maybeDeleteSelectedPlaylists();
-+  removeContextMenu();
-+  return false;
-+}
-+
-+function onRemoveFromPlaylistContextMenu() {
-+  // TODO
-+}
-+
-+function genericTreeUi($elem, options){
-+  $elem.on('mousedown', 'div.expandable > div.ui-icon', function(event){
-+    options.toggleExpansion($(this).closest('li'));
-+    return false;
-+  });
-+  $elem.on('dblclick', 'div.expandable > div.ui-icon', function(){
-+    return false;
-+  });
-+  $elem.on('dblclick', 'div.clickable', queueSelection);
-+  $elem.on('contextmenu', function(event){
-+    return event.altKey;
-+  });
-+  $elem.on('mousedown', '.clickable', function(event){
-+    $(document.activeElement).blur();
-+    var $this = $(this);
-+    var type = $this.attr('data-type');
-+    var key = $this.attr('data-key');
-+    if (event.which === 1) {
-+      leftMouseDown(event);
-+    } else if (event.which === 3) {
-+      if (event.altKey) {
-+        return;
-+      }
-+      rightMouseDown(event);
-+    }
-+    function leftMouseDown(event){
-+      event.preventDefault();
-+      removeContextMenu();
-+      var skipDrag = false;
-+      if (!options.isSelectionOwner()) {
-+        selection.selectOnly(type, key);
-+      } else if (event.ctrlKey || event.shiftKey) {
-+        skipDrag = true;
-+        selection.cursor = key;
-+        selection.type = type;
-+        if (!event.shiftKey && !event.ctrlKey) {
-+          selection.selectOnly(type, key);
-+        } else if (event.shiftKey) {
-+          selectTreeRange();
-+        } else if (event.ctrlKey) {
-+          toggleSelectionUnderCursor();
-+        }
-+      } else if (selection.ids[type][key] == null) {
-+        selection.selectOnly(type, key);
-+      }
-+      refreshSelection();
-+      if (!skipDrag) {
-+        performDrag(event, {
-+          complete: function(result, event){
-+            var delta = {
-+              top: 0,
-+              bottom: 1
-+            };
-+            var keys = selection.toTrackKeys(event.altKey);
-+            player.queueTracks(keys, result.previous_key, result.next_key);
-+          },
-+          cancel: function(){
-+            selection.selectOnly(type, key);
-+            refreshSelection();
-+          }
-+        });
-+      }
-+    }
-+    function rightMouseDown(event){
-+      event.preventDefault();
-+      removeContextMenu();
-+      if (!options.isSelectionOwner() || selection.ids[type][key] == null) {
-+        selection.selectOnly(type, key);
-+        refreshSelection();
-+      }
-+      var track = null;
-+      if (!selection.isMulti()) {
-+        if (type === 'track') {
-+          track = player.searchResults.trackTable[key];
-+        } else if (type === 'stored_playlist_item') {
-+          track = player.stored_playlist_item_table[key].track;
-+        }
-+      }
-+      var $deletePlaylistLi = $libraryMenu.find('.delete-playlist').closest('li');
-+      var $removeFromPlaylistLi = $libraryMenu.find('.remove').closest('li');
-+      if (type === 'stored_playlist') {
-+        $deletePlaylistLi.show();
-+      } else {
-+        $deletePlaylistLi.hide();
-+      }
-+      if (type === 'stored_playlist_item') {
-+        $removeFromPlaylistLi.show();
-+      } else {
-+        $removeFromPlaylistLi.hide();
-+      }
-+
-+      var $downloadItem = $libraryMenu.find('.download');
-+      if (track) {
-+        downloadMenuZipName = null;
-+        $downloadItem.attr('href', encodeDownloadHref(track.file));
-+      } else {
-+        downloadMenuZipName = zipNameForSelCursor();
-+        $downloadItem.attr('href', '#');
-+      }
-+      $libraryMenu.show().offset({
-+        left: event.pageX + 1,
-+        top: event.pageY + 1
-+      });
-+      updateMenuDisableState($libraryMenu);
-+    }
-+  });
-+  $elem.on('mousedown', function(){
-+    return false;
-+  });
-+}
-+
-+function encodeDownloadHref(file) {
-+  // be sure to escape #hashtags
-+  return 'library/' + encodeURI(file).replace(/#/g, "%23");
-+}
-+
-+function zipNameForSelCursor() {
-+  switch (selection.type) {
-+    case 'artist':
-+      return player.library.artistTable[selection.cursor].name;
-+    case 'album':
-+      return player.library.albumTable[selection.cursor].name;
-+    case 'track':
-+      return "songs";
-+    case 'stored_playlist':
-+      return player.stored_playlist_table[selection.cursor].name;
-+    case 'stored_playlist_item':
-+      return "songs";
-+    default:
-+      throw new Error("bad selection cursor type: " + selection.type);
-+  }
-+}
-+
-+function updateMenuDisableState($menu) {
-+  var menuPermDoms = {
-+    admin: $menu.find('.delete,.edit-tags'),
-+    control: $menu.find('.remove,.delete-playlist'),
-+  };
-+  for (var permName in menuPermDoms) {
-+    var $item = menuPermDoms[permName];
-+    if (permissions[permName]) {
-+      $item
-+        .removeClass('ui-state-disabled')
-+        .attr('title', '');
-+    } else {
-+      $item
-+        .addClass('ui-state-disabled')
-+        .attr('title', "Insufficient privileges. See Settings.");
-+    }
-+  }
-+}
-+
-+function setUpUi(){
-+  setUpGenericUi();
-+  setUpPlayQueueUi();
-+  setUpPlaylistsUi();
-+  setUpLibraryUi();
-+  setUpNowPlayingUi();
-+  setUpTabsUi();
-+  setUpUploadUi();
-+  setUpSettingsUi();
-+  setUpEditTagsUi();
-+}
-+
-+function toAlbumId(s) {
-+  return "lib-album-" + toHtmlId(s);
-+}
-+
-+function toTrackId(s) {
-+  return "lib-track-" + toHtmlId(s);
-+}
-+
-+function toStoredPlaylistItemId(s) {
-+  return "stored-pl-item-" + toHtmlId(s);
-+}
-+
-+function toStoredPlaylistId(s) {
-+  return "stored-pl-pl-" + toHtmlId(s);
-+}
-+
-+function handleResize(){
-+  $nowplaying.width(MARGIN);
-+  $queueWindow.height(MARGIN);
-+  $leftWindow.height(MARGIN);
-+  $library.height(MARGIN);
-+  $upload.height(MARGIN);
-+  $queueItems.height(MARGIN);
-+  $nowplaying.width($document.width() - MARGIN * 2);
-+  var second_layer_top = $nowplaying.offset().top + $nowplaying.height() + MARGIN;
-+  $leftWindow.offset({
-+    left: MARGIN,
-+    top: second_layer_top
-+  });
-+  $queueWindow.offset({
-+    left: $leftWindow.offset().left + $leftWindow.width() + MARGIN,
-+    top: second_layer_top
-+  });
-+  $queueWindow.width($window.width() - $queueWindow.offset().left - MARGIN);
-+  $leftWindow.height($window.height() - $leftWindow.offset().top);
-+  $queueWindow.height($leftWindow.height() - MARGIN);
-+  var tabContentsHeight = $leftWindow.height() - $tabs.height() - MARGIN;
-+  $library.height(tabContentsHeight - $libHeader.height());
-+  $upload.height(tabContentsHeight);
-+  $queueItems.height($queueWindow.height() - $queueHeader.position().top - $queueHeader.height());
-+}
-+function refreshPage(){
-+  location.href = location.protocol + "//" + location.host + "/";
-+}
-+
-+$document.ready(function(){
-+  loadLocalState();
-+  socket = new Socket();
-+  var queryObj = querystring.parse(location.search.substring(1));
-+  if (queryObj.token) {
-+    socket.on('connect', function() {
-+      socket.send('LastFmGetSession', queryObj.token);
-+    });
-+    socket.on('LastFmGetSessionSuccess', function(params){
-+      localState.lastfm.username = params.session.name;
-+      localState.lastfm.session_key = params.session.key;
-+      localState.lastfm.scrobbling_on = false;
-+      saveLocalState();
-+      refreshPage();
-+    });
-+    socket.on('LastFmGetSessionError', function(message){
-+      alert("Error authenticating: " + message);
-+      refreshPage();
-+    });
-+    return;
-+  }
-+  socket.on('hardwarePlayback', function(isOn) {
-+    hardwarePlaybackOn = isOn;
-+    updateSettingsAdminUi();
-+  });
-+  socket.on('LastFmApiKey', updateLastFmApiKey);
-+  socket.on('permissions', function(data){
-+    permissions = data;
-+    updateSettingsAuthUi();
-+  });
-+  socket.on('token', function(token) {
-+    document.cookie = "token=" + token + "; path=/";
-+  });
-+  socket.on('volumeUpdate', function(vol) {
-+    player.volume = vol;
-+    renderVolumeSlider();
-+  });
-+  socket.on('dynamicModeOn', function(data) {
-+    dynamicModeOn = data;
-+    renderPlaylistButtons();
-+    triggerRenderQueue();
-+  });
-+  socket.on('connect', function(){
-+    sendAuth();
-+    socket.send('subscribe', {name: 'dynamicModeOn'});
-+    socket.send('subscribe', {name: 'hardwarePlayback'});
-+    load_status = LoadStatus.GoodToGo;
-+    render();
-+  });
-+  player = new PlayerClient(socket);
-+  player.on('libraryupdate', triggerRenderLibrary);
-+  player.on('queueUpdate', triggerRenderQueue);
-+  player.on('scanningUpdate', triggerRenderQueue);
-+  player.on('playlistsUpdate', triggerPlaylistsUpdate);
-+  player.on('statusupdate', function(){
-+    renderNowPlaying();
-+    renderPlaylistButtons();
-+    labelPlaylistItems();
-+  });
-+  socket.on('disconnect', function(){
-+    load_status = LoadStatus.NoServer;
-+    render();
-+  });
-+  setUpUi();
-+  streaming.init(player, socket);
-+  render();
-+  $window.resize(handleResize);
-+  window._debug_player = player;
-+});
-+
-+function compareArrays(arr1, arr2) {
-+  for (var i1 = 0; i1 < arr1.length; i1 += 1) {
-+    var val1 = arr1[i1];
-+    var val2 = arr2[i1];
-+    var diff = (val1 != null ? val1 : -1) - (val2 != null ? val2 : -1);
-+    if (diff !== 0) return diff;
-+  }
-+  return 0;
-+}
-+
-+function formatTime(seconds) {
-+  if (seconds == null) return "";
-+  var sign = "";
-+  if (seconds < 0) {
-+    sign = "-";
-+    seconds = -seconds;
-+  }
-+  seconds = Math.floor(seconds);
-+  var minutes = Math.floor(seconds / 60);
-+  seconds -= minutes * 60;
-+  var hours = Math.floor(minutes / 60);
-+  minutes -= hours * 60;
-+  if (hours !== 0) {
-+    return sign + hours + ":" + zfill(minutes, 2) + ":" + zfill(seconds, 2);
-+  } else {
-+    return sign + minutes + ":" + zfill(seconds, 2);
-+  }
-+}
-+
-+var badCharRe = new RegExp('[^a-zA-Z0-9-]', 'gm');
-+function toHtmlId(string) {
-+  return string.replace(badCharRe, function(c) {
-+    return "_" + c.charCodeAt(0) + "_";
-+  });
-+}
-+
-+},{"./playerclient":36,"./socket":37,"./streaming":38,"mess":29,"querystring":9,"uuid":33,"zfill":34}],36:[function(require,module,exports){
-+var EventEmitter = require('events').EventEmitter;
-+var util = require('util');
-+var uuid = require('uuid');
-+var MusicLibraryIndex = require('music-library-index');
-+var keese = require('keese');
-+var jsondiffpatch = require('jsondiffpatch');
-+
-+module.exports = PlayerClient;
-+
-+var compareSortKeyAndId = makeCompareProps(['sortKey', 'id']);
-+var compareNameAndId = makeCompareProps(['name', 'id']);
-+
-+PlayerClient.REPEAT_OFF = 0;
-+PlayerClient.REPEAT_ONE = 1;
-+PlayerClient.REPEAT_ALL = 2;
-+
-+util.inherits(PlayerClient, EventEmitter);
-+function PlayerClient(socket) {
-+  EventEmitter.call(this);
-+
-+  var self = this;
-+  self.socket = socket;
-+  self.serverTimeOffset = 0;
-+  self.serverTrackStartDate = null;
-+  self.queueFromServer = undefined;
-+  self.queueFromServerVersion = null;
-+  self.libraryFromServer = undefined;
-+  self.libraryFromServerVersion = null;
-+  self.scanningFromServer = undefined;
-+  self.scanningFromServerVersion = null;
-+  self.playlistsFromServer = undefined;
-+  self.playlistsFromServerVersion = null;
-+  self.resetServerState();
-+  self.socket.on('disconnect', function() {
-+    self.resetServerState();
-+  });
-+  if (self.socket.isConnected) {
-+    self.handleConnectionStart();
-+  } else {
-+    self.socket.on('connect', self.handleConnectionStart.bind(self));
-+  }
-+  self.socket.on('time', function(o) {
-+    self.serverTimeOffset = new Date(o) - new Date();
-+    self.updateTrackStartDate();
-+    self.emit('statusupdate');
-+  });
-+  self.socket.on('volume', function(volume) {
-+    self.volume = volume;
-+    self.emit('statusupdate');
-+  });
-+  self.socket.on('repeat', function(repeat) {
-+    self.repeat = repeat;
-+    self.emit('statusupdate');
-+  });
-+  self.socket.on('streamers', function(streamers) {
-+    self.streamers = streamers;
-+    self.emit('streamers');
-+  });
-+
-+  self.socket.on('currentTrack', function(o) {
-+    self.isPlaying = o.isPlaying;
-+    self.serverTrackStartDate = o.trackStartDate && new Date(o.trackStartDate);
-+    self.pausedTime = o.pausedTime;
-+    self.currentItemId = o.currentItemId;
-+    self.updateTrackStartDate();
-+    self.updateCurrentItem();
-+    self.emit('statusupdate');
-+    self.emit('currentTrack');
-+  });
-+
-+  self.socket.on('queue', function(o) {
-+    if (o.reset) self.queueFromServer = undefined;
-+    self.queueFromServer = jsondiffpatch.patch(self.queueFromServer, o.delta);
-+    deleteUndefineds(self.queueFromServer);
-+    self.queueFromServerVersion = o.version;
-+    self.updateQueueIndex();
-+    self.emit('statusupdate');
-+    self.emit('queueUpdate');
-+  });
-+
-+  self.socket.on('library', function(o) {
-+    if (o.reset) self.libraryFromServer = undefined;
-+    self.libraryFromServer = jsondiffpatch.patch(self.libraryFromServer, o.delta);
-+    deleteUndefineds(self.libraryFromServer);
-+    self.libraryFromServerVersion = o.version;
-+    self.library.clear();
-+    for (var key in self.libraryFromServer) {
-+      var track = self.libraryFromServer[key];
-+      self.library.addTrack(track);
-+    }
-+    self.library.rebuild();
-+    self.updateQueueIndex();
-+    self.haveFileListCache = true;
-+    var lastQuery = self.lastQuery;
-+    self.lastQuery = null;
-+    self.search(lastQuery);
-+  });
-+
-+  self.socket.on('scanning', function(o) {
-+    if (o.reset) self.scanningFromServer = undefined;
-+    self.scanningFromServer = jsondiffpatch.patch(self.scanningFromServer, o.delta);
-+    deleteUndefineds(self.scanningFromServer);
-+    self.scanningFromServerVersion = o.version;
-+    self.emit('scanningUpdate');
-+  });
-+
-+  self.socket.on('playlists', function(o) {
-+    if (o.reset) self.playlistsFromServer = undefined;
-+    self.playlistsFromServer = jsondiffpatch.patch(self.playlistsFromServer, o.delta);
-+    deleteUndefineds(self.playlistsFromServer);
-+    self.playlistsFromServerVersion = o.version;
-+    self.updatePlaylistsIndex();
-+    self.emit('playlistsUpdate');
-+  });
-+
-+  function deleteUndefineds(o) {
-+    for (var key in o) {
-+      if (o[key] === undefined) delete o[key];
-+    }
-+  }
-+}
-+
-+PlayerClient.prototype.handleConnectionStart = function(){
-+  this.sendCommand('subscribe', {
-+    name: 'library',
-+    delta: true,
-+    version: this.libraryFromServerVersion,
-+  });
-+  this.sendCommand('subscribe', {name: 'volume'});
-+  this.sendCommand('subscribe', {name: 'repeat'});
-+  this.sendCommand('subscribe', {name: 'currentTrack'});
-+  this.sendCommand('subscribe', {
-+    name: 'queue',
-+    delta: true,
-+    version: this.queueFromServerVersion,
-+  });
-+  this.sendCommand('subscribe', {
-+    name: 'scanning',
-+    delta: true,
-+    version: this.scanningFromServerVersion,
-+  });
-+  this.sendCommand('subscribe', {
-+    name: 'playlists',
-+    delta: true,
-+    version: this.playlistsFromServerVersion,
-+  });
-+  this.sendCommand('subscribe', {name: 'streamers'});
-+};
-+
-+PlayerClient.prototype.updateTrackStartDate = function() {
-+  this.trackStartDate = (this.serverTrackStartDate != null) ?
-+    new Date(new Date(this.serverTrackStartDate) - this.serverTimeOffset) : null;
-+};
-+
-+PlayerClient.prototype.updateCurrentItem = function() {
-+  this.currentItem = (this.currentItemId != null) ?
-+    this.queue.itemTable[this.currentItemId] : null;
-+};
-+
-+PlayerClient.prototype.clearStoredPlaylists = function() {
-+  this.stored_playlist_table = {};
-+  this.stored_playlist_item_table = {};
-+  this.stored_playlists = [];
-+};
-+
-+PlayerClient.prototype.sortAndIndexPlaylists = function() {
-+  this.stored_playlists.sort(compareNameAndId);
-+  this.stored_playlists.forEach(function(playlist, index) {
-+    playlist.index = index;
-+  });
-+};
-+
-+PlayerClient.prototype.updatePlaylistsIndex = function() {
-+  this.clearStoredPlaylists();
-+  if (!this.playlistsFromServer) return;
-+  for (var id in this.playlistsFromServer) {
-+    var playlistFromServer = this.playlistsFromServer[id];
-+    var playlist = {
-+      itemList: [],
-+      itemTable: {},
-+      id: playlistFromServer.id,
-+      name: playlistFromServer.name,
-+      index: 0, // we'll set this correctly later
-+    };
-+    for (var itemId in playlistFromServer.items) {
-+      var itemFromServer = playlistFromServer.items[itemId];
-+      var track = this.library.trackTable[itemFromServer.key];
-+      var item = {
-+        id: itemId,
-+        sortKey: itemFromServer.sortKey,
-+        isRandom: false,
-+        track: track,
-+        playlist: playlist,
-+      };
-+      playlist.itemTable[itemId] = item;
-+      this.stored_playlist_item_table[itemId] = item;
-+    }
-+    this.refreshPlaylistList(playlist);
-+    this.stored_playlists.push(playlist);
-+    this.stored_playlist_table[playlist.id] = playlist;
-+  }
-+  this.sortAndIndexPlaylists();
-+};
-+
-+PlayerClient.prototype.updateQueueIndex = function() {
-+  this.clearQueue();
-+  if (!this.queueFromServer) return;
-+  for (var id in this.queueFromServer) {
-+    var item = this.queueFromServer[id];
-+    var track = this.library.trackTable[item.key];
-+    this.queue.itemTable[id] = {
-+      id: id,
-+      sortKey: item.sortKey,
-+      isRandom: item.isRandom,
-+      track: track,
-+      playlist: this.queue,
-+    };
-+  }
-+  this.refreshPlaylistList(this.queue);
-+  this.updateCurrentItem();
-+};
-+
-+PlayerClient.prototype.isScanning = function(track) {
-+  var scanInfo = this.scanningFromServer && this.scanningFromServer[track.key];
-+  return scanInfo && (!scanInfo.fingerprintDone || !scanInfo.loudnessDone);
-+};
-+
-+PlayerClient.prototype.search = function(query) {
-+  query = query.trim();
-+
-+  var words = query.split(/\s+/);
-+  query = words.join(" ");
-+  if (query === this.lastQuery) return;
-+
-+  this.lastQuery = query;
-+  this.searchResults = this.library.search(query);
-+  this.emit('libraryupdate');
-+  this.emit('queueUpdate');
-+  this.emit('statusupdate');
-+};
-+
-+PlayerClient.prototype.getDefaultQueuePosition = function() {
-+  var previousKey = this.currentItem && this.currentItem.sortKey;
-+  var nextKey = null;
-+  var startPos = this.currentItem ? this.currentItem.index + 1 : 0;
-+  for (var i = startPos; i < this.queue.itemList.length; i += 1) {
-+    var track = this.queue.itemList[i];
-+    var sortKey = track.sortKey;
-+    if (track.isRandom) {
-+      nextKey = sortKey;
-+      break;
-+    }
-+    previousKey = sortKey;
-+  }
-+  return {
-+    previousKey: previousKey,
-+    nextKey: nextKey
-+  };
-+};
-+
-+PlayerClient.prototype.queueTracks = function(keys, previousKey, nextKey) {
-+  if (!keys.length) return;
-+
-+  if (previousKey == null && nextKey == null) {
-+    var defaultPos = this.getDefaultQueuePosition();
-+    previousKey = defaultPos.previousKey;
-+    nextKey = defaultPos.nextKey;
-+  }
-+
-+  var items = {};
-+  for (var i = 0; i < keys.length; i += 1) {
-+    var key = keys[i];
-+    var sortKey = keese(previousKey, nextKey);
-+    var id = uuid();
-+    items[id] = {
-+      key: key,
-+      sortKey: sortKey,
-+    };
-+    this.queue.itemTable[id] = {
-+      id: id,
-+      key: key,
-+      sortKey: sortKey,
-+      isRandom: false,
-+      track: this.library.trackTable[key],
-+    };
-+    previousKey = sortKey;
-+  }
-+  this.refreshPlaylistList(this.queue);
-+  this.sendCommand('addid', items);
-+  this.emit('queueUpdate');
-+};
-+
-+PlayerClient.prototype.queueTracksNext = function(keys) {
-+  var prevKey = this.currentItem && this.currentItem.sortKey;
-+  var nextKey = null;
-+  var itemList = this.queue.itemList;
-+  for (var i = 0; i < itemList.length; ++i) {
-+    var track = itemList[i];
-+    if (prevKey == null || track.sortKey > prevKey) {
-+      if (nextKey == null || track.sortKey < nextKey) {
-+        nextKey = track.sortKey;
-+      }
-+    }
-+  }
-+  this.queueTracks(keys, prevKey, nextKey);
-+};
-+
-+PlayerClient.prototype.clear = function(){
-+  this.sendCommand('clear');
-+  this.clearQueue();
-+  this.emit('queueUpdate');
-+};
-+
-+PlayerClient.prototype.shuffle = function(){
-+  this.sendCommand('shuffle');
-+};
-+
-+PlayerClient.prototype.play = function(){
-+  this.sendCommand('play');
-+  if (this.isPlaying === false) {
-+    this.trackStartDate = elapsedToDate(this.pausedTime);
-+    this.isPlaying = true;
-+    this.emit('statusupdate');
-+  }
-+};
-+
-+PlayerClient.prototype.stop = function(){
-+  this.sendCommand('stop');
-+  if (this.isPlaying === true) {
-+    this.pausedTime = 0;
-+    this.isPlaying = false;
-+    this.emit('statusupdate');
-+  }
-+};
-+
-+PlayerClient.prototype.pause = function(){
-+  this.sendCommand('pause');
-+  if (this.isPlaying === true) {
-+    this.pausedTime = dateToElapsed(this.trackStartDate);
-+    this.isPlaying = false;
-+    this.emit('statusupdate');
-+  }
-+};
-+
-+PlayerClient.prototype.next = function(){
-+  var index = this.currentItem ? this.currentItem.index + 1 : 0;
-+
-+  // handle the case of Repeat All
-+  if (index >= this.queue.itemList.length &&
-+      this.repeat === PlayerClient.REPEAT_ALL)
-+  {
-+    index = 0;
-+  }
-+
-+  var item = this.queue.itemList[index];
-+  var id = item && item.id;
-+
-+  this.seek(id, 0);
-+};
-+
-+PlayerClient.prototype.prev = function(){
-+  var index = this.currentItem ? this.currentItem.index - 1 : this.queue.itemList.length - 1;
-+
-+  // handle case of Repeat All
-+  if (index < 0 && this.repeat === PlayerClient.REPEAT_ALL) {
-+    index = this.queue.itemList.length - 1;
-+  }
-+
-+  var item = this.queue.itemList[index];
-+  var id = item && item.id;
-+
-+  this.seek(id, 0);
-+};
-+
-+PlayerClient.prototype.moveIds = function(trackIds, previousKey, nextKey){
-+  var track, i;
-+  var tracks = [];
-+  for (i = 0; i < trackIds.length; i += 1) {
-+    var id = trackIds[i];
-+    track = this.queue.itemTable[id];
-+    if (track) tracks.push(track);
-+  }
-+  tracks.sort(compareSortKeyAndId);
-+  var items = {};
-+  for (i = 0; i < tracks.length; i += 1) {
-+    track = tracks[i];
-+    var sortKey = keese(previousKey, nextKey);
-+    items[track.id] = {
-+      sortKey: sortKey,
-+    };
-+    track.sortKey = sortKey;
-+    previousKey = sortKey;
-+  }
-+  this.refreshPlaylistList(this.queue);
-+  this.sendCommand('move', items);
-+  this.emit('queueUpdate');
-+};
-+
-+PlayerClient.prototype.shiftIds = function(trackIdSet, offset) {
-+  // an example of shifting 5 items (a,c,f,g,i) "down":
-+  // offset: +1, reverse: false, this -> way
-+  // selection: *     *        *  *     *
-+  //    before: a, b, c, d, e, f, g, h, i
-+  //             \     \        \  \    |
-+  //              \     \        \  \   |
-+  //     after: b, a, d, c, e, h, f, g, i
-+  // selection:    *     *        *  *  *
-+  // (note that "i" does not move because it has no futher to go.)
-+  //
-+  // an alternate way to think about it: some items "leapfrog" backwards over the selected items.
-+  // this ends up being much simpler to compute, and even more compact to communicate.
-+  // selection: *     *        *  *     *
-+  //    before: a, b, c, d, e, f, g, h, i
-+  //              /     /        ___/
-+  //             /     /        /
-+  //     after: b, a, d, c, e, h, f, g, i
-+  // selection:    *     *        *  *  *
-+  // (note that the moved items are not the selected items)
-+  var itemList = this.queue.itemList;
-+  var movedItems = {};
-+  var reverse = offset === -1;
-+  function getKeeseBetween(itemA, itemB) {
-+    if (reverse) {
-+      var tmp = itemA;
-+      itemA = itemB;
-+      itemB = tmp;
-+    }
-+    var keyA = itemA == null ? null : itemA.sortKey;
-+    var keyB = itemB == null ? null : itemB.sortKey;
-+    return keese(keyA, keyB);
-+  }
-+  if (reverse) {
-+    // to make this easier, just reverse the item list in place so we can write one iteration routine.
-+    // note that we are editing our data model live! so don't forget to refresh it later.
-+    itemList.reverse();
-+  }
-+  for (var i = itemList.length - 1; i >= 1; i--) {
-+    var track = itemList[i];
-+    if (!(track.id in trackIdSet) && (itemList[i - 1].id in trackIdSet)) {
-+      // this one needs to move backwards (e.g. found "h" is not selected, and "g" is selected)
-+      i--; // e.g. g
-+      i--; // e.g. f
-+      while (true) {
-+        if (i < 0) {
-+          // fell off the end (or beginning) of the list
-+          track.sortKey = getKeeseBetween(null, itemList[0]);
-+          break;
-+        }
-+        if (!(itemList[i].id in trackIdSet)) {
-+          // this is where it goes (e.g. found "d" is not selected)
-+          track.sortKey = getKeeseBetween(itemList[i], itemList[i + 1]);
-+          break;
-+        }
-+        i--;
-+      }
-+      movedItems[track.id] = {sortKey: track.sortKey};
-+      i++;
-+    }
-+  }
-+  // we may have reversed the table and adjusted all the sort keys, so we need to refresh this.
-+  this.refreshPlaylistList(this.queue);
-+
-+  this.sendCommand('move', movedItems);
-+  this.emit('queueUpdate');
-+};
-+
-+PlayerClient.prototype.removeIds = function(trackIds){
-+  if (trackIds.length === 0) return;
-+  var ids = [];
-+  for (var i = 0; i < trackIds.length; i += 1) {
-+    var trackId = trackIds[i];
-+    var currentId = this.currentItem && this.currentItem.id;
-+    if (currentId === trackId) {
-+      this.currentItemId = null;
-+      this.currentItem = null;
-+    }
-+    ids.push(trackId);
-+    var item = this.queue.itemTable[trackId];
-+    delete this.queue.itemTable[item.id];
-+    this.refreshPlaylistList(this.queue);
-+  }
-+  this.sendCommand('deleteid', ids);
-+  this.emit('queueUpdate');
-+};
-+
-+PlayerClient.prototype.deleteTracks = function(keysList) {
-+  this.sendCommand('deleteTracks', keysList);
-+  [this.library, this.searchResults].forEach(function(lib) {
-+    keysList.forEach(function(key) {
-+      lib.removeTrack(key);
-+    });
-+    lib.rebuild();
-+  });
-+  this.emit('libraryupdate');
-+};
-+
-+PlayerClient.prototype.deletePlaylists = function(idsList) {
-+  this.sendCommand('playlistDelete', idsList);
-+  for (var i = 0; i < idsList.length; i += 1) {
-+    var id = idsList[i];
-+    var playlist = this.stored_playlist_table[id];
-+    for (var j = 0; j < playlist.itemList; j += 1) {
-+      var item = playlist.itemList[j];
-+      delete this.stored_playlist_item_table[item.id];
-+    }
-+    delete this.stored_playlist_table[id];
-+    this.stored_playlists.splice(playlist.index, 1);
-+    for (j = playlist.index; j < this.stored_playlists.length; j += 1) {
-+      this.stored_playlists[j].index -= 1;
-+    }
-+  }
-+  this.emit('playlistsUpdate');
-+};
-+
-+PlayerClient.prototype.seek = function(id, pos) {
-+  pos = parseFloat(pos || 0);
-+  var item = id ? this.queue.itemTable[id] : this.currentItem;
-+  if (item == null) return;
-+  if (pos < 0) pos = 0;
-+  if (pos > item.track.duration) pos = item.track.duration;
-+  this.sendCommand('seek', {
-+    id: item.id,
-+    pos: pos,
-+  });
-+  this.currentItem = item;
-+  this.currentItemId = item.id;
-+  this.duration = item.track.duration;
-+  if (this.isPlaying) {
-+    this.trackStartDate = elapsedToDate(pos);
-+  } else {
-+    this.pausedTime = pos;
-+  }
-+  this.emit('statusupdate');
-+};
-+
-+PlayerClient.prototype.setVolume = function(vol){
-+  if (vol > 1.0) vol = 1.0;
-+  if (vol < 0.0) vol = 0.0;
-+  this.volume = vol;
-+  this.sendCommand('setvol', this.volume);
-+  this.emit('statusupdate');
-+};
-+
-+PlayerClient.prototype.setRepeatMode = function(mode) {
-+  this.repeat = mode;
-+  this.sendCommand('repeat', mode);
-+  this.emit('statusupdate');
-+};
-+
-+PlayerClient.prototype.sendCommand = function(name, args) {
-+  this.socket.send(name, args);
-+};
-+
-+PlayerClient.prototype.clearQueue = function(){
-+  this.queue = {
-+    itemList: [],
-+    itemTable: {},
-+    index: null,
-+    name: null
-+  };
-+};
-+
-+PlayerClient.prototype.refreshPlaylistList = function(playlist) {
-+  playlist.itemList = [];
-+  var item;
-+  for (var id in playlist.itemTable) {
-+    item = playlist.itemTable[id];
-+    item.playlist = playlist;
-+    playlist.itemList.push(item);
-+  }
-+  playlist.itemList.sort(compareSortKeyAndId);
-+  for (var i = 0; i < playlist.itemList.length; i += 1) {
-+    item = playlist.itemList[i];
-+    item.index = i;
-+  }
-+};
-+
-+// sort keys according to how they appear in the library
-+PlayerClient.prototype.sortKeys = function(keys) {
-+  var realLib = this.library;
-+  var lib = new MusicLibraryIndex();
-+  keys.forEach(function(key) {
-+    var track = realLib.trackTable[key];
-+    if (track) lib.addTrack(track);
-+  });
-+  lib.rebuild();
-+  var results = [];
-+  lib.artistList.forEach(function(artist) {
-+    artist.albumList.forEach(function(album) {
-+      album.trackList.forEach(function(track) {
-+        results.push(track.key);
-+      });
-+    });
-+  });
-+  return results;
-+};
-+
-+PlayerClient.prototype.resetServerState = function(){
-+  this.haveFileListCache = false;
-+  this.library = new MusicLibraryIndex({
-+    searchFields: MusicLibraryIndex.defaultSearchFields.concat('file'),
-+  });
-+  this.searchResults = this.library;
-+  this.lastQuery = "";
-+  this.clearQueue();
-+  this.repeat = 0;
-+  this.currentItem = null;
-+  this.currentItemId = null;
-+  this.streamers = {
-+    anonCount: 0,
-+    clientIds: [],
-+  };
-+
-+  this.clearStoredPlaylists();
-+};
-+
-+PlayerClient.prototype.createPlaylist = function(name) {
-+  var id = uuid();
-+  this.sendCommand('playlistCreate', {
-+    id: id,
-+    name: name,
-+  });
-+  // anticipate server response
-+  var playlist = {
-+    itemList: [],
-+    itemTable: {},
-+    id: id,
-+    name: name,
-+    index: 0,
-+  };
-+  this.stored_playlist_table[id] = playlist;
-+  this.stored_playlists.push(playlist);
-+  this.sortAndIndexPlaylists();
-+  this.emit('playlistsUpdate');
-+
-+  return playlist;
-+};
-+
-+function elapsedToDate(elapsed){
-+  return new Date(new Date() - elapsed * 1000);
-+}
-+
-+function dateToElapsed(date){
-+  return (new Date() - date) / 1000;
-+}
-+
-+function noop(err){
-+  if (err) throw err;
-+}
-+
-+function operatorCompare(a, b){
-+  if (a === b) {
-+    return 0;
-+  }
-+  if (a < b) {
-+    return -1;
-+  } else {
-+    return 1;
-+  }
-+}
-+
-+function makeCompareProps(props){
-+  return function(a, b) {
-+    for (var i = 0; i < props.length; i += 1) {
-+      var prop = props[i];
-+      var result = operatorCompare(a[prop], b[prop]);
-+      if (result) return result;
-+    }
-+    return 0;
-+  };
-+}
-+
-+},{"events":4,"jsondiffpatch":25,"keese":28,"music-library-index":30,"util":11,"uuid":33}],37:[function(require,module,exports){
-+var EventEmitter = require('events').EventEmitter;
-+var util = require('util');
-+
-+module.exports = Socket;
-+
-+util.inherits(Socket, EventEmitter);
-+function Socket() {
-+  var self = this;
-+  EventEmitter.call(self);
-+  self.isConnected = false;
-+  createWs();
-+
-+  function createWs() {
-+    var host = window.document.location.host;
-+    var pathname = window.document.location.pathname;
-+    var isHttps = window.document.location.protocol === 'https:';
-+    var match = host.match(/^(.+):(\d+)$/);
-+    var defaultPort = isHttps ? 443 : 80;
-+    var port = match ? parseInt(match[2], 10) : defaultPort;
-+    var hostName = match ? match[1] : host;
-+    var wsProto = isHttps ? "wss:" : "ws:";
-+    var wsUrl = wsProto + '//' + hostName + ':' + port + pathname;
-+    self.ws = new WebSocket(wsUrl);
-+
-+    self.ws.addEventListener('message', onMessage, false);
-+    self.ws.addEventListener('error', timeoutThenCreateNew, false);
-+    self.ws.addEventListener('close', timeoutThenCreateNew, false);
-+    self.ws.addEventListener('open', onOpen, false);
-+
-+    function onOpen() {
-+      self.isConnected = true;
-+      self.emit('connect');
-+    }
-+
-+    function onMessage(event) {
-+      var msg = JSON.parse(event.data);
-+      self.emit(msg.name, msg.args);
-+    }
-+
-+    function timeoutThenCreateNew() {
-+      self.ws.removeEventListener('error', timeoutThenCreateNew, false);
-+      self.ws.removeEventListener('close', timeoutThenCreateNew, false);
-+      self.ws.removeEventListener('open', onOpen, false);
-+      if (self.isConnected) {
-+        self.isConnected = false;
-+        self.emit('disconnect');
-+      }
-+      setTimeout(createWs, 1000);
-+    }
-+  }
-+}
-+
-+Socket.prototype.send = function(name, args) {
-+  this.ws.send(JSON.stringify({
-+    name: name,
-+    args: args,
-+  }));
-+};
-+
-+},{"events":4,"util":11}],38:[function(require,module,exports){
-+exports.getUrl = getUrl;
-+exports.toggleStatus = toggleStatus;
-+exports.init = init;
-+
-+var tryingToStream = false;
-+var actuallyStreaming = false;
-+var stillBuffering = false;
-+var player = null;
-+var audio = new Audio();
-+audio.addEventListener('playing', onPlaying, false);
-+
-+var $ = window.$;
-+var $streamBtn = $('#stream-btn');
-+
-+document.getElementById('stream-btn-label').addEventListener('mousedown', onLabelDown, false);
-+
-+function onLabelDown(event) {
-+  event.stopPropagation();
-+}
-+
-+function getStreamerCount() {
-+  return player.streamers.anonCount + player.streamers.clientIds.length;
-+}
-+
-+function getStatusLabel() {
-+  if (tryingToStream) {
-+    if (actuallyStreaming) {
-+      if (stillBuffering) {
-+        return "Buffering";
-+      } else {
-+        return "On";
-+      }
-+    } else {
-+      return "Paused";
-+    }
-+  } else {
-+    return "Off";
-+  }
-+}
-+
-+function getButtonLabel() {
-+  return getStreamerCount() + " Stream: " + getStatusLabel();
-+}
-+
-+function renderStreamButton(){
-+  var label = getButtonLabel();
-+  $streamBtn
-+    .button("option", "label", label)
-+    .prop("checked", tryingToStream)
-+    .button("refresh");
-+}
-+
-+function toggleStatus() {
-+  tryingToStream = !tryingToStream;
-+  renderStreamButton();
-+  updatePlayer();
-+  return false;
-+}
-+
-+function getUrl() {
-+  // keep the URL relative so that reverse proxies can work
-+  return "stream.mp3";
-+}
-+
-+function onPlaying() {
-+  stillBuffering = false;
-+  renderStreamButton();
-+}
-+
-+function clearBuffer() {
-+  if (tryingToStream) {
-+    tryingToStream = !tryingToStream;
-+    updatePlayer();
-+    tryingToStream = !tryingToStream;
-+    updatePlayer();
-+  }
-+}
-+
-+function updatePlayer() {
-+  var shouldStream = tryingToStream && player.isPlaying === true;
-+  if (actuallyStreaming !== shouldStream) {
-+    if (shouldStream) {
-+      audio.src = getUrl();
-+      audio.load();
-+      audio.play();
-+      stillBuffering = true;
-+    } else {
-+      audio.pause();
-+      audio.src = "";
-+      audio.load();
-+      stillBuffering = false;
-+    }
-+    actuallyStreaming = shouldStream;
-+  }
-+  renderStreamButton();
-+}
-+
-+function setUpUi() {
-+  $streamBtn.button({
-+    icons: {
-+      primary: "ui-icon-signal-diag"
-+    }
-+  });
-+  $streamBtn.on('click', toggleStatus);
-+}
-+
-+function init(playerInstance, socket) {
-+  player = playerInstance;
-+
-+  player.on('currentTrack', updatePlayer);
-+  player.on('streamers', renderStreamButton);
-+  socket.on('seek', clearBuffer);
-+  setUpUi();
-+}
-+
-+},{}]},{},[35])
-\ No newline at end of file
diff --git a/debian/patches/node-uuid.patch b/debian/patches/node-uuid.patch
deleted file mode 100644
index fd05f22..0000000
--- a/debian/patches/node-uuid.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Description: require('node-uuid') instead of require('uuid') :-(
- Sadly debian has the wrong uuid module and so it must be patched around.
-Author: Andrew Kelley <superjoe30 at gmail.com>
-Forwarded: not-needed
-Last-Update: 2014-07-04
-
---- groovebasin-1.2.0.orig/lib/player.js
-+++ groovebasin-1.2.0/lib/player.js
-@@ -4,7 +4,7 @@ var EventEmitter = require('events').Eve
- var util = require('util');
- var mkdirp = require('mkdirp');
- var fs = require('fs');
--var uuid = require('uuid');
-+var uuid = require('node-uuid');
- var path = require('path');
- var Pend = require('pend');
- var DedupedQueue = require('./deduped_queue');
---- groovebasin-1.2.0.orig/lib/player_server.js
-+++ groovebasin-1.2.0/lib/player_server.js
-@@ -1,4 +1,4 @@
--var uuid = require('uuid');
-+var uuid = require('node-uuid');
- var jsondiffpatch = require('jsondiffpatch');
- var Player = require('./player');
- var crypto = require('crypto');
diff --git a/debian/patches/series b/debian/patches/series
index 3b54307..60611ea 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1 @@
-bundle_node_modules.patch
 shebang.patch
-node-uuid.patch

-- 
groovebasin packaging



More information about the pkg-multimedia-commits mailing list