[deps] Adds sinon

R=jacktfranklin@chromium.org

DISABLE_THIRD_PARTY_CHECK=Adding sinon to deps

Change-Id: If47962332a4d9a4b4f0edbe637bca4f9894545ba
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2562704
Auto-Submit: Paul Lewis <aerotwist@chromium.org>
Commit-Queue: Paul Lewis <aerotwist@chromium.org>
Commit-Queue: Jack Franklin <jacktfranklin@chromium.org>
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
diff --git a/node_modules/path-to-regexp/History.md b/node_modules/path-to-regexp/History.md
new file mode 100644
index 0000000..abe4a65
--- /dev/null
+++ b/node_modules/path-to-regexp/History.md
@@ -0,0 +1,158 @@
+1.7.0 / 2016-11-08
+==================
+
+  * Allow a `delimiter` option to be passed in with `tokensToRegExp` which will be used for "non-ending" token match situations
+
+1.6.0 / 2016-10-03
+==================
+
+  * Populate `RegExp.keys` when using the `tokensToRegExp` method (making it consistent with the main export)
+  * Allow a `delimiter` option to be passed in with `parse`
+  * Updated TypeScript definition with `Keys` and `Options` updated
+
+1.5.3 / 2016-06-15
+==================
+
+  * Add `\\` to the ignore character group to avoid backtracking on mismatched parens
+
+1.5.2 / 2016-06-15
+==================
+
+  * Escape `\\` in string segments of regexp
+
+1.5.1 / 2016-06-08
+==================
+
+  * Add `index.d.ts` to NPM package
+
+1.5.0 / 2016-05-20
+==================
+
+  * Handle partial token segments (better)
+  * Allow compile to handle asterisk token segments
+
+1.4.0 / 2016-05-18
+==================
+
+  * Handle RegExp unions in path matching groups
+
+1.3.0 / 2016-05-08
+==================
+
+  * Clarify README language and named parameter token support
+  * Support advanced Closure Compiler with type annotations
+  * Add pretty paths options to compiled function output
+  * Add TypeScript definition to project
+  * Improved prefix handling with non-complete segment parameters (E.g. `/:foo?-bar`)
+
+1.2.1 / 2015-08-17
+==================
+
+  * Encode values before validation with path compilation function
+  * More examples of using compilation in README
+
+1.2.0 / 2015-05-20
+==================
+
+  * Add support for matching an asterisk (`*`) as an unnamed match everything group (`(.*)`)
+
+1.1.1 / 2015-05-11
+==================
+
+  * Expose methods for working with path tokens
+
+1.1.0 / 2015-05-09
+==================
+
+  * Expose the parser implementation to consumers
+  * Implement a compiler function to generate valid strings
+  * Huge refactor of tests to be more DRY and cover new parse and compile functions
+  * Use chai in tests
+  * Add .editorconfig
+
+1.0.3 / 2015-01-17
+==================
+
+  * Optimised function runtime
+  * Added `files` to `package.json`
+
+1.0.2 / 2014-12-17
+==================
+
+  * Use `Array.isArray` shim
+  * Remove ES5 incompatible code
+  * Fixed repository path
+  * Added new readme badges
+
+1.0.1 / 2014-08-27
+==================
+
+  * Ensure installation works correctly on 0.8
+
+1.0.0 / 2014-08-17
+==================
+
+  * No more API changes
+
+0.2.5 / 2014-08-07
+==================
+
+  * Allow keys parameter to be omitted
+
+0.2.4 / 2014-08-02
+==================
+
+  * Code coverage badge
+  * Updated readme
+  * Attach keys to the generated regexp
+
+0.2.3 / 2014-07-09
+==================
+
+  * Add MIT license
+
+0.2.2 / 2014-07-06
+==================
+
+  * A passed in trailing slash in non-strict mode will become optional
+  * In non-end mode, the optional trailing slash will only match at the end
+
+0.2.1 / 2014-06-11
+==================
+
+  * Fixed a major capturing group regexp regression
+
+0.2.0 / 2014-06-09
+==================
+
+  * Improved support for arrays
+  * Improved support for regexps
+  * Better support for non-ending strict mode matches with a trailing slash
+  * Travis CI support
+  * Block using regexp special characters in the path
+  * Removed support for the asterisk to match all
+  * New support for parameter suffixes - `*`, `+` and `?`
+  * Updated readme
+  * Provide delimiter information with keys array
+
+0.1.2 / 2014-03-10
+==================
+
+  * Move testing dependencies to `devDependencies`
+
+0.1.1 / 2014-03-10
+==================
+
+  * Match entire substring with `options.end`
+  * Properly handle ending and non-ending matches
+
+0.1.0 / 2014-03-06
+==================
+
+  * Add `options.end`
+
+0.0.2 / 2013-02-10
+==================
+
+  * Update to match current express
+  * Add .license property to component.json
diff --git a/node_modules/path-to-regexp/LICENSE b/node_modules/path-to-regexp/LICENSE
new file mode 100644
index 0000000..983fbe8
--- /dev/null
+++ b/node_modules/path-to-regexp/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/node_modules/path-to-regexp/Readme.md b/node_modules/path-to-regexp/Readme.md
new file mode 100644
index 0000000..379ecf4
--- /dev/null
+++ b/node_modules/path-to-regexp/Readme.md
@@ -0,0 +1,257 @@
+# Path-to-RegExp
+
+> Turn an Express-style path string such as `/user/:name` into a regular expression.
+
+[![NPM version][npm-image]][npm-url]
+[![Build status][travis-image]][travis-url]
+[![Test coverage][coveralls-image]][coveralls-url]
+[![Dependency Status][david-image]][david-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+## Installation
+
+```
+npm install path-to-regexp --save
+```
+
+## Usage
+
+```javascript
+var pathToRegexp = require('path-to-regexp')
+
+// pathToRegexp(path, keys, options)
+// pathToRegexp.parse(path)
+// pathToRegexp.compile(path)
+```
+
+- **path** An Express-style string, an array of strings, or a regular expression.
+- **keys** An array to be populated with the keys found in the path.
+- **options**
+  - **sensitive** When `true` the route will be case sensitive. (default: `false`)
+  - **strict** When `false` the trailing slash is optional. (default: `false`)
+  - **end** When `false` the path will match at the beginning. (default: `true`)
+  - **delimiter** Set the default delimiter for repeat parameters. (default: `'/'`)
+
+```javascript
+var keys = []
+var re = pathToRegexp('/foo/:bar', keys)
+// re = /^\/foo\/([^\/]+?)\/?$/i
+// keys = [{ name: 'bar', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }]
+```
+
+**Please note:** The `RegExp` returned by `path-to-regexp` is intended for use with pathnames or hostnames. It can not handle the query strings or fragments of a URL.
+
+### Parameters
+
+The path string can be used to define parameters and populate the keys.
+
+#### Named Parameters
+
+Named parameters are defined by prefixing a colon to the parameter name (`:foo`). By default, the parameter will match until the following path segment.
+
+```js
+var re = pathToRegexp('/:foo/:bar', keys)
+// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]
+
+re.exec('/test/route')
+//=> ['/test/route', 'test', 'route']
+```
+
+**Please note:** Named parameters must be made up of "word characters" (`[A-Za-z0-9_]`).
+
+```js
+var re = pathToRegexp('/(apple-)?icon-:res(\\d+).png', keys)
+// keys = [{ name: 0, prefix: '/', ... }, { name: 'res', prefix: '', ... }]
+
+re.exec('/icon-76.png')
+//=> ['/icon-76.png', undefined, '76']
+```
+
+#### Modified Parameters
+
+##### Optional
+
+Parameters can be suffixed with a question mark (`?`) to make the parameter optional. This will also make the prefix optional.
+
+```js
+var re = pathToRegexp('/:foo/:bar?', keys)
+// keys = [{ name: 'foo', ... }, { name: 'bar', delimiter: '/', optional: true, repeat: false }]
+
+re.exec('/test')
+//=> ['/test', 'test', undefined]
+
+re.exec('/test/route')
+//=> ['/test', 'test', 'route']
+```
+
+##### Zero or more
+
+Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches. The prefix is taken into account for each match.
+
+```js
+var re = pathToRegexp('/:foo*', keys)
+// keys = [{ name: 'foo', delimiter: '/', optional: true, repeat: true }]
+
+re.exec('/')
+//=> ['/', undefined]
+
+re.exec('/bar/baz')
+//=> ['/bar/baz', 'bar/baz']
+```
+
+##### One or more
+
+Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches. The prefix is taken into account for each match.
+
+```js
+var re = pathToRegexp('/:foo+', keys)
+// keys = [{ name: 'foo', delimiter: '/', optional: false, repeat: true }]
+
+re.exec('/')
+//=> null
+
+re.exec('/bar/baz')
+//=> ['/bar/baz', 'bar/baz']
+```
+
+#### Custom Match Parameters
+
+All parameters can be provided a custom regexp, which overrides the default (`[^\/]+`).
+
+```js
+var re = pathToRegexp('/:foo(\\d+)', keys)
+// keys = [{ name: 'foo', ... }]
+
+re.exec('/123')
+//=> ['/123', '123']
+
+re.exec('/abc')
+//=> null
+```
+
+**Please note:** Backslashes need to be escaped with another backslash in strings.
+
+#### Unnamed Parameters
+
+It is possible to write an unnamed parameter that only consists of a matching group. It works the same as a named parameter, except it will be numerically indexed.
+
+```js
+var re = pathToRegexp('/:foo/(.*)', keys)
+// keys = [{ name: 'foo', ... }, { name: 0, ... }]
+
+re.exec('/test/route')
+//=> ['/test/route', 'test', 'route']
+```
+
+#### Asterisk
+
+An asterisk can be used for matching everything. It is equivalent to an unnamed matching group of `(.*)`.
+
+```js
+var re = pathToRegexp('/foo/*', keys)
+// keys = [{ name: '0', ... }]
+
+re.exec('/foo/bar/baz')
+//=> ['/foo/bar/baz', 'bar/baz']
+```
+
+### Parse
+
+The parse function is exposed via `pathToRegexp.parse`. This will return an array of strings and keys.
+
+```js
+var tokens = pathToRegexp.parse('/route/:foo/(.*)')
+
+console.log(tokens[0])
+//=> "/route"
+
+console.log(tokens[1])
+//=> { name: 'foo', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }
+
+console.log(tokens[2])
+//=> { name: 0, prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '.*' }
+```
+
+**Note:** This method only works with Express-style strings.
+
+### Compile ("Reverse" Path-To-RegExp)
+
+Path-To-RegExp exposes a compile function for transforming an Express-style path into a valid path.
+
+```js
+var toPath = pathToRegexp.compile('/user/:id')
+
+toPath({ id: 123 }) //=> "/user/123"
+toPath({ id: 'café' }) //=> "/user/caf%C3%A9"
+toPath({ id: '/' }) //=> "/user/%2F"
+
+toPath({ id: ':' }) //=> "/user/%3A"
+toPath({ id: ':' }, { pretty: true }) //=> "/user/:"
+
+var toPathRepeated = pathToRegexp.compile('/:segment+')
+
+toPathRepeated({ segment: 'foo' }) //=> "/foo"
+toPathRepeated({ segment: ['a', 'b', 'c'] }) //=> "/a/b/c"
+
+var toPathRegexp = pathToRegexp.compile('/user/:id(\\d+)')
+
+toPathRegexp({ id: 123 }) //=> "/user/123"
+toPathRegexp({ id: '123' }) //=> "/user/123"
+toPathRegexp({ id: 'abc' }) //=> Throws `TypeError`.
+```
+
+**Note:** The generated function will throw on invalid input. It will do all necessary checks to ensure the generated path is valid. This method only works with strings.
+
+### Working with Tokens
+
+Path-To-RegExp exposes the two functions used internally that accept an array of tokens.
+
+* `pathToRegexp.tokensToRegExp(tokens, options)` Transform an array of tokens into a matching regular expression.
+* `pathToRegexp.tokensToFunction(tokens)` Transform an array of tokens into a path generator function.
+
+#### Token Information
+
+* `name` The name of the token (`string` for named or `number` for index)
+* `prefix` The prefix character for the segment (`/` or `.`)
+* `delimiter` The delimiter for the segment (same as prefix or `/`)
+* `optional` Indicates the token is optional (`boolean`)
+* `repeat` Indicates the token is repeated (`boolean`)
+* `partial` Indicates this token is a partial path segment (`boolean`)
+* `pattern` The RegExp used to match this token (`string`)
+* `asterisk` Indicates the token is an `*` match (`boolean`)
+
+## Compatibility with Express <= 4.x
+
+Path-To-RegExp breaks compatibility with Express <= `4.x`:
+
+* No longer a direct conversion to a RegExp with sugar on top - it's a path matcher with named and unnamed matching groups
+  * It's unlikely you previously abused this feature, it's rare and you could always use a RegExp instead
+* All matching RegExp special characters can be used in a matching group. E.g. `/:user(.*)`
+  * Other RegExp features are not support - no nested matching groups, non-capturing groups or look aheads
+* Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*`
+
+## TypeScript
+
+Includes a [`.d.ts`](index.d.ts) file for TypeScript users.
+
+## Live Demo
+
+You can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).
+
+## License
+
+MIT
+
+[npm-image]: https://img.shields.io/npm/v/path-to-regexp.svg?style=flat
+[npm-url]: https://npmjs.org/package/path-to-regexp
+[travis-image]: https://img.shields.io/travis/pillarjs/path-to-regexp.svg?style=flat
+[travis-url]: https://travis-ci.org/pillarjs/path-to-regexp
+[coveralls-image]: https://img.shields.io/coveralls/pillarjs/path-to-regexp.svg?style=flat
+[coveralls-url]: https://coveralls.io/r/pillarjs/path-to-regexp?branch=master
+[david-image]: http://img.shields.io/david/pillarjs/path-to-regexp.svg?style=flat
+[david-url]: https://david-dm.org/pillarjs/path-to-regexp
+[license-image]: http://img.shields.io/npm/l/path-to-regexp.svg?style=flat
+[license-url]: LICENSE.md
+[downloads-image]: http://img.shields.io/npm/dm/path-to-regexp.svg?style=flat
+[downloads-url]: https://npmjs.org/package/path-to-regexp
diff --git a/node_modules/path-to-regexp/index.d.ts b/node_modules/path-to-regexp/index.d.ts
new file mode 100644
index 0000000..4a1f65c
--- /dev/null
+++ b/node_modules/path-to-regexp/index.d.ts
@@ -0,0 +1,84 @@
+declare function pathToRegexp (path: pathToRegexp.Path, options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
+declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
+
+declare namespace pathToRegexp {
+  export interface PathRegExp extends RegExp {
+    // An array to be populated with the keys found in the path.
+    keys: Key[];
+  }
+
+  export interface RegExpOptions {
+    /**
+     * When `true` the route will be case sensitive. (default: `false`)
+     */
+    sensitive?: boolean;
+    /**
+     * When `false` the trailing slash is optional. (default: `false`)
+     */
+    strict?: boolean;
+    /**
+     * When `false` the path will match at the beginning. (default: `true`)
+     */
+    end?: boolean;
+    /**
+     * Sets the final character for non-ending optimistic matches. (default: `/`)
+     */
+    delimiter?: string;
+  }
+
+  export interface ParseOptions {
+    /**
+     * Set the default delimiter for repeat parameters. (default: `'/'`)
+     */
+    delimiter?: string;
+  }
+
+  export interface TokensToFunctionOptions {
+    /**
+     * When `true` the regexp will be case sensitive. (default: `false`)
+     */
+    sensitive?: boolean;
+  }
+
+  /**
+   * Parse an Express-style path into an array of tokens.
+   */
+  export function parse (path: string, options?: ParseOptions): Token[];
+
+  /**
+   * Transforming an Express-style path into a valid path.
+   */
+  export function compile (path: string, options?: ParseOptions & TokensToFunctionOptions): PathFunction;
+
+  /**
+   * Transform an array of tokens into a path generator function.
+   */
+  export function tokensToFunction (tokens: Token[], options?: TokensToFunctionOptions): PathFunction;
+
+  /**
+   * Transform an array of tokens into a matching regular expression.
+   */
+  export function tokensToRegExp (tokens: Token[], options?: RegExpOptions): PathRegExp;
+  export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): PathRegExp;
+
+  export interface Key {
+    name: string | number;
+    prefix: string;
+    delimiter: string;
+    optional: boolean;
+    repeat: boolean;
+    pattern: string;
+    partial: boolean;
+    asterisk: boolean;
+  }
+
+  interface PathFunctionOptions {
+    pretty?: boolean;
+  }
+
+  export type Token = string | Key;
+  export type Path = string | RegExp | Array<string | RegExp>;
+  export type PathFunction = (data?: Object, options?: PathFunctionOptions) => string;
+}
+
+export = pathToRegexp;
diff --git a/node_modules/path-to-regexp/index.js b/node_modules/path-to-regexp/index.js
new file mode 100644
index 0000000..e485afe
--- /dev/null
+++ b/node_modules/path-to-regexp/index.js
@@ -0,0 +1,426 @@
+var isarray = require('isarray')
+
+/**
+ * Expose `pathToRegexp`.
+ */
+module.exports = pathToRegexp
+module.exports.parse = parse
+module.exports.compile = compile
+module.exports.tokensToFunction = tokensToFunction
+module.exports.tokensToRegExp = tokensToRegExp
+
+/**
+ * The main path matching regexp utility.
+ *
+ * @type {RegExp}
+ */
+var PATH_REGEXP = new RegExp([
+  // Match escaped characters that would otherwise appear in future matches.
+  // This allows the user to escape special characters that won't transform.
+  '(\\\\.)',
+  // Match Express-style parameters and un-named parameters with a prefix
+  // and optional suffixes. Matches appear as:
+  //
+  // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
+  // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined]
+  // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"]
+  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
+].join('|'), 'g')
+
+/**
+ * Parse a string for the raw tokens.
+ *
+ * @param  {string}  str
+ * @param  {Object=} options
+ * @return {!Array}
+ */
+function parse (str, options) {
+  var tokens = []
+  var key = 0
+  var index = 0
+  var path = ''
+  var defaultDelimiter = options && options.delimiter || '/'
+  var res
+
+  while ((res = PATH_REGEXP.exec(str)) != null) {
+    var m = res[0]
+    var escaped = res[1]
+    var offset = res.index
+    path += str.slice(index, offset)
+    index = offset + m.length
+
+    // Ignore already escaped sequences.
+    if (escaped) {
+      path += escaped[1]
+      continue
+    }
+
+    var next = str[index]
+    var prefix = res[2]
+    var name = res[3]
+    var capture = res[4]
+    var group = res[5]
+    var modifier = res[6]
+    var asterisk = res[7]
+
+    // Push the current path onto the tokens.
+    if (path) {
+      tokens.push(path)
+      path = ''
+    }
+
+    var partial = prefix != null && next != null && next !== prefix
+    var repeat = modifier === '+' || modifier === '*'
+    var optional = modifier === '?' || modifier === '*'
+    var delimiter = res[2] || defaultDelimiter
+    var pattern = capture || group
+
+    tokens.push({
+      name: name || key++,
+      prefix: prefix || '',
+      delimiter: delimiter,
+      optional: optional,
+      repeat: repeat,
+      partial: partial,
+      asterisk: !!asterisk,
+      pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
+    })
+  }
+
+  // Match any characters still remaining.
+  if (index < str.length) {
+    path += str.substr(index)
+  }
+
+  // If the path exists, push it onto the end.
+  if (path) {
+    tokens.push(path)
+  }
+
+  return tokens
+}
+
+/**
+ * Compile a string to a template function for the path.
+ *
+ * @param  {string}             str
+ * @param  {Object=}            options
+ * @return {!function(Object=, Object=)}
+ */
+function compile (str, options) {
+  return tokensToFunction(parse(str, options), options)
+}
+
+/**
+ * Prettier encoding of URI path segments.
+ *
+ * @param  {string}
+ * @return {string}
+ */
+function encodeURIComponentPretty (str) {
+  return encodeURI(str).replace(/[\/?#]/g, function (c) {
+    return '%' + c.charCodeAt(0).toString(16).toUpperCase()
+  })
+}
+
+/**
+ * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
+ *
+ * @param  {string}
+ * @return {string}
+ */
+function encodeAsterisk (str) {
+  return encodeURI(str).replace(/[?#]/g, function (c) {
+    return '%' + c.charCodeAt(0).toString(16).toUpperCase()
+  })
+}
+
+/**
+ * Expose a method for transforming tokens into the path function.
+ */
+function tokensToFunction (tokens, options) {
+  // Compile all the tokens into regexps.
+  var matches = new Array(tokens.length)
+
+  // Compile all the patterns before compilation.
+  for (var i = 0; i < tokens.length; i++) {
+    if (typeof tokens[i] === 'object') {
+      matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options))
+    }
+  }
+
+  return function (obj, opts) {
+    var path = ''
+    var data = obj || {}
+    var options = opts || {}
+    var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
+
+    for (var i = 0; i < tokens.length; i++) {
+      var token = tokens[i]
+
+      if (typeof token === 'string') {
+        path += token
+
+        continue
+      }
+
+      var value = data[token.name]
+      var segment
+
+      if (value == null) {
+        if (token.optional) {
+          // Prepend partial segment prefixes.
+          if (token.partial) {
+            path += token.prefix
+          }
+
+          continue
+        } else {
+          throw new TypeError('Expected "' + token.name + '" to be defined')
+        }
+      }
+
+      if (isarray(value)) {
+        if (!token.repeat) {
+          throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
+        }
+
+        if (value.length === 0) {
+          if (token.optional) {
+            continue
+          } else {
+            throw new TypeError('Expected "' + token.name + '" to not be empty')
+          }
+        }
+
+        for (var j = 0; j < value.length; j++) {
+          segment = encode(value[j])
+
+          if (!matches[i].test(segment)) {
+            throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
+          }
+
+          path += (j === 0 ? token.prefix : token.delimiter) + segment
+        }
+
+        continue
+      }
+
+      segment = token.asterisk ? encodeAsterisk(value) : encode(value)
+
+      if (!matches[i].test(segment)) {
+        throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
+      }
+
+      path += token.prefix + segment
+    }
+
+    return path
+  }
+}
+
+/**
+ * Escape a regular expression string.
+ *
+ * @param  {string} str
+ * @return {string}
+ */
+function escapeString (str) {
+  return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
+}
+
+/**
+ * Escape the capturing group by escaping special characters and meaning.
+ *
+ * @param  {string} group
+ * @return {string}
+ */
+function escapeGroup (group) {
+  return group.replace(/([=!:$\/()])/g, '\\$1')
+}
+
+/**
+ * Attach the keys as a property of the regexp.
+ *
+ * @param  {!RegExp} re
+ * @param  {Array}   keys
+ * @return {!RegExp}
+ */
+function attachKeys (re, keys) {
+  re.keys = keys
+  return re
+}
+
+/**
+ * Get the flags for a regexp from the options.
+ *
+ * @param  {Object} options
+ * @return {string}
+ */
+function flags (options) {
+  return options && options.sensitive ? '' : 'i'
+}
+
+/**
+ * Pull out keys from a regexp.
+ *
+ * @param  {!RegExp} path
+ * @param  {!Array}  keys
+ * @return {!RegExp}
+ */
+function regexpToRegexp (path, keys) {
+  // Use a negative lookahead to match only capturing groups.
+  var groups = path.source.match(/\((?!\?)/g)
+
+  if (groups) {
+    for (var i = 0; i < groups.length; i++) {
+      keys.push({
+        name: i,
+        prefix: null,
+        delimiter: null,
+        optional: false,
+        repeat: false,
+        partial: false,
+        asterisk: false,
+        pattern: null
+      })
+    }
+  }
+
+  return attachKeys(path, keys)
+}
+
+/**
+ * Transform an array into a regexp.
+ *
+ * @param  {!Array}  path
+ * @param  {Array}   keys
+ * @param  {!Object} options
+ * @return {!RegExp}
+ */
+function arrayToRegexp (path, keys, options) {
+  var parts = []
+
+  for (var i = 0; i < path.length; i++) {
+    parts.push(pathToRegexp(path[i], keys, options).source)
+  }
+
+  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
+
+  return attachKeys(regexp, keys)
+}
+
+/**
+ * Create a path regexp from string input.
+ *
+ * @param  {string}  path
+ * @param  {!Array}  keys
+ * @param  {!Object} options
+ * @return {!RegExp}
+ */
+function stringToRegexp (path, keys, options) {
+  return tokensToRegExp(parse(path, options), keys, options)
+}
+
+/**
+ * Expose a function for taking tokens and returning a RegExp.
+ *
+ * @param  {!Array}          tokens
+ * @param  {(Array|Object)=} keys
+ * @param  {Object=}         options
+ * @return {!RegExp}
+ */
+function tokensToRegExp (tokens, keys, options) {
+  if (!isarray(keys)) {
+    options = /** @type {!Object} */ (keys || options)
+    keys = []
+  }
+
+  options = options || {}
+
+  var strict = options.strict
+  var end = options.end !== false
+  var route = ''
+
+  // Iterate over the tokens and create our regexp string.
+  for (var i = 0; i < tokens.length; i++) {
+    var token = tokens[i]
+
+    if (typeof token === 'string') {
+      route += escapeString(token)
+    } else {
+      var prefix = escapeString(token.prefix)
+      var capture = '(?:' + token.pattern + ')'
+
+      keys.push(token)
+
+      if (token.repeat) {
+        capture += '(?:' + prefix + capture + ')*'
+      }
+
+      if (token.optional) {
+        if (!token.partial) {
+          capture = '(?:' + prefix + '(' + capture + '))?'
+        } else {
+          capture = prefix + '(' + capture + ')?'
+        }
+      } else {
+        capture = prefix + '(' + capture + ')'
+      }
+
+      route += capture
+    }
+  }
+
+  var delimiter = escapeString(options.delimiter || '/')
+  var endsWithDelimiter = route.slice(-delimiter.length) === delimiter
+
+  // In non-strict mode we allow a slash at the end of match. If the path to
+  // match already ends with a slash, we remove it for consistency. The slash
+  // is valid at the end of a path match, not in the middle. This is important
+  // in non-ending mode, where "/test/" shouldn't match "/test//route".
+  if (!strict) {
+    route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'
+  }
+
+  if (end) {
+    route += '$'
+  } else {
+    // In non-ending mode, we need the capturing groups to match as much as
+    // possible by using a positive lookahead to the end or next path segment.
+    route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'
+  }
+
+  return attachKeys(new RegExp('^' + route, flags(options)), keys)
+}
+
+/**
+ * Normalize the given path string, returning a regular expression.
+ *
+ * An empty array can be passed in for the keys, which will hold the
+ * placeholder key descriptions. For example, using `/user/:id`, `keys` will
+ * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
+ *
+ * @param  {(string|RegExp|Array)} path
+ * @param  {(Array|Object)=}       keys
+ * @param  {Object=}               options
+ * @return {!RegExp}
+ */
+function pathToRegexp (path, keys, options) {
+  if (!isarray(keys)) {
+    options = /** @type {!Object} */ (keys || options)
+    keys = []
+  }
+
+  options = options || {}
+
+  if (path instanceof RegExp) {
+    return regexpToRegexp(path, /** @type {!Array} */ (keys))
+  }
+
+  if (isarray(path)) {
+    return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
+  }
+
+  return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
+}
diff --git a/node_modules/path-to-regexp/node_modules/isarray/README.md b/node_modules/path-to-regexp/node_modules/isarray/README.md
new file mode 100644
index 0000000..052a62b
--- /dev/null
+++ b/node_modules/path-to-regexp/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 &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/path-to-regexp/node_modules/isarray/build/build.js b/node_modules/path-to-regexp/node_modules/isarray/build/build.js
new file mode 100644
index 0000000..ec58596
--- /dev/null
+++ b/node_modules/path-to-regexp/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");
+
diff --git a/node_modules/path-to-regexp/node_modules/isarray/component.json b/node_modules/path-to-regexp/node_modules/isarray/component.json
new file mode 100644
index 0000000..9e31b68
--- /dev/null
+++ b/node_modules/path-to-regexp/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@juliangruber.com",
+    "url": "http://juliangruber.com"
+  },
+  "license": "MIT"
+}
diff --git a/node_modules/path-to-regexp/node_modules/isarray/index.js b/node_modules/path-to-regexp/node_modules/isarray/index.js
new file mode 100644
index 0000000..5f5ad45
--- /dev/null
+++ b/node_modules/path-to-regexp/node_modules/isarray/index.js
@@ -0,0 +1,3 @@
+module.exports = Array.isArray || function (arr) {
+  return Object.prototype.toString.call(arr) == '[object Array]';
+};
diff --git a/node_modules/path-to-regexp/node_modules/isarray/package.json b/node_modules/path-to-regexp/node_modules/isarray/package.json
new file mode 100644
index 0000000..f458fba
--- /dev/null
+++ b/node_modules/path-to-regexp/node_modules/isarray/package.json
@@ -0,0 +1,29 @@
+{
+  "author": {
+    "email": "mail@juliangruber.com",
+    "name": "Julian Gruber",
+    "url": "http://juliangruber.com"
+  },
+  "dependencies": {},
+  "description": "Array#isArray for older browsers",
+  "devDependencies": {
+    "tap": "*"
+  },
+  "homepage": "https://github.com/juliangruber/isarray",
+  "keywords": [
+    "browser",
+    "isarray",
+    "array"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "isarray",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/juliangruber/isarray.git"
+  },
+  "scripts": {
+    "test": "tap test/*.js"
+  },
+  "version": "0.0.1"
+}
diff --git a/node_modules/path-to-regexp/package.json b/node_modules/path-to-regexp/package.json
new file mode 100644
index 0000000..bdb272e
--- /dev/null
+++ b/node_modules/path-to-regexp/package.json
@@ -0,0 +1,47 @@
+{
+  "component": {
+    "scripts": {
+      "path-to-regexp": "index.js"
+    }
+  },
+  "dependencies": {
+    "isarray": "0.0.1"
+  },
+  "description": "Express style path to RegExp utility",
+  "devDependencies": {
+    "chai": "^2.3.0",
+    "istanbul": "~0.3.0",
+    "mocha": "~2.2.4",
+    "standard": "~3.7.3",
+    "ts-node": "^0.5.5",
+    "typescript": "^1.8.7",
+    "typings": "^1.0.4"
+  },
+  "files": [
+    "index.js",
+    "index.d.ts",
+    "LICENSE"
+  ],
+  "keywords": [
+    "express",
+    "regexp",
+    "route",
+    "routing"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "path-to-regexp",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/pillarjs/path-to-regexp.git"
+  },
+  "scripts": {
+    "lint": "standard",
+    "prepublish": "typings install",
+    "test": "npm run lint && npm run test-cov",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require ts-node/register -R spec test.ts",
+    "test-spec": "mocha --require ts-node/register -R spec --bail test.ts"
+  },
+  "typings": "index.d.ts",
+  "version": "1.8.0"
+}