Index: frontend/node_modules/thenify/History.md
===================================================================
--- frontend/node_modules/thenify/History.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/thenify/History.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,11 @@
+
+3.3.1 / 2020-06-18
+==================
+
+**fixes**
+  * [[`0d94a24`](http://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a)] - fix: remove eval (#30) (Yiyu He <<dead_horse@qq.com>>)
+
+3.3.0 / 2017-05-19
+==================
+
+  * feat: support options.multiArgs and options.withCallback (#27)
Index: frontend/node_modules/thenify/LICENSE
===================================================================
--- frontend/node_modules/thenify/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/thenify/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+
+The MIT License (MIT)
+
+Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com 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.
Index: frontend/node_modules/thenify/README.md
===================================================================
--- frontend/node_modules/thenify/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/thenify/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,120 @@
+
+# thenify
+
+[![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]
+
+Promisify a callback-based function using [`any-promise`](https://github.com/kevinbeaty/any-promise).
+
+- Preserves function names
+- Uses a native promise implementation if available and tries to fall back to a promise implementation such as `bluebird`
+- Converts multiple arguments from the callback into an `Array`, also support change the behavior by `options.multiArgs`
+- Resulting function never deoptimizes
+- Supports both callback and promise style
+
+An added benefit is that `throw`n errors in that async function will be caught by the promise!
+
+## API
+
+### fn = thenify(fn, options)
+
+Promisifies a function.
+
+### Options
+
+`options` are optional.
+
+- `options.withCallback` - support both callback and promise style, default to `false`.
+- `options.multiArgs` - change the behavior when callback have multiple arguments. default to `true`.
+  - `true` - converts multiple arguments to an array
+  - `false`- always use the first argument
+  - `Array` - converts multiple arguments to an object with keys provided in `options.multiArgs`
+
+- Turn async functions into promises
+
+```js
+var thenify = require('thenify');
+
+var somethingAsync = thenify(function somethingAsync(a, b, c, callback) {
+  callback(null, a, b, c);
+});
+```
+
+- Backward compatible with callback
+
+```js
+var thenify = require('thenify');
+
+var somethingAsync = thenify(function somethingAsync(a, b, c, callback) {
+  callback(null, a, b, c);
+}, { withCallback: true });
+
+// somethingAsync(a, b, c).then(onFulfilled).catch(onRejected);
+// somethingAsync(a, b, c, function () {});
+```
+
+or use `thenify.withCallback()`
+
+```js
+var thenify = require('thenify').withCallback;
+
+var somethingAsync = thenify(function somethingAsync(a, b, c, callback) {
+  callback(null, a, b, c);
+});
+
+// somethingAsync(a, b, c).then(onFulfilled).catch(onRejected);
+// somethingAsync(a, b, c, function () {});
+```
+
+- Always return the first argument in callback
+
+```js
+var thenify = require('thenify');
+
+var promise = thenify(function (callback) {
+  callback(null, 1, 2, 3);
+}, { multiArgs: false });
+
+// promise().then(function onFulfilled(value) {
+//   assert.equal(value, 1);
+// });
+```
+
+- Converts callback arguments to an object
+
+```js
+var thenify = require('thenify');
+
+var promise = thenify(function (callback) {
+  callback(null, 1, 2, 3);
+}, { multiArgs: [ 'one', 'tow', 'three' ] });
+
+// promise().then(function onFulfilled(value) {
+//   assert.deepEqual(value, {
+//     one: 1,
+//     tow: 2,
+//     three: 3
+//   });
+// });
+```
+
+[gitter-image]: https://badges.gitter.im/thenables/thenify.png
+[gitter-url]: https://gitter.im/thenables/thenify
+[npm-image]: https://img.shields.io/npm/v/thenify.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/thenify
+[github-tag]: http://img.shields.io/github/tag/thenables/thenify.svg?style=flat-square
+[github-url]: https://github.com/thenables/thenify/tags
+[travis-image]: https://img.shields.io/travis/thenables/thenify.svg?style=flat-square
+[travis-url]: https://travis-ci.org/thenables/thenify
+[coveralls-image]: https://img.shields.io/coveralls/thenables/thenify.svg?style=flat-square
+[coveralls-url]: https://coveralls.io/r/thenables/thenify
+[david-image]: http://img.shields.io/david/thenables/thenify.svg?style=flat-square
+[david-url]: https://david-dm.org/thenables/thenify
+[license-image]: http://img.shields.io/npm/l/thenify.svg?style=flat-square
+[license-url]: LICENSE
+[downloads-image]: http://img.shields.io/npm/dm/thenify.svg?style=flat-square
+[downloads-url]: https://npmjs.org/package/thenify
Index: frontend/node_modules/thenify/index.js
===================================================================
--- frontend/node_modules/thenify/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/thenify/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+
+var Promise = require('any-promise')
+var assert = require('assert')
+
+module.exports = thenify
+
+/**
+ * Turn async functions into promises
+ *
+ * @param {Function} fn
+ * @return {Function}
+ * @api public
+ */
+
+function thenify(fn, options) {
+  assert(typeof fn === 'function')
+  return createWrapper(fn, options)
+}
+
+/**
+ * Turn async functions into promises and backward compatible with callback
+ *
+ * @param {Function} fn
+ * @return {Function}
+ * @api public
+ */
+
+thenify.withCallback = function (fn, options) {
+  assert(typeof fn === 'function')
+  options = options || {}
+  options.withCallback = true
+  return createWrapper(fn, options)
+}
+
+function createCallback(resolve, reject, multiArgs) {
+  // default to true
+  if (multiArgs === undefined) multiArgs = true
+  return function(err, value) {
+    if (err) return reject(err)
+    var length = arguments.length
+
+    if (length <= 2 || !multiArgs) return resolve(value)
+
+    if (Array.isArray(multiArgs)) {
+      var values = {}
+      for (var i = 1; i < length; i++) values[multiArgs[i - 1]] = arguments[i]
+      return resolve(values)
+    }
+
+    var values = new Array(length - 1)
+    for (var i = 1; i < length; ++i) values[i - 1] = arguments[i]
+    resolve(values)
+  }
+}
+
+function createWrapper(fn, options) {
+  options = options || {}
+  var name = fn.name;
+  name = (name || '').replace(/\s|bound(?!$)/g, '')
+  var newFn = function () {
+    var self = this
+    var len = arguments.length
+    if (options.withCallback) {
+      var lastType = typeof arguments[len - 1]
+      if (lastType === 'function') return fn.apply(self, arguments)
+    }
+    var args = new Array(len + 1)
+    for (var i = 0; i < len; ++i) args[i] = arguments[i]
+    var lastIndex = i
+    return new Promise(function (resolve, reject) {
+      args[lastIndex] = createCallback(resolve, reject, options.multiArgs)
+      fn.apply(self, args)
+    })
+  }
+  Object.defineProperty(newFn, 'name', { value: name })
+  return newFn
+}
Index: frontend/node_modules/thenify/package.json
===================================================================
--- frontend/node_modules/thenify/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/thenify/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+{
+  "name": "thenify",
+  "description": "Promisify a callback-based function",
+  "version": "3.3.1",
+  "author": "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)",
+  "license": "MIT",
+  "repository": "thenables/thenify",
+  "dependencies": {
+    "any-promise": "^1.0.0"
+  },
+  "devDependencies": {
+    "bluebird": "^3.1.1",
+    "istanbul": "^0.4.0",
+    "mocha": "^3.0.2"
+  },
+  "scripts": {
+    "test": "mocha --reporter spec",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",
+    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot"
+  },
+  "keywords": [
+    "promisify",
+    "promise",
+    "thenify",
+    "then",
+    "es6"
+  ],
+  "files": [
+    "index.js"
+  ]
+}
