diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/README.md b/README.md
index 7513987..ec57b3a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
# assignment_thoreddit
A social news web application for Viking thunder Gods
+
+Benny and Will
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..ac2e462
--- /dev/null
+++ b/app.js
@@ -0,0 +1,65 @@
+const express = require("express");
+const app = express();
+
+// Templates
+const expressHandlebars = require("express-handlebars");
+const hbs = expressHandlebars.create({
+ partialsDir: "views/",
+ defaultLayout: "application",
+ helpers: require("./helpers")
+});
+app.engine("handlebars", hbs.engine);
+app.set("view engine", "handlebars");
+
+// Post Data
+const bodyParser = require("body-parser");
+app.use(bodyParser.urlencoded({ extended: true }));
+
+// Session
+const cookieSession = require("cookie-session");
+app.use(
+ cookieSession({
+ name: "session",
+ keys: ["asdf90890sdfa980sdf98a"]
+ })
+);
+
+// Flash
+const flash = require("express-flash-messages");
+app.use(flash());
+
+// Log Request Info
+const morgan = require("morgan");
+const morganToolkit = require("morgan-toolkit")(morgan);
+app.use(morganToolkit());
+
+// Method Overriding
+const methodOverride = require("method-override");
+const getPostSupport = require("express-method-override-get-post-support");
+app.use(methodOverride(getPostSupport.callback, getPostSupport.options));
+
+// Connect to Mongoose
+const mongoose = require("mongoose");
+app.use((req, res, next) => {
+ if (mongoose.connection.readyState) next();
+ else require("./mongo")().then(() => next());
+});
+
+// Routes
+app.use("/posts", require("./routers/posts"));
+app.all("/", (req, res) => res.redirect("/posts"));
+app.use("/users", require("./routers/users"));
+app.use("/comments", require("./routers/comments"));
+
+// Set up port/host
+const port = process.env.PORT || process.argv[2] || 3000;
+const host = "localhost";
+let args = process.env.NODE_ENV === "production" ? [port] : [port, host];
+
+// helpful log when the server starts
+args.push(() => {
+ console.log(`Listening: http://${host}:${port}`);
+});
+
+// Use apply to pass the args to listen
+app.listen.apply(app, args);
diff --git a/config/mongo.json b/config/mongo.json
new file mode 100644
index 0000000..ea355cc
--- /dev/null
+++ b/config/mongo.json
@@ -0,0 +1,13 @@
+{
+ "development": {
+ "database": "thoreddit_dev",
+ "host": "localhost"
+ },
+ "test": {
+ "database": "",
+ "host": "localhost"
+ },
+ "production": {
+ "use_env_variable": "MONGODB_URI"
+ }
+}
diff --git a/config/mongoUrl.js b/config/mongoUrl.js
new file mode 100644
index 0000000..69828e0
--- /dev/null
+++ b/config/mongoUrl.js
@@ -0,0 +1,6 @@
+const env = process.env.NODE_ENV || "development";
+const config = require("./mongo.json")[env];
+module.exports =
+ process.env.NODE_ENV === "production"
+ ? process.env[config.use_env_variable]
+ : `mongodb://${config.host}/${config.database}`;
diff --git a/helpers/CommentHelper.js b/helpers/CommentHelper.js
new file mode 100644
index 0000000..c8c61c3
--- /dev/null
+++ b/helpers/CommentHelper.js
@@ -0,0 +1,7 @@
+module.exports = {
+ commentsPath: () => "/comments",
+ commentPath: id => `/comments/${id}`,
+ newCommentPath: () => "/comments/new",
+ editCommentPath: id => `/comments/${id}/edit`,
+ destroyCommentPath: id => `/comments/${id}/?_method=delete`
+};
diff --git a/helpers/FlashHelper.js b/helpers/FlashHelper.js
new file mode 100644
index 0000000..0d14458
--- /dev/null
+++ b/helpers/FlashHelper.js
@@ -0,0 +1,11 @@
+const FlashHelper = {};
+FlashHelper.bootstrapAlertClassFor = function(key) {
+ return (
+ {
+ error: "danger",
+ alert: "danger",
+ notice: "info"
+ }[key] || key
+ );
+};
+module.exports = FlashHelper;
diff --git a/helpers/PostHelper.js b/helpers/PostHelper.js
new file mode 100644
index 0000000..34f7994
--- /dev/null
+++ b/helpers/PostHelper.js
@@ -0,0 +1,7 @@
+module.exports = {
+ postsPath: () => "/posts",
+ postPath: id => `/posts/${id}`,
+ newPostPath: () => "/posts/new",
+ editPostPath: id => `/posts/${id}/edit`,
+ destroyPostPath: id => `/posts/${id}/?_method=delete`
+};
diff --git a/helpers/UserHelper.js b/helpers/UserHelper.js
new file mode 100644
index 0000000..c5489ce
--- /dev/null
+++ b/helpers/UserHelper.js
@@ -0,0 +1,7 @@
+module.exports = {
+ usersPath: () => "/users",
+ userPath: id => `/users/${id}`,
+ newUserPath: () => "/users/new",
+ editUserPath: id => `/users/${id}/edit`,
+ destroyUserPath: id => `/users/${id}/?_method=delete`
+};
diff --git a/helpers/index.js b/helpers/index.js
new file mode 100644
index 0000000..4efd3b2
--- /dev/null
+++ b/helpers/index.js
@@ -0,0 +1,5 @@
+const LoadHelpers = require("load-helpers");
+const helperLoader = new LoadHelpers();
+const helpers = helperLoader.load("helpers/*Helper.js").cache;
+
+module.exports = helpers;
diff --git a/models/Comment.js b/models/Comment.js
new file mode 100644
index 0000000..52f8fa1
--- /dev/null
+++ b/models/Comment.js
@@ -0,0 +1,76 @@
+const mongoose = require("mongoose");
+const Scorable = require("./Scorable");
+const Schema = mongoose.Schema;
+
+const CommentSchema = new Schema(
+ {
+ post: { type: Schema.Types.ObjectId, ref: "Post" },
+ user: { type: Schema.Types.ObjectId, ref: "User" },
+ body: String
+ },
+ {
+ discriminatorKey: "scorableKind"
+ }
+);
+
+CommentSchema.virtual("summary").get(function() {
+ return this.body.slice(0, 100) + "...";
+});
+
+CommentSchema.statics.new = function(params) {
+ return this.create({
+ body: params.body,
+ user: params.userId,
+ post: params.postId
+ });
+};
+
+CommentSchema.post("save", function() {
+ mongoose
+ .model("User")
+ .update(
+ { _id: this.user },
+ { $pull: { comments: this._id } },
+ { multi: true }
+ )
+ .exec();
+ mongoose
+ .model("User")
+ .update({ _id: this.user }, { $push: { comments: this._id } })
+ .exec();
+ mongoose
+ .model("Post")
+ .update(
+ { _id: this.post },
+ { $pull: { comments: this._id } },
+ { multi: true }
+ )
+ .exec();
+ mongoose
+ .model("Post")
+ .update({ _id: this.post }, { $push: { comments: this._id } })
+ .exec();
+});
+
+CommentSchema.pre("remove", function(next) {
+ mongoose
+ .model("User")
+ .update(
+ { _id: this.user },
+ { $pull: { comments: this._id } },
+ { multi: true }
+ )
+ .exec();
+ mongoose
+ .model("Post")
+ .update(
+ { _id: this.post },
+ { $pull: { comments: this._id } },
+ { multi: true }
+ )
+ .exec();
+ next();
+});
+
+let Comment = Scorable.discriminator("Comment", CommentSchema);
+module.exports = Comment;
diff --git a/models/Post.js b/models/Post.js
new file mode 100644
index 0000000..135adc4
--- /dev/null
+++ b/models/Post.js
@@ -0,0 +1,63 @@
+const mongoose = require("mongoose");
+const Scorable = require("./Scorable");
+const Schema = mongoose.Schema;
+
+const PostSchema = new Schema(
+ {
+ body: String,
+ title: String,
+ user: { type: Schema.Types.ObjectId, ref: "User" },
+ comments: [{ type: Schema.Types.ObjectId, ref: "Comment" }]
+ },
+ {
+ discriminatorKey: "scorableKind"
+ }
+);
+
+PostSchema.statics.getAll = function() {
+ return this.find({}, {}, { sort: { createdAt: -1 } }).populate("user");
+};
+
+PostSchema.statics.getById = function(id) {
+ return this.findById(id).populate("user").populate({
+ path: "comments",
+ populate: { path: "user", model: "User" },
+ options: { sort: { createdAt: -1 } }
+ });
+};
+
+PostSchema.statics.new = function(params) {
+ return this.create({
+ title: params.title,
+ body: params.body,
+ user: params.userId
+ });
+};
+
+PostSchema.post("save", function() {
+ mongoose
+ .model("User")
+ .update({ _id: this.user }, { $pull: { posts: this._id } }, { multi: true })
+ .exec();
+ mongoose
+ .model("User")
+ .update({ _id: this.user }, { $push: { posts: this._id } })
+ .exec();
+});
+
+PostSchema.pre("remove", function(next) {
+ mongoose
+ .model("User")
+ .update(
+ { posts: this._id },
+ { $pull: { posts: this._id } },
+ { multi: true }
+ )
+ .exec();
+ mongoose.model("Comment").remove({ post: this._id }).exec();
+ next();
+});
+
+let Post = Scorable.discriminator("Post", PostSchema);
+
+module.exports = Post;
diff --git a/models/Scorable.js b/models/Scorable.js
new file mode 100644
index 0000000..8028145
--- /dev/null
+++ b/models/Scorable.js
@@ -0,0 +1,23 @@
+const mongoose = require("mongoose");
+const Schema = mongoose.Schema;
+
+const ScorableSchema = new Schema(
+ {
+ score: Number
+ },
+ {
+ timestamps: true,
+ discriminatorKey: "scorableKind"
+ }
+);
+
+ScorableSchema.methods.upvote = function() {
+ return (this.score += 1);
+};
+
+ScorableSchema.methods.downvote = function() {
+ return (this.score -= 1);
+};
+
+let Scorable = mongoose.model("Scorable", ScorableSchema);
+module.exports = Scorable;
diff --git a/models/User.js b/models/User.js
new file mode 100644
index 0000000..c7cf43c
--- /dev/null
+++ b/models/User.js
@@ -0,0 +1,39 @@
+const mongoose = require("mongoose");
+const Schema = mongoose.Schema;
+
+const UserSchema = new Schema(
+ {
+ username: String,
+ email: String,
+ posts: [{ type: Schema.Types.ObjectId, ref: "Post" }],
+ comments: [{ type: Schema.Types.ObjectId, ref: "Comment" }]
+ },
+ {
+ timestamps: true
+ }
+);
+
+UserSchema.statics.getAll = function() {
+ return this.find({}, {}, { sort: { createdAt: -1 } })
+ .populate({ path: "comments", options: { sort: { createdAt: -1 } } })
+ .populate({ path: "posts", options: { sort: { createdAt: -1 } } });
+};
+
+UserSchema.statics.getById = function(id) {
+ return this.findById(id)
+ .populate({ path: "comments", options: { sort: { createdAt: -1 } } })
+ .populate({ path: "posts", options: { sort: { createdAt: -1 } } });
+};
+
+UserSchema.statics.new = function(params) {
+ return this.create({ username: params.username, email: params.email });
+};
+
+UserSchema.pre("remove", function(next) {
+ mongoose.model("Post").remove({ user: this._id }).exec();
+ mongoose.model("Comment").remove({ user: this._id }).exec();
+ next();
+});
+
+let User = mongoose.model("User", UserSchema);
+module.exports = User;
diff --git a/models/index.js b/models/index.js
new file mode 100644
index 0000000..91ca7f8
--- /dev/null
+++ b/models/index.js
@@ -0,0 +1,10 @@
+const mongoose = require("mongoose");
+const bluebird = require("bluebird");
+
+mongoose.Promise = bluebird;
+
+module.exports = {
+ Comment: require("./Comment"),
+ Post: require("./Post"),
+ User: require("./User")
+};
diff --git a/mongo.js b/mongo.js
new file mode 100644
index 0000000..ca08019
--- /dev/null
+++ b/mongo.js
@@ -0,0 +1,5 @@
+const mongoose = require("mongoose");
+
+module.exports = () => {
+ return mongoose.connect(require("./config/mongoUrl"));
+};
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..e3b2d58
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1726 @@
+{
+ "name": "assignment_thoreddit",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+ "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+ "requires": {
+ "mime-types": "2.1.16",
+ "negotiator": "0.6.1"
+ }
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "requires": {
+ "kind-of": "3.2.2",
+ "longest": "1.0.1",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "async-array-reduce": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/async-array-reduce/-/async-array-reduce-0.2.1.tgz",
+ "integrity": "sha1-yL4BCitc0A3qlsgRFgNGk9/dgtE="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "basic-auth": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz",
+ "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ="
+ },
+ "bluebird": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
+ "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
+ },
+ "body-parser": {
+ "version": "1.17.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
+ "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
+ "requires": {
+ "bytes": "2.4.0",
+ "content-type": "1.0.2",
+ "debug": "2.6.7",
+ "depd": "1.1.1",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.15",
+ "on-finished": "2.3.0",
+ "qs": "6.4.0",
+ "raw-body": "2.2.0",
+ "type-is": "1.6.15"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "bson": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz",
+ "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw="
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
+ },
+ "bytes": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
+ "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "optional": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.2.1"
+ }
+ },
+ "cli-highlight": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-1.1.4.tgz",
+ "integrity": "sha1-5FWQwU+xjhOGXjiZ6CTFWSzCKSY=",
+ "requires": {
+ "chalk": "1.1.3",
+ "he": "1.1.1",
+ "highlight.js": "9.12.0",
+ "mz": "2.6.0",
+ "yargs": "4.8.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ },
+ "window-size": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU="
+ },
+ "yargs": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+ "requires": {
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "lodash.assign": "4.2.0",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "1.0.2",
+ "which-module": "1.0.0",
+ "window-size": "0.2.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "2.4.1"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "optional": true,
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "optional": true
+ }
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "color-convert": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+ "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
+ "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-session": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-1.3.0.tgz",
+ "integrity": "sha512-ql3gtHDd0yn3fX3Kjtm1aS8wkpwr3qbx8MhQMYuPFu5ENQTNukSFCIxiX6mPtw2AKWYer8BMWdXk2V3Sbnft0g==",
+ "requires": {
+ "cookies": "0.7.0",
+ "debug": "2.6.8",
+ "on-headers": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "cookies": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.0.tgz",
+ "integrity": "sha1-C8lh2RDDUlSYD8fJ7/XaEgEbvwA=",
+ "requires": {
+ "depd": "1.1.1",
+ "keygrip": "1.0.1"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "debug": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
+ "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "define-properties": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+ "requires": {
+ "foreach": "2.0.5",
+ "object-keys": "1.0.11"
+ }
+ },
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
+ },
+ "error-ex": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "requires": {
+ "is-arrayish": "0.2.1"
+ }
+ },
+ "es6-promise": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
+ "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "etag": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz",
+ "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE="
+ },
+ "expand-tilde": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
+ "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ },
+ "express": {
+ "version": "4.15.4",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
+ "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
+ "requires": {
+ "accepts": "1.3.3",
+ "array-flatten": "1.1.1",
+ "content-disposition": "0.5.2",
+ "content-type": "1.0.2",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.8",
+ "depd": "1.1.1",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.8.0",
+ "finalhandler": "1.0.4",
+ "fresh": "0.5.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.1",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "1.1.5",
+ "qs": "6.5.0",
+ "range-parser": "1.2.0",
+ "send": "0.15.4",
+ "serve-static": "1.12.4",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.3.1",
+ "type-is": "1.6.15",
+ "utils-merge": "1.0.0",
+ "vary": "1.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "qs": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
+ "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg=="
+ }
+ }
+ },
+ "express-flash-messages": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/express-flash-messages/-/express-flash-messages-0.1.1.tgz",
+ "integrity": "sha1-QCDOUXjDuzZjlN6QZiILwnBb1vI="
+ },
+ "express-handlebars": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz",
+ "integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=",
+ "requires": {
+ "glob": "6.0.4",
+ "graceful-fs": "4.1.11",
+ "handlebars": "4.0.10",
+ "object.assign": "4.0.4",
+ "promise": "7.3.1"
+ }
+ },
+ "express-method-override-get-post-support": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/express-method-override-get-post-support/-/express-method-override-get-post-support-0.0.7.tgz",
+ "integrity": "sha512-aHO/iYL9GV4FoRZACHkhOYfHXVljwu5LbGMOuq8++6K2JpG6437oZt64w1k3Ff6oPq1/0AtsGYnZwyivKUi67A=="
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "faker": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz",
+ "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8="
+ },
+ "finalhandler": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz",
+ "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==",
+ "requires": {
+ "debug": "2.6.8",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.1",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "requires": {
+ "path-exists": "2.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "forwarded": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
+ "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M="
+ },
+ "fresh": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
+ "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
+ },
+ "fs-exists-sync": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
+ "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "function-bind": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
+ "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E="
+ },
+ "get-caller-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U="
+ },
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "global-modules": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
+ "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=",
+ "requires": {
+ "global-prefix": "0.1.5",
+ "is-windows": "0.2.0"
+ }
+ },
+ "global-prefix": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
+ "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=",
+ "requires": {
+ "homedir-polyfill": "1.0.1",
+ "ini": "1.3.4",
+ "is-windows": "0.2.0",
+ "which": "1.3.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "handlebars": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
+ "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
+ "requires": {
+ "async": "1.5.2",
+ "optimist": "0.6.1",
+ "source-map": "0.4.4",
+ "uglify-js": "2.8.29"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "has-glob": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
+ "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
+ "requires": {
+ "is-glob": "2.0.1"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ }
+ }
+ },
+ "he": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
+ },
+ "highlight.js": {
+ "version": "9.12.0",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
+ "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4="
+ },
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "requires": {
+ "parse-passwd": "1.0.0"
+ }
+ },
+ "hooks-fixed": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.0.tgz",
+ "integrity": "sha1-oB2JTVKsf2WZu7H2PfycQR33DLo="
+ },
+ "hosted-git-info": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.3.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
+ "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ },
+ "ipaddr.js": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
+ "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA="
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "requires": {
+ "builtin-modules": "1.1.1"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+ },
+ "is-valid-glob": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz",
+ "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4="
+ },
+ "is-windows": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
+ "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "kareem": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz",
+ "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg="
+ },
+ "keygrip": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.1.tgz",
+ "integrity": "sha1-sC+kgW7vIajEs1yp5Skh/8iaMOk="
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "optional": true
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "requires": {
+ "invert-kv": "1.0.0"
+ }
+ },
+ "load-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/load-helpers/-/load-helpers-1.0.1.tgz",
+ "integrity": "sha1-ZoEbwF/PBwSO9w9lRzC0Ip5qrLM=",
+ "requires": {
+ "component-emitter": "1.2.1",
+ "extend-shallow": "2.0.1",
+ "is-glob": "3.1.0",
+ "is-valid-glob": "0.3.0",
+ "kind-of": "3.2.2",
+ "matched": "0.4.4",
+ "resolve-dir": "0.1.1",
+ "set-value": "0.4.3"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "strip-bom": "2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.4",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+ },
+ "lodash.assign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+ },
+ "matched": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
+ "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
+ "requires": {
+ "arr-union": "3.1.0",
+ "async-array-reduce": "0.2.1",
+ "extend-shallow": "2.0.1",
+ "fs-exists-sync": "0.1.0",
+ "glob": "7.1.2",
+ "has-glob": "0.1.1",
+ "is-valid-glob": "0.3.0",
+ "lazy-cache": "2.0.2",
+ "resolve-dir": "0.1.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ }
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "method-override": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.9.tgz",
+ "integrity": "sha1-vRUfLONM8Bp2ykAKuVwBKxAtj3E=",
+ "requires": {
+ "debug": "2.6.8",
+ "methods": "1.1.2",
+ "parseurl": "1.3.1",
+ "vary": "1.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ },
+ "mime-db": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz",
+ "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg="
+ },
+ "mime-types": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz",
+ "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=",
+ "requires": {
+ "mime-db": "1.29.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
+ },
+ "mongodb": {
+ "version": "2.2.30",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.30.tgz",
+ "integrity": "sha1-jM2AH2dsgXIEDC8rR+lgKg1WNKs=",
+ "requires": {
+ "es6-promise": "3.2.1",
+ "mongodb-core": "2.1.14",
+ "readable-stream": "2.2.7"
+ }
+ },
+ "mongodb-core": {
+ "version": "2.1.14",
+ "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.14.tgz",
+ "integrity": "sha1-E8uidkImtb49GJkq8Mljzl6g8P0=",
+ "requires": {
+ "bson": "1.0.4",
+ "require_optional": "1.0.1"
+ }
+ },
+ "mongoose": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.11.6.tgz",
+ "integrity": "sha512-TZQo1u8zd67ixiWFFoOhu3P7CB73XthLDX0GuGlFGR+49mi5L3I688GsMuayJo7bJhvCrMsG1d8BKJ2Lqdrsvg==",
+ "requires": {
+ "async": "2.1.4",
+ "bson": "1.0.4",
+ "hooks-fixed": "2.0.0",
+ "kareem": "1.5.0",
+ "mongodb": "2.2.30",
+ "mpath": "0.3.0",
+ "mpromise": "0.5.5",
+ "mquery": "2.3.1",
+ "ms": "2.0.0",
+ "muri": "1.2.2",
+ "regexp-clone": "0.0.1",
+ "sliced": "1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz",
+ "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=",
+ "requires": {
+ "lodash": "4.17.4"
+ }
+ }
+ }
+ },
+ "mongooseeder": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/mongooseeder/-/mongooseeder-2.0.5.tgz",
+ "integrity": "sha512-w1+g48UdomQKOukO4Kr89MikmX06qLXs8GvPVJMng1TRRbeZCEv5ZnL0cutoLvDeFfouH+xYB+qDpnqut7beFQ=="
+ },
+ "morgan": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz",
+ "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc=",
+ "requires": {
+ "basic-auth": "1.1.0",
+ "debug": "2.6.8",
+ "depd": "1.1.1",
+ "on-finished": "2.3.0",
+ "on-headers": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "morgan-toolkit": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/morgan-toolkit/-/morgan-toolkit-1.0.2.tgz",
+ "integrity": "sha512-tFhfamRSNrnGlaVfY384lFyeHZl8Y4IwSt2219+6YEuVeEJKVBlAQHT/NSAF5hlHrloI0G578zRy0Hxv4Iv10Q==",
+ "requires": {
+ "chalk": "2.1.0",
+ "cli-highlight": "1.1.4"
+ }
+ },
+ "mpath": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz",
+ "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q="
+ },
+ "mpromise": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz",
+ "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY="
+ },
+ "mquery": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.1.tgz",
+ "integrity": "sha1-mrNnSXFIAP8LtTpoHOS8TV8HyHs=",
+ "requires": {
+ "bluebird": "2.10.2",
+ "debug": "2.6.8",
+ "regexp-clone": "0.0.1",
+ "sliced": "0.0.5"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz",
+ "integrity": "sha1-AkpVFylTCIV/FPkfEQb8O1VfRGs="
+ },
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "sliced": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz",
+ "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8="
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "muri": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/muri/-/muri-1.2.2.tgz",
+ "integrity": "sha1-YxmBMmUNsIoEzHnM0A3Tia/SYxw="
+ },
+ "mz": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.6.0.tgz",
+ "integrity": "sha1-yLhSHZWN8KTydoAl22nHGe5O8c4=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "object-assign": "4.1.1",
+ "thenify-all": "1.6.0"
+ }
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "requires": {
+ "hosted-git-info": "2.5.0",
+ "is-builtin-module": "1.0.0",
+ "semver": "5.4.1",
+ "validate-npm-package-license": "3.0.1"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-keys": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
+ },
+ "object.assign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
+ "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=",
+ "requires": {
+ "define-properties": "1.1.2",
+ "function-bind": "1.1.0",
+ "object-keys": "1.0.11"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "requires": {
+ "minimist": "0.0.10",
+ "wordwrap": "0.0.3"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "requires": {
+ "lcid": "1.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "1.3.1"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
+ },
+ "parseurl": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
+ "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY="
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "requires": {
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "2.0.6"
+ }
+ },
+ "proxy-addr": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
+ "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
+ "requires": {
+ "forwarded": "0.1.0",
+ "ipaddr.js": "1.4.0"
+ }
+ },
+ "qs": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+ "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
+ "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=",
+ "requires": {
+ "bytes": "2.4.0",
+ "iconv-lite": "0.4.15",
+ "unpipe": "1.0.0"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "requires": {
+ "load-json-file": "1.1.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "1.1.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "requires": {
+ "find-up": "1.1.2",
+ "read-pkg": "1.1.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
+ "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
+ "requires": {
+ "buffer-shims": "1.0.0",
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "regexp-clone": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz",
+ "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk="
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "require_optional": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
+ "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
+ "requires": {
+ "resolve-from": "2.0.0",
+ "semver": "5.4.1"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
+ },
+ "resolve-dir": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
+ "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
+ "requires": {
+ "expand-tilde": "1.2.2",
+ "global-modules": "0.2.3"
+ }
+ },
+ "resolve-from": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+ "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "semver": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
+ },
+ "send": {
+ "version": "0.15.4",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz",
+ "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=",
+ "requires": {
+ "debug": "2.6.8",
+ "depd": "1.1.1",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.8.0",
+ "fresh": "0.5.0",
+ "http-errors": "1.6.2",
+ "mime": "1.3.4",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.12.4",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz",
+ "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=",
+ "requires": {
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.1",
+ "send": "0.15.4"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ },
+ "sliced": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
+ "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "requires": {
+ "spdx-license-ids": "1.2.2"
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "requires": {
+ "is-utf8": "0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
+ "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ },
+ "thenify": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
+ "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
+ "requires": {
+ "any-promise": "1.3.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "requires": {
+ "thenify": "3.3.0"
+ }
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "type-is": {
+ "version": "1.6.15",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+ "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.16"
+ }
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "optional": true,
+ "requires": {
+ "source-map": "0.5.6",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+ "optional": true
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "optional": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "requires": {
+ "spdx-correct": "1.0.2",
+ "spdx-expression-parse": "1.0.4"
+ }
+ },
+ "vary": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz",
+ "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc="
+ },
+ "voca": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/voca/-/voca-1.3.0.tgz",
+ "integrity": "sha1-AnUayDm/DJLiz+iOScOTyU3VCsM="
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "optional": true
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "optional": true,
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
+ "requires": {
+ "camelcase": "3.0.0",
+ "lodash.assign": "4.2.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..73763bd
--- /dev/null
+++ b/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "assignment_thoreddit",
+ "version": "1.0.0",
+ "description": "A social news web application for Viking thunder Gods",
+ "main": "app.js",
+ "dependencies": {
+ "bluebird": "^3.5.0",
+ "body-parser": "^1.17.2",
+ "cookie-session": "^1.3.0",
+ "express": "^4.15.4",
+ "express-flash-messages": "^0.1.1",
+ "express-handlebars": "^3.0.0",
+ "express-method-override-get-post-support": "0.0.7",
+ "faker": "^4.1.0",
+ "load-helpers": "^1.0.1",
+ "method-override": "^2.3.9",
+ "mongoose": "^4.11.6",
+ "mongooseeder": "^2.0.5",
+ "morgan": "^1.8.2",
+ "morgan-toolkit": "^1.0.2",
+ "voca": "^1.3.0"
+ },
+ "devDependencies": {},
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "console": "node repl",
+ "seed": "node seeds",
+ "start": "which nodemon > /dev/null && nodemon app.js || node app.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/thebopshoobop/assignment_thoreddit.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/thebopshoobop/assignment_thoreddit/issues"
+ },
+ "homepage": "https://github.com/thebopshoobop/assignment_thoreddit#readme"
+}
diff --git a/repl.js b/repl.js
new file mode 100644
index 0000000..457be81
--- /dev/null
+++ b/repl.js
@@ -0,0 +1,17 @@
+let repl = require("repl").start({});
+const mongoose = require("mongoose");
+const models = require("./models");
+
+// connect
+require("./mongo")().then(() => {
+ // Set `models` global
+ repl.context.models = models;
+
+ // model globals
+ Object.keys(models).forEach(modelName => {
+ repl.context[modelName] = mongoose.model(modelName);
+ });
+
+ // logger
+ repl.context.lg = data => console.log(data);
+});
diff --git a/routers/comments.js b/routers/comments.js
new file mode 100644
index 0000000..c381f68
--- /dev/null
+++ b/routers/comments.js
@@ -0,0 +1,44 @@
+const router = require("express").Router();
+const Comment = require("../models/Comment");
+const h = require("../helpers");
+
+// router.get("/", (req, res) => {
+// Comment.getAll()
+// .then(users => res.render("users/index", { users }))
+// .catch(e => res.status(500).send(e.stack));
+// });
+
+// router.get("/new", (req, res) => {
+// res.render("users/new");
+// });
+
+router.post("/new", (req, res) => {
+ if (!req.body.body || !req.body.userId) {
+ req.flash("alert", "You must include a comment!");
+ res.redirect("back");
+ } else {
+ Comment.new(req.body)
+ .then(comment => {
+ res.redirect("back");
+ })
+ .catch(e => res.status(500).send(e.stack));
+ }
+});
+
+router.delete("/:id", (req, res) => {
+ Comment.findByIdAndRemove(req.params.id)
+ .then(() => res.redirect("back"))
+ .catch(e => res.status(500).send(e.stack));
+});
+
+// router.get("/:id", (req, res) => {
+// User.getById(req.params.id).then(user => {
+// if (user) res.render("users/single", { user });
+// else {
+// req.flash("alert", "User not found");
+// res.redirect(h.usersPath());
+// }
+// });
+// });
+
+module.exports = router;
diff --git a/routers/posts.js b/routers/posts.js
new file mode 100644
index 0000000..3dd5383
--- /dev/null
+++ b/routers/posts.js
@@ -0,0 +1,52 @@
+const router = require("express").Router();
+const User = require("../models/User");
+const h = require("../helpers");
+const Post = require("../models/Post");
+
+router.get("/", (req, res) => {
+ Post.getAll()
+ .then(posts => {
+ res.render("posts/index", { posts });
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+router.get("/new", (req, res) => {
+ User.getAll().then(users => {
+ res.render("posts/new", { users });
+ });
+});
+
+router.post("/new", (req, res) => {
+ if (!req.body.title || !req.body.userId) {
+ req.flash("alert", "You must include a title!");
+ res.redirect(h.newPostPath());
+ } else {
+ Post.new(req.body)
+ .then(post => res.redirect(h.postPath(post._id)))
+ .catch(e => res.status(500).send(e.stack));
+ }
+});
+
+router.get("/:id", (req, res) => {
+ Post.getById(req.params.id)
+ .then(post => {
+ if (post) {
+ return User.getAll().then(users => {
+ res.render("posts/single", { post, users });
+ });
+ } else {
+ req.flash("alert", "Post not found");
+ res.redirect(h.postsPath());
+ }
+ })
+ .catch(e => res.status(500).send(e.stack));
+});
+
+router.delete("/:id", (req, res) => {
+ Post.findByIdAndRemove(req.params.id)
+ .then(() => res.redirect("back"))
+ .catch(e => res.status(500).send(e.stack));
+});
+
+module.exports = router;
diff --git a/routers/users.js b/routers/users.js
new file mode 100644
index 0000000..32a7491
--- /dev/null
+++ b/routers/users.js
@@ -0,0 +1,42 @@
+const router = require("express").Router();
+const User = require("../models/User");
+const h = require("../helpers");
+
+router.get("/", (req, res) => {
+ User.getAll()
+ .then(users => res.render("users/index", { users }))
+ .catch(e => res.status(500).send(e.stack));
+});
+
+router.get("/new", (req, res) => {
+ res.render("users/new");
+});
+
+router.post("/new", (req, res) => {
+ if (!req.body.username || !req.body.email) {
+ req.flash("alert", "You must fill out both fields!");
+ res.redirect(h.newUserPath());
+ } else {
+ User.new(req.body)
+ .then(user => res.redirect(h.userPath(user._id)))
+ .catch(e => res.status(500).send(e.stack));
+ }
+});
+
+router.get("/:id", (req, res) => {
+ User.getById(req.params.id).then(user => {
+ if (user) res.render("users/single", { user });
+ else {
+ req.flash("alert", "User not found");
+ res.redirect(h.usersPath());
+ }
+ });
+});
+
+router.delete("/:id", (req, res) => {
+ User.findByIdAndRemove(req.params.id)
+ .then(() => res.redirect("back"))
+ .catch(e => res.status(500).send(e.stack));
+});
+
+module.exports = router;
diff --git a/seeds/index.js b/seeds/index.js
new file mode 100644
index 0000000..dcdd8db
--- /dev/null
+++ b/seeds/index.js
@@ -0,0 +1,57 @@
+const models = require("../models");
+const faker = require("faker");
+const voca = require("voca");
+const mongoseeder = require("mongooseeder");
+
+let { Comment, User, Post } = models;
+
+function seeds() {
+ let users = [];
+ for (let i = 0; i < 10; i++) {
+ let user = new User({
+ username: faker.random.words(2).split(" ").join(""),
+ email: faker.internet.email()
+ });
+ users.push(user);
+ }
+
+ let posts = [];
+ for (let i = 0; i < 20; i++) {
+ let post = new Post({
+ title: voca.titleCase(faker.random.words(6)),
+ body: faker.random.words(100),
+ user: users[i % 10],
+ score: faker.random.number({ min: -100, max: 100 })
+ });
+ users[i % 10].posts.push(post);
+ posts.push(post);
+ }
+
+ let comments = [];
+ for (let i = 0; i < 200; i++) {
+ let comment = new Comment({
+ body: faker.random.words(50),
+ user: users[i % 10],
+ post: posts[i % 20]
+ });
+ users[i % 10].comments.push(comment);
+ posts[i % 20].comments.push(comment);
+ comments.push(comment);
+ }
+
+ let promises = [];
+ [posts, users, comments].forEach(collection => {
+ collection.forEach(model => {
+ promises.push(model.save());
+ });
+ });
+ return Promise.all(promises);
+}
+
+mongoseeder.seed({
+ mongodbUrl: require("../config/mongoUrl"),
+ models: models,
+ clean: true,
+ mongoose: require("mongoose"),
+ seeds: seeds
+});
diff --git a/views/layouts/application.handlebars b/views/layouts/application.handlebars
new file mode 100644
index 0000000..678ee1b
--- /dev/null
+++ b/views/layouts/application.handlebars
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+ Thoreddit{{#if title }} | {{ title }} {{/if }}
+
+
+
+
+
+
+
+
+ {{> shared/_nav }}
+
+ {{> shared/_flash }} {{{ body }}}
+
+
+
+
diff --git a/views/posts/index.handlebars b/views/posts/index.handlebars
new file mode 100644
index 0000000..b2f437e
--- /dev/null
+++ b/views/posts/index.handlebars
@@ -0,0 +1,40 @@
+
+
+
+{{#if posts.length }}
+
+{{else }}
+No posts
+{{/if }}
diff --git a/views/posts/new.handlebars b/views/posts/new.handlebars
new file mode 100644
index 0000000..6af3d25
--- /dev/null
+++ b/views/posts/new.handlebars
@@ -0,0 +1,24 @@
+
+
+
diff --git a/views/posts/single.handlebars b/views/posts/single.handlebars
new file mode 100644
index 0000000..5fbc82e
--- /dev/null
+++ b/views/posts/single.handlebars
@@ -0,0 +1,55 @@
+{{#if post.title }}
+
+
+Add a comment:
+
+
+
+ Comments
+
+
+ Created |
+ User |
+ Comment |
+ |
+
+
+
+ {{#each post.comments as |comment|}}
+
+ {{ comment.createdAt }} |
+ {{ comment.user.username }} |
+ {{ comment.body }} |
+
+
+ |
+
+ {{/each}}
+
+
+
+
+{{else }}
+Post does not exist
+{{/if }}
diff --git a/views/shared/_flash.handlebars b/views/shared/_flash.handlebars
new file mode 100644
index 0000000..e814a82
--- /dev/null
+++ b/views/shared/_flash.handlebars
@@ -0,0 +1,11 @@
+
+
+ {{#each getMessages as |messages key| }} {{#each messages as |message| }}
+
+ {{ message }}
+
+ {{/each }} {{/each }}
+
+
diff --git a/views/shared/_nav.handlebars b/views/shared/_nav.handlebars
new file mode 100644
index 0000000..4f9e6e6
--- /dev/null
+++ b/views/shared/_nav.handlebars
@@ -0,0 +1,31 @@
+
diff --git a/views/users/index.handlebars b/views/users/index.handlebars
new file mode 100644
index 0000000..08c6be4
--- /dev/null
+++ b/views/users/index.handlebars
@@ -0,0 +1,36 @@
+
+
+
+{{#if users.length }}
+
+
+
+ Created |
+ Username |
+ Email |
+ Comments |
+ Posts |
+ |
+
+
+
+ {{#each users as |user| }}
+
+ {{ user.createdAt }} |
+ {{ user.username }} |
+ {{ user.email }} |
+ {{ user.comments.length }} |
+ {{ user.posts.length }} |
+
+
+ |
+
+ {{/each }}
+
+
+{{else }}
+No users
+{{/if }}
diff --git a/views/users/new.handlebars b/views/users/new.handlebars
new file mode 100644
index 0000000..dab6840
--- /dev/null
+++ b/views/users/new.handlebars
@@ -0,0 +1,17 @@
+
+
+
diff --git a/views/users/single.handlebars b/views/users/single.handlebars
new file mode 100644
index 0000000..ac93ea2
--- /dev/null
+++ b/views/users/single.handlebars
@@ -0,0 +1,62 @@
+{{#if user.username }}
+
+
+
+
+
+ Posts
+
+
+ Created |
+ Title |
+ Comments |
+ |
+
+
+
+ {{#each user.posts as |post|}}
+
+ {{ post.createdAt }} |
+ {{ post.title }} |
+ {{ post.comments.length }} |
+
+
+ |
+
+ {{/each}}
+
+
+
+
+
+
+ Comments
+
+
+ Created |
+ Text |
+ |
+
+
+
+ {{#each user.comments as |comment|}}
+
+ {{ comment.createdAt }} |
+ {{ comment.summary }} |
+
+
+ |
+
+ {{/each}}
+
+
+
+
+
+
+{{else }}
+User does not exist
+{{/if }}