Index: frontend/node_modules/recursive-readdir/LICENSE
===================================================================
--- frontend/node_modules/recursive-readdir/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/recursive-readdir/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) <year> <copyright holders>
+
+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/recursive-readdir/README.md
===================================================================
--- frontend/node_modules/recursive-readdir/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/recursive-readdir/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+# recursive-readdir
+
+[![Build Status](https://travis-ci.org/jergason/recursive-readdir.svg?branch=master)](https://travis-ci.org/jergason/recursive-readdir)
+
+Recursively list all files in a directory and its subdirectories. It does not list the directories themselves.
+
+Because it uses fs.readdir, which calls [readdir](http://linux.die.net/man/3/readdir) under the hood
+on OS X and Linux, the order of files inside directories is [not guaranteed](http://stackoverflow.com/questions/8977441/does-readdir-guarantee-an-order).
+
+## Installation
+
+    npm install recursive-readdir
+
+## Usage
+
+```javascript
+var recursive = require("recursive-readdir");
+
+recursive("some/path", function (err, files) {
+  // `files` is an array of file paths
+  console.log(files);
+});
+```
+
+It can also take a list of files to ignore.
+
+```javascript
+var recursive = require("recursive-readdir");
+
+// ignore files named "foo.cs" or files that end in ".html".
+recursive("some/path", ["foo.cs", "*.html"], function (err, files) {
+  console.log(files);
+});
+```
+
+You can also pass functions which are called to determine whether or not to
+ignore a file:
+
+```javascript
+var recursive = require("recursive-readdir");
+
+function ignoreFunc(file, stats) {
+  // `file` is the path to the file, and `stats` is an `fs.Stats`
+  // object returned from `fs.lstat()`.
+  return stats.isDirectory() && path.basename(file) == "test";
+}
+
+// Ignore files named "foo.cs" and descendants of directories named test
+recursive("some/path", ["foo.cs", ignoreFunc], function (err, files) {
+  console.log(files);
+});
+```
+
+## Promises
+You can omit the callback and return a promise instead.
+
+```javascript
+var recursive = require("recursive-readdir");
+
+recursive("some/path").then(
+  function(files) {
+    console.log("files are", files);
+  },
+  function(error) {
+    console.error("something exploded", error);
+  }
+);
+```
+
+The ignore strings support Glob syntax via
+[minimatch](https://github.com/isaacs/minimatch).
Index: frontend/node_modules/recursive-readdir/index.js
===================================================================
--- frontend/node_modules/recursive-readdir/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/recursive-readdir/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,96 @@
+var fs = require("fs");
+var p = require("path");
+var minimatch = require("minimatch");
+
+function patternMatcher(pattern) {
+  return function(path, stats) {
+    var minimatcher = new minimatch.Minimatch(pattern, { matchBase: true });
+    return (!minimatcher.negate || stats.isFile()) && minimatcher.match(path);
+  };
+}
+
+function toMatcherFunction(ignoreEntry) {
+  if (typeof ignoreEntry == "function") {
+    return ignoreEntry;
+  } else {
+    return patternMatcher(ignoreEntry);
+  }
+}
+
+function readdir(path, ignores, callback) {
+  if (typeof ignores == "function") {
+    callback = ignores;
+    ignores = [];
+  }
+
+  if (!callback) {
+    return new Promise(function(resolve, reject) {
+      readdir(path, ignores || [], function(err, data) {
+        if (err) {
+          reject(err);
+        } else {
+          resolve(data);
+        }
+      });
+    });
+  }
+
+  ignores = ignores.map(toMatcherFunction);
+
+  var list = [];
+
+  fs.readdir(path, function(err, files) {
+    if (err) {
+      return callback(err);
+    }
+
+    var pending = files.length;
+    if (!pending) {
+      // we are done, woop woop
+      return callback(null, list);
+    }
+
+    files.forEach(function(file) {
+      var filePath = p.join(path, file);
+      fs.stat(filePath, function(_err, stats) {
+        if (_err) {
+          return callback(_err);
+        }
+
+        if (
+          ignores.some(function(matcher) {
+            return matcher(filePath, stats);
+          })
+        ) {
+          pending -= 1;
+          if (!pending) {
+            return callback(null, list);
+          }
+          return null;
+        }
+
+        if (stats.isDirectory()) {
+          readdir(filePath, ignores, function(__err, res) {
+            if (__err) {
+              return callback(__err);
+            }
+
+            list = list.concat(res);
+            pending -= 1;
+            if (!pending) {
+              return callback(null, list);
+            }
+          });
+        } else {
+          list.push(filePath);
+          pending -= 1;
+          if (!pending) {
+            return callback(null, list);
+          }
+        }
+      });
+    });
+  });
+}
+
+module.exports = readdir;
Index: frontend/node_modules/recursive-readdir/package.json
===================================================================
--- frontend/node_modules/recursive-readdir/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/recursive-readdir/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+{
+  "author": "Jamison Dance <jergason@gmail.com> (http://jamison.dance.com/)",
+  "name": "recursive-readdir",
+  "description": "Get an array of all files in a directory and subdirectories.",
+  "license": "MIT",
+  "version": "2.2.3",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/jergason/recursive-readdir.git"
+  },
+  "main": "./index.js",
+  "files": [
+    "index.js"
+  ],
+  "scripts": {
+    "test": "mocha test/"
+  },
+  "keywords": [
+    "directory",
+    "lister"
+  ],
+  "engines": {
+    "node": ">=6.0.0"
+  },
+  "dependencies": {
+    "minimatch": "^3.0.5"
+  },
+  "devDependencies": {
+    "mocha": "6.1.4"
+  }
+}
